diff --git a/MAKE.bat b/MAKE.bat index 8b5bdf1..7ee4b8c 100644 --- a/MAKE.bat +++ b/MAKE.bat @@ -357,6 +357,7 @@ rem del ??-*.* > nul 2> nul rd /q /s _devel > nul 2> nul rd /q /s _release > nul 2> nul rd /q /s _fwk > nul 2> nul + rd /q /s _cache > nul 2> nul rem rd /q /s _project > nul 2> nul del tcc.bat > nul 2> nul del sh.bat > nul 2> nul @@ -602,8 +603,32 @@ if not "!other!"=="" ( rem framework if "!v4k!"=="yes" ( -if "!vis!"=="yes" echo !cc! engine\v4k.c !export! !args! ^&^& if "!dll!"=="dll" copy /y v4k.dll engine\bind ^> nul -!echo! v4k && !cc! engine\v4k.c !export! !args! && if "!dll!"=="dll" copy /y v4k.dll engine\bind > nul || set rc=1 + tools\file2hash engine\v4k.c engine\v4k.h engine\v4k. engine\joint\v4k.h -- !build! !import! !export! !args! !dll! > nul + set cache=_cache\.!errorlevel! + md _cache 2>nul >nul + + rem cache for `make rel` cl:48s->25s, tcc:3.3s->1.8s + if exist !cache!.o copy /y !cache!.o v4k.o 2>nul >nul + if exist !cache!.obj copy /y !cache!.obj v4k.obj 2>nul >nul + if exist !cache!.lib copy /y !cache!.lib v4k.lib 2>nul >nul + if exist !cache!.dll copy /y !cache!.dll v4k.dll 2>nul >nul + if exist !cache!.def copy /y !cache!.def v4k.def 2>nul >nul + if exist !cache!.pdb copy /y !cache!.pdb v4k.pdb 2>nul >nul + + if not exist "!cache!" ( + !echo! v4k && !cc! engine\v4k.c !export! !args! && if "!dll!"=="dll" copy /y v4k.dll engine\bind\lua > nul || set rc=1 + echo. > !cache! + if exist v4k.o copy /y v4k.o !cache!.o 2>nul >nul + if exist v4k.obj copy /y v4k.obj !cache!.obj 2>nul >nul + if exist v4k.lib copy /y v4k.lib !cache!.lib 2>nul >nul + if exist v4k.dll copy /y v4k.dll !cache!.dll 2>nul >nul + if exist v4k.def copy /y v4k.def !cache!.def 2>nul >nul + if exist v4k.pdb copy /y v4k.pdb !cache!.pdb 2>nul >nul + ) else ( + rem cached. do not compile... + echo v4k.c ^(cached^) + if "!dll!"=="dll" copy /y !cache!.dll engine\bind\v4k.dll > nul || set rc=1 + ) ) rem editor @@ -632,7 +657,6 @@ for %%f in ("workbench\plugins\*.c") do ( rem demos if "!demos!"=="yes" ( -!echo! 00-demo && !cc! !o! 00-demo.exe demos\00-demo.c !import! !args! || set rc=1 !echo! 00-ui && !cc! !o! 00-ui.exe demos\00-ui.c !import! !args! || set rc=1 !echo! 01-sprite && !cc! !o! 01-sprite.exe demos\01-sprite.c !import! !args! || set rc=1 !echo! 02-ddraw && !cc! !o! 02-ddraw.exe demos\02-ddraw.c !import! !args! || set rc=1 diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..a8e2d89 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,146 @@ +[d93c8fe](https://dev.v4.games/v4games/v4k/commit/d93c8febbef956207e73483a82bd813da41a3a7b): fix html5 build + add a new HTML5 demo (**Dominik Madarász**) +[2d56c30](https://dev.v4.games/v4games/v4k/commit/2d56c302b85ccf4f86ed676c90054726e69babb2): dont delete .art[00].zip (**Dominik Madarász**) +[d029777](https://dev.v4.games/v4games/v4k/commit/d029777c9db9ec29eba3aa78bd3dfdcee0b17eb4): sync with fwk (**Dominik Madarász**) +[a486908](https://dev.v4.games/v4games/v4k/commit/a4869085a4207ab0f615f736c1600426d034bfee): window: improve transparency pass (r-lyeh) (**Dominik Madarász**) +[a8c4b18](https://dev.v4.games/v4games/v4k/commit/a8c4b1816f179797b0e989c7c9f2a25a7471599a): html5: replace viewport_color3 call (**Dominik Madarász**) +[e437dca](https://dev.v4.games/v4games/v4k/commit/e437dcabe2a1c81ce725905ff37b12b01d225009): sync to FWK (**Dominik Madarász**) +[4cd8f82](https://dev.v4.games/v4games/v4k/commit/4cd8f820def83e275619082ed31caac2e2b9183e): render: optimise lighting (**Dominik Madarász**) +[9731ca6](https://dev.v4.games/v4games/v4k/commit/9731ca611cb83d40d9615ef1ab035c521754cf48): render: finalize phong shader (**Dominik Madarász**) +[fff4880](https://dev.v4.games/v4games/v4k/commit/fff4880c4f7d3dcbe1e9e1360eb2cfa4a1adba4d): render: finish up phong shading (**Dominik Madarász**) +[b44fd79](https://dev.v4.games/v4games/v4k/commit/b44fd791a6af3852d14e49239b9e81b5e3f09065): render: fx_end() no longer takes fb handle (**Dominik Madarász**) +[0beb264](https://dev.v4.games/v4games/v4k/commit/0beb264e2b9778b0fe43bdfe92359726a229cf19): scene: WIP lighting pass (**Dominik Madarász**) +[8129920](https://dev.v4.games/v4games/v4k/commit/8129920be21094342d6ae84007ab6862b709c483): window: transparent windows (r-lyeh) (**Dominik Madarász**) +[1b294f1](https://dev.v4.games/v4games/v4k/commit/1b294f1a27fb87ab77094eb074d89c7cc3ebd7c9): rimlight control (**Dominik Madarász**) +[70678e6](https://dev.v4.games/v4games/v4k/commit/70678e6ee1a9afa9f38f5c67950a2cea51a44a15): render: shader() now takes GLSL defines (**Dominik Madarász**) +[aeffb03](https://dev.v4.games/v4games/v4k/commit/aeffb03aad81693b0d967ed9b849b3375931c134): fix up docs (**Dominik Madarász**) +[9408093](https://dev.v4.games/v4games/v4k/commit/9408093b0e3627e2d15d74fec6b6ed8900f00f21): net: use InternetReadFile() on win32 tcc (r-lyeh) (**Dominik Madarász**) +[20796c3](https://dev.v4.games/v4games/v4k/commit/20796c35fa25c9492d4fe3ef2e5f14537cbe0657): dll based wb plugins (**Dominik Madarász**) +[e4269db](https://dev.v4.games/v4games/v4k/commit/e4269dbc0d98b49619d5a91cd2d10795482eb202): and again (**Dominik Madarász**) +[1dea3ea](https://dev.v4.games/v4games/v4k/commit/1dea3eac158a5bc980bae01ce6bf74158a35b445): fix readme authors (**Dominik Madarász**) +[67527c7](https://dev.v4.games/v4games/v4k/commit/67527c770d3cd3b972007737358cac62b84aa044): net: fix IPV6_V6ONLY being 0, should be 27 on win32 (**Dominik Madarász**) +[b7a6543](https://dev.v4.games/v4games/v4k/commit/b7a6543c0785e4bc0d4896dbcfb3e991f486665b): wip asset reload (**Dominik Madarász**) +[5f6fbab](https://dev.v4.games/v4games/v4k/commit/5f6fbab4dee55d0f203afab3e5984de020e3860d): system: add app_spawn (**Dominik Madarász**) +[2ec6999](https://dev.v4.games/v4games/v4k/commit/2ec699948c803575108efef175bbe85ca3a8ecf2): workbench: initial impl wip render: supporting changes ui: new methods (**Dominik Madarász**) +[5451fa6](https://dev.v4.games/v4games/v4k/commit/5451fa6e9d5a973ebb042a58d4bc4e1683121d22): art: new system fonts video: support VIDEO_LOOP html5: drop JS worker (**Dominik Madarász**) +[9724d06](https://dev.v4.games/v4games/v4k/commit/9724d064cf19126c9308e97423baa5e9392366fa): html5: add worker js back (**Dominik Madarász**) +[ad9d3e8](https://dev.v4.games/v4games/v4k/commit/ad9d3e8eee2c2510bfed4e3d2de8bb260352f2a1): bt: introduced a new behavior tree module html5: drop the use of JS worker and provide host.py to serve test build instead demo: use pathfinding in 99-pathfind (**Dominik Madarász**) +[43ca1c8](https://dev.v4.games/v4games/v4k/commit/43ca1c86bd1b799be3d42df6304a445a0c95af2c): demo: use pathfind_astar for player movement (**Dominik Madarász**) +[b437da6](https://dev.v4.games/v4games/v4k/commit/b437da684121d8029336d6b872882d74f848d780): add tiny_impdef (**Dominik Madarász**) +[7a89e8b](https://dev.v4.games/v4games/v4k/commit/7a89e8b6ca8594a2dffb93fab352317aac1c9753): delete info.obj on `make docs` (**Dominik Madarász**) +[08b9fd0](https://dev.v4.games/v4games/v4k/commit/08b9fd045746c9c4e3827eee35b6ad1cee0fc20f): update help screen (**Dominik Madarász**) +[0275294](https://dev.v4.games/v4games/v4k/commit/0275294472c682b05a2e4260a16f2d05f50120b1): add runtime args (**Dominik Madarász**) +[95cb58a](https://dev.v4.games/v4games/v4k/commit/95cb58aaff55b16470f84bb8801cf17df950d9a3): add run command (**Dominik Madarász**) +[c75cff8](https://dev.v4.games/v4games/v4k/commit/c75cff8b0f7d539b2b2509d7c78f905bb76c024d): new motto (**Dominik Madarász**) +[07b002d](https://dev.v4.games/v4games/v4k/commit/07b002d5365d76967ad1d64b11e3f438fb7cc9e7): render: fix skybox_mie_calc_sh cast (**Dominik Madarász**) +[b47c47d](https://dev.v4.games/v4games/v4k/commit/b47c47df5461f69480432c8ee856e811dbcd620b): render: improve skybox_mie_calc_sh and add sky_intensity (**Dominik Madarász**) +[5747b95](https://dev.v4.games/v4games/v4k/commit/5747b95739b89b396ee3ee736759a0dc4941959d): adjust make.bat (**Dominik Madarász**) +[1546a56](https://dev.v4.games/v4games/v4k/commit/1546a56a4aab7e3498af10575482907aee38028c): sponza demo slower cycle (**Dominik Madarász**) +[53b63df](https://dev.v4.games/v4games/v4k/commit/53b63dff586d6178bd7ed8051f704f8280766553): update sponza demo with day/night cycle (**Dominik Madarász**) +[aa66b03](https://dev.v4.games/v4games/v4k/commit/aa66b03929791687f058912d1c806b00beb28199): render: expose all params in mie sky shader (**Dominik Madarász**) +[2e643e6](https://dev.v4.games/v4games/v4k/commit/2e643e69c3715f8366073a80c0c5aeb1a004b712): improve fwk and back cmds (**Dominik Madarász**) +[5841bfb](https://dev.v4.games/v4games/v4k/commit/5841bfbff25a671316b3dd7db522674d50968aed): fwk: sync up (**Dominik Madarász**) +[afd2399](https://dev.v4.games/v4games/v4k/commit/afd2399ec0ed40b8b6198cd13816be59d64cf682): fwk: sync + window: em fix resize + support fixed resize (**Dominik Madarász**) +[a20b0b7](https://dev.v4.games/v4games/v4k/commit/a20b0b73adc6495c36a3fdff972fcd2c3043ae38): mie skybox no longer uses non-standard uniform default value (**Dominik Madarász**) +[959f988](https://dev.v4.games/v4games/v4k/commit/959f988836b8a408f5455f70e4d66db8e7fca989): render: fix skybox_mie_calc_sh sampling cubemap upside down render: skybox_mie_calc_sh match res to 1024 (**Dominik Madarász**) +[2a7b177](https://dev.v4.games/v4games/v4k/commit/2a7b177fd8ee4c2b774b4893c5b4896b2f801b48): small tweaks (**Dominik Madarász**) +[031dbe0](https://dev.v4.games/v4games/v4k/commit/031dbe05dfee2edad61f7e13ecdb321109a1f5b1): temp: revert demo url (**Dominik Madarász**) +[b31edaf](https://dev.v4.games/v4games/v4k/commit/b31edaf5c01d82bba5405a79627939f22b789c89): update docs (**Dominik Madarász**) +[495f997](https://dev.v4.games/v4games/v4k/commit/495f9972e5c5a4ab5b8150121e98c25e4b5b4da1): render: api adjustments (**Dominik Madarász**) +[b8422c6](https://dev.v4.games/v4games/v4k/commit/b8422c6eb94832f60cc7bb1258af246b91b6fa3e): render: rework engine shaders to be loaded from disk (**Dominik Madarász**) +[358522e](https://dev.v4.games/v4games/v4k/commit/358522ea22b49e45c115d487140f3f5b51f5595a): wip: shadowmap (**Dominik Madarász**) +[687993e](https://dev.v4.games/v4games/v4k/commit/687993ef40153213e41efb0c9a77da103d11db1c): code cleanup (**Dominik Madarász**) +[47e0d6c](https://dev.v4.games/v4games/v4k/commit/47e0d6c9698b61a0b924ee0141f9b22ad9beb12f): small render fixes (**Dominik Madarász**) +[2d6ed97](https://dev.v4.games/v4games/v4k/commit/2d6ed9740d38aece3fa055c9519d170b9a019f83): render: add skybox_mie_calc_sh (**Dominik Madarász**) +[d6d0294](https://dev.v4.games/v4games/v4k/commit/d6d0294ae57d1ecb133c4c8f552316250166f45a): demo: temp F8 to switch backend (**Dominik Madarász**) +[dc2555a](https://dev.v4.games/v4games/v4k/commit/dc2555af5833cf6f400ff75953c8d7739d45cb6e): demo: cook on demand (**Dominik Madarász**) +[bc5727e](https://dev.v4.games/v4games/v4k/commit/bc5727eb20786474f32fa1c0644c74ec7ced4a7f): demo: temperature sim (**Dominik Madarász**) +[27805e2](https://dev.v4.games/v4games/v4k/commit/27805e26545e6d0689e648123688f568c963d87d): improve docs about page (**Dominik Madarász**) +[bda4cbb](https://dev.v4.games/v4games/v4k/commit/bda4cbb857fb34dab6209bffffa4a6d9a8305a5c): rpc: improve msg ctor (**Dominik Madarász**) +[d848c6a](https://dev.v4.games/v4games/v4k/commit/d848c6a06a5673e1ececd1df2ae4fed81bbbcb39): rpc: fix RPC_SIGNATURE_v_s case (**Dominik Madarász**) +[3ed96fc](https://dev.v4.games/v4games/v4k/commit/3ed96fc62a741167fa449352d318a2e5e0f03bbb): netsync: improve event ctor (**Dominik Madarász**) +[9fa0c9f](https://dev.v4.games/v4games/v4k/commit/9fa0c9f1ba89ab36cd2a40be18cc1b9a575c4cf7): we go public now! (**Dominik Madarász**) +[d83377e](https://dev.v4.games/v4games/v4k/commit/d83377e86c9b808699f1427a62e05563359e1cab): docs: add commit url to commits (**Dominik Madarász**) +[1062874](https://dev.v4.games/v4games/v4k/commit/1062874d2701d9a05f22de7843e7c48670ef98f0): ignore v4k.html from now on (**Dominik Madarász**) +[5f99b67](https://dev.v4.games/v4games/v4k/commit/5f99b6777855e09c3ac553997898e4d522e21494): sync up with FWK (**Dominik Madarász**) +[208a5d8](https://dev.v4.games/v4games/v4k/commit/208a5d877291a79e7647939e0de6ccf936340c68): add changelog to docs (**Dominik Madarász**) +[fb3e0c5](https://dev.v4.games/v4games/v4k/commit/fb3e0c55e8e50243aee68b1aee215b3ed0090922): readme stuff (**Dominik Madarász**) +[0440bfd](https://dev.v4.games/v4games/v4k/commit/0440bfd3ccc5c09be70b7dca56ae4f492ed374f6): ugly but works html5 cook (**Dominik Madarász**) +[64ee470](https://dev.v4.games/v4games/v4k/commit/64ee470bc462f57f2d8bef79c473b614061df784): fix html5 build (**Dominik Madarász**) +[f77e031](https://dev.v4.games/v4games/v4k/commit/f77e03123ba4730755c98b8c63f5a352282116ca): update docs (**Dominik Madarász**) +[4bd94d7](https://dev.v4.games/v4games/v4k/commit/4bd94d78242fd2fc8bdb893d2442229b1758f5a3): add vps command to update v4k.dev site (**Dominik Madarász**) +[aea5470](https://dev.v4.games/v4games/v4k/commit/aea5470ca6a9adf471a21c8a8971fce5c3974b11): update readme (**Dominik Madarász**) +[d1204ac](https://dev.v4.games/v4games/v4k/commit/d1204acadaa0ff398dcb6c4623caeb6c7210526b): mesh_render_prim addition (**Dominik Madarász**) +[cf45869](https://dev.v4.games/v4games/v4k/commit/cf45869d14a1fbec8fc2cde288a7f6e3bebb53a5): geom shader support (**Dominik Madarász**) +[5af4968](https://dev.v4.games/v4games/v4k/commit/5af4968eed87a1cbbaa9c121422265475d8eeed5): ssbo impl (**Dominik Madarász**) +[34c58f0](https://dev.v4.games/v4games/v4k/commit/34c58f04a9d602785b18b301fbe4b9ed5ce9fef9): improve shaders (**Dominik Madarász**) +[51320bf](https://dev.v4.games/v4games/v4k/commit/51320bfab11853b3bba51da83bb350a6adb8402c): compute shaders! (**Dominik Madarász**) +[1d7e68f](https://dev.v4.games/v4games/v4k/commit/1d7e68f18c6ebc28611585ca44ec953c365d9b6d): anims_t drop M (**Dominik Madarász**) +[3a70df5](https://dev.v4.games/v4games/v4k/commit/3a70df594b5786d238cd83f8ad320a1b90d28c46): update cooker (**Dominik Madarász**) +[380732c](https://dev.v4.games/v4games/v4k/commit/380732c4ada0e0143560679930c3871c885481d7): animlist support (**Dominik Madarász**) +[99d6884](https://dev.v4.games/v4games/v4k/commit/99d688498434dc6897543af3071eadf96a9be1ce): netsync improv (**Dominik Madarász**) +[3e1e170](https://dev.v4.games/v4games/v4k/commit/3e1e170e1645d28ceadef7078198205a0be7c36b): use va() for events (**Dominik Madarász**) +[36c7a81](https://dev.v4.games/v4games/v4k/commit/36c7a8188465049c45b36dca4df18a68f91371f2): stuff (**Dominik Madarász**) +[86e129e](https://dev.v4.games/v4games/v4k/commit/86e129e210fa0fc0eae1edacde316298ca3e0ba9): add NETWORK_BUF_CLEAR_ON_JOIN option (**Dominik Madarász**) +[1928f0a](https://dev.v4.games/v4games/v4k/commit/1928f0a531888c16f36a114230f243f924f1b5d3): reuse IDs on reconnect (**Dominik Madarász**) +[917a636](https://dev.v4.games/v4games/v4k/commit/917a63625b06330b69f960ad21b0399606d88f10): improve (**Dominik Madarász**) +[849b7cf](https://dev.v4.games/v4games/v4k/commit/849b7cfef7d7ac5f7d74b0d5373c5f527bccaf39): allow for polling methods to return events (**Dominik Madarász**) +[27b580d](https://dev.v4.games/v4games/v4k/commit/27b580dbd20b42e99f03c815b7bb37e635b077d6): refactor netsync polling (**Dominik Madarász**) +[4969ab4](https://dev.v4.games/v4games/v4k/commit/4969ab42d91abf291ac43c2d4873bd970beacbf5): rpc support (**Dominik Madarász**) +[d5496d4](https://dev.v4.games/v4games/v4k/commit/d5496d4ddbd2e772f9a741af84b605f037e9036d): add network event handling (**Dominik Madarász**) +[4bc37fc](https://dev.v4.games/v4games/v4k/commit/4bc37fc6be085446d09eac2c172b47f3d406e5cf): changes (**Dominik Madarász**) +[4391fa7](https://dev.v4.games/v4games/v4k/commit/4391fa7b33179fbbceffd04581035c4d373ff596): netsync improvements (**Dominik Madarász**) +[37db0c0](https://dev.v4.games/v4games/v4k/commit/37db0c09fe525b90adb2f6b0581de2d758f6ba33): improve shaders (**Dominik Madarász**) +[178320f](https://dev.v4.games/v4games/v4k/commit/178320f636a48ff757ce7763cd5e85f103f2fcd7): rsdf (**Dominik Madarász**) +[ec6e6c0](https://dev.v4.games/v4games/v4k/commit/ec6e6c0e953507d8ab2b4054f15cb907186f8a5f): oom (**Dominik Madarász**) +[6f196a9](https://dev.v4.games/v4games/v4k/commit/6f196a9fb6f505d2b2169c93692585e7bb340d9d): make git now runs make prep (**Dominik Madarász**) +[9fa2bf5](https://dev.v4.games/v4games/v4k/commit/9fa2bf5e6fb895c183560f48737df5b2ea921942): update deps (**Dominik Madarász**) +[5264e11](https://dev.v4.games/v4games/v4k/commit/5264e113c312dae0e4b31fbd6391c5062e9f8ac5): new ver (**Dominik Madarász**) +[eea0b62](https://dev.v4.games/v4games/v4k/commit/eea0b62112fc0d450c924f460473544f79255442): rebrand (**Dominik Madarász**) +[bf8d7ae](https://dev.v4.games/v4games/v4k/commit/bf8d7aecfd53a3b913861ca7715b104c907e5b93): oompsie (**Dominik Madarász**) +[5908765](https://dev.v4.games/v4games/v4k/commit/59087657b3eff653abe3f887ca99c3ac15ae1bac): dont do tools (**Dominik Madarász**) +[6e90950](https://dev.v4.games/v4games/v4k/commit/6e9095097e319ba03391bafff03b9e9ec5028fbe): fixes (**Dominik Madarász**) +[aa850b9](https://dev.v4.games/v4games/v4k/commit/aa850b906f60f92ef7a9fd62beffa173e251ac45): improve fwk/back (**Dominik Madarász**) +[24775d1](https://dev.v4.games/v4games/v4k/commit/24775d1c825be80cfbb53f1ba0a10611275b33ba): drop rem (**Dominik Madarász**) +[a70af46](https://dev.v4.games/v4games/v4k/commit/a70af46f954a38aa8151e155072ddeece355302b): fwkren improvements (**Dominik Madarász**) +[e4b6b8b](https://dev.v4.games/v4games/v4k/commit/e4b6b8ba1f55496d14836622c25c0b80180acc66): add fwkren as a replacement for powershell exec (**Dominik Madarász**) +[8b6f07e](https://dev.v4.games/v4games/v4k/commit/8b6f07e5c5b30f74b929fe09767b8c41f74268be): ass2iqe: animlist support + sample anim file (**Dominik Madarász**) +[fb2f7ee](https://dev.v4.games/v4games/v4k/commit/fb2f7ee532bcfecc056c5d8754ca378816441f67): update demo (**Dominik Madarász**) +[1a1683a](https://dev.v4.games/v4games/v4k/commit/1a1683aa29d8a7a64ca1d4672c15038f4feeb95b): upstream files (**Dominik Madarász**) +[cb37e1e](https://dev.v4.games/v4games/v4k/commit/cb37e1e9f4abe69ae53f41b6fa0d34e4229f4dd5): upstream changes (**Dominik Madarász**) +[69b7782](https://dev.v4.games/v4games/v4k/commit/69b7782b2ed97b5bce40176e35b9acc2f3745185): 0 (**Dominik Madarász**) +[458f0e6](https://dev.v4.games/v4games/v4k/commit/458f0e6bd41270bf4e14751e201cf3575327fc22): update MAKE.bat (**Dominik Madarász**) +[b118b99](https://dev.v4.games/v4games/v4k/commit/b118b990b85f4345e45fd20082cf80b85529041b): x (**Dominik Madarász**) +[affc8a9](https://dev.v4.games/v4games/v4k/commit/affc8a9da5177346705207da0af0f9e817120a98): Merge remote-tracking branch 'fwk/main' (**Dominik Madarász**) +[7f04463](https://dev.v4.games/v4games/v4k/commit/7f04463de96f51fd62467abb6f61d2d9de8c14d2): chg: bring back project generators `MAKE proj` (premake5) chg: bring back most demos/ `MAKE demos` fix: ui: fixed crash when no cooked fonts were available (ui_notify) fix: html5: added pthreads support (@zpl-zak) fix: html5: allowed coi requests in localhost served contents (@zpl-zak) chg: html5: instantiate web server only if content is not being served chg: bring back demos/html5/ chg: bring back tools/editor/ chg: bring back some audio tunes chg: update docs (**r-lyeh**) +[355f7b5](https://dev.v4.games/v4games/v4k/commit/355f7b52cea0bda89d99a997a7ce09267cb11245): add sponza demo (**Dominik Madarász**) +[d11546a](https://dev.v4.games/v4games/v4k/commit/d11546ad726a7d9d3d0f57694e4f9c607593336c): fix FX load (**Dominik Madarász**) +[4093f97](https://dev.v4.games/v4games/v4k/commit/4093f97dec674d6fccb0bf26d6fca24001c334f9): another change (**Dominik Madarász**) +[4964c6d](https://dev.v4.games/v4games/v4k/commit/4964c6dc045c5fda145d079fbd6cb0f6d00c8fa0): all means extras too (**Dominik Madarász**) +[7f5f6e7](https://dev.v4.games/v4games/v4k/commit/7f5f6e7a5830cb78492a97a8a02dbe27a2c551ab): add more demos (**Dominik Madarász**) +[0a87150](https://dev.v4.games/v4games/v4k/commit/0a87150932821fa323223e9d125b77574dbd8725): keep comments (**Dominik Madarász**) +[82a2db5](https://dev.v4.games/v4games/v4k/commit/82a2db5301413c9436f76a4760c015f0a04e834a): keep comments (**Dominik Madarász**) +[a706369](https://dev.v4.games/v4games/v4k/commit/a70636955779db0067e7cbf35e4e3c3f7b754720): add glslcc tool (**Dominik Madarász**) +[e30c8bb](https://dev.v4.games/v4games/v4k/commit/e30c8bb1900eee8a37dba694a2bc0a305cadba39): add extras switch (**Dominik Madarász**) +[5565dcc](https://dev.v4.games/v4games/v4k/commit/5565dcc4ad48d1fa6408312c4a2e33348dcb0ba7): add some assets from FWK 2022 (**Dominik Madarász**) +[3c3c88d](https://dev.v4.games/v4games/v4k/commit/3c3c88df5fc3b8e6782f52481e08926c1b5e0c1a): update demos (**Dominik Madarász**) +[8550b12](https://dev.v4.games/v4games/v4k/commit/8550b1275731ffb3ddd3652d5ac5d53fc2113e94): Merge remote-tracking branch 'fwk/main' (**Dominik Madarász**) +[1c9f410](https://dev.v4.games/v4games/v4k/commit/1c9f410e361a2e4b5f7a93834ff041466fec91c7): add glsl join/split tools (**Dominik Madarász**) +[54aa82a](https://dev.v4.games/v4games/v4k/commit/54aa82aecfc13709cf8331e520f1712a200167cd): chg: bring back project generators `MAKE proj` (premake5) chg: bring back most demos/ `MAKE demos` fix: ui: fixed crash when no cooked fonts were available (ui_notify) fix: html5: added pthreads support (@zpl-zak) fix: html5: allowed coi requests in localhost served contents (@zpl-zak) chg: html5: instantiate web server only if content is not being served chg: bring back demos/html5/ chg: bring back tools/editor/ chg: bring back some audio tunes chg: update docs (**r-lyeh**) +[e5b5047](https://dev.v4.games/v4games/v4k/commit/e5b504773f4e81988f3ed0ea813f9e1b976d44c3): make web (**Dominik Madarász**) +[9e2d449](https://dev.v4.games/v4games/v4k/commit/9e2d449d926c6bd15d8a37942573444f376fc2ba): lua stuff (**Dominik Madarász**) +[654bf9f](https://dev.v4.games/v4games/v4k/commit/654bf9ff5bd03518a0ecada5f65a8f238bd96d5e): improve rpc (**Dominik Madarász**) +[6fe631b](https://dev.v4.games/v4games/v4k/commit/6fe631b5d5f79e030ac0262a5fe9900445088550): Merge remote-tracking branch 'fwk/main' (**Dominik Madarász**) +[3b958eb](https://dev.v4.games/v4games/v4k/commit/3b958eb73d1640a0f4bb2e526715d21c0fc57ab0): dont complain about missing dir (**Dominik Madarász**) +[d5979e1](https://dev.v4.games/v4games/v4k/commit/d5979e16dd60f8eb5ac3a5c0f964c28f0dccdea0): add fwk command to prep fwk PRs (**Dominik Madarász**) +[1fa7710](https://dev.v4.games/v4games/v4k/commit/1fa7710d349b62b007b56be792bb072f5c0bae67): fix: html5: added pthreads support (@zpl-zak) fix: html5: allowed coi requests in localhost served contents (@zpl-zak) fix: html5: instantiate web server only if content is not being served chg: bring back demos/html5/ chg: bring back tools/editor/ chg: bring back some audio tunes chg: update docs (**r-lyeh**) +[8fc280e](https://dev.v4.games/v4games/v4k/commit/8fc280e6ff13a5e3f437f99ff45c84e61e38d2ca): update docs (**Dominik Madarász**) +[5cb2c38](https://dev.v4.games/v4games/v4k/commit/5cb2c38b253ec3e2390c622ec640f2f6de1ee85b): rpc support in v4k (**Dominik Madarász**) +[ee76c55](https://dev.v4.games/v4games/v4k/commit/ee76c55b0ee7fd8f65d3a99486691e5c70a3610c): update make pull (**Dominik Madarász**) +[109a410](https://dev.v4.games/v4games/v4k/commit/109a41093a47caa43b3e7162bffdc6fcfe772fc0): rename (**Dominik Madarász**) +[9dbeb39](https://dev.v4.games/v4games/v4k/commit/9dbeb39fd3c2b955f574b4f21f369cea37a6db7c): Merge remote-tracking branch 'fwk/main' (**Dominik Madarász**) +[80effb7](https://dev.v4.games/v4games/v4k/commit/80effb7e2e4644b81b53e8e10799041637d04f0b): ensure FWK upstream is always present (**Dominik Madarász**) +[aa5f708](https://dev.v4.games/v4games/v4k/commit/aa5f7085fe26a4fc128d34f06024a40215fc5e63): add sublime-project (**Dominik Madarász**) +[01f7395](https://dev.v4.games/v4games/v4k/commit/01f7395c8215f2df936a6dab0442fe12c28af387): update ports (**Dominik Madarász**) +[5f798d0](https://dev.v4.games/v4games/v4k/commit/5f798d0d8df7d0fc2c3573fa37cfedc034c3caa4): v4k initial commit (**Dominik Madarász**) +[e2fa783](https://dev.v4.games/v4games/v4k/commit/e2fa783a689b5dcdc579bbf56c12774332ecc2c1): chg: bring back some audio tunes chg: bring back tools/editor/ chg: update docs (**r-lyeh**) +[3b67efc](https://dev.v4.games/v4games/v4k/commit/3b67efc1f56b4d7b1e35165ecc32e46adf50aa03): chg: replicate previous project tree layout fix: fixed issue when mounting empty zipfiles (likely to happen in computers with many cpu cores) (thanks @zpl-zak!) new: forked milestone in https://github.com/r-lyeh/FWK.2022 chg: update teal + gamecontrollerdb add: added tools/plugins/ stub folder brk: renamed `WITH_` > `ENABLE_` directives chg: updated docs (**r-lyeh**) \ No newline at end of file diff --git a/demos/00-demo.c b/demos/00-demo.c deleted file mode 100644 index 4605db4..0000000 --- a/demos/00-demo.c +++ /dev/null @@ -1,276 +0,0 @@ -// framework demo -// - rlyeh, public domain - -#include "v4k.h" - -int main() { - // options - bool do_about = 0; - float do_scale = 0.10f; - bool do_debugdraw = 0; - float do_gamepad_deadzone = 0.15f; - vec2 do_gamepad_polarity = vec2(+1,+1); - vec2 do_gamepad_sensitivity = vec2(0.1f,0.1f); - vec2 do_mouse_polarity = vec2(+1,-1); - vec2 do_mouse_sensitivity = vec2(0.2f,0.2f); - bool do_billboard_x = 0, do_billboard_y = 0, do_billboard_z = 0; - - // window (80% sized, MSAA x4 flag) - window_create(80, WINDOW_MSAA4); - window_title(__FILE__); - - // load all fx files - fx_load("fx**.fs"); - - // load skybox - skybox_t sky = skybox(flag("--mie") ? 0 : "cubemaps/stardust", 0); // --mie for rayleigh/mie scattering - - // load static scene - model_t sponza; - int do_sponza = flag("--sponza"); - if( do_sponza ) { - sponza = model("sponza.obj", 0); // MODEL_NO_TEXTURES); - translation44(sponza.pivot, 0,-1,0); - rotate44(sponza.pivot, -90,1,0,0); - scale44(sponza.pivot, 10,10,10); - } - - model_t shaderball; - int do_shaderball = flag("--shaderball"); - if( do_shaderball ) { - shaderball = model("shaderball.glb", 0); - translation44(shaderball.pivot, 0,0,-10); - rotate44(shaderball.pivot, -90,1,0,0); - scale44(shaderball.pivot, 0.02,0.02,0.02); - } - - // animated models loading - int model_flags = flag("--matcaps") ? MODEL_MATCAPS : 0; - model_t girl = model("kgirl/kgirls01.fbx", model_flags); - model_t alien = model("alien/alien_helmet.fbx", model_flags); rotation44(alien.pivot, -90,1,0,0); - model_t george = model("robots/george.fbx", model_flags); - model_t leela = model("robots/leela.fbx", model_flags); - model_t mike = model("robots/mike.fbx", model_flags); - model_t stan = model("robots/stan.fbx", model_flags); - model_t robots[4] = { george, leela, mike, stan }; - for( int i = 0; i < countof(robots); ++i ) { - rotation44(robots[i].pivot, -90,1,0,0); - } - - if( flag("--matcaps") ) { - // patch models to use matcaps - model_set_texture(george, texture("matcaps/3B6E10_E3F2C3_88AC2E_99CE51-256px", 0)); // green - model_set_texture(leela, texture("matcaps/39433A_65866E_86BF8B_BFF8D8-256px", 0)); - model_set_texture(mike, texture("matcaps/394641_B1A67E_75BEBE_7D7256-256px.png", 0)); - model_set_texture(stan, texture("matcaps/test_steel", 0)); - model_set_texture(girl, texture("matcaps/material3", 0)); - model_set_texture(alien, texture("matcaps/material3", 0)); - - if( flag("--shaderball") ) - model_set_texture(shaderball, texture("matcaps/normals", 0)); - } - - // camera - camera_t cam = camera(); - cam.speed = 0.2f; - - // audio (both clips & streams) - audio_t SFX1 = audio_clip( "coin.wav" ); - audio_t SFX2 = audio_clip( "pew.sfxr" ); - audio_t BGM1 = audio_stream( "waterworld-map.fur"); // wrath_of_the_djinn.xm" ); - audio_t BGM2 = audio_stream( "larry.mid" ); - audio_t BGM3 = audio_stream( "monkey1.mid" ), BGM = BGM1; - audio_play(SFX1, 0); - audio_play(BGM, 0); - - // demo loop - while (window_swap()) - { - // input - if( input_down(KEY_ESC) ) break; - if( input_down(KEY_F5) ) window_reload(); - if( input_down(KEY_W) && input_held(KEY_LCTRL) ) break; - if( input_down(KEY_F11) ) window_fullscreen( window_has_fullscreen() ^ 1 ); - if( input_down(KEY_X) ) window_screenshot(__FILE__ ".png"); - if( input_down(KEY_Z) ) window_record(__FILE__ ".mp4"); - - // vec2 filtered_lpad = input_filter_deadzone(input2(GAMEPAD_LPAD), do_gamepad_deadzone + 1e-3); - // vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), do_gamepad_deadzone + 1e-3); - - // fps camera - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( !active ); - - // apply post-fxs from here - fx_begin(); - - // queue debug drawcalls - profile("Debugdraw") { - ddraw_grid(0); - ddraw_color(YELLOW); - ddraw_text(vec3(+1,+1,-1), 0.04f, va("(%f,%f,%f)", cam.position.x,cam.position.y,cam.position.z)); - if(do_debugdraw) ddraw_demo(); // showcase many debugdraw shapes - ddraw_color(YELLOW); - ddraw_flush(); - } - - // draw skybox - profile("Skybox") { - skybox_render(&sky, cam.proj, cam.view); - } - - profile("Skeletal update") if(!window_has_pause()) { - float delta = window_delta() * 30; // 30fps anim - - // animate girl & alien - girl.curframe = model_animate(girl, girl.curframe + delta); - alien.curframe = model_animate(alien, alien.curframe + delta); - - // animate robots - for(int i = 0; i < countof(robots); ++i) { - robots[i].curframe = model_animate(robots[i], robots[i].curframe + delta); - } - } - - profile("Skeletal render") { - static vec3 p = {-10,0,-10}, r = {0,0,0}, s = {2,2,2}; - gizmo(&p, &r, &s); - mat44 M; rotationq44(M, eulerq(r)); scale44(M, s.x,s.y,s.z); relocate44(M, p.x,p.y,p.z); - - model_render(girl, cam.proj, cam.view, M, 0); - - aabb box = model_aabb(girl, M); - ddraw_color(YELLOW); - ddraw_aabb(box.min, box.max); - } - - profile("Skeletal render") { - static vec3 p = {+10,0,-10}, r = {0,-90,0}, s = {1,1,1}; - //gizmo(&p, &r, &s); - mat44 M; rotationq44(M, eulerq(r)); scale44(M, s.x,s.y,s.z); relocate44(M, p.x,p.y,p.z); - - model_render(alien, cam.proj, cam.view, M, 0); - - aabb box = model_aabb(alien, M); // @fixme: neg Y - ddraw_color(YELLOW); - //ddraw_aabb(box.min, box.max); - } - - profile("Skeletal render") for(int i = 0; i < countof(robots); ++i) { - float scale = 0.50; - mat44 M; copy44(M, robots[i].pivot); translate44(M, i*3,0,0); scale44(M, scale,scale,scale); - model_render(robots[i], cam.proj, cam.view, M, 0); - } - - if(do_sponza) profile("Sponza") { - float scale = 1.00; - mat44 M; copy44(M, sponza.pivot); translate44(M, 0,0,0); scale44(M, scale,scale,scale); - model_render(sponza, cam.proj, cam.view, M, 0); - } - - if(do_shaderball) profile("Shaderball") { - float scale = 1.00; - mat44 M; copy44(M, shaderball.pivot); translate44(M, 0,0,0); scale44(M, scale,scale,scale); - model_render(shaderball, cam.proj, cam.view, M, 0); - } - - // post-fxs end here - fx_end(); - - // font demo - do_once font_scales(FONT_FACE1, 48, 24, 18, 12, 9, 6); - font_print(va(FONT_RIGHT FONT_BOTTOM FONT_H4 "%5.2f FPS", window_fps())); - - // queue ui - if( ui_panel("App", 0)) { - if(ui_bool("Show debugdraw demo", &do_debugdraw)) {} - if(ui_separator()) {} - if(ui_slider("Gamepad deadzone", &do_gamepad_deadzone)) {} - if(ui_float2("Gamepad polarity", do_gamepad_polarity.v2)) {} - if(ui_float2("Gamepad sensitivity", do_gamepad_sensitivity.v2)) {} - if(ui_separator()) {} - if(ui_float2("Mouse polarity", do_mouse_polarity.v2)) {} - if(ui_float2("Mouse sensitivity", do_mouse_sensitivity.v2)) {} - if(ui_separator()) {} - if(ui_button("About...")) { do_about = 1; audio_play(SFX1, 0); } - if(ui_dialog("About", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 0, &do_about)) {} - ui_panel_end(); - } - if( ui_panel("Camera", 0)) { - if( ui_float("Speed", &cam.speed) ) {} - if( ui_float3("Position", cam.position.v3) ) {} - ui_panel_end(); - } - if( ui_panel("FX", 0) ) { - for( int i = 0; i < 64; ++i ) { - char *name = fx_name(i); if( !name ) break; - bool b = fx_enabled(i); - if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); - } - ui_panel_end(); - } - if( ui_panel("Audio", 0)) { - static float bgm = 1, sfx = 1, master = 1; - if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); - if( ui_slider2("SFX", &sfx, va("%.2f", sfx))) audio_volume_clip(sfx); - if( ui_slider2("Master", &master, va("%.2f", master))) audio_volume_master(master); - if( ui_label2_toolbar("BGM: Waterworld Map" /*Wrath of the Djinn"*/, ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM1, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Leisure Suit Larry", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM2, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("BGM: Monkey Island", ICON_MD_VOLUME_UP)) audio_stop(BGM), audio_play(BGM = BGM3, AUDIO_SINGLE_INSTANCE); - if( ui_label2_toolbar("SFX: Coin", ICON_MD_VOLUME_UP)) audio_play(SFX1, 0); - if( ui_label2_toolbar("SFX: Pew", ICON_MD_VOLUME_UP)) audio_play(SFX2, 0); - ui_panel_end(); - } - - input_demo(); // show some keyboard/mouse/gamepad UI tabs - ui_demo(1); // show all UI widgets in a tab - } - - // data tests (json5) - const char json5[] = - " /* json5 */ // comment\n" - " abc: 42.67, def: true, integer:0x100 \n" - " huge: 2.2239333e5, \n" - " hello: 'world /*comment in string*/ //again', \n" - " children : { a: 1, b: 2, c: 3 },\n" - " array: [+1,2,-3,4,5], \n" - " invalids : [ nan, NaN, -nan, -NaN, inf, Infinity, -inf, -Infinity ],"; - if( json_push(json5) ) { - assert( json_float("/abc") == 42.67 ); - assert( json_int("/def") == 1 ); - assert( json_int("/integer") == 0x100 ); - assert( json_float("/huge") > 2.22e5 ); - assert( strlen(json_string("/hello")) == 35 ); - assert( json_int("/children/a") == 1 ); - assert( json_int("/children.b") == 2 ); - assert( json_int("/children[c]") == 3 ); - assert( json_int("/array[%d]", 2) == -3 ); - assert( json_count("/invalids") == 8 ); - assert( isnan(json_float("/invalids[0]")) ); - assert( !json_find("/non_existing") ); - assert( PRINTF("json5 tests OK\n") ); - json_pop(); - } - - // data tests (xml) - const char *xml = vfs_read("test1.xml"); - if( xml_push(xml) ) { - puts( xml ); - puts( xml_string("/person/firstName/$") ); - puts( xml_string("/person/lastName/$") ); - puts( xml_string("/person/address/@type") ); - xml_pop(); - } - - // network test (https) - array(char) webfile = download("https://www.google.com/"); - printf("Network test: %d bytes downloaded from google.com\n", array_count(webfile)); - - // script test (lua) - script_run( "-- Bye.lua\nio.write(\"script test: Bye world!, from \", _VERSION, \"\\n\")" ); -} diff --git a/demos/02-ddraw.c b/demos/02-ddraw.c index 46359d5..78cbf87 100644 --- a/demos/02-ddraw.c +++ b/demos/02-ddraw.c @@ -37,7 +37,7 @@ int main() { vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 ); vec2 mouse = scale2(vec2(filtered_rpad.x, filtered_rpad.y), 1.0f); vec3 wasdec = scale3(vec3(filtered_lpad.x, input(GAMEPAD_LT) - input(GAMEPAD_RT), filtered_lpad.y), 1.0f); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); + camera_moveby(&cam, wasdec); camera_fps(&cam, mouse.x,mouse.y); window_cursor( true ); } else { @@ -45,7 +45,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); } @@ -97,11 +97,6 @@ int main() { ui_swarm(&sw); ui_panel_end(); } - if( ui_panel("Camera", 0)) { - if( ui_float("Speed", &cam.speed) ) {} - if( ui_float3("Position", cam.position.v3) ) {} - ui_panel_end(); - } } } diff --git a/demos/02-frustum.c b/demos/02-frustum.c index 0e1988d..36eb6db 100644 --- a/demos/02-frustum.c +++ b/demos/02-frustum.c @@ -1,20 +1,5 @@ #include "v4k.h" -void ddraw_camera(camera_t *c) { - vec3 center = c->position; -// ddraw_prism(add3(center,vec3(2,0,0)), 0.5, 1, vec3(-1,0,0), 4); // center,radius,height,normal,segments -// ddraw_box(center, vec3(2,2,1)); // center,extents - - mat33 r; rotationq33(r, eulerq(vec3(-c->yaw,-c->pitch,0))); - ddraw_cube33(center, vec3(2,2,2), r); - - ddraw_circle(add3(center,vec3(+1,1,0)), vec3(0,0,1), 0.8); // pos,normal,radius - ddraw_circle(add3(center,vec3(-1,1,0)), vec3(0,0,1), 0.8); // pos,normal,radius - - mat44 projview; multiply44x2(projview, c->proj, c->view); - ddraw_frustum(projview); -} - int main() { window_create(0.75, 0); @@ -24,28 +9,25 @@ int main() { int spin = 1; while( window_swap() ) { + // controls if(input_down(KEY_SPACE)) spin^=1; + + // setup scene + cam.fov = 30; + cam.position = vec3(180,180,180); + camera_enable(&cam); + // spin 2nd camera double t = window_time(), c = cos(t), s = sin(t); if(spin) camera_teleport(&cam2, vec3(c * 100, 100, s * 100)); camera_lookat(&cam2, vec3(0,0,0)); - // fps camera - bool active = ui_active() || ui_hover() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); - if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); - vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); - vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); - camera_fps(&cam, mouse.x,mouse.y); - window_cursor( !active ); - + // render world (ground and cubes only in frustum of cam2) mat44 projview; multiply44x2(projview, cam2.proj, cam2.view); frustum f = frustum_build(projview); ddraw_ground(0); - ddraw_camera(&cam2); - int drawn = 0, total = 0; for(int z = -300; z < 300; z += 5) { for(int x = -300; x < 300; x += 5) { @@ -60,6 +42,8 @@ int main() { } } + // debug + ddraw_camera(&cam2); font_print(va(FONT_RIGHT "%d/%d cubes drawn", drawn, total)); } } diff --git a/demos/03-anims.c b/demos/03-anims.c index 65f1c9e..c3d0f6f 100644 --- a/demos/03-anims.c +++ b/demos/03-anims.c @@ -53,7 +53,7 @@ int main() { vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 ); vec2 mouse = scale2(vec2(filtered_rpad.x, filtered_rpad.y), 1.0f); vec3 wasdec = scale3(vec3(filtered_lpad.x, input(GAMEPAD_LT) - input(GAMEPAD_RT), filtered_lpad.y), 1.0f); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); + camera_moveby(&cam, wasdec); camera_fps(&cam, mouse.x,mouse.y); window_cursor( true ); } else { @@ -61,7 +61,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); } @@ -106,7 +106,20 @@ int main() { fx_end(); - if( ui_panel("Animation", 0) ) { + if ( ui_panel("Rim lighting", 0) ) { + static vec3 rimcolor = {0.2,0.2,0.2}; + static vec3 rimrange = {0.11,0.98,0.5}; + ui_color3f("Color", &rimcolor.x); + ui_clampf("Low", &rimrange.x, 0, 1); + ui_clampf("High", &rimrange.y, 0, 1); + ui_clampf("Mix", &rimrange.z, 0, 1); + // ui_vec + shader_bind(mdl.program); + shader_vec3("u_rimcolor", rimcolor); + shader_vec3("u_rimrange", rimrange); + ui_panel_end(); + } + if( ui_panel("Animation", PANEL_OPEN) ) { if( ui_bool("Show aabb", &do_showaabb) ); if( ui_bool("Show bones", &do_showbones) ); if( ui_bool("Show models", &do_showmodel) ); @@ -134,8 +147,8 @@ int main() { float progress = selected ? (mdl.curframe - anim.min) * 100.f / (anim.max - anim.min) : 0.f; const char *caption = va("%s%s%s %.2f%%", selected ? "*":"", a.anims[i].name, a.anims[i].flags & ANIM_LOOP ? " (Loop)":"", progress); int choice = ui_label2_toolbar(caption, va("%s %s %s", ICON_MD_REPLAY_CIRCLE_FILLED, a.inuse == i && a.speed <= 0 ? ICON_MD_NOT_STARTED : ICON_MD_PAUSE_CIRCLE, ICON_MD_PLAY_CIRCLE) ); - if( choice == 1 ) { // play/restart - if( mdl.curframe >= anim.max ) mdl.curframe = anim.min; // restart animation + if( choice == 1 ) { // play/pause + if( mdl.curframe >= anim.max ) mdl.curframe = anim.min; // rewind animation a.speed = 1.0f; a.inuse = i; } @@ -150,23 +163,11 @@ int main() { else a.anims[ i ].flags |= ANIM_LOOP; a.inuse = i; + mdl.curframe = anim.min; // restart anim } } ui_panel_end(); } - if ( ui_panel("Rim lighting", 0) ) { - static vec3 rimcolor = {0.2,0.2,0.2}; - static vec3 rimrange = {0.11,0.98,0.5}; - ui_color3f("Color", &rimcolor.x); - ui_clampf("Low", &rimrange.x, 0, 1); - ui_clampf("High", &rimrange.y, 0, 1); - ui_clampf("Mix", &rimrange.z, 0, 1); - // ui_vec - shader_bind(mdl.program); - shader_vec3("u_rimcolor", rimcolor); - shader_vec3("u_rimrange", rimrange); - ui_panel_end(); - } } } diff --git a/demos/04-lod.c b/demos/04-lod.c index 0804b32..99bfe91 100644 --- a/demos/04-lod.c +++ b/demos/04-lod.c @@ -203,7 +203,7 @@ int main() { vec2 filtered_rpad = input_filter_deadzone(input2(GAMEPAD_RPAD), 0.15f/*do_gamepad_deadzone*/ + 1e-3 ); vec2 mouse = scale2(vec2(filtered_rpad.x, filtered_rpad.y), 1.0f); vec3 wasdec = scale3(vec3(filtered_lpad.x, input(GAMEPAD_LT) - input(GAMEPAD_RT), filtered_lpad.y), 1.0f); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); + camera_moveby(&cam, wasdec); camera_fps(&cam, mouse.x,mouse.y); window_cursor( true ); } else { @@ -211,7 +211,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); } diff --git a/demos/05-scene.c b/demos/05-scene.c index dcfc682..9af4f2a 100644 --- a/demos/05-scene.c +++ b/demos/05-scene.c @@ -76,7 +76,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); // queue model scale bounces diff --git a/demos/06-material.c b/demos/06-material.c index d23f79c..103a9f0 100644 --- a/demos/06-material.c +++ b/demos/06-material.c @@ -67,7 +67,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouselook = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdec = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-input(KEY_C),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); + camera_moveby(&cam, wasdec); camera_fps(&cam, mouselook.x,mouselook.y); window_cursor( !active ); } diff --git a/demos/09-cubemap.c b/demos/09-cubemap.c index 50a1592..52a9040 100644 --- a/demos/09-cubemap.c +++ b/demos/09-cubemap.c @@ -48,7 +48,7 @@ int main(int argc, char** argv) { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdec = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-input(KEY_C),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdec.x,wasdec.y,wasdec.z); + camera_moveby(&cam, wasdec); camera_fps(&cam, mouse.x,mouse.y); // render diff --git a/demos/99-demo.c b/demos/99-demo.c index 8061ea0..80c9dc3 100644 --- a/demos/99-demo.c +++ b/demos/99-demo.c @@ -72,7 +72,6 @@ int main() { // camera camera_t cam = camera(); - cam.speed = 0.2f; // audio (both clips & streams) audio_t SFX1 = audio_clip( "coin.wav" ); @@ -102,7 +101,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); @@ -201,11 +200,6 @@ int main() { if(ui_dialog("About", __FILE__ "\n" __DATE__ "\n" "Public Domain.", 0, &do_about)) {} ui_panel_end(); } - if( ui_panel("Camera", 0)) { - if( ui_float("Speed", &cam.speed) ) {} - if( ui_float3("Position", cam.position.v3) ) {} - ui_panel_end(); - } if( ui_panel("Audio", 0)) { static float bgm = 1, sfx = 1, master = 1; if( ui_slider2("BGM", &bgm, va("%.2f", bgm))) audio_volume_stream(bgm); @@ -219,7 +213,6 @@ int main() { ui_panel_end(); } - input_demo(); // show some keyboard/mouse/gamepad UI tabs ui_demo(1); // show all UI widgets in a tab } diff --git a/demos/99-pathfind.c b/demos/99-pathfind.c index 5492ae4..d43803f 100644 --- a/demos/99-pathfind.c +++ b/demos/99-pathfind.c @@ -12,7 +12,7 @@ void move_players(); int main() { window_create(85, 0); // WINDOW_MSAA4); window_title(__FILE__); - window_fps_lock(60); + // window_fps_lock(60); // game loop while( window_swap() && !input(KEY_ESC) ) { diff --git a/demos/99-pbr.c b/demos/99-pbr.c index e2b1c9c..5244487 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -446,7 +446,7 @@ int main( int argc, const char *argv[] ) { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); } else { // orbit camera diff --git a/demos/99-sponza.c b/demos/99-sponza.c index d6a54dc..533e190 100644 --- a/demos/99-sponza.c +++ b/demos/99-sponza.c @@ -22,7 +22,6 @@ int main() { // camera camera_t cam = camera(); - cam.speed = 0.2f; double sky_update_until = 0.0; @@ -49,7 +48,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); diff --git a/demos/lua b/demos/lua new file mode 100644 index 0000000..b4db036 Binary files /dev/null and b/demos/lua differ diff --git a/engine/bind/lua b/engine/bind/lua new file mode 100644 index 0000000..a1db579 Binary files /dev/null and b/engine/bind/lua differ diff --git a/engine/bind/v4k.lua b/engine/bind/v4k.lua index b946a68..37b2f6d 100644 --- a/engine/bind/v4k.lua +++ b/engine/bind/v4k.lua @@ -1179,9 +1179,9 @@ ffi.cdef([[ //lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 input_diff2( int vk ); //lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 input_diff2( int vk ); //lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 input_diff2( int vk ); -//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 input_frame2( int vk, int frame ); -//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 input_frame2( int vk, int frame ); -//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 input_frame2( int vk, int frame ); +//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 input_frame2( int vk, int Nth_frame ); +//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 input_frame2( int vk, int Nth_frame ); +//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 input_frame2( int vk, int Nth_frame ); //lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 input_filter_positive2( vec2 v ); //lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 input_filter_positive2( vec2 v ); //lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 input_filter_positive2( vec2 v ); @@ -1445,11 +1445,15 @@ ffi.cdef([[ //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void ddraw_prism(vec3 center, float radius, float height, vec3 normal, int segments); //lcpp INF [0000] vec3: macro name but used as C declaration in: void ddraw_prism(vec3 center, float radius, float height, vec3 normal, int segments); //lcpp INF [0000] vec3: macro name but used as C declaration in: void ddraw_prism(vec3 center, float radius, float height, vec3 normal, int segments); -//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 position, up, look; -//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 last_look, last_move; +//lcpp INF [0000] vec3: macro name but used as C declaration in:vec3 position, updir, lookdir; +//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 last_look; vec3 last_move; +//lcpp INF [0000] vec3: macro name but used as C declaration in:vec2 last_look; vec3 last_move; //lcpp INF [0000] vec3: macro name but used as C declaration in:API void camera_teleport(camera_t *cam, vec3 pos); //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void camera_teleport(camera_t *cam, vec3 pos); //lcpp INF [0000] vec3: macro name but used as C declaration in: void camera_teleport(camera_t *cam, vec3 pos); +//lcpp INF [0000] vec3: macro name but used as C declaration in:API void camera_moveby(camera_t *cam, vec3 inc); +//lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void camera_moveby(camera_t *cam, vec3 inc); +//lcpp INF [0000] vec3: macro name but used as C declaration in: void camera_moveby(camera_t *cam, vec3 inc); //lcpp INF [0000] vec3: macro name but used as C declaration in:API void camera_lookat(camera_t *cam, vec3 target); //lcpp INF [0000] vec3: macro name but used as C declaration in:STATIC void camera_lookat(camera_t *cam, vec3 target); //lcpp INF [0000] vec3: macro name but used as C declaration in: void camera_lookat(camera_t *cam, vec3 target); @@ -1508,9 +1512,10 @@ typedef long unsigned int size_t; uint32_t hash_32(uint32_t x); uint64_t hash_64(uint64_t x); uint64_t hash_flt(double x); - uint64_t hash_str(const char* str); uint64_t hash_int(int key); uint64_t hash_ptr(const void* ptr); + uint64_t hash_bin(const void* ptr, unsigned len); + uint64_t hash_str(const char* str); uint64_t popcnt64(uint64_t x); void* vrealloc( void* p, size_t sz ); size_t vlen( void* p ); @@ -2155,9 +2160,9 @@ FONT_CJK = FONT_ZH|FONT_JP|FONT_KR, vec2 input2( int vk ); float input_diff( int vk ); vec2 input_diff2( int vk ); - float input_frame( int vk, int frame ); - vec2 input_frame2( int vk, int frame ); - const char* input_frames( int vk, int frame ); + const char* input_string( int vk ); + float input_frame( int vk, int Nth_frame ); + vec2 input_frame2( int vk, int Nth_frame ); int input_up( int vk ); int input_down( int vk ); int input_held( int vk ); @@ -2181,13 +2186,16 @@ TOUCH_1, vec2 input_touch_delta(unsigned button, float sensitivity); vec2 input_touch_delta_from_origin(unsigned button, float sensitivity); bool input_touch_active(); - void input_demo(); void input_mappings(const char *filename); - void input_send( int vk ); - void* input_save_state( int id, int *size); - bool input_load_state( int id, void *ptr, int size); char input_keychar(unsigned code); int input_anykey(); + void input_send( int vk ); + char* save_input(); + bool load_input(char* replay); + int ui_keyboard(); + int ui_mouse(); + int ui_gamepad(int id); + int ui_gamepads(); enum INPUT_ENUMS { KEY_ESC, KEY_TICK, KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,KEY_0, KEY_BS, @@ -2757,20 +2765,25 @@ float *pixels; void ddraw_flush_projview(mat44 proj, mat44 view); typedef struct camera_t { mat44 view, proj; -vec3 position, up, look; -float yaw, pitch, speed; -vec3 last_look, last_move; -float fov; +vec3 position, updir, lookdir; +float yaw, pitch; +float speed, fov; +float move_friction, move_damping; +float look_friction, look_damping; +vec2 last_look; vec3 last_move; +bool damping; } camera_t; camera_t camera(); void camera_teleport(camera_t *cam, vec3 pos); - void camera_move(camera_t *cam, float incx, float incy, float incz); + void camera_moveby(camera_t *cam, vec3 inc); void camera_fov(camera_t *cam, float fov); void camera_fps(camera_t *cam, float yaw, float pitch); void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); void camera_lookat(camera_t *cam, vec3 target); void camera_enable(camera_t *cam); camera_t *camera_get_active(); + int ui_camera(camera_t *cam); + void ddraw_camera(camera_t *cam); typedef struct object_t { uint64_t renderbucket; mat44 transform; @@ -2967,6 +2980,9 @@ PANEL_OPEN = 1, int ui_float2(const char *label, float value[2]); int ui_float3(const char *label, float value[3]); int ui_float4(const char *label, float value[4]); + int ui_mat33(const char *label, float mat33[9]); + int ui_mat34(const char *label, float mat34[12]); + int ui_mat44(const char *label, float mat44[16]); int ui_double(const char *label, double *value); int ui_buffer(const char *label, char *buffer, int buflen); int ui_string(const char *label, char **string); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index a4c85e7..e52814f 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -202,6 +202,7 @@ #define ICON_MD_ASPECT_RATIO "\xee\xa1\x9b" // U+e85b #define ICON_MD_ASSESSMENT "\xee\xa1\x9c" // U+e85c #define ICON_MD_ASSIGNMENT "\xee\xa1\x9d" // U+e85d +#define ICON_MD_ASSIGNMENT_ADD "\xef\xa1\x88" // U+f848 #define ICON_MD_ASSIGNMENT_IND "\xee\xa1\x9e" // U+e85e #define ICON_MD_ASSIGNMENT_LATE "\xee\xa1\x9f" // U+e85f #define ICON_MD_ASSIGNMENT_RETURN "\xee\xa1\xa0" // U+e860 @@ -247,6 +248,7 @@ #define ICON_MD_BALCONY "\xee\x96\x8f" // U+e58f #define ICON_MD_BALLOT "\xee\x85\xb2" // U+e172 #define ICON_MD_BAR_CHART "\xee\x89\xab" // U+e26b +#define ICON_MD_BARCODE_READER "\xef\xa1\x9c" // U+f85c #define ICON_MD_BATCH_PREDICTION "\xef\x83\xb5" // U+f0f5 #define ICON_MD_BATHROOM "\xee\xbf\x9d" // U+efdd #define ICON_MD_BATHTUB "\xee\xa9\x81" // U+ea41 @@ -485,6 +487,7 @@ #define ICON_MD_CONTROL_CAMERA "\xee\x81\xb4" // U+e074 #define ICON_MD_CONTROL_POINT "\xee\x8e\xba" // U+e3ba #define ICON_MD_CONTROL_POINT_DUPLICATE "\xee\x8e\xbb" // U+e3bb +#define ICON_MD_CONVEYOR_BELT "\xef\xa1\xa7" // U+f867 #define ICON_MD_COOKIE "\xee\xaa\xac" // U+eaac #define ICON_MD_COPY_ALL "\xee\x8b\xac" // U+e2ec #define ICON_MD_COPYRIGHT "\xee\xa4\x8c" // U+e90c @@ -568,6 +571,7 @@ #define ICON_MD_DEVICES "\xee\x86\xb1" // U+e1b1 #define ICON_MD_DEVICES_FOLD "\xee\xaf\x9e" // U+ebde #define ICON_MD_DEVICES_OTHER "\xee\x8c\xb7" // U+e337 +#define ICON_MD_DEW_POINT "\xef\xa1\xb9" // U+f879 #define ICON_MD_DIALER_SIP "\xee\x82\xbb" // U+e0bb #define ICON_MD_DIALPAD "\xee\x82\xbc" // U+e0bc #define ICON_MD_DIAMOND "\xee\xab\x95" // U+ead5 @@ -663,12 +667,14 @@ #define ICON_MD_EDIT "\xee\x8f\x89" // U+e3c9 #define ICON_MD_EDIT_ATTRIBUTES "\xee\x95\xb8" // U+e578 #define ICON_MD_EDIT_CALENDAR "\xee\x9d\x82" // U+e742 +#define ICON_MD_EDIT_DOCUMENT "\xef\xa2\x8c" // U+f88c #define ICON_MD_EDIT_LOCATION "\xee\x95\xa8" // U+e568 #define ICON_MD_EDIT_LOCATION_ALT "\xee\x87\x85" // U+e1c5 #define ICON_MD_EDIT_NOTE "\xee\x9d\x85" // U+e745 #define ICON_MD_EDIT_NOTIFICATIONS "\xee\x94\xa5" // U+e525 #define ICON_MD_EDIT_OFF "\xee\xa5\x90" // U+e950 #define ICON_MD_EDIT_ROAD "\xee\xbd\x8d" // U+ef4d +#define ICON_MD_EDIT_SQUARE "\xef\xa2\x8d" // U+f88d #define ICON_MD_EGG "\xee\xab\x8c" // U+eacc #define ICON_MD_EGG_ALT "\xee\xab\x88" // U+eac8 #define ICON_MD_EJECT "\xee\xa3\xbb" // U+e8fb @@ -770,6 +776,7 @@ #define ICON_MD_FILE_OPEN "\xee\xab\xb3" // U+eaf3 #define ICON_MD_FILE_PRESENT "\xee\xa8\x8e" // U+ea0e #define ICON_MD_FILE_UPLOAD "\xee\x8b\x86" // U+e2c6 +#define ICON_MD_FILE_UPLOAD_OFF "\xef\xa2\x86" // U+f886 #define ICON_MD_FILTER "\xee\x8f\x93" // U+e3d3 #define ICON_MD_FILTER_1 "\xee\x8f\x90" // U+e3d0 #define ICON_MD_FILTER_2 "\xee\x8f\x91" // U+e3d1 @@ -827,6 +834,7 @@ #define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 #define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 #define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31 #define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b #define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e #define ICON_MD_FMD_GOOD "\xef\x80\x8f" // U+f00f @@ -846,6 +854,7 @@ #define ICON_MD_FOREST "\xee\xaa\x99" // U+ea99 #define ICON_MD_FORK_LEFT "\xee\xae\xa0" // U+eba0 #define ICON_MD_FORK_RIGHT "\xee\xae\xac" // U+ebac +#define ICON_MD_FORKLIFT "\xef\xa1\xa8" // U+f868 #define ICON_MD_FORMAT_ALIGN_CENTER "\xee\x88\xb4" // U+e234 #define ICON_MD_FORMAT_ALIGN_JUSTIFY "\xee\x88\xb5" // U+e235 #define ICON_MD_FORMAT_ALIGN_LEFT "\xee\x88\xb6" // U+e236 @@ -860,6 +869,7 @@ #define ICON_MD_FORMAT_ITALIC "\xee\x88\xbf" // U+e23f #define ICON_MD_FORMAT_LINE_SPACING "\xee\x89\x80" // U+e240 #define ICON_MD_FORMAT_LIST_BULLETED "\xee\x89\x81" // U+e241 +#define ICON_MD_FORMAT_LIST_BULLETED_ADD "\xef\xa1\x89" // U+f849 #define ICON_MD_FORMAT_LIST_NUMBERED "\xee\x89\x82" // U+e242 #define ICON_MD_FORMAT_LIST_NUMBERED_RTL "\xee\x89\xa7" // U+e267 #define ICON_MD_FORMAT_OVERLINE "\xee\xad\xa5" // U+eb65 @@ -883,6 +893,7 @@ #define ICON_MD_FREE_BREAKFAST "\xee\xad\x84" // U+eb44 #define ICON_MD_FREE_CANCELLATION "\xee\x9d\x88" // U+e748 #define ICON_MD_FRONT_HAND "\xee\x9d\xa9" // U+e769 +#define ICON_MD_FRONT_LOADER "\xef\xa1\xa9" // U+f869 #define ICON_MD_FULLSCREEN "\xee\x97\x90" // U+e5d0 #define ICON_MD_FULLSCREEN_EXIT "\xee\x97\x91" // U+e5d1 #define ICON_MD_FUNCTIONS "\xee\x89\x8a" // U+e24a @@ -1285,6 +1296,7 @@ #define ICON_MD_MOVE_UP "\xee\xad\xa4" // U+eb64 #define ICON_MD_MOVIE "\xee\x80\xac" // U+e02c #define ICON_MD_MOVIE_CREATION "\xee\x90\x84" // U+e404 +#define ICON_MD_MOVIE_EDIT "\xef\xa1\x80" // U+f840 #define ICON_MD_MOVIE_FILTER "\xee\x90\xba" // U+e43a #define ICON_MD_MOVING "\xee\x94\x81" // U+e501 #define ICON_MD_MP "\xee\xa7\x83" // U+e9c3 @@ -1399,6 +1411,7 @@ #define ICON_MD_PAGEVIEW "\xee\xa2\xa0" // U+e8a0 #define ICON_MD_PAID "\xef\x81\x81" // U+f041 #define ICON_MD_PALETTE "\xee\x90\x8a" // U+e40a +#define ICON_MD_PALLET "\xef\xa1\xaa" // U+f86a #define ICON_MD_PAN_TOOL "\xee\xa4\xa5" // U+e925 #define ICON_MD_PAN_TOOL_ALT "\xee\xae\xb9" // U+ebb9 #define ICON_MD_PANORAMA "\xee\x90\x8b" // U+e40b @@ -1593,6 +1606,7 @@ #define ICON_MD_RAW_ON "\xef\x81\x90" // U+f050 #define ICON_MD_READ_MORE "\xee\xbd\xad" // U+ef6d #define ICON_MD_REAL_ESTATE_AGENT "\xee\x9c\xba" // U+e73a +#define ICON_MD_REBASE_EDIT "\xef\xa1\x86" // U+f846 #define ICON_MD_RECEIPT "\xee\xa2\xb0" // U+e8b0 #define ICON_MD_RECEIPT_LONG "\xee\xbd\xae" // U+ef6e #define ICON_MD_RECENT_ACTORS "\xee\x80\xbf" // U+e03f @@ -1758,6 +1772,7 @@ #define ICON_MD_SHARE "\xee\xa0\x8d" // U+e80d #define ICON_MD_SHARE_ARRIVAL_TIME "\xee\x94\xa4" // U+e524 #define ICON_MD_SHARE_LOCATION "\xef\x81\x9f" // U+f05f +#define ICON_MD_SHELVES "\xef\xa1\xae" // U+f86e #define ICON_MD_SHIELD "\xee\xa7\xa0" // U+e9e0 #define ICON_MD_SHIELD_MOON "\xee\xaa\xa9" // U+eaa9 #define ICON_MD_SHOP "\xee\xa3\x89" // U+e8c9 @@ -2050,6 +2065,7 @@ #define ICON_MD_TRENDING_NEUTRAL "\xee\xa3\xa4" // U+e8e4 #define ICON_MD_TRENDING_UP "\xee\xa3\xa5" // U+e8e5 #define ICON_MD_TRIP_ORIGIN "\xee\x95\xbb" // U+e57b +#define ICON_MD_TROLLEY "\xef\xa1\xab" // U+f86b #define ICON_MD_TROUBLESHOOT "\xee\x87\x92" // U+e1d2 #define ICON_MD_TRY "\xef\x81\xbc" // U+f07c #define ICON_MD_TSUNAMI "\xee\xaf\x98" // U+ebd8 @@ -2103,6 +2119,7 @@ #define ICON_MD_VIDEO_CALL "\xee\x81\xb0" // U+e070 #define ICON_MD_VIDEO_CAMERA_BACK "\xef\x81\xbf" // U+f07f #define ICON_MD_VIDEO_CAMERA_FRONT "\xef\x82\x80" // U+f080 +#define ICON_MD_VIDEO_CHAT "\xef\xa2\xa0" // U+f8a0 #define ICON_MD_VIDEO_COLLECTION "\xee\x81\x8a" // U+e04a #define ICON_MD_VIDEO_FILE "\xee\xae\x87" // U+eb87 #define ICON_MD_VIDEO_LABEL "\xee\x81\xb1" // U+e071 @@ -2187,7 +2204,6 @@ #define ICON_MD_WECHAT "\xee\xaa\x81" // U+ea81 #define ICON_MD_WEEKEND "\xee\x85\xab" // U+e16b #define ICON_MD_WEST "\xef\x87\xa6" // U+f1e6 -#define ICON_MD_WHATSAPP "\xee\xaa\x9c" // U+ea9c #define ICON_MD_WHATSHOT "\xee\xa0\x8e" // U+e80e #define ICON_MD_WHEELCHAIR_PICKUP "\xef\x86\xab" // U+f1ab #define ICON_MD_WHERE_TO_VOTE "\xee\x85\xb7" // U+e177 @@ -14332,9 +14348,10 @@ API uint32_t unhash_32(uint32_t x); API uint32_t hash_32(uint32_t x); API uint64_t hash_64(uint64_t x); API uint64_t hash_flt(double x); -API uint64_t hash_str(const char* str); API uint64_t hash_int(int key); API uint64_t hash_ptr(const void* ptr); +API uint64_t hash_bin(const void* ptr, unsigned len); +API uint64_t hash_str(const char* str); // ----------------------------------------------------------------------------- // bits @@ -15935,12 +15952,12 @@ API float input( int vk ); API vec2 input2( int vk ); API float input_diff( int vk ); // @todo: rename diff->delta API vec2 input_diff2( int vk ); // @todo: rename diff2->delta2 +API const char* input_string( int vk ); // -- extended polling api (read input at Nth frame ago) -API float input_frame( int vk, int frame ); -API vec2 input_frame2( int vk, int frame ); -API const char* input_frames( int vk, int frame ); +API float input_frame( int vk, int Nth_frame ); +API vec2 input_frame2( int vk, int Nth_frame ); // -- events api @@ -15979,14 +15996,22 @@ API bool input_touch_active(); // -- utils -API void input_demo(); API void input_mappings(const char *filename); // update gamepad mappings (usually "gamecontrollerdb.txt" file) -API void input_send( int vk ); // @todo -API void* input_save_state( int id, int *size); // @todo -API bool input_load_state( int id, void *ptr, int size); // @todo API char input_keychar(unsigned code); // Converts keyboard code to its latin char (if any) API int input_anykey(); +// inject state +API void input_send( int vk ); // @todo +// load/save input +API array(char) save_input(); // @todo +API bool load_input(array(char) replay); // @todo + +// visualize input +API int ui_keyboard(); +API int ui_mouse(); +API int ui_gamepad(int id); +API int ui_gamepads(); + // -- enum INPUT_ENUMS { @@ -17147,15 +17172,19 @@ API void ddraw_flush_projview(mat44 proj, mat44 view); typedef struct camera_t { mat44 view, proj; - vec3 position, up, look; // position, updir, lookdir - float yaw, pitch, speed; // mirror_x, mirror_y; - vec3 last_look, last_move; // used for friction and smoothing - float fov; // deg(45) + vec3 position, updir, lookdir; + float yaw, pitch; // mirror of (x,y) lookdir in deg; + float speed, fov; // fov in deg(45) + + float move_friction, move_damping; + float look_friction, look_damping; + vec2 last_look; vec3 last_move; // used for friction and damping + bool damping; } camera_t; API camera_t camera(); API void camera_teleport(camera_t *cam, vec3 pos); -API void camera_move(camera_t *cam, float incx, float incy, float incz); +API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); @@ -17163,6 +17192,9 @@ API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam); API camera_t *camera_get_active(); +API int ui_camera(camera_t *cam); +API void ddraw_camera(camera_t *cam); + // object typedef struct object_t { @@ -17485,6 +17517,9 @@ API int ui_float(const char *label, float *value); API int ui_float2(const char *label, float value[2]); API int ui_float3(const char *label, float value[3]); API int ui_float4(const char *label, float value[4]); +API int ui_mat33(const char *label, float mat33[9]); +API int ui_mat34(const char *label, float mat34[12]); +API int ui_mat44(const char *label, float mat44[16]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); @@ -29601,6 +29636,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_ASPECT_RATIO "\xee\xa1\x9b" // U+e85b #define ICON_MD_ASSESSMENT "\xee\xa1\x9c" // U+e85c #define ICON_MD_ASSIGNMENT "\xee\xa1\x9d" // U+e85d +#define ICON_MD_ASSIGNMENT_ADD "\xef\xa1\x88" // U+f848 #define ICON_MD_ASSIGNMENT_IND "\xee\xa1\x9e" // U+e85e #define ICON_MD_ASSIGNMENT_LATE "\xee\xa1\x9f" // U+e85f #define ICON_MD_ASSIGNMENT_RETURN "\xee\xa1\xa0" // U+e860 @@ -29646,6 +29682,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_BALCONY "\xee\x96\x8f" // U+e58f #define ICON_MD_BALLOT "\xee\x85\xb2" // U+e172 #define ICON_MD_BAR_CHART "\xee\x89\xab" // U+e26b +#define ICON_MD_BARCODE_READER "\xef\xa1\x9c" // U+f85c #define ICON_MD_BATCH_PREDICTION "\xef\x83\xb5" // U+f0f5 #define ICON_MD_BATHROOM "\xee\xbf\x9d" // U+efdd #define ICON_MD_BATHTUB "\xee\xa9\x81" // U+ea41 @@ -29884,6 +29921,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_CONTROL_CAMERA "\xee\x81\xb4" // U+e074 #define ICON_MD_CONTROL_POINT "\xee\x8e\xba" // U+e3ba #define ICON_MD_CONTROL_POINT_DUPLICATE "\xee\x8e\xbb" // U+e3bb +#define ICON_MD_CONVEYOR_BELT "\xef\xa1\xa7" // U+f867 #define ICON_MD_COOKIE "\xee\xaa\xac" // U+eaac #define ICON_MD_COPY_ALL "\xee\x8b\xac" // U+e2ec #define ICON_MD_COPYRIGHT "\xee\xa4\x8c" // U+e90c @@ -29967,6 +30005,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_DEVICES "\xee\x86\xb1" // U+e1b1 #define ICON_MD_DEVICES_FOLD "\xee\xaf\x9e" // U+ebde #define ICON_MD_DEVICES_OTHER "\xee\x8c\xb7" // U+e337 +#define ICON_MD_DEW_POINT "\xef\xa1\xb9" // U+f879 #define ICON_MD_DIALER_SIP "\xee\x82\xbb" // U+e0bb #define ICON_MD_DIALPAD "\xee\x82\xbc" // U+e0bc #define ICON_MD_DIAMOND "\xee\xab\x95" // U+ead5 @@ -30062,12 +30101,14 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_EDIT "\xee\x8f\x89" // U+e3c9 #define ICON_MD_EDIT_ATTRIBUTES "\xee\x95\xb8" // U+e578 #define ICON_MD_EDIT_CALENDAR "\xee\x9d\x82" // U+e742 +#define ICON_MD_EDIT_DOCUMENT "\xef\xa2\x8c" // U+f88c #define ICON_MD_EDIT_LOCATION "\xee\x95\xa8" // U+e568 #define ICON_MD_EDIT_LOCATION_ALT "\xee\x87\x85" // U+e1c5 #define ICON_MD_EDIT_NOTE "\xee\x9d\x85" // U+e745 #define ICON_MD_EDIT_NOTIFICATIONS "\xee\x94\xa5" // U+e525 #define ICON_MD_EDIT_OFF "\xee\xa5\x90" // U+e950 #define ICON_MD_EDIT_ROAD "\xee\xbd\x8d" // U+ef4d +#define ICON_MD_EDIT_SQUARE "\xef\xa2\x8d" // U+f88d #define ICON_MD_EGG "\xee\xab\x8c" // U+eacc #define ICON_MD_EGG_ALT "\xee\xab\x88" // U+eac8 #define ICON_MD_EJECT "\xee\xa3\xbb" // U+e8fb @@ -30169,6 +30210,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FILE_OPEN "\xee\xab\xb3" // U+eaf3 #define ICON_MD_FILE_PRESENT "\xee\xa8\x8e" // U+ea0e #define ICON_MD_FILE_UPLOAD "\xee\x8b\x86" // U+e2c6 +#define ICON_MD_FILE_UPLOAD_OFF "\xef\xa2\x86" // U+f886 #define ICON_MD_FILTER "\xee\x8f\x93" // U+e3d3 #define ICON_MD_FILTER_1 "\xee\x8f\x90" // U+e3d0 #define ICON_MD_FILTER_2 "\xee\x8f\x91" // U+e3d1 @@ -30226,6 +30268,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 #define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 #define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31 #define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b #define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e #define ICON_MD_FMD_GOOD "\xef\x80\x8f" // U+f00f @@ -30245,6 +30288,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FOREST "\xee\xaa\x99" // U+ea99 #define ICON_MD_FORK_LEFT "\xee\xae\xa0" // U+eba0 #define ICON_MD_FORK_RIGHT "\xee\xae\xac" // U+ebac +#define ICON_MD_FORKLIFT "\xef\xa1\xa8" // U+f868 #define ICON_MD_FORMAT_ALIGN_CENTER "\xee\x88\xb4" // U+e234 #define ICON_MD_FORMAT_ALIGN_JUSTIFY "\xee\x88\xb5" // U+e235 #define ICON_MD_FORMAT_ALIGN_LEFT "\xee\x88\xb6" // U+e236 @@ -30259,6 +30303,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FORMAT_ITALIC "\xee\x88\xbf" // U+e23f #define ICON_MD_FORMAT_LINE_SPACING "\xee\x89\x80" // U+e240 #define ICON_MD_FORMAT_LIST_BULLETED "\xee\x89\x81" // U+e241 +#define ICON_MD_FORMAT_LIST_BULLETED_ADD "\xef\xa1\x89" // U+f849 #define ICON_MD_FORMAT_LIST_NUMBERED "\xee\x89\x82" // U+e242 #define ICON_MD_FORMAT_LIST_NUMBERED_RTL "\xee\x89\xa7" // U+e267 #define ICON_MD_FORMAT_OVERLINE "\xee\xad\xa5" // U+eb65 @@ -30282,6 +30327,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FREE_BREAKFAST "\xee\xad\x84" // U+eb44 #define ICON_MD_FREE_CANCELLATION "\xee\x9d\x88" // U+e748 #define ICON_MD_FRONT_HAND "\xee\x9d\xa9" // U+e769 +#define ICON_MD_FRONT_LOADER "\xef\xa1\xa9" // U+f869 #define ICON_MD_FULLSCREEN "\xee\x97\x90" // U+e5d0 #define ICON_MD_FULLSCREEN_EXIT "\xee\x97\x91" // U+e5d1 #define ICON_MD_FUNCTIONS "\xee\x89\x8a" // U+e24a @@ -30684,6 +30730,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_MOVE_UP "\xee\xad\xa4" // U+eb64 #define ICON_MD_MOVIE "\xee\x80\xac" // U+e02c #define ICON_MD_MOVIE_CREATION "\xee\x90\x84" // U+e404 +#define ICON_MD_MOVIE_EDIT "\xef\xa1\x80" // U+f840 #define ICON_MD_MOVIE_FILTER "\xee\x90\xba" // U+e43a #define ICON_MD_MOVING "\xee\x94\x81" // U+e501 #define ICON_MD_MP "\xee\xa7\x83" // U+e9c3 @@ -30798,6 +30845,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_PAGEVIEW "\xee\xa2\xa0" // U+e8a0 #define ICON_MD_PAID "\xef\x81\x81" // U+f041 #define ICON_MD_PALETTE "\xee\x90\x8a" // U+e40a +#define ICON_MD_PALLET "\xef\xa1\xaa" // U+f86a #define ICON_MD_PAN_TOOL "\xee\xa4\xa5" // U+e925 #define ICON_MD_PAN_TOOL_ALT "\xee\xae\xb9" // U+ebb9 #define ICON_MD_PANORAMA "\xee\x90\x8b" // U+e40b @@ -30992,6 +31040,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_RAW_ON "\xef\x81\x90" // U+f050 #define ICON_MD_READ_MORE "\xee\xbd\xad" // U+ef6d #define ICON_MD_REAL_ESTATE_AGENT "\xee\x9c\xba" // U+e73a +#define ICON_MD_REBASE_EDIT "\xef\xa1\x86" // U+f846 #define ICON_MD_RECEIPT "\xee\xa2\xb0" // U+e8b0 #define ICON_MD_RECEIPT_LONG "\xee\xbd\xae" // U+ef6e #define ICON_MD_RECENT_ACTORS "\xee\x80\xbf" // U+e03f @@ -31157,6 +31206,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_SHARE "\xee\xa0\x8d" // U+e80d #define ICON_MD_SHARE_ARRIVAL_TIME "\xee\x94\xa4" // U+e524 #define ICON_MD_SHARE_LOCATION "\xef\x81\x9f" // U+f05f +#define ICON_MD_SHELVES "\xef\xa1\xae" // U+f86e #define ICON_MD_SHIELD "\xee\xa7\xa0" // U+e9e0 #define ICON_MD_SHIELD_MOON "\xee\xaa\xa9" // U+eaa9 #define ICON_MD_SHOP "\xee\xa3\x89" // U+e8c9 @@ -31449,6 +31499,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_TRENDING_NEUTRAL "\xee\xa3\xa4" // U+e8e4 #define ICON_MD_TRENDING_UP "\xee\xa3\xa5" // U+e8e5 #define ICON_MD_TRIP_ORIGIN "\xee\x95\xbb" // U+e57b +#define ICON_MD_TROLLEY "\xef\xa1\xab" // U+f86b #define ICON_MD_TROUBLESHOOT "\xee\x87\x92" // U+e1d2 #define ICON_MD_TRY "\xef\x81\xbc" // U+f07c #define ICON_MD_TSUNAMI "\xee\xaf\x98" // U+ebd8 @@ -31502,6 +31553,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_VIDEO_CALL "\xee\x81\xb0" // U+e070 #define ICON_MD_VIDEO_CAMERA_BACK "\xef\x81\xbf" // U+f07f #define ICON_MD_VIDEO_CAMERA_FRONT "\xef\x82\x80" // U+f080 +#define ICON_MD_VIDEO_CHAT "\xef\xa2\xa0" // U+f8a0 #define ICON_MD_VIDEO_COLLECTION "\xee\x81\x8a" // U+e04a #define ICON_MD_VIDEO_FILE "\xee\xae\x87" // U+eb87 #define ICON_MD_VIDEO_LABEL "\xee\x81\xb1" // U+e071 @@ -31586,7 +31638,6 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_WECHAT "\xee\xaa\x81" // U+ea81 #define ICON_MD_WEEKEND "\xee\x85\xab" // U+e16b #define ICON_MD_WEST "\xef\x87\xa6" // U+f1e6 -#define ICON_MD_WHATSAPP "\xee\xaa\x9c" // U+ea9c #define ICON_MD_WHATSHOT "\xee\xa0\x8e" // U+e80e #define ICON_MD_WHEELCHAIR_PICKUP "\xef\x86\xab" // U+f1ab #define ICON_MD_WHERE_TO_VOTE "\xee\x85\xb7" // U+e177 @@ -231540,7 +231591,7 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, (type == NK_SYMBOL_TRIANGLE_DOWN) ? NK_GLYPH_CARET_DOWN_: //< @r-lyeh (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_GLYPH_CARET_LEFT_ : NK_GLYPH_CARET_RIGHT_; //< @r-lyeh struct nk_text text; //< @r-lyeh - text.padding = nk_vec2(-6,-2); //< @r-lyeh: 0,0 for FA + text.padding = nk_vec2(-6,-0); //< @r-lyeh: -6,-2 for MD, 0,0 for FA text.background = background; //< @r-lyeh text.text = foreground; //< @r-lyeh nk_widget_text(out, content, X, strlen(X), &text, NK_TEXT_LEFT|NK_TEXT_ALIGN_BOTTOM, font); //< @r-lyeh @@ -238585,8 +238636,9 @@ static int browser_run(struct nk_context *ctx, struct browser *browser, int wind if( windowed ) nk_menubar_end(ctx); ctx->style.window.spacing.x = spacing_x; -if(nk_window_has_focus(ctx)) -browser->zooming = clampf( browser->zooming + input_diff(MOUSE_W) * 0.1, 1, 3); +if(nk_window_has_focus(ctx)) { +browser->zooming = clampf( browser->zooming + (input(KEY_LCTRL) || input(KEY_RCTRL)) * input_diff(MOUSE_W) * 0.1, 1, 3); +} bool compact = 0, tiny = browser->listing; // compact, no left panel. tiny, no large icons size_t cols = total_space.w / (100 * browser->zooming); @@ -310408,7 +310460,7 @@ extern "C" { // =======================================================================// #if (defined _MSC_VER && defined _WIN32 && !defined _WIN64) || \ - (defined __MINGW32__ && !defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh + (defined __MINGW32__ || defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh #define MUST_DEFINE_NTOP_PTON 1 #else #define MUST_DEFINE_NTOP_PTON 0 @@ -329557,6 +329609,12 @@ uint64_t hash_str(const char* str) { while( *str ) hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; return hash; } +uint64_t hash_bin(const void* ptr, unsigned len) { + uint64_t hash = 14695981039346656037ULL; // hash(0),mul(131) faster than fnv1a, a few more collisions though + for( unsigned char *str = (unsigned char *)ptr; len--; ) + hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; + return hash; +} uint64_t hash_int(int key) { return hash_32((uint32_t)key); } @@ -333706,7 +333764,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio int ids_count = 0; char ids[64][64] = { 0 }; // split path stems - for each_substring(stem, "/\\", key) { + for each_substring(stem, "/\\@", key) { int tokens_count = 0; char* tokens[64] = { 0 }; // split tokens @@ -337286,7 +337344,9 @@ float input_frame( int vk, int frame ) { vec2 input_frame2( int vk, int frame ) { return vec2( input_frame(vk, frame), input_frame(vk+1, frame) ); } -const char *input_frames( int vk, int frame ) { + +const char *input_string( int vk ) { + int frame = 0; if( controller_id > 0 ) return ""; // @fixme struct controller_t *c = input_logger(frame, +0); return vk >= GAMEPAD_GUID ? c->strings[vk - GAMEPAD_GUID] : ""; // if in strings... @@ -337538,37 +337598,9 @@ bool input_touch_active() { #endif // !is(ems) -// ---------------------------------------------------------------------------- - -void input_demo() { - if( ui_panel("Input",0) ) { - ui_section("Keyboard"); - - uint8_t keymap = 0; - keymap |= (!!input(KEY_1)) << 7; - keymap |= (!!input(KEY_2)) << 6; - keymap |= (!!input(KEY_3)) << 5; - keymap |= (!!input(KEY_4)) << 4; - keymap |= (!!input(KEY_5)) << 3; - keymap |= (!!input(KEY_6)) << 2; - keymap |= (!!input(KEY_7)) << 1; - keymap |= (!!input(KEY_8)) << 0; - ui_bitmask8("[Keys 1..8]", &keymap); - - ui_separator(); - ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); - ui_separator(); - - ui_section("Mouse"); +int ui_mouse() { ui_label2_float("X", input(MOUSE_X)); ui_label2_float("Y", input(MOUSE_Y)); - ui_separator(); ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); ui_label2_bool("Left", input(MOUSE_L)); @@ -337576,17 +337608,52 @@ void input_demo() { ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); - ui_separator(); - static int gamepad_id = 0; - const char *list[] = {"1","2","3","4"}; - ui_section("GamePads"); - ui_list("Gamepad", list, 4, &gamepad_id); + return 0; +} +int ui_keyboard() { + char *keys[] = { + "ESC", + "TICK","1","2","3","4","5","6","7","8","9","0","BS", + "TAB","Q","W","E","R","T","Y","U","I","O","P", + "CAPS","A","S","D","F","G","H","J","K","L","ENTER", + "LSHIFT","Z","X","C","V","B","N","M","RSHIFT","^", + "LCTRL","LALT","SPACE","RALT","RCTRL","<","V",">", + }; + + vec2i rows[] = { + vec2i(0,1), + vec2i(1,13), + vec2i(13,24), + vec2i(24,35), + vec2i(35,45), + vec2i(45,countof(keys)), + }; + + for( int i = 0; i < countof(rows); ++i ) { + int any = 0; + char *row = 0; + for( int j = rows[i].x; j < rows[i].y; ++j ) { + strcatf(&row, input(KEY_ESC + j) ? (any|=1, "[%s]") : " %s ", keys[j]); + } + if(!any) ui_disable(); + ui_label(row); + ui_enable(); + FREE(row); + } + + return 0; +} + +int ui_gamepad(int gamepad_id) { input_use(gamepad_id); - ui_label2("Name", input_frames(GAMEPAD_NAME,0)); - ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); + bool connected = !!input(GAMEPAD_CONNECTED); + + ui_label2("Name", connected ? input_string(GAMEPAD_NAME) : "(Not connected)"); + + if( !connected ) ui_disable(); ui_separator(); @@ -337625,10 +337692,16 @@ void input_demo() { ui_label2_float("Filtered pad x", w.x); ui_label2_float("Filtered pad y", w.y); - input_use(0); + ui_enable(); - ui_panel_end(); + input_use(0); + return 0; } + +int ui_gamepads() { + for( int i = 0; i < 4; ++i ) ui_gamepad(i); + + return 0; } #line 0 @@ -340105,7 +340178,7 @@ int ui_shader(unsigned shader) { } int ui_shaders() { - if( !map_count(shader_reflect) ) return 0; + if( !map_count(shader_reflect) ) return ui_label(ICON_MD_WARNING " No shaders with annotations loaded."), 0; int changed = 0; for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { @@ -343208,7 +343281,7 @@ int ui_fx(int pass) { return ui_postfx(&fx, pass); } int ui_fxs() { - if(!fx.num_loaded) return 0; + if(!fx.num_loaded) return ui_label(ICON_MD_WARNING " No Post FXs with annotations loaded."), 0; int changed = 0; for( int i = 0; i < 64; ++i ) { @@ -343216,6 +343289,7 @@ int ui_fxs() { bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); ui_fx(i); + ui_separator(); } return changed; } @@ -344476,17 +344550,21 @@ void model_destroy(model_t m) { anims_t animations(const char *pathfile, int flags) { anims_t a = {0}; - char *anim_file = vfs_read(va("%s@animlist.txt", pathfile)); - if( !anim_file ) anim_file = vfs_read(pathfile); + char *anim_file = vfs_read(strendi(pathfile,".txt") ? pathfile : va("%s@animlist.txt", pathfile)); if( anim_file ) { + // deserialize anim + a.speed = 1.0; for each_substring(anim_file, "\r\n", anim) { int from, to; char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; - array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] + array_push(a.anims, !!strstri(anim_name, "loop") || !strcmpi(anim_name, "idle") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } - a.speed = 1.0; + } else { + // placeholder + array_push(a.anims, clip(0,1,0,0)); + array_back(a.anims)->name = STRDUP("Error"); // @leak } return a; } @@ -345123,6 +345201,30 @@ void ddraw_frustum(float projview[16]) { // Connect the dots: ddraw_bounds(points); } + +void ddraw_camera(camera_t *cam) { + vec3 center = cam->position; + vec3 rightdir = cross3(cam->lookdir,cam->updir); + float proj[16]; // reproject perspective matrix with a smaller view distance (100 units) + perspective44(proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 100.f); + + ddraw_color_push(YELLOW); + // frustum + mat44 projview; multiply44x2(projview, /*cam->*/proj, cam->view); + ddraw_frustum(projview); + // top circles + ddraw_circle(add3(center,add3(cam->lookdir,cam->updir)), rightdir, 2); + ddraw_circle(add3(center,add3(neg3(cam->lookdir),cam->updir)), rightdir, 2); + // orientation + ddraw_color(RED); + ddraw_arrow(cam->position, add3(cam->position,cam->lookdir)); + ddraw_color(GREEN); + ddraw_arrow(cam->position, add3(cam->position,cam->updir)); + ddraw_color(BLUE); + ddraw_arrow(cam->position, add3(cam->position,rightdir)); + ddraw_color_pop(); +} + void ddraw_arrow(vec3 begin, vec3 end) { vec3 diff = sub3(end, begin); float len = len3(diff), stick_len = len * 2 / 3; @@ -345325,24 +345427,33 @@ static camera_t *last_camera; camera_t camera() { camera_t *old = last_camera; - camera_t cam = {0}; - cam.speed = 1; + static camera_t cam = {0}; + do_once { + cam.speed = 0.50f; cam.position = vec3(10,10,10); - cam.last_look = cam.last_move = vec3(0,0,0); - cam.up = vec3(0,1,0); + cam.updir = vec3(0,1,0); cam.fov = 45; + cam.damping = false; + cam.move_friction = 0.09f; + cam.move_damping = 0.96f; + cam.look_friction = 0.30f; + cam.look_damping = 0.96f; + cam.last_look = vec2(0,0); + cam.last_move = vec3(0,0,0); + // update proj & view camera_lookat(&cam,vec3(-5,0,-5)); - // @todo: remove this hack - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { + // @todo: remove this hack that is used to consolidate dampings + if( 1 ) { + vec3 zero = {0}; for( int i = 0; i < 1000; ++i ) { - camera_move(&cam,0,0,0); + camera_moveby(&cam, zero); camera_fps(&cam,0,0); } } + } last_camera = old; *camera_get_active() = cam; @@ -345359,33 +345470,37 @@ camera_t *camera_get_active() { return last_camera; } -void camera_move(camera_t *cam, float incx, float incy, float incz) { - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float move_friction = 0.99f; - cam->last_move = scale3(cam->last_move, move_friction); - float move_filtering = 0.975f; - incx = cam->last_move.x = incx * (1 - move_filtering) + cam->last_move.x * move_filtering; - incy = cam->last_move.y = incy * (1 - move_filtering) + cam->last_move.y * move_filtering; - incz = cam->last_move.z = incz * (1 - move_filtering) + cam->last_move.z * move_filtering; +void camera_moveby(camera_t *cam, vec3 inc) { + // calculate camera damping + if( cam->damping ) { + float fr = cam->move_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->move_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_move = scale3(cam->last_move, 1 - fr); + inc.x = cam->last_move.x = inc.x * (1 - sm) + cam->last_move.x * sm; + inc.y = cam->last_move.y = inc.y * (1 - sm) + cam->last_move.y * sm; + inc.z = cam->last_move.z = inc.z * (1 - sm) + cam->last_move.z * sm; } - vec3 dir = norm3(cross3(cam->look, cam->up)); - cam->position = add3(cam->position, scale3(dir, incx)); // right - cam->position = add3(cam->position, scale3(cam->up, incy)); // up - cam->position = add3(cam->position, scale3(cam->look, incz)); // front + vec3 dir = norm3(cross3(cam->lookdir, cam->updir)); + cam->position = add3(cam->position, scale3(dir, inc.x)); // right + cam->position = add3(cam->position, scale3(cam->updir, inc.y)); // up + cam->position = add3(cam->position, scale3(cam->lookdir, inc.z)); // front camera_fps(cam, 0, 0); } void camera_teleport(camera_t *cam, vec3 pos) { + bool damping = cam->damping; + cam->damping = 0; + cam->last_move = vec3(0,0,0); cam->position = pos; camera_fps(cam, 0, 0); + cam->damping = damping; } void camera_lookat(camera_t *cam, vec3 target) { - // invert expression that cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + // invert expression that cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); // look.y = sin p > y = asin(p) // look.x = cos y * cos p; -> cos p = look.x / cos y \ look.x / cos y = look.z / sin y // look.z = sin y * cos p; -> cos p = look.z / sin y / @@ -345407,34 +345522,8 @@ void camera_enable(camera_t *cam) { } void camera_fov(camera_t *cam, float fov) { - cam->fov = fov; -} - -void camera_fps(camera_t *cam, float yaw, float pitch) { last_camera = cam; - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float look_friction = 0.999f; - cam->last_look.x *= look_friction; - cam->last_look.y *= look_friction; - float look_filtering = 0.05f; - yaw = cam->last_look.y = yaw * look_filtering + cam->last_look.y * (1 - look_filtering); - pitch = cam->last_look.x = pitch * look_filtering + cam->last_look.x * (1 - look_filtering); - } - - cam->yaw += yaw; - cam->yaw = fmod(cam->yaw, 360); - cam->pitch += pitch; - cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; - - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; - cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); - - lookat44(cam->view, cam->position, add3(cam->position, cam->look), cam->up); // eye,center,up - perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); - #if 0 // isometric/dimetric #define orthogonal(proj, fov, aspect, znear, zfar) \ ortho44((proj), -(fov) * (aspect), (fov) * (aspect), -(fov), (fov), (znear), (zfar)) @@ -345446,6 +345535,33 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { // cam->yaw = 45; cam->pitch = -ISOMETRIC; #endif + cam->fov = fov; + perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); +} + +void camera_fps(camera_t *cam, float yaw, float pitch) { + last_camera = cam; + + // camera damping + if( cam->damping ) { + float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_look = scale2(cam->last_look, 1 - fr); + yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; + pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + } + + cam->yaw += yaw; + cam->yaw = fmod(cam->yaw, 360); + cam->pitch += pitch; + cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up + + camera_fov(cam, cam->fov); } void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { @@ -345485,6 +345601,28 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { cam->last_move.y = _mouse.y; } +int ui_camera( camera_t *cam ) { + int changed = 0; + changed |= ui_float("Speed", &cam->speed); + ui_separator(); + changed |= ui_bool("Damping", &cam->damping); + if( !cam->damping ) ui_disable(); + changed |= ui_slider2("Move friction", &cam->move_friction, va("%5.2f", cam->move_friction)); + changed |= ui_slider2("Move damping", &cam->move_damping, va("%5.2f", cam->move_damping)); + changed |= ui_slider2("View driction", &cam->look_friction, va("%5.2f", cam->look_friction)); + changed |= ui_slider2("View damping", &cam->look_damping, va("%5.2f", cam->look_damping)); + if( !cam->damping ) ui_enable(); + ui_separator(); + changed |= ui_float3("Position", &cam->position.x); + changed |= ui_float3("LookDir", &cam->lookdir.x); + changed |= ui_float3("UpDir", &cam->updir.x); + changed |= ui_mat44("View matrix", cam->view); + ui_separator(); + changed |= ui_float("FOV (degrees)", &cam->fov); + changed |= ui_mat44("Projection matrix", cam->proj); + return changed; +} + // ----------------------------------------------------------------------------- static @@ -347146,7 +347284,7 @@ void thread_destroy( void *thd ) { #else #define UI_ICON_FONTSIZE UI_FONT_ENUM(20,20) #define UI_ICON_SPACING_X UI_FONT_ENUM(0,0) - #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,4.5f) + #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,5.0f) #endif #define MAX_VERTEX_MEMORY 512 * 1024 @@ -347909,7 +348047,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(1); + ui_enable(); } } @@ -348567,26 +348705,35 @@ int ui_label_(const char *label, int alignment) { if( is_hovering ) { struct nk_rect winbounds = nk_window_get_bounds(ui_ctx); is_hovering &= nk_input_is_mouse_hovering_rect(input, winbounds); - is_hovering &= nk_window_has_focus(ui_ctx); + + struct nk_window *win = ui_ctx->current; + bool has_contextual = !win->name; // contextual windows are annonymous + + is_hovering &= has_contextual || nk_window_has_focus(ui_ctx); } int skip_color_tab = label && label[0] == '!'; if( skip_color_tab) label++; - int indent = 8; + int spacing = 8; // between left colorbar and content struct nk_window *win = ui_ctx->current; struct nk_panel *layout = win->layout; - layout->at_x += indent; - layout->bounds.w -= indent; + layout->at_x += spacing; + layout->bounds.w -= spacing; if( !skip_color_tab ) { - bounds.w = is_hovering ? indent*3/4 : indent/2-1; + float w = is_hovering ? 4 : 2; // spacing*3/4 : spacing/2-1; + bounds.w = w; bounds.h -= 1; struct nk_command_buffer *canvas = nk_window_get_canvas(ui_ctx); nk_fill_rect(canvas, bounds, 0, nk_hsva_f(ui_hue, 0.75f, 0.8f, ui_alpha) ); } - if(!label) return 0; - if(!label[0]) return 0; + if(!label || !label[0]) { + nk_label(ui_ctx, "", alignment); + layout->at_x -= spacing; + layout->bounds.w += spacing; + return 0; + } const char *split = strchr(label, '@'); char buffer[128]; if( split ) label = (snprintf(buffer, 128, "%.*s", (int)(split-label), label), buffer); @@ -348628,8 +348775,8 @@ if( font ) nk_style_pop_font(ui_ctx); nk_tooltip(ui_ctx, split + 1); } - layout->at_x -= indent; - layout->bounds.w += indent; + layout->at_x -= spacing; + layout->bounds.w += spacing; // old way // ui_labeicon_l_icked_L.x = is_hovering ? nk_input_has_mouse_click_down_in_rect(input, NK_BUTTON_LEFT, layout->bounds, nk_true) : 0; @@ -348647,7 +348794,7 @@ int ui_label(const char *text) { return ui_label_(text, align); } int ui_label2(const char *label, const char *text_) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); int align1 = label[0] == '>' ? (label++, NK_TEXT_RIGHT) : label[0] == '=' ? (label++, NK_TEXT_CENTERED) : label[0] == '<' ? (label++, NK_TEXT_LEFT) : NK_TEXT_LEFT; int align2 = text_[0] == '>' ? (text_++, NK_TEXT_RIGHT) : text_[0] == '=' ? (text_++, NK_TEXT_CENTERED) : text_[0] == '<' ? (text_++, NK_TEXT_LEFT) : NK_TEXT_LEFT; @@ -348679,7 +348826,7 @@ int ui_label2_float(const char *text, float value) { return ui_float(text, &f), 0; } int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_text_wrap(ui_ctx, str, strlen(str)); return 0; @@ -348799,7 +348946,7 @@ int ui_button(const char *s) { } int ui_toggle(const char *label, bool *value) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); // nk_label(ui_ctx, label, alignment); @@ -348817,7 +348964,7 @@ int ui_color4f(const char *label, float *color4) { static enum color_mode {COL_RGB, COL_HSV} ui_color_mode = COL_RGB; int ui_color4(const char *label, float *color4) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color4[0]*ui_alpha/255, color4[1]*ui_alpha/255, color4[2]*ui_alpha/255, color4[3]/255 }, before = after; @@ -348863,7 +349010,7 @@ int ui_color3f(const char *label, float *color3) { } int ui_color3(const char *label, float *color3) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color3[0]*ui_alpha/255, color3[1]*ui_alpha/255, color3[2]*ui_alpha/255, 1 }, before = after; @@ -348899,7 +349046,7 @@ int ui_color3(const char *label, float *color3) { } int ui_list(const char *label, const char **items, int num_items, int *selector) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = nk_combo(ui_ctx, items, num_items, *selector, UI_ROW_HEIGHT, nk_vec2(200,200)); @@ -348910,7 +349057,7 @@ int ui_list(const char *label, const char **items, int num_items, int *selector) int ui_slider(const char *label, float *slider) { // return ui_slider2(label, slider, va("%.2f ", *slider)); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_size val = *slider * 1000; @@ -348919,7 +349066,7 @@ int ui_slider(const char *label, float *slider) { return chg; } int ui_slider2(const char *label, float *slider, const char *caption) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_window *win = ui_ctx->current; @@ -348943,7 +349090,7 @@ int ui_slider2(const char *label, float *slider, const char *caption) { } int ui_bool(const char *label, bool *enabled ) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = *enabled; @@ -348957,7 +349104,7 @@ int ui_bool(const char *label, bool *enabled ) { } int ui_int(const char *label, int *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int prev = *v; @@ -348966,7 +349113,7 @@ int ui_int(const char *label, int *v) { } int ui_unsigned(const char *label, unsigned *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); unsigned prev = *v; @@ -348980,7 +349127,7 @@ int ui_short(const char *label, short *v) { } int ui_float(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f); @@ -348988,7 +349135,7 @@ int ui_float(const char *label, float *v) { } int ui_double(const char *label, double *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, 0.01f,0.005f); @@ -348998,7 +349145,7 @@ int ui_double(const char *label, double *v) { int ui_clampf(const char *label, float *v, float minf, float maxf) { if( minf > maxf ) return ui_clampf(label, v, maxf, minf); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f); @@ -349006,7 +349153,7 @@ int ui_clampf(const char *label, float *v, float minf, float maxf) { } int ui_float2(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f", v[0], v[1]); @@ -349021,7 +349168,7 @@ int ui_float2(const char *label, float *v) { } int ui_float3(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f", v[0], v[1], v[2]); @@ -349037,7 +349184,7 @@ int ui_float3(const char *label, float *v) { } int ui_float4(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f, %.2f", v[0], v[1], v[2], v[3]); @@ -349053,8 +349200,34 @@ int ui_float4(const char *label, float *v) { return 0; } +int ui_mat33(const char *label, float M[9]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float3(NULL, M); + changed |= ui_float3(NULL, M+3); + changed |= ui_float3(NULL, M+6); + return changed; +} +int ui_mat34(const char *label, float M[12]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + return changed; +} +int ui_mat44(const char *label, float M[16]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + changed |= ui_float4(NULL, M+12); + return changed; +} + int ui_buffer(const char *label, char *buffer, int buflen) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int active = nk_edit_string_zero_terminated(ui_ctx, NK_EDIT_AUTO_SELECT|NK_EDIT_CLIPBOARD|NK_EDIT_FIELD/*NK_EDIT_BOX*/|NK_EDIT_SIG_ENTER, buffer, buflen, nk_filter_default); @@ -349086,7 +349259,7 @@ int ui_separator() { } int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh) { - nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, label && label[0] ? 2 : 1); + nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, 1 + (label && label[0])); if( label && label[0] ) ui_label_(label, NK_TEXT_LEFT); struct nk_rect bounds; nk_layout_peek(&bounds, ui_ctx); bounds.w -= 10; // bounds.w *= 0.95f; @@ -350331,33 +350504,94 @@ int window_frame_begin() { } // @transparent - static bool has_transparent_attrib = 0; do_once ifdef(ems, false, has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); + static bool has_transparent_attrib = 0; ifndef(ems, do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); if( has_transparent_attrib ) may_render_stats = 0; // @transparent // generate Debug panel contents if( may_render_stats ) { - if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + if( has_menu ? ui_window("Debug " ICON_MD_SETTINGS, 0) : ui_panel("Debug " ICON_MD_SETTINGS, 0) ) { + +#if 1 + static char *filter = 0; + static int do_filter = 0; + if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1; + int choice = ui_toolbar(ICON_MD_SEARCH ";"); + if( choice == 1 ) do_filter = 1; + if( do_filter ) { + ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &filter); + if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon) + do_filter = 0; + } + } else { + if( filter ) filter[0] = '\0'; + } + char *filter_mask = filter && filter[0] ? va("*%s*", filter) : "*"; +#endif int open = 0, clicked_or_toggled = 0; - for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + #define ui_collapse_filtered(lbl,id) (strmatchi(lbl,filter_mask) && ui_collapse(lbl,id)) + + for( int p = (open = ui_collapse_filtered(ICON_MD_FOLDER_SPECIAL " Art", "Debug.Art")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + bool inlined = true; + const char *file = 0; + if( ui_browse(&file, &inlined) ) { + const char *sep = ifdef(win32, "\"", "'"); + app_exec(va("%s %s%s%s", ifdef(win32, "start \"\"", ifdef(osx, "open", "xdg-open")), sep, file, sep)); + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_ROCKET_LAUNCH " AI", "Debug.AI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VOLUME_UP " Audio", "Debug.Audio")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIDEOCAM " Camera", "Debug.Camera")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_camera( camera_get_active() ); + } + for( int p = (open = ui_collapse_filtered(ICON_MD_BUILD " Cook", "Debug.Cook")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_SIGNAL_CELLULAR_ALT " Network", "Debug.Network")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_CONTENT_PASTE " Scripts", "Debug.Scripts")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_MOVIE " FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); } - for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_SPEED " Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_profiler(); } - for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_STAR_HALF " Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_shaders(); } - for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_KEYBOARD " Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_keyboard(); } - for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_MOUSE " Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_mouse(); } - for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_GAMEPAD " Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int q = 0; q < 4; ++q ) { + for( int r = (open = ui_collapse(va("Gamepad #%d",q+1), va("Debug.Gamepads%d",q))), dummy = (clicked_or_toggled = ui_collapse_clicked()); r; ui_collapse_end(), r = 0) { + ui_gamepad(q); + } + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIEW_QUILT " UI", "Debug.UI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + int choice = ui_toolbar(ICON_MD_RECYCLING " Reset layout;" ICON_MD_SAVE_AS " Save layout"); + if( choice == 1 ) ui_layout_all_reset("*"); + if( choice == 2 ) file_delete(WINDOWS_INI), ui_layout_all_save_disk("*"); + for each_map_ptr_sorted(ui_windows, char*, k, unsigned, v) { + bool visible = ui_visible(*k); + if( ui_bool( *k, &visible ) ) { + ui_show( *k, ui_visible(*k) ^ true ); + } + } } (has_menu ? ui_window_end : ui_panel_end)(); @@ -350431,6 +350665,9 @@ void window_frame_swap() { #endif glfwSwapBuffers(window); // emscripten_webgl_commit_frame(); + + static int delay = 0; do_once delay = optioni("--delay", 0); + if( delay && !COOK_ON_DEMAND && cook_progress() >= 100 ) sleep_ms( delay ); } static diff --git a/engine/split/3rd_enet.h b/engine/split/3rd_enet.h index 0927b83..71e5d12 100644 --- a/engine/split/3rd_enet.h +++ b/engine/split/3rd_enet.h @@ -4910,7 +4910,7 @@ extern "C" { // =======================================================================// #if (defined _MSC_VER && defined _WIN32 && !defined _WIN64) || \ - (defined __MINGW32__ && !defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh + (defined __MINGW32__ || defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh #define MUST_DEFINE_NTOP_PTON 1 #else #define MUST_DEFINE_NTOP_PTON 0 diff --git a/engine/split/3rd_font_md.h b/engine/split/3rd_font_md.h index ba65937..1b74cb4 100644 --- a/engine/split/3rd_font_md.h +++ b/engine/split/3rd_font_md.h @@ -195,6 +195,7 @@ #define ICON_MD_ASPECT_RATIO "\xee\xa1\x9b" // U+e85b #define ICON_MD_ASSESSMENT "\xee\xa1\x9c" // U+e85c #define ICON_MD_ASSIGNMENT "\xee\xa1\x9d" // U+e85d +#define ICON_MD_ASSIGNMENT_ADD "\xef\xa1\x88" // U+f848 #define ICON_MD_ASSIGNMENT_IND "\xee\xa1\x9e" // U+e85e #define ICON_MD_ASSIGNMENT_LATE "\xee\xa1\x9f" // U+e85f #define ICON_MD_ASSIGNMENT_RETURN "\xee\xa1\xa0" // U+e860 @@ -240,6 +241,7 @@ #define ICON_MD_BALCONY "\xee\x96\x8f" // U+e58f #define ICON_MD_BALLOT "\xee\x85\xb2" // U+e172 #define ICON_MD_BAR_CHART "\xee\x89\xab" // U+e26b +#define ICON_MD_BARCODE_READER "\xef\xa1\x9c" // U+f85c #define ICON_MD_BATCH_PREDICTION "\xef\x83\xb5" // U+f0f5 #define ICON_MD_BATHROOM "\xee\xbf\x9d" // U+efdd #define ICON_MD_BATHTUB "\xee\xa9\x81" // U+ea41 @@ -478,6 +480,7 @@ #define ICON_MD_CONTROL_CAMERA "\xee\x81\xb4" // U+e074 #define ICON_MD_CONTROL_POINT "\xee\x8e\xba" // U+e3ba #define ICON_MD_CONTROL_POINT_DUPLICATE "\xee\x8e\xbb" // U+e3bb +#define ICON_MD_CONVEYOR_BELT "\xef\xa1\xa7" // U+f867 #define ICON_MD_COOKIE "\xee\xaa\xac" // U+eaac #define ICON_MD_COPY_ALL "\xee\x8b\xac" // U+e2ec #define ICON_MD_COPYRIGHT "\xee\xa4\x8c" // U+e90c @@ -561,6 +564,7 @@ #define ICON_MD_DEVICES "\xee\x86\xb1" // U+e1b1 #define ICON_MD_DEVICES_FOLD "\xee\xaf\x9e" // U+ebde #define ICON_MD_DEVICES_OTHER "\xee\x8c\xb7" // U+e337 +#define ICON_MD_DEW_POINT "\xef\xa1\xb9" // U+f879 #define ICON_MD_DIALER_SIP "\xee\x82\xbb" // U+e0bb #define ICON_MD_DIALPAD "\xee\x82\xbc" // U+e0bc #define ICON_MD_DIAMOND "\xee\xab\x95" // U+ead5 @@ -656,12 +660,14 @@ #define ICON_MD_EDIT "\xee\x8f\x89" // U+e3c9 #define ICON_MD_EDIT_ATTRIBUTES "\xee\x95\xb8" // U+e578 #define ICON_MD_EDIT_CALENDAR "\xee\x9d\x82" // U+e742 +#define ICON_MD_EDIT_DOCUMENT "\xef\xa2\x8c" // U+f88c #define ICON_MD_EDIT_LOCATION "\xee\x95\xa8" // U+e568 #define ICON_MD_EDIT_LOCATION_ALT "\xee\x87\x85" // U+e1c5 #define ICON_MD_EDIT_NOTE "\xee\x9d\x85" // U+e745 #define ICON_MD_EDIT_NOTIFICATIONS "\xee\x94\xa5" // U+e525 #define ICON_MD_EDIT_OFF "\xee\xa5\x90" // U+e950 #define ICON_MD_EDIT_ROAD "\xee\xbd\x8d" // U+ef4d +#define ICON_MD_EDIT_SQUARE "\xef\xa2\x8d" // U+f88d #define ICON_MD_EGG "\xee\xab\x8c" // U+eacc #define ICON_MD_EGG_ALT "\xee\xab\x88" // U+eac8 #define ICON_MD_EJECT "\xee\xa3\xbb" // U+e8fb @@ -763,6 +769,7 @@ #define ICON_MD_FILE_OPEN "\xee\xab\xb3" // U+eaf3 #define ICON_MD_FILE_PRESENT "\xee\xa8\x8e" // U+ea0e #define ICON_MD_FILE_UPLOAD "\xee\x8b\x86" // U+e2c6 +#define ICON_MD_FILE_UPLOAD_OFF "\xef\xa2\x86" // U+f886 #define ICON_MD_FILTER "\xee\x8f\x93" // U+e3d3 #define ICON_MD_FILTER_1 "\xee\x8f\x90" // U+e3d0 #define ICON_MD_FILTER_2 "\xee\x8f\x91" // U+e3d1 @@ -820,6 +827,7 @@ #define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 #define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 #define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31 #define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b #define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e #define ICON_MD_FMD_GOOD "\xef\x80\x8f" // U+f00f @@ -839,6 +847,7 @@ #define ICON_MD_FOREST "\xee\xaa\x99" // U+ea99 #define ICON_MD_FORK_LEFT "\xee\xae\xa0" // U+eba0 #define ICON_MD_FORK_RIGHT "\xee\xae\xac" // U+ebac +#define ICON_MD_FORKLIFT "\xef\xa1\xa8" // U+f868 #define ICON_MD_FORMAT_ALIGN_CENTER "\xee\x88\xb4" // U+e234 #define ICON_MD_FORMAT_ALIGN_JUSTIFY "\xee\x88\xb5" // U+e235 #define ICON_MD_FORMAT_ALIGN_LEFT "\xee\x88\xb6" // U+e236 @@ -853,6 +862,7 @@ #define ICON_MD_FORMAT_ITALIC "\xee\x88\xbf" // U+e23f #define ICON_MD_FORMAT_LINE_SPACING "\xee\x89\x80" // U+e240 #define ICON_MD_FORMAT_LIST_BULLETED "\xee\x89\x81" // U+e241 +#define ICON_MD_FORMAT_LIST_BULLETED_ADD "\xef\xa1\x89" // U+f849 #define ICON_MD_FORMAT_LIST_NUMBERED "\xee\x89\x82" // U+e242 #define ICON_MD_FORMAT_LIST_NUMBERED_RTL "\xee\x89\xa7" // U+e267 #define ICON_MD_FORMAT_OVERLINE "\xee\xad\xa5" // U+eb65 @@ -876,6 +886,7 @@ #define ICON_MD_FREE_BREAKFAST "\xee\xad\x84" // U+eb44 #define ICON_MD_FREE_CANCELLATION "\xee\x9d\x88" // U+e748 #define ICON_MD_FRONT_HAND "\xee\x9d\xa9" // U+e769 +#define ICON_MD_FRONT_LOADER "\xef\xa1\xa9" // U+f869 #define ICON_MD_FULLSCREEN "\xee\x97\x90" // U+e5d0 #define ICON_MD_FULLSCREEN_EXIT "\xee\x97\x91" // U+e5d1 #define ICON_MD_FUNCTIONS "\xee\x89\x8a" // U+e24a @@ -1278,6 +1289,7 @@ #define ICON_MD_MOVE_UP "\xee\xad\xa4" // U+eb64 #define ICON_MD_MOVIE "\xee\x80\xac" // U+e02c #define ICON_MD_MOVIE_CREATION "\xee\x90\x84" // U+e404 +#define ICON_MD_MOVIE_EDIT "\xef\xa1\x80" // U+f840 #define ICON_MD_MOVIE_FILTER "\xee\x90\xba" // U+e43a #define ICON_MD_MOVING "\xee\x94\x81" // U+e501 #define ICON_MD_MP "\xee\xa7\x83" // U+e9c3 @@ -1392,6 +1404,7 @@ #define ICON_MD_PAGEVIEW "\xee\xa2\xa0" // U+e8a0 #define ICON_MD_PAID "\xef\x81\x81" // U+f041 #define ICON_MD_PALETTE "\xee\x90\x8a" // U+e40a +#define ICON_MD_PALLET "\xef\xa1\xaa" // U+f86a #define ICON_MD_PAN_TOOL "\xee\xa4\xa5" // U+e925 #define ICON_MD_PAN_TOOL_ALT "\xee\xae\xb9" // U+ebb9 #define ICON_MD_PANORAMA "\xee\x90\x8b" // U+e40b @@ -1586,6 +1599,7 @@ #define ICON_MD_RAW_ON "\xef\x81\x90" // U+f050 #define ICON_MD_READ_MORE "\xee\xbd\xad" // U+ef6d #define ICON_MD_REAL_ESTATE_AGENT "\xee\x9c\xba" // U+e73a +#define ICON_MD_REBASE_EDIT "\xef\xa1\x86" // U+f846 #define ICON_MD_RECEIPT "\xee\xa2\xb0" // U+e8b0 #define ICON_MD_RECEIPT_LONG "\xee\xbd\xae" // U+ef6e #define ICON_MD_RECENT_ACTORS "\xee\x80\xbf" // U+e03f @@ -1751,6 +1765,7 @@ #define ICON_MD_SHARE "\xee\xa0\x8d" // U+e80d #define ICON_MD_SHARE_ARRIVAL_TIME "\xee\x94\xa4" // U+e524 #define ICON_MD_SHARE_LOCATION "\xef\x81\x9f" // U+f05f +#define ICON_MD_SHELVES "\xef\xa1\xae" // U+f86e #define ICON_MD_SHIELD "\xee\xa7\xa0" // U+e9e0 #define ICON_MD_SHIELD_MOON "\xee\xaa\xa9" // U+eaa9 #define ICON_MD_SHOP "\xee\xa3\x89" // U+e8c9 @@ -2043,6 +2058,7 @@ #define ICON_MD_TRENDING_NEUTRAL "\xee\xa3\xa4" // U+e8e4 #define ICON_MD_TRENDING_UP "\xee\xa3\xa5" // U+e8e5 #define ICON_MD_TRIP_ORIGIN "\xee\x95\xbb" // U+e57b +#define ICON_MD_TROLLEY "\xef\xa1\xab" // U+f86b #define ICON_MD_TROUBLESHOOT "\xee\x87\x92" // U+e1d2 #define ICON_MD_TRY "\xef\x81\xbc" // U+f07c #define ICON_MD_TSUNAMI "\xee\xaf\x98" // U+ebd8 @@ -2096,6 +2112,7 @@ #define ICON_MD_VIDEO_CALL "\xee\x81\xb0" // U+e070 #define ICON_MD_VIDEO_CAMERA_BACK "\xef\x81\xbf" // U+f07f #define ICON_MD_VIDEO_CAMERA_FRONT "\xef\x82\x80" // U+f080 +#define ICON_MD_VIDEO_CHAT "\xef\xa2\xa0" // U+f8a0 #define ICON_MD_VIDEO_COLLECTION "\xee\x81\x8a" // U+e04a #define ICON_MD_VIDEO_FILE "\xee\xae\x87" // U+eb87 #define ICON_MD_VIDEO_LABEL "\xee\x81\xb1" // U+e071 @@ -2180,7 +2197,6 @@ #define ICON_MD_WECHAT "\xee\xaa\x81" // U+ea81 #define ICON_MD_WEEKEND "\xee\x85\xab" // U+e16b #define ICON_MD_WEST "\xef\x87\xa6" // U+f1e6 -#define ICON_MD_WHATSAPP "\xee\xaa\x9c" // U+ea9c #define ICON_MD_WHATSHOT "\xee\xa0\x8e" // U+e80e #define ICON_MD_WHEELCHAIR_PICKUP "\xef\x86\xab" // U+f1ab #define ICON_MD_WHERE_TO_VOTE "\xee\x85\xb7" // U+e177 diff --git a/engine/split/3rd_nuklear.h b/engine/split/3rd_nuklear.h index ca606b9..3bdb781 100644 --- a/engine/split/3rd_nuklear.h +++ b/engine/split/3rd_nuklear.h @@ -24096,7 +24096,7 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, (type == NK_SYMBOL_TRIANGLE_DOWN) ? NK_GLYPH_CARET_DOWN_: //< @r-lyeh (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_GLYPH_CARET_LEFT_ : NK_GLYPH_CARET_RIGHT_; //< @r-lyeh struct nk_text text; //< @r-lyeh - text.padding = nk_vec2(-6,-2); //< @r-lyeh: 0,0 for FA + text.padding = nk_vec2(-6,-0); //< @r-lyeh: -6,-2 for MD, 0,0 for FA text.background = background; //< @r-lyeh text.text = foreground; //< @r-lyeh nk_widget_text(out, content, X, strlen(X), &text, NK_TEXT_LEFT|NK_TEXT_ALIGN_BOTTOM, font); //< @r-lyeh diff --git a/engine/split/3rd_nuklear_filebrowser.h b/engine/split/3rd_nuklear_filebrowser.h index ffa3f34..36c3800 100644 --- a/engine/split/3rd_nuklear_filebrowser.h +++ b/engine/split/3rd_nuklear_filebrowser.h @@ -229,8 +229,9 @@ static int browser_run(struct nk_context *ctx, struct browser *browser, int wind if( windowed ) nk_menubar_end(ctx); ctx->style.window.spacing.x = spacing_x; -if(nk_window_has_focus(ctx)) -browser->zooming = clampf( browser->zooming + input_diff(MOUSE_W) * 0.1, 1, 3); +if(nk_window_has_focus(ctx)) { +browser->zooming = clampf( browser->zooming + (input(KEY_LCTRL) || input(KEY_RCTRL)) * input_diff(MOUSE_W) * 0.1, 1, 3); +} bool compact = 0, tiny = browser->listing; // compact, no left panel. tiny, no large icons size_t cols = total_space.w / (100 * browser->zooming); diff --git a/engine/split/v4k_ds.c b/engine/split/v4k_ds.c index b790a7f..5878a48 100644 --- a/engine/split/v4k_ds.c +++ b/engine/split/v4k_ds.c @@ -57,6 +57,12 @@ uint64_t hash_str(const char* str) { while( *str ) hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; return hash; } +uint64_t hash_bin(const void* ptr, unsigned len) { + uint64_t hash = 14695981039346656037ULL; // hash(0),mul(131) faster than fnv1a, a few more collisions though + for( unsigned char *str = (unsigned char *)ptr; len--; ) + hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; + return hash; +} uint64_t hash_int(int key) { return hash_32((uint32_t)key); } diff --git a/engine/split/v4k_ds.h b/engine/split/v4k_ds.h index 8ced554..049aa75 100644 --- a/engine/split/v4k_ds.h +++ b/engine/split/v4k_ds.h @@ -21,9 +21,10 @@ API uint32_t unhash_32(uint32_t x); API uint32_t hash_32(uint32_t x); API uint64_t hash_64(uint64_t x); API uint64_t hash_flt(double x); -API uint64_t hash_str(const char* str); API uint64_t hash_int(int key); API uint64_t hash_ptr(const void* ptr); +API uint64_t hash_bin(const void* ptr, unsigned len); +API uint64_t hash_str(const char* str); // ----------------------------------------------------------------------------- // bits diff --git a/engine/split/v4k_file.c b/engine/split/v4k_file.c index d93a935..ef7b47b 100644 --- a/engine/split/v4k_file.c +++ b/engine/split/v4k_file.c @@ -174,7 +174,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio int ids_count = 0; char ids[64][64] = { 0 }; // split path stems - for each_substring(stem, "/\\", key) { + for each_substring(stem, "/\\@", key) { int tokens_count = 0; char* tokens[64] = { 0 }; // split tokens diff --git a/engine/split/v4k_input.c b/engine/split/v4k_input.c index 7be527e..6ae7c66 100644 --- a/engine/split/v4k_input.c +++ b/engine/split/v4k_input.c @@ -369,7 +369,9 @@ float input_frame( int vk, int frame ) { vec2 input_frame2( int vk, int frame ) { return vec2( input_frame(vk, frame), input_frame(vk+1, frame) ); } -const char *input_frames( int vk, int frame ) { + +const char *input_string( int vk ) { + int frame = 0; if( controller_id > 0 ) return ""; // @fixme struct controller_t *c = input_logger(frame, +0); return vk >= GAMEPAD_GUID ? c->strings[vk - GAMEPAD_GUID] : ""; // if in strings... @@ -621,37 +623,9 @@ bool input_touch_active() { #endif // !is(ems) -// ---------------------------------------------------------------------------- - -void input_demo() { - if( ui_panel("Input",0) ) { - ui_section("Keyboard"); - - uint8_t keymap = 0; - keymap |= (!!input(KEY_1)) << 7; - keymap |= (!!input(KEY_2)) << 6; - keymap |= (!!input(KEY_3)) << 5; - keymap |= (!!input(KEY_4)) << 4; - keymap |= (!!input(KEY_5)) << 3; - keymap |= (!!input(KEY_6)) << 2; - keymap |= (!!input(KEY_7)) << 1; - keymap |= (!!input(KEY_8)) << 0; - ui_bitmask8("[Keys 1..8]", &keymap); - - ui_separator(); - ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); - ui_separator(); - - ui_section("Mouse"); +int ui_mouse() { ui_label2_float("X", input(MOUSE_X)); ui_label2_float("Y", input(MOUSE_Y)); - ui_separator(); ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); ui_label2_bool("Left", input(MOUSE_L)); @@ -659,17 +633,52 @@ void input_demo() { ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); - ui_separator(); - static int gamepad_id = 0; - const char *list[] = {"1","2","3","4"}; - ui_section("GamePads"); - ui_list("Gamepad", list, 4, &gamepad_id); + return 0; +} +int ui_keyboard() { + char *keys[] = { + "ESC", + "TICK","1","2","3","4","5","6","7","8","9","0","BS", + "TAB","Q","W","E","R","T","Y","U","I","O","P", + "CAPS","A","S","D","F","G","H","J","K","L","ENTER", + "LSHIFT","Z","X","C","V","B","N","M","RSHIFT","^", + "LCTRL","LALT","SPACE","RALT","RCTRL","<","V",">", + }; + + vec2i rows[] = { + vec2i(0,1), + vec2i(1,13), + vec2i(13,24), + vec2i(24,35), + vec2i(35,45), + vec2i(45,countof(keys)), + }; + + for( int i = 0; i < countof(rows); ++i ) { + int any = 0; + char *row = 0; + for( int j = rows[i].x; j < rows[i].y; ++j ) { + strcatf(&row, input(KEY_ESC + j) ? (any|=1, "[%s]") : " %s ", keys[j]); + } + if(!any) ui_disable(); + ui_label(row); + ui_enable(); + FREE(row); + } + + return 0; +} + +int ui_gamepad(int gamepad_id) { input_use(gamepad_id); - ui_label2("Name", input_frames(GAMEPAD_NAME,0)); - ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); + bool connected = !!input(GAMEPAD_CONNECTED); + + ui_label2("Name", connected ? input_string(GAMEPAD_NAME) : "(Not connected)"); + + if( !connected ) ui_disable(); ui_separator(); @@ -708,8 +717,14 @@ void input_demo() { ui_label2_float("Filtered pad x", w.x); ui_label2_float("Filtered pad y", w.y); - input_use(0); + ui_enable(); - ui_panel_end(); + input_use(0); + return 0; } + +int ui_gamepads() { + for( int i = 0; i < 4; ++i ) ui_gamepad(i); + + return 0; } diff --git a/engine/split/v4k_input.h b/engine/split/v4k_input.h index 5f17f2f..8e6f07c 100644 --- a/engine/split/v4k_input.h +++ b/engine/split/v4k_input.h @@ -18,12 +18,12 @@ API float input( int vk ); API vec2 input2( int vk ); API float input_diff( int vk ); // @todo: rename diff->delta API vec2 input_diff2( int vk ); // @todo: rename diff2->delta2 +API const char* input_string( int vk ); // -- extended polling api (read input at Nth frame ago) -API float input_frame( int vk, int frame ); -API vec2 input_frame2( int vk, int frame ); -API const char* input_frames( int vk, int frame ); +API float input_frame( int vk, int Nth_frame ); +API vec2 input_frame2( int vk, int Nth_frame ); // -- events api @@ -62,14 +62,22 @@ API bool input_touch_active(); // -- utils -API void input_demo(); API void input_mappings(const char *filename); // update gamepad mappings (usually "gamecontrollerdb.txt" file) -API void input_send( int vk ); // @todo -API void* input_save_state( int id, int *size); // @todo -API bool input_load_state( int id, void *ptr, int size); // @todo API char input_keychar(unsigned code); // Converts keyboard code to its latin char (if any) API int input_anykey(); +// inject state +API void input_send( int vk ); // @todo +// load/save input +API array(char) save_input(); // @todo +API bool load_input(array(char) replay); // @todo + +// visualize input +API int ui_keyboard(); +API int ui_mouse(); +API int ui_gamepad(int id); +API int ui_gamepads(); + // -- enum INPUT_ENUMS { diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index ddaa218..ecea305 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -378,7 +378,7 @@ int ui_shader(unsigned shader) { } int ui_shaders() { - if( !map_count(shader_reflect) ) return 0; + if( !map_count(shader_reflect) ) return ui_label(ICON_MD_WARNING " No shaders with annotations loaded."), 0; int changed = 0; for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { @@ -3481,7 +3481,7 @@ int ui_fx(int pass) { return ui_postfx(&fx, pass); } int ui_fxs() { - if(!fx.num_loaded) return 0; + if(!fx.num_loaded) return ui_label(ICON_MD_WARNING " No Post FXs with annotations loaded."), 0; int changed = 0; for( int i = 0; i < 64; ++i ) { @@ -3489,6 +3489,7 @@ int ui_fxs() { bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); ui_fx(i); + ui_separator(); } return changed; } @@ -4749,17 +4750,21 @@ void model_destroy(model_t m) { anims_t animations(const char *pathfile, int flags) { anims_t a = {0}; - char *anim_file = vfs_read(va("%s@animlist.txt", pathfile)); - if( !anim_file ) anim_file = vfs_read(pathfile); + char *anim_file = vfs_read(strendi(pathfile,".txt") ? pathfile : va("%s@animlist.txt", pathfile)); if( anim_file ) { + // deserialize anim + a.speed = 1.0; for each_substring(anim_file, "\r\n", anim) { int from, to; char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; - array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] + array_push(a.anims, !!strstri(anim_name, "loop") || !strcmpi(anim_name, "idle") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } - a.speed = 1.0; + } else { + // placeholder + array_push(a.anims, clip(0,1,0,0)); + array_back(a.anims)->name = STRDUP("Error"); // @leak } return a; } diff --git a/engine/split/v4k_renderdd.c b/engine/split/v4k_renderdd.c index 2894346..780de6e 100644 --- a/engine/split/v4k_renderdd.c +++ b/engine/split/v4k_renderdd.c @@ -628,6 +628,30 @@ void ddraw_frustum(float projview[16]) { // Connect the dots: ddraw_bounds(points); } + +void ddraw_camera(camera_t *cam) { + vec3 center = cam->position; + vec3 rightdir = cross3(cam->lookdir,cam->updir); + float proj[16]; // reproject perspective matrix with a smaller view distance (100 units) + perspective44(proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 100.f); + + ddraw_color_push(YELLOW); + // frustum + mat44 projview; multiply44x2(projview, /*cam->*/proj, cam->view); + ddraw_frustum(projview); + // top circles + ddraw_circle(add3(center,add3(cam->lookdir,cam->updir)), rightdir, 2); + ddraw_circle(add3(center,add3(neg3(cam->lookdir),cam->updir)), rightdir, 2); + // orientation + ddraw_color(RED); + ddraw_arrow(cam->position, add3(cam->position,cam->lookdir)); + ddraw_color(GREEN); + ddraw_arrow(cam->position, add3(cam->position,cam->updir)); + ddraw_color(BLUE); + ddraw_arrow(cam->position, add3(cam->position,rightdir)); + ddraw_color_pop(); +} + void ddraw_arrow(vec3 begin, vec3 end) { vec3 diff = sub3(end, begin); float len = len3(diff), stick_len = len * 2 / 3; diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index 7e5bf67..7aae56d 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -6,24 +6,33 @@ static camera_t *last_camera; camera_t camera() { camera_t *old = last_camera; - camera_t cam = {0}; - cam.speed = 1; + static camera_t cam = {0}; + do_once { + cam.speed = 0.50f; cam.position = vec3(10,10,10); - cam.last_look = cam.last_move = vec3(0,0,0); - cam.up = vec3(0,1,0); + cam.updir = vec3(0,1,0); cam.fov = 45; + cam.damping = false; + cam.move_friction = 0.09f; + cam.move_damping = 0.96f; + cam.look_friction = 0.30f; + cam.look_damping = 0.96f; + cam.last_look = vec2(0,0); + cam.last_move = vec3(0,0,0); + // update proj & view camera_lookat(&cam,vec3(-5,0,-5)); - // @todo: remove this hack - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { + // @todo: remove this hack that is used to consolidate dampings + if( 1 ) { + vec3 zero = {0}; for( int i = 0; i < 1000; ++i ) { - camera_move(&cam,0,0,0); + camera_moveby(&cam, zero); camera_fps(&cam,0,0); } } + } last_camera = old; *camera_get_active() = cam; @@ -40,33 +49,37 @@ camera_t *camera_get_active() { return last_camera; } -void camera_move(camera_t *cam, float incx, float incy, float incz) { - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float move_friction = 0.99f; - cam->last_move = scale3(cam->last_move, move_friction); - float move_filtering = 0.975f; - incx = cam->last_move.x = incx * (1 - move_filtering) + cam->last_move.x * move_filtering; - incy = cam->last_move.y = incy * (1 - move_filtering) + cam->last_move.y * move_filtering; - incz = cam->last_move.z = incz * (1 - move_filtering) + cam->last_move.z * move_filtering; +void camera_moveby(camera_t *cam, vec3 inc) { + // calculate camera damping + if( cam->damping ) { + float fr = cam->move_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->move_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_move = scale3(cam->last_move, 1 - fr); + inc.x = cam->last_move.x = inc.x * (1 - sm) + cam->last_move.x * sm; + inc.y = cam->last_move.y = inc.y * (1 - sm) + cam->last_move.y * sm; + inc.z = cam->last_move.z = inc.z * (1 - sm) + cam->last_move.z * sm; } - vec3 dir = norm3(cross3(cam->look, cam->up)); - cam->position = add3(cam->position, scale3(dir, incx)); // right - cam->position = add3(cam->position, scale3(cam->up, incy)); // up - cam->position = add3(cam->position, scale3(cam->look, incz)); // front + vec3 dir = norm3(cross3(cam->lookdir, cam->updir)); + cam->position = add3(cam->position, scale3(dir, inc.x)); // right + cam->position = add3(cam->position, scale3(cam->updir, inc.y)); // up + cam->position = add3(cam->position, scale3(cam->lookdir, inc.z)); // front camera_fps(cam, 0, 0); } void camera_teleport(camera_t *cam, vec3 pos) { + bool damping = cam->damping; + cam->damping = 0; + cam->last_move = vec3(0,0,0); cam->position = pos; camera_fps(cam, 0, 0); + cam->damping = damping; } void camera_lookat(camera_t *cam, vec3 target) { - // invert expression that cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + // invert expression that cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); // look.y = sin p > y = asin(p) // look.x = cos y * cos p; -> cos p = look.x / cos y \ look.x / cos y = look.z / sin y // look.z = sin y * cos p; -> cos p = look.z / sin y / @@ -88,34 +101,8 @@ void camera_enable(camera_t *cam) { } void camera_fov(camera_t *cam, float fov) { - cam->fov = fov; -} - -void camera_fps(camera_t *cam, float yaw, float pitch) { last_camera = cam; - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float look_friction = 0.999f; - cam->last_look.x *= look_friction; - cam->last_look.y *= look_friction; - float look_filtering = 0.05f; - yaw = cam->last_look.y = yaw * look_filtering + cam->last_look.y * (1 - look_filtering); - pitch = cam->last_look.x = pitch * look_filtering + cam->last_look.x * (1 - look_filtering); - } - - cam->yaw += yaw; - cam->yaw = fmod(cam->yaw, 360); - cam->pitch += pitch; - cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; - - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; - cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); - - lookat44(cam->view, cam->position, add3(cam->position, cam->look), cam->up); // eye,center,up - perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); - #if 0 // isometric/dimetric #define orthogonal(proj, fov, aspect, znear, zfar) \ ortho44((proj), -(fov) * (aspect), (fov) * (aspect), -(fov), (fov), (znear), (zfar)) @@ -127,6 +114,33 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { // cam->yaw = 45; cam->pitch = -ISOMETRIC; #endif + cam->fov = fov; + perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); +} + +void camera_fps(camera_t *cam, float yaw, float pitch) { + last_camera = cam; + + // camera damping + if( cam->damping ) { + float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_look = scale2(cam->last_look, 1 - fr); + yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; + pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + } + + cam->yaw += yaw; + cam->yaw = fmod(cam->yaw, 360); + cam->pitch += pitch; + cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up + + camera_fov(cam, cam->fov); } void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { @@ -166,6 +180,28 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { cam->last_move.y = _mouse.y; } +int ui_camera( camera_t *cam ) { + int changed = 0; + changed |= ui_float("Speed", &cam->speed); + ui_separator(); + changed |= ui_bool("Damping", &cam->damping); + if( !cam->damping ) ui_disable(); + changed |= ui_slider2("Move friction", &cam->move_friction, va("%5.2f", cam->move_friction)); + changed |= ui_slider2("Move damping", &cam->move_damping, va("%5.2f", cam->move_damping)); + changed |= ui_slider2("View driction", &cam->look_friction, va("%5.2f", cam->look_friction)); + changed |= ui_slider2("View damping", &cam->look_damping, va("%5.2f", cam->look_damping)); + if( !cam->damping ) ui_enable(); + ui_separator(); + changed |= ui_float3("Position", &cam->position.x); + changed |= ui_float3("LookDir", &cam->lookdir.x); + changed |= ui_float3("UpDir", &cam->updir.x); + changed |= ui_mat44("View matrix", cam->view); + ui_separator(); + changed |= ui_float("FOV (degrees)", &cam->fov); + changed |= ui_mat44("Projection matrix", cam->proj); + return changed; +} + // ----------------------------------------------------------------------------- static diff --git a/engine/split/v4k_scene.h b/engine/split/v4k_scene.h index f827f0e..1952a8a 100644 --- a/engine/split/v4k_scene.h +++ b/engine/split/v4k_scene.h @@ -6,15 +6,19 @@ typedef struct camera_t { mat44 view, proj; - vec3 position, up, look; // position, updir, lookdir - float yaw, pitch, speed; // mirror_x, mirror_y; - vec3 last_look, last_move; // used for friction and smoothing - float fov; // deg(45) + vec3 position, updir, lookdir; + float yaw, pitch; // mirror of (x,y) lookdir in deg; + float speed, fov; // fov in deg(45) + + float move_friction, move_damping; + float look_friction, look_damping; + vec2 last_look; vec3 last_move; // used for friction and damping + bool damping; } camera_t; API camera_t camera(); API void camera_teleport(camera_t *cam, vec3 pos); -API void camera_move(camera_t *cam, float incx, float incy, float incz); +API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); @@ -22,6 +26,9 @@ API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam); API camera_t *camera_get_active(); +API int ui_camera(camera_t *cam); +API void ddraw_camera(camera_t *cam); + // object typedef struct object_t { diff --git a/engine/split/v4k_ui.c b/engine/split/v4k_ui.c index 764b9a7..5f4fd28 100644 --- a/engine/split/v4k_ui.c +++ b/engine/split/v4k_ui.c @@ -37,7 +37,7 @@ #else #define UI_ICON_FONTSIZE UI_FONT_ENUM(20,20) #define UI_ICON_SPACING_X UI_FONT_ENUM(0,0) - #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,4.5f) + #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,5.0f) #endif #define MAX_VERTEX_MEMORY 512 * 1024 @@ -800,7 +800,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(1); + ui_enable(); } } @@ -1458,26 +1458,35 @@ int ui_label_(const char *label, int alignment) { if( is_hovering ) { struct nk_rect winbounds = nk_window_get_bounds(ui_ctx); is_hovering &= nk_input_is_mouse_hovering_rect(input, winbounds); - is_hovering &= nk_window_has_focus(ui_ctx); + + struct nk_window *win = ui_ctx->current; + bool has_contextual = !win->name; // contextual windows are annonymous + + is_hovering &= has_contextual || nk_window_has_focus(ui_ctx); } int skip_color_tab = label && label[0] == '!'; if( skip_color_tab) label++; - int indent = 8; + int spacing = 8; // between left colorbar and content struct nk_window *win = ui_ctx->current; struct nk_panel *layout = win->layout; - layout->at_x += indent; - layout->bounds.w -= indent; + layout->at_x += spacing; + layout->bounds.w -= spacing; if( !skip_color_tab ) { - bounds.w = is_hovering ? indent*3/4 : indent/2-1; + float w = is_hovering ? 4 : 2; // spacing*3/4 : spacing/2-1; + bounds.w = w; bounds.h -= 1; struct nk_command_buffer *canvas = nk_window_get_canvas(ui_ctx); nk_fill_rect(canvas, bounds, 0, nk_hsva_f(ui_hue, 0.75f, 0.8f, ui_alpha) ); } - if(!label) return 0; - if(!label[0]) return 0; + if(!label || !label[0]) { + nk_label(ui_ctx, "", alignment); + layout->at_x -= spacing; + layout->bounds.w += spacing; + return 0; + } const char *split = strchr(label, '@'); char buffer[128]; if( split ) label = (snprintf(buffer, 128, "%.*s", (int)(split-label), label), buffer); @@ -1519,8 +1528,8 @@ if( font ) nk_style_pop_font(ui_ctx); nk_tooltip(ui_ctx, split + 1); } - layout->at_x -= indent; - layout->bounds.w += indent; + layout->at_x -= spacing; + layout->bounds.w += spacing; // old way // ui_labeicon_l_icked_L.x = is_hovering ? nk_input_has_mouse_click_down_in_rect(input, NK_BUTTON_LEFT, layout->bounds, nk_true) : 0; @@ -1538,7 +1547,7 @@ int ui_label(const char *text) { return ui_label_(text, align); } int ui_label2(const char *label, const char *text_) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); int align1 = label[0] == '>' ? (label++, NK_TEXT_RIGHT) : label[0] == '=' ? (label++, NK_TEXT_CENTERED) : label[0] == '<' ? (label++, NK_TEXT_LEFT) : NK_TEXT_LEFT; int align2 = text_[0] == '>' ? (text_++, NK_TEXT_RIGHT) : text_[0] == '=' ? (text_++, NK_TEXT_CENTERED) : text_[0] == '<' ? (text_++, NK_TEXT_LEFT) : NK_TEXT_LEFT; @@ -1570,7 +1579,7 @@ int ui_label2_float(const char *text, float value) { return ui_float(text, &f), 0; } int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_text_wrap(ui_ctx, str, strlen(str)); return 0; @@ -1690,7 +1699,7 @@ int ui_button(const char *s) { } int ui_toggle(const char *label, bool *value) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); // nk_label(ui_ctx, label, alignment); @@ -1708,7 +1717,7 @@ int ui_color4f(const char *label, float *color4) { static enum color_mode {COL_RGB, COL_HSV} ui_color_mode = COL_RGB; int ui_color4(const char *label, float *color4) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color4[0]*ui_alpha/255, color4[1]*ui_alpha/255, color4[2]*ui_alpha/255, color4[3]/255 }, before = after; @@ -1754,7 +1763,7 @@ int ui_color3f(const char *label, float *color3) { } int ui_color3(const char *label, float *color3) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color3[0]*ui_alpha/255, color3[1]*ui_alpha/255, color3[2]*ui_alpha/255, 1 }, before = after; @@ -1790,7 +1799,7 @@ int ui_color3(const char *label, float *color3) { } int ui_list(const char *label, const char **items, int num_items, int *selector) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = nk_combo(ui_ctx, items, num_items, *selector, UI_ROW_HEIGHT, nk_vec2(200,200)); @@ -1801,7 +1810,7 @@ int ui_list(const char *label, const char **items, int num_items, int *selector) int ui_slider(const char *label, float *slider) { // return ui_slider2(label, slider, va("%.2f ", *slider)); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_size val = *slider * 1000; @@ -1810,7 +1819,7 @@ int ui_slider(const char *label, float *slider) { return chg; } int ui_slider2(const char *label, float *slider, const char *caption) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_window *win = ui_ctx->current; @@ -1834,7 +1843,7 @@ int ui_slider2(const char *label, float *slider, const char *caption) { } int ui_bool(const char *label, bool *enabled ) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = *enabled; @@ -1848,7 +1857,7 @@ int ui_bool(const char *label, bool *enabled ) { } int ui_int(const char *label, int *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int prev = *v; @@ -1857,7 +1866,7 @@ int ui_int(const char *label, int *v) { } int ui_unsigned(const char *label, unsigned *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); unsigned prev = *v; @@ -1871,7 +1880,7 @@ int ui_short(const char *label, short *v) { } int ui_float(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f); @@ -1879,7 +1888,7 @@ int ui_float(const char *label, float *v) { } int ui_double(const char *label, double *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, 0.01f,0.005f); @@ -1889,7 +1898,7 @@ int ui_double(const char *label, double *v) { int ui_clampf(const char *label, float *v, float minf, float maxf) { if( minf > maxf ) return ui_clampf(label, v, maxf, minf); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f); @@ -1897,7 +1906,7 @@ int ui_clampf(const char *label, float *v, float minf, float maxf) { } int ui_float2(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f", v[0], v[1]); @@ -1912,7 +1921,7 @@ int ui_float2(const char *label, float *v) { } int ui_float3(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f", v[0], v[1], v[2]); @@ -1928,7 +1937,7 @@ int ui_float3(const char *label, float *v) { } int ui_float4(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f, %.2f", v[0], v[1], v[2], v[3]); @@ -1944,8 +1953,34 @@ int ui_float4(const char *label, float *v) { return 0; } +int ui_mat33(const char *label, float M[9]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float3(NULL, M); + changed |= ui_float3(NULL, M+3); + changed |= ui_float3(NULL, M+6); + return changed; +} +int ui_mat34(const char *label, float M[12]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + return changed; +} +int ui_mat44(const char *label, float M[16]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + changed |= ui_float4(NULL, M+12); + return changed; +} + int ui_buffer(const char *label, char *buffer, int buflen) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int active = nk_edit_string_zero_terminated(ui_ctx, NK_EDIT_AUTO_SELECT|NK_EDIT_CLIPBOARD|NK_EDIT_FIELD/*NK_EDIT_BOX*/|NK_EDIT_SIG_ENTER, buffer, buflen, nk_filter_default); @@ -1977,7 +2012,7 @@ int ui_separator() { } int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh) { - nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, label && label[0] ? 2 : 1); + nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, 1 + (label && label[0])); if( label && label[0] ) ui_label_(label, NK_TEXT_LEFT); struct nk_rect bounds; nk_layout_peek(&bounds, ui_ctx); bounds.w -= 10; // bounds.w *= 0.95f; diff --git a/engine/split/v4k_ui.h b/engine/split/v4k_ui.h index 129c24b..b74839b 100644 --- a/engine/split/v4k_ui.h +++ b/engine/split/v4k_ui.h @@ -22,6 +22,9 @@ API int ui_float(const char *label, float *value); API int ui_float2(const char *label, float value[2]); API int ui_float3(const char *label, float value[3]); API int ui_float4(const char *label, float value[4]); +API int ui_mat33(const char *label, float mat33[9]); +API int ui_mat34(const char *label, float mat34[12]); +API int ui_mat44(const char *label, float mat44[16]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); diff --git a/engine/split/v4k_window.c b/engine/split/v4k_window.c index 8b4b616..8353093 100644 --- a/engine/split/v4k_window.c +++ b/engine/split/v4k_window.c @@ -523,33 +523,94 @@ int window_frame_begin() { } // @transparent - static bool has_transparent_attrib = 0; do_once ifdef(ems, false, has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); + static bool has_transparent_attrib = 0; ifndef(ems, do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); if( has_transparent_attrib ) may_render_stats = 0; // @transparent // generate Debug panel contents if( may_render_stats ) { - if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + if( has_menu ? ui_window("Debug " ICON_MD_SETTINGS, 0) : ui_panel("Debug " ICON_MD_SETTINGS, 0) ) { + +#if 1 + static char *filter = 0; + static int do_filter = 0; + if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1; + int choice = ui_toolbar(ICON_MD_SEARCH ";"); + if( choice == 1 ) do_filter = 1; + if( do_filter ) { + ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &filter); + if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon) + do_filter = 0; + } + } else { + if( filter ) filter[0] = '\0'; + } + char *filter_mask = filter && filter[0] ? va("*%s*", filter) : "*"; +#endif int open = 0, clicked_or_toggled = 0; - for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + #define ui_collapse_filtered(lbl,id) (strmatchi(lbl,filter_mask) && ui_collapse(lbl,id)) + + for( int p = (open = ui_collapse_filtered(ICON_MD_FOLDER_SPECIAL " Art", "Debug.Art")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + bool inlined = true; + const char *file = 0; + if( ui_browse(&file, &inlined) ) { + const char *sep = ifdef(win32, "\"", "'"); + app_exec(va("%s %s%s%s", ifdef(win32, "start \"\"", ifdef(osx, "open", "xdg-open")), sep, file, sep)); + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_ROCKET_LAUNCH " AI", "Debug.AI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VOLUME_UP " Audio", "Debug.Audio")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIDEOCAM " Camera", "Debug.Camera")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_camera( camera_get_active() ); + } + for( int p = (open = ui_collapse_filtered(ICON_MD_BUILD " Cook", "Debug.Cook")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_SIGNAL_CELLULAR_ALT " Network", "Debug.Network")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_CONTENT_PASTE " Scripts", "Debug.Scripts")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_MOVIE " FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); } - for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_SPEED " Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_profiler(); } - for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_STAR_HALF " Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_shaders(); } - for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_KEYBOARD " Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_keyboard(); } - for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_MOUSE " Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_mouse(); } - for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_GAMEPAD " Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int q = 0; q < 4; ++q ) { + for( int r = (open = ui_collapse(va("Gamepad #%d",q+1), va("Debug.Gamepads%d",q))), dummy = (clicked_or_toggled = ui_collapse_clicked()); r; ui_collapse_end(), r = 0) { + ui_gamepad(q); + } + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIEW_QUILT " UI", "Debug.UI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + int choice = ui_toolbar(ICON_MD_RECYCLING " Reset layout;" ICON_MD_SAVE_AS " Save layout"); + if( choice == 1 ) ui_layout_all_reset("*"); + if( choice == 2 ) file_delete(WINDOWS_INI), ui_layout_all_save_disk("*"); + for each_map_ptr_sorted(ui_windows, char*, k, unsigned, v) { + bool visible = ui_visible(*k); + if( ui_bool( *k, &visible ) ) { + ui_show( *k, ui_visible(*k) ^ true ); + } + } } (has_menu ? ui_window_end : ui_panel_end)(); @@ -623,6 +684,9 @@ void window_frame_swap() { #endif glfwSwapBuffers(window); // emscripten_webgl_commit_frame(); + + static int delay = 0; do_once delay = optioni("--delay", 0); + if( delay && !COOK_ON_DEMAND && cook_progress() >= 100 ) sleep_ms( delay ); } static diff --git a/engine/v4k b/engine/v4k index d864bf7..0470f4e 100644 --- a/engine/v4k +++ b/engine/v4k @@ -11886,6 +11886,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_ASPECT_RATIO "\xee\xa1\x9b" // U+e85b #define ICON_MD_ASSESSMENT "\xee\xa1\x9c" // U+e85c #define ICON_MD_ASSIGNMENT "\xee\xa1\x9d" // U+e85d +#define ICON_MD_ASSIGNMENT_ADD "\xef\xa1\x88" // U+f848 #define ICON_MD_ASSIGNMENT_IND "\xee\xa1\x9e" // U+e85e #define ICON_MD_ASSIGNMENT_LATE "\xee\xa1\x9f" // U+e85f #define ICON_MD_ASSIGNMENT_RETURN "\xee\xa1\xa0" // U+e860 @@ -11931,6 +11932,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_BALCONY "\xee\x96\x8f" // U+e58f #define ICON_MD_BALLOT "\xee\x85\xb2" // U+e172 #define ICON_MD_BAR_CHART "\xee\x89\xab" // U+e26b +#define ICON_MD_BARCODE_READER "\xef\xa1\x9c" // U+f85c #define ICON_MD_BATCH_PREDICTION "\xef\x83\xb5" // U+f0f5 #define ICON_MD_BATHROOM "\xee\xbf\x9d" // U+efdd #define ICON_MD_BATHTUB "\xee\xa9\x81" // U+ea41 @@ -12169,6 +12171,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_CONTROL_CAMERA "\xee\x81\xb4" // U+e074 #define ICON_MD_CONTROL_POINT "\xee\x8e\xba" // U+e3ba #define ICON_MD_CONTROL_POINT_DUPLICATE "\xee\x8e\xbb" // U+e3bb +#define ICON_MD_CONVEYOR_BELT "\xef\xa1\xa7" // U+f867 #define ICON_MD_COOKIE "\xee\xaa\xac" // U+eaac #define ICON_MD_COPY_ALL "\xee\x8b\xac" // U+e2ec #define ICON_MD_COPYRIGHT "\xee\xa4\x8c" // U+e90c @@ -12252,6 +12255,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_DEVICES "\xee\x86\xb1" // U+e1b1 #define ICON_MD_DEVICES_FOLD "\xee\xaf\x9e" // U+ebde #define ICON_MD_DEVICES_OTHER "\xee\x8c\xb7" // U+e337 +#define ICON_MD_DEW_POINT "\xef\xa1\xb9" // U+f879 #define ICON_MD_DIALER_SIP "\xee\x82\xbb" // U+e0bb #define ICON_MD_DIALPAD "\xee\x82\xbc" // U+e0bc #define ICON_MD_DIAMOND "\xee\xab\x95" // U+ead5 @@ -12347,12 +12351,14 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_EDIT "\xee\x8f\x89" // U+e3c9 #define ICON_MD_EDIT_ATTRIBUTES "\xee\x95\xb8" // U+e578 #define ICON_MD_EDIT_CALENDAR "\xee\x9d\x82" // U+e742 +#define ICON_MD_EDIT_DOCUMENT "\xef\xa2\x8c" // U+f88c #define ICON_MD_EDIT_LOCATION "\xee\x95\xa8" // U+e568 #define ICON_MD_EDIT_LOCATION_ALT "\xee\x87\x85" // U+e1c5 #define ICON_MD_EDIT_NOTE "\xee\x9d\x85" // U+e745 #define ICON_MD_EDIT_NOTIFICATIONS "\xee\x94\xa5" // U+e525 #define ICON_MD_EDIT_OFF "\xee\xa5\x90" // U+e950 #define ICON_MD_EDIT_ROAD "\xee\xbd\x8d" // U+ef4d +#define ICON_MD_EDIT_SQUARE "\xef\xa2\x8d" // U+f88d #define ICON_MD_EGG "\xee\xab\x8c" // U+eacc #define ICON_MD_EGG_ALT "\xee\xab\x88" // U+eac8 #define ICON_MD_EJECT "\xee\xa3\xbb" // U+e8fb @@ -12454,6 +12460,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FILE_OPEN "\xee\xab\xb3" // U+eaf3 #define ICON_MD_FILE_PRESENT "\xee\xa8\x8e" // U+ea0e #define ICON_MD_FILE_UPLOAD "\xee\x8b\x86" // U+e2c6 +#define ICON_MD_FILE_UPLOAD_OFF "\xef\xa2\x86" // U+f886 #define ICON_MD_FILTER "\xee\x8f\x93" // U+e3d3 #define ICON_MD_FILTER_1 "\xee\x8f\x90" // U+e3d0 #define ICON_MD_FILTER_2 "\xee\x8f\x91" // U+e3d1 @@ -12511,6 +12518,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FLIP_TO_FRONT "\xee\xa2\x83" // U+e883 #define ICON_MD_FLOOD "\xee\xaf\xa6" // U+ebe6 #define ICON_MD_FLOURESCENT "\xef\x80\x8d" // U+f00d +#define ICON_MD_FLUORESCENT "\xee\xb0\xb1" // U+ec31 #define ICON_MD_FLUTTER_DASH "\xee\x80\x8b" // U+e00b #define ICON_MD_FMD_BAD "\xef\x80\x8e" // U+f00e #define ICON_MD_FMD_GOOD "\xef\x80\x8f" // U+f00f @@ -12530,6 +12538,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FOREST "\xee\xaa\x99" // U+ea99 #define ICON_MD_FORK_LEFT "\xee\xae\xa0" // U+eba0 #define ICON_MD_FORK_RIGHT "\xee\xae\xac" // U+ebac +#define ICON_MD_FORKLIFT "\xef\xa1\xa8" // U+f868 #define ICON_MD_FORMAT_ALIGN_CENTER "\xee\x88\xb4" // U+e234 #define ICON_MD_FORMAT_ALIGN_JUSTIFY "\xee\x88\xb5" // U+e235 #define ICON_MD_FORMAT_ALIGN_LEFT "\xee\x88\xb6" // U+e236 @@ -12544,6 +12553,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FORMAT_ITALIC "\xee\x88\xbf" // U+e23f #define ICON_MD_FORMAT_LINE_SPACING "\xee\x89\x80" // U+e240 #define ICON_MD_FORMAT_LIST_BULLETED "\xee\x89\x81" // U+e241 +#define ICON_MD_FORMAT_LIST_BULLETED_ADD "\xef\xa1\x89" // U+f849 #define ICON_MD_FORMAT_LIST_NUMBERED "\xee\x89\x82" // U+e242 #define ICON_MD_FORMAT_LIST_NUMBERED_RTL "\xee\x89\xa7" // U+e267 #define ICON_MD_FORMAT_OVERLINE "\xee\xad\xa5" // U+eb65 @@ -12567,6 +12577,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_FREE_BREAKFAST "\xee\xad\x84" // U+eb44 #define ICON_MD_FREE_CANCELLATION "\xee\x9d\x88" // U+e748 #define ICON_MD_FRONT_HAND "\xee\x9d\xa9" // U+e769 +#define ICON_MD_FRONT_LOADER "\xef\xa1\xa9" // U+f869 #define ICON_MD_FULLSCREEN "\xee\x97\x90" // U+e5d0 #define ICON_MD_FULLSCREEN_EXIT "\xee\x97\x91" // U+e5d1 #define ICON_MD_FUNCTIONS "\xee\x89\x8a" // U+e24a @@ -12969,6 +12980,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_MOVE_UP "\xee\xad\xa4" // U+eb64 #define ICON_MD_MOVIE "\xee\x80\xac" // U+e02c #define ICON_MD_MOVIE_CREATION "\xee\x90\x84" // U+e404 +#define ICON_MD_MOVIE_EDIT "\xef\xa1\x80" // U+f840 #define ICON_MD_MOVIE_FILTER "\xee\x90\xba" // U+e43a #define ICON_MD_MOVING "\xee\x94\x81" // U+e501 #define ICON_MD_MP "\xee\xa7\x83" // U+e9c3 @@ -13083,6 +13095,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_PAGEVIEW "\xee\xa2\xa0" // U+e8a0 #define ICON_MD_PAID "\xef\x81\x81" // U+f041 #define ICON_MD_PALETTE "\xee\x90\x8a" // U+e40a +#define ICON_MD_PALLET "\xef\xa1\xaa" // U+f86a #define ICON_MD_PAN_TOOL "\xee\xa4\xa5" // U+e925 #define ICON_MD_PAN_TOOL_ALT "\xee\xae\xb9" // U+ebb9 #define ICON_MD_PANORAMA "\xee\x90\x8b" // U+e40b @@ -13277,6 +13290,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_RAW_ON "\xef\x81\x90" // U+f050 #define ICON_MD_READ_MORE "\xee\xbd\xad" // U+ef6d #define ICON_MD_REAL_ESTATE_AGENT "\xee\x9c\xba" // U+e73a +#define ICON_MD_REBASE_EDIT "\xef\xa1\x86" // U+f846 #define ICON_MD_RECEIPT "\xee\xa2\xb0" // U+e8b0 #define ICON_MD_RECEIPT_LONG "\xee\xbd\xae" // U+ef6e #define ICON_MD_RECENT_ACTORS "\xee\x80\xbf" // U+e03f @@ -13442,6 +13456,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_SHARE "\xee\xa0\x8d" // U+e80d #define ICON_MD_SHARE_ARRIVAL_TIME "\xee\x94\xa4" // U+e524 #define ICON_MD_SHARE_LOCATION "\xef\x81\x9f" // U+f05f +#define ICON_MD_SHELVES "\xef\xa1\xae" // U+f86e #define ICON_MD_SHIELD "\xee\xa7\xa0" // U+e9e0 #define ICON_MD_SHIELD_MOON "\xee\xaa\xa9" // U+eaa9 #define ICON_MD_SHOP "\xee\xa3\x89" // U+e8c9 @@ -13734,6 +13749,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_TRENDING_NEUTRAL "\xee\xa3\xa4" // U+e8e4 #define ICON_MD_TRENDING_UP "\xee\xa3\xa5" // U+e8e5 #define ICON_MD_TRIP_ORIGIN "\xee\x95\xbb" // U+e57b +#define ICON_MD_TROLLEY "\xef\xa1\xab" // U+f86b #define ICON_MD_TROUBLESHOOT "\xee\x87\x92" // U+e1d2 #define ICON_MD_TRY "\xef\x81\xbc" // U+f07c #define ICON_MD_TSUNAMI "\xee\xaf\x98" // U+ebd8 @@ -13787,6 +13803,7 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_VIDEO_CALL "\xee\x81\xb0" // U+e070 #define ICON_MD_VIDEO_CAMERA_BACK "\xef\x81\xbf" // U+f07f #define ICON_MD_VIDEO_CAMERA_FRONT "\xef\x82\x80" // U+f080 +#define ICON_MD_VIDEO_CHAT "\xef\xa2\xa0" // U+f8a0 #define ICON_MD_VIDEO_COLLECTION "\xee\x81\x8a" // U+e04a #define ICON_MD_VIDEO_FILE "\xee\xae\x87" // U+eb87 #define ICON_MD_VIDEO_LABEL "\xee\x81\xb1" // U+e071 @@ -13871,7 +13888,6 @@ int gladLoadGL( GLADloadfunc load) { #define ICON_MD_WECHAT "\xee\xaa\x81" // U+ea81 #define ICON_MD_WEEKEND "\xee\x85\xab" // U+e16b #define ICON_MD_WEST "\xef\x87\xa6" // U+f1e6 -#define ICON_MD_WHATSAPP "\xee\xaa\x9c" // U+ea9c #define ICON_MD_WHATSHOT "\xee\xa0\x8e" // U+e80e #define ICON_MD_WHEELCHAIR_PICKUP "\xef\x86\xab" // U+f1ab #define ICON_MD_WHERE_TO_VOTE "\xee\x85\xb7" // U+e177 @@ -213825,7 +213841,7 @@ nk_draw_symbol(struct nk_command_buffer *out, enum nk_symbol_type type, (type == NK_SYMBOL_TRIANGLE_DOWN) ? NK_GLYPH_CARET_DOWN_: //< @r-lyeh (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_GLYPH_CARET_LEFT_ : NK_GLYPH_CARET_RIGHT_; //< @r-lyeh struct nk_text text; //< @r-lyeh - text.padding = nk_vec2(-6,-2); //< @r-lyeh: 0,0 for FA + text.padding = nk_vec2(-6,-0); //< @r-lyeh: -6,-2 for MD, 0,0 for FA text.background = background; //< @r-lyeh text.text = foreground; //< @r-lyeh nk_widget_text(out, content, X, strlen(X), &text, NK_TEXT_LEFT|NK_TEXT_ALIGN_BOTTOM, font); //< @r-lyeh @@ -220870,8 +220886,9 @@ static int browser_run(struct nk_context *ctx, struct browser *browser, int wind if( windowed ) nk_menubar_end(ctx); ctx->style.window.spacing.x = spacing_x; -if(nk_window_has_focus(ctx)) -browser->zooming = clampf( browser->zooming + input_diff(MOUSE_W) * 0.1, 1, 3); +if(nk_window_has_focus(ctx)) { +browser->zooming = clampf( browser->zooming + (input(KEY_LCTRL) || input(KEY_RCTRL)) * input_diff(MOUSE_W) * 0.1, 1, 3); +} bool compact = 0, tiny = browser->listing; // compact, no left panel. tiny, no large icons size_t cols = total_space.w / (100 * browser->zooming); @@ -292693,7 +292710,7 @@ extern "C" { // =======================================================================// #if (defined _MSC_VER && defined _WIN32 && !defined _WIN64) || \ - (defined __MINGW32__ && !defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh + (defined __MINGW32__ || defined __MINGW64__) // (!defined _WIN32 && defined __MINGW32__ && defined ENET_MINGW_COMPAT) //< @r-lyeh #define MUST_DEFINE_NTOP_PTON 1 #else #define MUST_DEFINE_NTOP_PTON 0 diff --git a/engine/v4k.c b/engine/v4k.c index a078936..5d2f205 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -161,6 +161,12 @@ uint64_t hash_str(const char* str) { while( *str ) hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; return hash; } +uint64_t hash_bin(const void* ptr, unsigned len) { + uint64_t hash = 14695981039346656037ULL; // hash(0),mul(131) faster than fnv1a, a few more collisions though + for( unsigned char *str = (unsigned char *)ptr; len--; ) + hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; + return hash; +} uint64_t hash_int(int key) { return hash_32((uint32_t)key); } @@ -4310,7 +4316,7 @@ char *ext = strrchr(base, '.'); //if (ext) ext[0] = '\0'; // remove all extensio int ids_count = 0; char ids[64][64] = { 0 }; // split path stems - for each_substring(stem, "/\\", key) { + for each_substring(stem, "/\\@", key) { int tokens_count = 0; char* tokens[64] = { 0 }; // split tokens @@ -7890,7 +7896,9 @@ float input_frame( int vk, int frame ) { vec2 input_frame2( int vk, int frame ) { return vec2( input_frame(vk, frame), input_frame(vk+1, frame) ); } -const char *input_frames( int vk, int frame ) { + +const char *input_string( int vk ) { + int frame = 0; if( controller_id > 0 ) return ""; // @fixme struct controller_t *c = input_logger(frame, +0); return vk >= GAMEPAD_GUID ? c->strings[vk - GAMEPAD_GUID] : ""; // if in strings... @@ -8142,37 +8150,9 @@ bool input_touch_active() { #endif // !is(ems) -// ---------------------------------------------------------------------------- - -void input_demo() { - if( ui_panel("Input",0) ) { - ui_section("Keyboard"); - - uint8_t keymap = 0; - keymap |= (!!input(KEY_1)) << 7; - keymap |= (!!input(KEY_2)) << 6; - keymap |= (!!input(KEY_3)) << 5; - keymap |= (!!input(KEY_4)) << 4; - keymap |= (!!input(KEY_5)) << 3; - keymap |= (!!input(KEY_6)) << 2; - keymap |= (!!input(KEY_7)) << 1; - keymap |= (!!input(KEY_8)) << 0; - ui_bitmask8("[Keys 1..8]", &keymap); - - ui_separator(); - ui_label2_bool("[Key 1] Down event", input_down(KEY_1) ); - ui_label2_bool("[Key 2] Held event", input_held(KEY_2) ); - ui_label2_bool("[Key 3] Up event", input_up(KEY_3) ); - ui_label2_bool("[Key 4] Idle event", input_idle(KEY_4) ); - ui_label2_bool("[Key 5] Click event", input_click(KEY_5,500) ); - ui_label2_bool("[Key 6] Click2 event", input_click2(KEY_6,1000) ); - ui_label2_bool("[Key 7] Repeat event", input_repeat(KEY_7,750) ); - ui_separator(); - - ui_section("Mouse"); +int ui_mouse() { ui_label2_float("X", input(MOUSE_X)); ui_label2_float("Y", input(MOUSE_Y)); - ui_separator(); ui_label2_float("Wheel", input(MOUSE_W)); ui_separator(); ui_label2_bool("Left", input(MOUSE_L)); @@ -8180,17 +8160,52 @@ void input_demo() { ui_label2_bool("Right", input(MOUSE_R)); ui_separator(); for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i); - ui_separator(); - static int gamepad_id = 0; - const char *list[] = {"1","2","3","4"}; - ui_section("GamePads"); - ui_list("Gamepad", list, 4, &gamepad_id); + return 0; +} +int ui_keyboard() { + char *keys[] = { + "ESC", + "TICK","1","2","3","4","5","6","7","8","9","0","BS", + "TAB","Q","W","E","R","T","Y","U","I","O","P", + "CAPS","A","S","D","F","G","H","J","K","L","ENTER", + "LSHIFT","Z","X","C","V","B","N","M","RSHIFT","^", + "LCTRL","LALT","SPACE","RALT","RCTRL","<","V",">", + }; + + vec2i rows[] = { + vec2i(0,1), + vec2i(1,13), + vec2i(13,24), + vec2i(24,35), + vec2i(35,45), + vec2i(45,countof(keys)), + }; + + for( int i = 0; i < countof(rows); ++i ) { + int any = 0; + char *row = 0; + for( int j = rows[i].x; j < rows[i].y; ++j ) { + strcatf(&row, input(KEY_ESC + j) ? (any|=1, "[%s]") : " %s ", keys[j]); + } + if(!any) ui_disable(); + ui_label(row); + ui_enable(); + FREE(row); + } + + return 0; +} + +int ui_gamepad(int gamepad_id) { input_use(gamepad_id); - ui_label2("Name", input_frames(GAMEPAD_NAME,0)); - ui_label2_bool("Connected", input(GAMEPAD_CONNECTED)); + bool connected = !!input(GAMEPAD_CONNECTED); + + ui_label2("Name", connected ? input_string(GAMEPAD_NAME) : "(Not connected)"); + + if( !connected ) ui_disable(); ui_separator(); @@ -8229,10 +8244,16 @@ void input_demo() { ui_label2_float("Filtered pad x", w.x); ui_label2_float("Filtered pad y", w.y); - input_use(0); + ui_enable(); - ui_panel_end(); + input_use(0); + return 0; } + +int ui_gamepads() { + for( int i = 0; i < 4; ++i ) ui_gamepad(i); + + return 0; } #line 0 @@ -10709,7 +10730,7 @@ int ui_shader(unsigned shader) { } int ui_shaders() { - if( !map_count(shader_reflect) ) return 0; + if( !map_count(shader_reflect) ) return ui_label(ICON_MD_WARNING " No shaders with annotations loaded."), 0; int changed = 0; for each_map_ptr(shader_reflect, unsigned, k, array(char*), v) { @@ -13812,7 +13833,7 @@ int ui_fx(int pass) { return ui_postfx(&fx, pass); } int ui_fxs() { - if(!fx.num_loaded) return 0; + if(!fx.num_loaded) return ui_label(ICON_MD_WARNING " No Post FXs with annotations loaded."), 0; int changed = 0; for( int i = 0; i < 64; ++i ) { @@ -13820,6 +13841,7 @@ int ui_fxs() { bool b = fx_enabled(i); if( ui_bool(name, &b) ) fx_enable(i, fx_enabled(i) ^ 1); ui_fx(i); + ui_separator(); } return changed; } @@ -15080,17 +15102,21 @@ void model_destroy(model_t m) { anims_t animations(const char *pathfile, int flags) { anims_t a = {0}; - char *anim_file = vfs_read(va("%s@animlist.txt", pathfile)); - if( !anim_file ) anim_file = vfs_read(pathfile); + char *anim_file = vfs_read(strendi(pathfile,".txt") ? pathfile : va("%s@animlist.txt", pathfile)); if( anim_file ) { + // deserialize anim + a.speed = 1.0; for each_substring(anim_file, "\r\n", anim) { int from, to; char anim_name[128] = {0}; if( sscanf(anim, "%*s %d-%d %127[^\r\n]", &from, &to, anim_name) != 3) continue; - array_push(a.anims, !!strstri(anim_name, "loop") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] + array_push(a.anims, !!strstri(anim_name, "loop") || !strcmpi(anim_name, "idle") ? loop(from, to, 0, 0) : clip(from, to, 0, 0)); // [from,to,flags] array_back(a.anims)->name = strswap(strswap(strswap(STRDUP(anim_name), "Loop", ""), "loop", ""), "()", ""); // @leak } - a.speed = 1.0; + } else { + // placeholder + array_push(a.anims, clip(0,1,0,0)); + array_back(a.anims)->name = STRDUP("Error"); // @leak } return a; } @@ -15727,6 +15753,30 @@ void ddraw_frustum(float projview[16]) { // Connect the dots: ddraw_bounds(points); } + +void ddraw_camera(camera_t *cam) { + vec3 center = cam->position; + vec3 rightdir = cross3(cam->lookdir,cam->updir); + float proj[16]; // reproject perspective matrix with a smaller view distance (100 units) + perspective44(proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 100.f); + + ddraw_color_push(YELLOW); + // frustum + mat44 projview; multiply44x2(projview, /*cam->*/proj, cam->view); + ddraw_frustum(projview); + // top circles + ddraw_circle(add3(center,add3(cam->lookdir,cam->updir)), rightdir, 2); + ddraw_circle(add3(center,add3(neg3(cam->lookdir),cam->updir)), rightdir, 2); + // orientation + ddraw_color(RED); + ddraw_arrow(cam->position, add3(cam->position,cam->lookdir)); + ddraw_color(GREEN); + ddraw_arrow(cam->position, add3(cam->position,cam->updir)); + ddraw_color(BLUE); + ddraw_arrow(cam->position, add3(cam->position,rightdir)); + ddraw_color_pop(); +} + void ddraw_arrow(vec3 begin, vec3 end) { vec3 diff = sub3(end, begin); float len = len3(diff), stick_len = len * 2 / 3; @@ -15929,24 +15979,33 @@ static camera_t *last_camera; camera_t camera() { camera_t *old = last_camera; - camera_t cam = {0}; - cam.speed = 1; + static camera_t cam = {0}; + do_once { + cam.speed = 0.50f; cam.position = vec3(10,10,10); - cam.last_look = cam.last_move = vec3(0,0,0); - cam.up = vec3(0,1,0); + cam.updir = vec3(0,1,0); cam.fov = 45; + cam.damping = false; + cam.move_friction = 0.09f; + cam.move_damping = 0.96f; + cam.look_friction = 0.30f; + cam.look_damping = 0.96f; + cam.last_look = vec2(0,0); + cam.last_move = vec3(0,0,0); + // update proj & view camera_lookat(&cam,vec3(-5,0,-5)); - // @todo: remove this hack - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { + // @todo: remove this hack that is used to consolidate dampings + if( 1 ) { + vec3 zero = {0}; for( int i = 0; i < 1000; ++i ) { - camera_move(&cam,0,0,0); + camera_moveby(&cam, zero); camera_fps(&cam,0,0); } } + } last_camera = old; *camera_get_active() = cam; @@ -15963,33 +16022,37 @@ camera_t *camera_get_active() { return last_camera; } -void camera_move(camera_t *cam, float incx, float incy, float incz) { - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float move_friction = 0.99f; - cam->last_move = scale3(cam->last_move, move_friction); - float move_filtering = 0.975f; - incx = cam->last_move.x = incx * (1 - move_filtering) + cam->last_move.x * move_filtering; - incy = cam->last_move.y = incy * (1 - move_filtering) + cam->last_move.y * move_filtering; - incz = cam->last_move.z = incz * (1 - move_filtering) + cam->last_move.z * move_filtering; +void camera_moveby(camera_t *cam, vec3 inc) { + // calculate camera damping + if( cam->damping ) { + float fr = cam->move_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->move_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_move = scale3(cam->last_move, 1 - fr); + inc.x = cam->last_move.x = inc.x * (1 - sm) + cam->last_move.x * sm; + inc.y = cam->last_move.y = inc.y * (1 - sm) + cam->last_move.y * sm; + inc.z = cam->last_move.z = inc.z * (1 - sm) + cam->last_move.z * sm; } - vec3 dir = norm3(cross3(cam->look, cam->up)); - cam->position = add3(cam->position, scale3(dir, incx)); // right - cam->position = add3(cam->position, scale3(cam->up, incy)); // up - cam->position = add3(cam->position, scale3(cam->look, incz)); // front + vec3 dir = norm3(cross3(cam->lookdir, cam->updir)); + cam->position = add3(cam->position, scale3(dir, inc.x)); // right + cam->position = add3(cam->position, scale3(cam->updir, inc.y)); // up + cam->position = add3(cam->position, scale3(cam->lookdir, inc.z)); // front camera_fps(cam, 0, 0); } void camera_teleport(camera_t *cam, vec3 pos) { + bool damping = cam->damping; + cam->damping = 0; + cam->last_move = vec3(0,0,0); cam->position = pos; camera_fps(cam, 0, 0); + cam->damping = damping; } void camera_lookat(camera_t *cam, vec3 target) { - // invert expression that cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + // invert expression that cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); // look.y = sin p > y = asin(p) // look.x = cos y * cos p; -> cos p = look.x / cos y \ look.x / cos y = look.z / sin y // look.z = sin y * cos p; -> cos p = look.z / sin y / @@ -16011,34 +16074,8 @@ void camera_enable(camera_t *cam) { } void camera_fov(camera_t *cam, float fov) { - cam->fov = fov; -} - -void camera_fps(camera_t *cam, float yaw, float pitch) { last_camera = cam; - // enable camera smoothing - static int smoothing = -1; if( smoothing < 0 ) smoothing = flag("--camera-smooth"); - if( smoothing ) { - float look_friction = 0.999f; - cam->last_look.x *= look_friction; - cam->last_look.y *= look_friction; - float look_filtering = 0.05f; - yaw = cam->last_look.y = yaw * look_filtering + cam->last_look.y * (1 - look_filtering); - pitch = cam->last_look.x = pitch * look_filtering + cam->last_look.x * (1 - look_filtering); - } - - cam->yaw += yaw; - cam->yaw = fmod(cam->yaw, 360); - cam->pitch += pitch; - cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; - - const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; - cam->look = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); - - lookat44(cam->view, cam->position, add3(cam->position, cam->look), cam->up); // eye,center,up - perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); - #if 0 // isometric/dimetric #define orthogonal(proj, fov, aspect, znear, zfar) \ ortho44((proj), -(fov) * (aspect), (fov) * (aspect), -(fov), (fov), (znear), (zfar)) @@ -16050,6 +16087,33 @@ void camera_fps(camera_t *cam, float yaw, float pitch) { // cam->yaw = 45; cam->pitch = -ISOMETRIC; #endif + cam->fov = fov; + perspective44(cam->proj, cam->fov, window_width() / ((float)window_height()+!window_height()), 0.01f, 1000.f); +} + +void camera_fps(camera_t *cam, float yaw, float pitch) { + last_camera = cam; + + // camera damping + if( cam->damping ) { + float fr = cam->look_friction; fr *= fr; fr *= fr; fr *= fr; + float sm = clampf(cam->look_damping, 0, 0.999f); sm *= sm; sm *= sm; + + cam->last_look = scale2(cam->last_look, 1 - fr); + yaw = cam->last_look.y = yaw * (1 - sm) + cam->last_look.y * sm; + pitch = cam->last_look.x = pitch * (1 - sm) + cam->last_look.x * sm; + } + + cam->yaw += yaw; + cam->yaw = fmod(cam->yaw, 360); + cam->pitch += pitch; + cam->pitch = cam->pitch > 89 ? 89 : cam->pitch < -89 ? -89 : cam->pitch; + + const float deg2rad = 0.0174532f, y = cam->yaw * deg2rad, p = cam->pitch * deg2rad; + cam->lookdir = norm3(vec3(cos(y) * cos(p), sin(p), sin(y) * cos(p))); + lookat44(cam->view, cam->position, add3(cam->position, cam->lookdir), cam->updir); // eye,center,up + + camera_fov(cam, cam->fov); } void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { @@ -16089,6 +16153,28 @@ void camera_orbit( camera_t *cam, float yaw, float pitch, float inc_distance ) { cam->last_move.y = _mouse.y; } +int ui_camera( camera_t *cam ) { + int changed = 0; + changed |= ui_float("Speed", &cam->speed); + ui_separator(); + changed |= ui_bool("Damping", &cam->damping); + if( !cam->damping ) ui_disable(); + changed |= ui_slider2("Move friction", &cam->move_friction, va("%5.2f", cam->move_friction)); + changed |= ui_slider2("Move damping", &cam->move_damping, va("%5.2f", cam->move_damping)); + changed |= ui_slider2("View driction", &cam->look_friction, va("%5.2f", cam->look_friction)); + changed |= ui_slider2("View damping", &cam->look_damping, va("%5.2f", cam->look_damping)); + if( !cam->damping ) ui_enable(); + ui_separator(); + changed |= ui_float3("Position", &cam->position.x); + changed |= ui_float3("LookDir", &cam->lookdir.x); + changed |= ui_float3("UpDir", &cam->updir.x); + changed |= ui_mat44("View matrix", cam->view); + ui_separator(); + changed |= ui_float("FOV (degrees)", &cam->fov); + changed |= ui_mat44("Projection matrix", cam->proj); + return changed; +} + // ----------------------------------------------------------------------------- static @@ -17750,7 +17836,7 @@ void thread_destroy( void *thd ) { #else #define UI_ICON_FONTSIZE UI_FONT_ENUM(20,20) #define UI_ICON_SPACING_X UI_FONT_ENUM(0,0) - #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,4.5f) + #define UI_ICON_SPACING_Y UI_FONT_ENUM(6.5f,5.0f) #endif #define MAX_VERTEX_MEMORY 512 * 1024 @@ -18513,7 +18599,7 @@ void ui_create() { nk_glfw3_new_frame(&nk_glfw); //g->nk_glfw); ui_dirty = 0; - ui_enable(1); + ui_enable(); } } @@ -19171,26 +19257,35 @@ int ui_label_(const char *label, int alignment) { if( is_hovering ) { struct nk_rect winbounds = nk_window_get_bounds(ui_ctx); is_hovering &= nk_input_is_mouse_hovering_rect(input, winbounds); - is_hovering &= nk_window_has_focus(ui_ctx); + + struct nk_window *win = ui_ctx->current; + bool has_contextual = !win->name; // contextual windows are annonymous + + is_hovering &= has_contextual || nk_window_has_focus(ui_ctx); } int skip_color_tab = label && label[0] == '!'; if( skip_color_tab) label++; - int indent = 8; + int spacing = 8; // between left colorbar and content struct nk_window *win = ui_ctx->current; struct nk_panel *layout = win->layout; - layout->at_x += indent; - layout->bounds.w -= indent; + layout->at_x += spacing; + layout->bounds.w -= spacing; if( !skip_color_tab ) { - bounds.w = is_hovering ? indent*3/4 : indent/2-1; + float w = is_hovering ? 4 : 2; // spacing*3/4 : spacing/2-1; + bounds.w = w; bounds.h -= 1; struct nk_command_buffer *canvas = nk_window_get_canvas(ui_ctx); nk_fill_rect(canvas, bounds, 0, nk_hsva_f(ui_hue, 0.75f, 0.8f, ui_alpha) ); } - if(!label) return 0; - if(!label[0]) return 0; + if(!label || !label[0]) { + nk_label(ui_ctx, "", alignment); + layout->at_x -= spacing; + layout->bounds.w += spacing; + return 0; + } const char *split = strchr(label, '@'); char buffer[128]; if( split ) label = (snprintf(buffer, 128, "%.*s", (int)(split-label), label), buffer); @@ -19232,8 +19327,8 @@ if( font ) nk_style_pop_font(ui_ctx); nk_tooltip(ui_ctx, split + 1); } - layout->at_x -= indent; - layout->bounds.w += indent; + layout->at_x -= spacing; + layout->bounds.w += spacing; // old way // ui_labeicon_l_icked_L.x = is_hovering ? nk_input_has_mouse_click_down_in_rect(input, NK_BUTTON_LEFT, layout->bounds, nk_true) : 0; @@ -19251,7 +19346,7 @@ int ui_label(const char *text) { return ui_label_(text, align); } int ui_label2(const char *label, const char *text_) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); int align1 = label[0] == '>' ? (label++, NK_TEXT_RIGHT) : label[0] == '=' ? (label++, NK_TEXT_CENTERED) : label[0] == '<' ? (label++, NK_TEXT_LEFT) : NK_TEXT_LEFT; int align2 = text_[0] == '>' ? (text_++, NK_TEXT_RIGHT) : text_[0] == '=' ? (text_++, NK_TEXT_CENTERED) : text_[0] == '<' ? (text_++, NK_TEXT_LEFT) : NK_TEXT_LEFT; @@ -19283,7 +19378,7 @@ int ui_label2_float(const char *text, float value) { return ui_float(text, &f), 0; } int ui_label2_wrap(const char *label, const char *str) { // @fixme: does not work (remove dynamic layout?) - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_text_wrap(ui_ctx, str, strlen(str)); return 0; @@ -19403,7 +19498,7 @@ int ui_button(const char *s) { } int ui_toggle(const char *label, bool *value) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); // nk_label(ui_ctx, label, alignment); @@ -19421,7 +19516,7 @@ int ui_color4f(const char *label, float *color4) { static enum color_mode {COL_RGB, COL_HSV} ui_color_mode = COL_RGB; int ui_color4(const char *label, float *color4) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color4[0]*ui_alpha/255, color4[1]*ui_alpha/255, color4[2]*ui_alpha/255, color4[3]/255 }, before = after; @@ -19467,7 +19562,7 @@ int ui_color3f(const char *label, float *color3) { } int ui_color3(const char *label, float *color3) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_colorf after = { color3[0]*ui_alpha/255, color3[1]*ui_alpha/255, color3[2]*ui_alpha/255, 1 }, before = after; @@ -19503,7 +19598,7 @@ int ui_color3(const char *label, float *color3) { } int ui_list(const char *label, const char **items, int num_items, int *selector) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = nk_combo(ui_ctx, items, num_items, *selector, UI_ROW_HEIGHT, nk_vec2(200,200)); @@ -19514,7 +19609,7 @@ int ui_list(const char *label, const char **items, int num_items, int *selector) int ui_slider(const char *label, float *slider) { // return ui_slider2(label, slider, va("%.2f ", *slider)); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); nk_size val = *slider * 1000; @@ -19523,7 +19618,7 @@ int ui_slider(const char *label, float *slider) { return chg; } int ui_slider2(const char *label, float *slider, const char *caption) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); struct nk_window *win = ui_ctx->current; @@ -19547,7 +19642,7 @@ int ui_slider2(const char *label, float *slider, const char *caption) { } int ui_bool(const char *label, bool *enabled ) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int val = *enabled; @@ -19561,7 +19656,7 @@ int ui_bool(const char *label, bool *enabled ) { } int ui_int(const char *label, int *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int prev = *v; @@ -19570,7 +19665,7 @@ int ui_int(const char *label, int *v) { } int ui_unsigned(const char *label, unsigned *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); unsigned prev = *v; @@ -19584,7 +19679,7 @@ int ui_short(const char *label, short *v) { } int ui_float(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", -FLT_MAX, v[0], FLT_MAX, 0.01f,0.005f); @@ -19592,7 +19687,7 @@ int ui_float(const char *label, float *v) { } int ui_double(const char *label, double *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); double prev = v[0]; v[0] = nk_propertyd(ui_ctx, "#", -DBL_MAX, v[0], DBL_MAX, 0.01f,0.005f); @@ -19602,7 +19697,7 @@ int ui_double(const char *label, double *v) { int ui_clampf(const char *label, float *v, float minf, float maxf) { if( minf > maxf ) return ui_clampf(label, v, maxf, minf); - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); float prev = v[0]; v[0] = nk_propertyf(ui_ctx, "#", minf, v[0], maxf, 0.1f,0.05f); @@ -19610,7 +19705,7 @@ int ui_clampf(const char *label, float *v, float minf, float maxf) { } int ui_float2(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f", v[0], v[1]); @@ -19625,7 +19720,7 @@ int ui_float2(const char *label, float *v) { } int ui_float3(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f", v[0], v[1], v[2]); @@ -19641,7 +19736,7 @@ int ui_float3(const char *label, float *v) { } int ui_float4(const char *label, float *v) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); char *buffer = va("%.2f, %.2f, %.2f, %.2f", v[0], v[1], v[2], v[3]); @@ -19657,8 +19752,34 @@ int ui_float4(const char *label, float *v) { return 0; } +int ui_mat33(const char *label, float M[9]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float3(NULL, M); + changed |= ui_float3(NULL, M+3); + changed |= ui_float3(NULL, M+6); + return changed; +} +int ui_mat34(const char *label, float M[12]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + return changed; +} +int ui_mat44(const char *label, float M[16]) { + int changed = 0; + changed |= ui_label(label); + changed |= ui_float4(NULL, M); + changed |= ui_float4(NULL, M+4); + changed |= ui_float4(NULL, M+8); + changed |= ui_float4(NULL, M+12); + return changed; +} + int ui_buffer(const char *label, char *buffer, int buflen) { - nk_layout_row_dynamic(ui_ctx, 0, 2 - (label ? !label[0] : 1)); + nk_layout_row_dynamic(ui_ctx, 0, 2); ui_label_(label, NK_TEXT_LEFT); int active = nk_edit_string_zero_terminated(ui_ctx, NK_EDIT_AUTO_SELECT|NK_EDIT_CLIPBOARD|NK_EDIT_FIELD/*NK_EDIT_BOX*/|NK_EDIT_SIG_ENTER, buffer, buflen, nk_filter_default); @@ -19690,7 +19811,7 @@ int ui_separator() { } int ui_subimage(const char *label, handle id, unsigned iw, unsigned ih, unsigned sx, unsigned sy, unsigned sw, unsigned sh) { - nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, label && label[0] ? 2 : 1); + nk_layout_row_dynamic(ui_ctx, sh < 30 || id == texture_checker().id ? 0 : sh, 1 + (label && label[0])); if( label && label[0] ) ui_label_(label, NK_TEXT_LEFT); struct nk_rect bounds; nk_layout_peek(&bounds, ui_ctx); bounds.w -= 10; // bounds.w *= 0.95f; @@ -20935,33 +21056,94 @@ int window_frame_begin() { } // @transparent - static bool has_transparent_attrib = 0; do_once ifdef(ems, false, has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); + static bool has_transparent_attrib = 0; ifndef(ems, do_once has_transparent_attrib = glfwGetWindowAttrib(window_handle(), GLFW_TRANSPARENT_FRAMEBUFFER) == GLFW_TRUE); if( has_transparent_attrib ) may_render_stats = 0; // @transparent // generate Debug panel contents if( may_render_stats ) { - if( has_menu ? ui_window("Debug", 0) : ui_panel("Debug", 0) ) { + if( has_menu ? ui_window("Debug " ICON_MD_SETTINGS, 0) : ui_panel("Debug " ICON_MD_SETTINGS, 0) ) { + +#if 1 + static char *filter = 0; + static int do_filter = 0; + if( input_down(KEY_F) ) if( input(KEY_LCTRL) || input(KEY_RCTRL) ) do_filter ^= 1; + int choice = ui_toolbar(ICON_MD_SEARCH ";"); + if( choice == 1 ) do_filter = 1; + if( do_filter ) { + ui_string(ICON_MD_CLOSE " Filter " ICON_MD_SEARCH, &filter); + if( ui_label_icon_clicked_L.x > 0 && ui_label_icon_clicked_L.x <= 24 ) { // if clicked on CANCEL icon (1st icon) + do_filter = 0; + } + } else { + if( filter ) filter[0] = '\0'; + } + char *filter_mask = filter && filter[0] ? va("*%s*", filter) : "*"; +#endif int open = 0, clicked_or_toggled = 0; - for( int p = (open = ui_collapse("FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + #define ui_collapse_filtered(lbl,id) (strmatchi(lbl,filter_mask) && ui_collapse(lbl,id)) + + for( int p = (open = ui_collapse_filtered(ICON_MD_FOLDER_SPECIAL " Art", "Debug.Art")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + bool inlined = true; + const char *file = 0; + if( ui_browse(&file, &inlined) ) { + const char *sep = ifdef(win32, "\"", "'"); + app_exec(va("%s %s%s%s", ifdef(win32, "start \"\"", ifdef(osx, "open", "xdg-open")), sep, file, sep)); + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_ROCKET_LAUNCH " AI", "Debug.AI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VOLUME_UP " Audio", "Debug.Audio")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIDEOCAM " Camera", "Debug.Camera")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_camera( camera_get_active() ); + } + for( int p = (open = ui_collapse_filtered(ICON_MD_BUILD " Cook", "Debug.Cook")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_SIGNAL_CELLULAR_ALT " Network", "Debug.Network")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_CONTENT_PASTE " Scripts", "Debug.Scripts")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + // @todo + } + for( int p = (open = ui_collapse_filtered(ICON_MD_MOVIE " FXs", "Debug.FXs")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_fxs(); } - for( int p = (open = ui_collapse("Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_SPEED " Profiler", "Debug.Profiler")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_profiler(); } - for( int p = (open = ui_collapse("Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_STAR_HALF " Shaders", "Debug.Shaders")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { ui_shaders(); } - for( int p = (open = ui_collapse("Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_KEYBOARD " Keyboard", "Debug.Keyboard")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_keyboard(); } - for( int p = (open = ui_collapse("Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { - + for( int p = (open = ui_collapse_filtered(ICON_MD_MOUSE " Mouse", "Debug.Mouse")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + ui_mouse(); } - for( int p = (open = ui_collapse("Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int p = (open = ui_collapse_filtered(ICON_MD_GAMEPAD " Gamepads", "Debug.Gamepads")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + for( int q = 0; q < 4; ++q ) { + for( int r = (open = ui_collapse(va("Gamepad #%d",q+1), va("Debug.Gamepads%d",q))), dummy = (clicked_or_toggled = ui_collapse_clicked()); r; ui_collapse_end(), r = 0) { + ui_gamepad(q); + } + } + } + for( int p = (open = ui_collapse_filtered(ICON_MD_VIEW_QUILT " UI", "Debug.UI")), dummy = (clicked_or_toggled = ui_collapse_clicked()); p; ui_collapse_end(), p = 0) { + int choice = ui_toolbar(ICON_MD_RECYCLING " Reset layout;" ICON_MD_SAVE_AS " Save layout"); + if( choice == 1 ) ui_layout_all_reset("*"); + if( choice == 2 ) file_delete(WINDOWS_INI), ui_layout_all_save_disk("*"); + for each_map_ptr_sorted(ui_windows, char*, k, unsigned, v) { + bool visible = ui_visible(*k); + if( ui_bool( *k, &visible ) ) { + ui_show( *k, ui_visible(*k) ^ true ); + } + } } (has_menu ? ui_window_end : ui_panel_end)(); @@ -21035,6 +21217,9 @@ void window_frame_swap() { #endif glfwSwapBuffers(window); // emscripten_webgl_commit_frame(); + + static int delay = 0; do_once delay = optioni("--delay", 0); + if( delay && !COOK_ON_DEMAND && cook_progress() >= 100 ) sleep_ms( delay ); } static diff --git a/engine/v4k.h b/engine/v4k.h index d983ee4..feefa2b 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -415,9 +415,10 @@ API uint32_t unhash_32(uint32_t x); API uint32_t hash_32(uint32_t x); API uint64_t hash_64(uint64_t x); API uint64_t hash_flt(double x); -API uint64_t hash_str(const char* str); API uint64_t hash_int(int key); API uint64_t hash_ptr(const void* ptr); +API uint64_t hash_bin(const void* ptr, unsigned len); +API uint64_t hash_str(const char* str); // ----------------------------------------------------------------------------- // bits @@ -2018,12 +2019,12 @@ API float input( int vk ); API vec2 input2( int vk ); API float input_diff( int vk ); // @todo: rename diff->delta API vec2 input_diff2( int vk ); // @todo: rename diff2->delta2 +API const char* input_string( int vk ); // -- extended polling api (read input at Nth frame ago) -API float input_frame( int vk, int frame ); -API vec2 input_frame2( int vk, int frame ); -API const char* input_frames( int vk, int frame ); +API float input_frame( int vk, int Nth_frame ); +API vec2 input_frame2( int vk, int Nth_frame ); // -- events api @@ -2062,14 +2063,22 @@ API bool input_touch_active(); // -- utils -API void input_demo(); API void input_mappings(const char *filename); // update gamepad mappings (usually "gamecontrollerdb.txt" file) -API void input_send( int vk ); // @todo -API void* input_save_state( int id, int *size); // @todo -API bool input_load_state( int id, void *ptr, int size); // @todo API char input_keychar(unsigned code); // Converts keyboard code to its latin char (if any) API int input_anykey(); +// inject state +API void input_send( int vk ); // @todo +// load/save input +API array(char) save_input(); // @todo +API bool load_input(array(char) replay); // @todo + +// visualize input +API int ui_keyboard(); +API int ui_mouse(); +API int ui_gamepad(int id); +API int ui_gamepads(); + // -- enum INPUT_ENUMS { @@ -3230,15 +3239,19 @@ API void ddraw_flush_projview(mat44 proj, mat44 view); typedef struct camera_t { mat44 view, proj; - vec3 position, up, look; // position, updir, lookdir - float yaw, pitch, speed; // mirror_x, mirror_y; - vec3 last_look, last_move; // used for friction and smoothing - float fov; // deg(45) + vec3 position, updir, lookdir; + float yaw, pitch; // mirror of (x,y) lookdir in deg; + float speed, fov; // fov in deg(45) + + float move_friction, move_damping; + float look_friction, look_damping; + vec2 last_look; vec3 last_move; // used for friction and damping + bool damping; } camera_t; API camera_t camera(); API void camera_teleport(camera_t *cam, vec3 pos); -API void camera_move(camera_t *cam, float incx, float incy, float incz); +API void camera_moveby(camera_t *cam, vec3 inc); API void camera_fov(camera_t *cam, float fov); API void camera_fps(camera_t *cam, float yaw, float pitch); API void camera_orbit(camera_t *cam, float yaw, float pitch, float inc_distance); @@ -3246,6 +3259,9 @@ API void camera_lookat(camera_t *cam, vec3 target); API void camera_enable(camera_t *cam); API camera_t *camera_get_active(); +API int ui_camera(camera_t *cam); +API void ddraw_camera(camera_t *cam); + // object typedef struct object_t { @@ -3568,6 +3584,9 @@ API int ui_float(const char *label, float *value); API int ui_float2(const char *label, float value[2]); API int ui_float3(const char *label, float value[3]); API int ui_float4(const char *label, float value[4]); +API int ui_mat33(const char *label, float mat33[9]); +API int ui_mat34(const char *label, float mat34[12]); +API int ui_mat44(const char *label, float mat44[16]); API int ui_double(const char *label, double *value); API int ui_buffer(const char *label, char *buffer, int buflen); API int ui_string(const char *label, char **string); diff --git a/hello.c b/hello.c index 94e9de6..2c07e60 100644 --- a/hello.c +++ b/hello.c @@ -56,7 +56,7 @@ int main() { if( active ) cam.speed = clampf(cam.speed + input_diff(MOUSE_W) / 10, 0.05f, 5.0f); vec2 mouse = scale2(vec2(input_diff(MOUSE_X), -input_diff(MOUSE_Y)), 0.2f * active); vec3 wasdecq = scale3(vec3(input(KEY_D)-input(KEY_A),input(KEY_E)-(input(KEY_C)||input(KEY_Q)),input(KEY_W)-input(KEY_S)), cam.speed); - camera_move(&cam, wasdecq.x,wasdecq.y,wasdecq.z); + camera_moveby(&cam, wasdecq); camera_fps(&cam, mouse.x,mouse.y); window_cursor( !active ); diff --git a/tools/file2hash.c b/tools/file2hash.c new file mode 100644 index 0000000..850367b --- /dev/null +++ b/tools/file2hash.c @@ -0,0 +1,69 @@ +// cl modhash.c /O2 /Oy /MT /DNDEBUG /link setargv.obj +// tcc modhash.c -O2 + +#include +#include +#include +#include + +uint64_t hash_64(uint64_t x) { + x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9); + x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb); + x = x ^ (x >> 31); + return x; +} + +uint64_t hash_bin(const void* ptr, unsigned len) { + uint64_t hash = 14695981039346656037ULL; // hash(0),mul(131) faster than fnv1a, a few more collisions though + for( unsigned char *str = (unsigned char *)ptr; len--; ) + hash = ( (unsigned char)*str++ ^ hash ) * 0x100000001b3ULL; + return hash; +} + +uint64_t hash_str(const char* str) { + return hash_bin(str, strlen(str)+1); +} + +char *file_load(const char *filename, int *len) { // @todo: 32 counters/thread enough? + FILE *fp = fopen(filename, "rb"); + if( fp ) { + fseek(fp, 0L, SEEK_END); + size_t sz = ftell(fp); + fseek(fp, 0L, SEEK_SET); + char *buffer = malloc(sz+1); + sz *= fread(buffer,sz,1,fp) == 1; + buffer[sz] = 0; + if(len) *len = (int)sz; + fclose(fp); + return buffer; // @fixme: return 0 on error instead? + } + if (len) *len = 0; + return 0; +} + +uint64_t file_stamp(const char *fname) { + struct stat st; + return stat(fname, &st) < 0 ? 0ULL : st.st_mtime; +} + +int main(int argc, char **argv) { + if( argc < 2 ) return printf("%s [infiles...] [-- strings...]\n", argv[0]), 0; + + int strings = 0; + uint64_t hash = 0; + for(int i = 1; i < argc; ++i) { + if( !strcmp(argv[i], "--") ) strings = 1; + else { + int size = 0; char *ptr = strings ? 0 : file_load(argv[i], &size); + uint64_t hash_contents = ptr ? hash_bin(ptr, size) : hash_str(argv[i]); + uint64_t hash_modt = ptr ? hash_64( file_stamp(argv[i]) ) : 0; + uint64_t hash_size = ptr ? hash_64( size ) : strlen(argv[i]); + // if( ptr ) free(ptr); // speed optimization, do not free() + + hash ^= hash_contents ^ hash_modt ^ hash_size; + } + } + + printf("%llu\n", hash); + return hash & 0x7FFFFFFF; +} diff --git a/tools/file2hash.exe b/tools/file2hash.exe new file mode 100644 index 0000000..f831239 Binary files /dev/null and b/tools/file2hash.exe differ diff --git a/v4k.html b/v4k.html new file mode 100644 index 0000000..e69de29