Compare commits

...
290 Commits
Author SHA1 Message Date
Dakotah fe065803aa THIS ADDS FEATURE REQUEST ISSUE TO GITHUB (#514)
* Add feature request template

* Add feature request template

* Add labels to feature request template automatically

* switch labels to enhancement
2024-05-30 16:30:09 -07:00
ah-OOG-ah f94268c384 Add null check to FluidRenderer (#513)
* Add null check to FluidRenderer

* Update FluidRenderer.java
2024-05-30 17:56:32 -04:00
jss2a98aj f7a8b0f3bf Cloud scaling, distance, and some fixes 2024-05-24 22:16:41 -07:00
embeddedt 8893cf2291 Mark chunk graph as dirty when FOV changes (#506) 2024-05-24 15:59:46 -04:00
Jason Mitchell adc575c5ab remaps 2024-05-23 20:00:21 -07:00
Jason Mitchell 35a056b73b Patches vanilla getFlowDirection to not crash with a ClassCastException if another mod implements their own fluid renderer and calls getFlowDirection when COFH ASM is loaded 2024-05-23 20:00:21 -07:00
jss2a98aj fbbb0ed4f2 Various cleanup (IJK -> XYZ etc) 2024-05-23 19:49:49 -07:00
jss2a98aj bc148ba09c Updated file overlooked in previous sync 2024-05-23 19:49:49 -07:00
jss2a98aj 1db3932af0 Roll ITileOverride into TileOverride 2024-05-23 19:49:49 -07:00
jss2a98aj 0fd4611a97 Refactor glass pane mixins to solve compat issues 2024-05-23 19:49:49 -07:00
jss2a98aj 27243991b7 Add near fog distance percentage slider
Initial commit by MellowArpeggiation and George Paton
FOG_NEAR to FOG_NEAR_DISTANCE, minimum of 1% by jss2a98aj
2024-05-23 19:49:49 -07:00
jss2a98aj 956eec0366 Face culling for the Enchantment Table 2024-05-23 19:49:49 -07:00
jss2a98aj 9b06c5a210 Add interpolated icon support (Roadhog360) 2024-05-23 19:49:49 -07:00
jss2a98aj 5511759b6d Fix door smooth lighting, cull sides against solid blocks 2024-05-23 19:49:49 -07:00
jss2a98aj fb5aa81e01 Sandstone connected textures 2024-05-23 19:49:49 -07:00
jss2a98aj 6592e13e02 Improve Bookshelf connected textures 2024-05-23 19:49:49 -07:00
Jason Mitchell 31174dc35a Update README.MD 2024-05-23 17:57:46 -07:00
Caedis f0bd9de081 Disable Dynamic Lights video option when module is disabled (#491) 2024-05-17 20:18:23 +00:00
Jason Mitchell 75617a5456 More null checks 2024-05-14 23:23:01 -07:00
Jason Mitchell e158faada0 Only set/access texture info cache from the main thread 2024-05-14 22:35:21 -07:00
Raven Szewczyk f684bc0a1b Fix RenderBlockFluid reading the block type from the world access multiple times (#482)
* Fix RenderBlockFluid reading the block type from the world access multiple times

* Fix compiler warnings
2024-05-13 18:04:58 +01:00
Jason Mitchell 3d56b1c2fc Make TextureInfoCache safer 2024-05-12 09:35:43 -07:00
Jason Mitchell 6e60f671b5 Neuter FML optifine detection/reporting 2024-05-11 10:33:45 -07:00
Caedis 323d2e726c Adjust dynamic lights in World#getLightBrightnessForSkyBlocks as well (#466)
This can be called when rendering is done on the main there as
WorldSlice is only used outside the main thread.
2024-05-06 08:50:25 -07:00
88d5030aa9 Add Dynamic Lights to Alpha (Module Off, Lights Off) (#465)
If a player is reading this and wants dynamic lights during alpha, please enable the module in the angelica-modules config file then the config option in the video settings will take effect.

* Implement Dynamic Lights (#360)

* inital dynamicLights

* continue work

* Add credit

* More implementations

* "Working"

* NotFine 0.2.2 sync (#462)

* Slight cleanup in ColorizeBlock

* Don't call System.gc

* Add toggle for Renderpass (forced to false)

* Dont rebuild the same chunk 8 times

* Use client pos

* Fully working + configs

* Clean up

* Fix readme and gradle properties

* Fix tooltip

* nit changes

---------

Co-authored-by: jss2a98aj <[email protected]>

* Might help if the dynamic lights mixins follow the config setting

* Fix shadows from showing on sides of blocks

* Set dynamic lights module to off for alpha

* Add missed enable checks

---------

Co-authored-by: jss2a98aj <[email protected]>
Co-authored-by: Jason Mitchell <[email protected]>
2024-05-06 00:19:50 +00:00
jss2a98aj 894b9573db Natura + Tinker's Construct berry bush leaf mode support 2024-05-05 13:42:36 -07:00
jss2a98aj d8d8cd93c5 Leaf render mode edge case handling 2024-05-05 13:42:36 -07:00
jss2a98aj 986f1bd6a1 NotFine 0.2.2 sync (#462)
* Slight cleanup in ColorizeBlock

* Don't call System.gc

* Add toggle for Renderpass (forced to false)
2024-05-03 23:54:02 -04:00
jss2a98aj e85ca85027 Small NotFine style settings menu fix (#457)
* Fix allowToggle3DAnaglyph

* Remove unused import
2024-05-01 07:26:18 -07:00
Raven Szewczyk d96023f36c Fix FontRenderer intel issue (#456) 2024-04-30 17:55:03 +00:00
Jason Mitchell 203b552993 Attempt at BetterCrashes Compat
- clean up the CapturingTessellator
- clean up GLStateManager
2024-04-29 10:50:56 -07:00
Jason Mitchell 96e2f42251 Update Mixins.java (#447)
Move some Notfine guarded mixins to enableMCPatcherForgeFeatures
2024-04-28 15:06:23 -07:00
Raven Szewczyk 9a73dc9bfd Fix glMultMatrix using the wrong variable for multiplication (#444)
* Fix glMultMatrix using the wrong variable for multiplication

* Fix "conersion" typo
2024-04-27 18:46:35 +00:00
Darren Eberly f01cdfda4b Thread safe ISBRH compatibility with Extra Utilities 2 (#439)
* Initial ASM stuff for Extra Utils thread safety

* Thread safety for connected textures

* More thread-safe blocks

* Remove EU2 references, combine ASM transformers

* Remove unusued ModStatus check for Extra Utils
2024-04-25 12:56:24 -07:00
Caedis daa1405ba4 Only disable holoinventory when hudcaching is enabled 2024-04-25 08:14:24 -07:00
jss2a98aj 846d70f0c0 Fix NotFine Twilight Forest compat mixins builder 2024-04-19 11:35:56 -07:00
jss2a98aj e59e41bfdb Sync NotFine
Could scale and render distance NYI
2024-04-19 07:56:08 -07:00
George PatonandGeorge Paton eb8a826419 Fix render distance being capped at 20 (#428)
* Fix render distance being capped at 20 in singleplayer

* Clean up imports

---------

Co-authored-by: George Paton <[email protected]>
2024-04-19 12:58:33 +00:00
boubou19 efe7c16c50 remove donations as author has nothing to do with angelica 2024-04-17 12:49:21 +02:00
wahfl2 c4b4b79f6c Add more methods present in modern MatrixStack 2024-04-11 09:37:54 -07:00
Caedis 2e5ce0abdb Check if hudcaching is enabled before removing xaeros ASM (#419) 2024-04-10 19:36:49 -07:00
Caedis d317b05f5b Fix flickering of Xaero's Map Waypoints (#418)
* update bs

* Fix Xaero's Waypoints
2024-04-10 16:05:45 +00:00
Jason Mitchell cc51a464f1 Remove duplicate unimixins dependency 2024-04-04 10:23:50 -07:00
makamys 3e6aa461c6 Fix crash when Sodium is disabled 2024-03-27 09:06:48 -07:00
Moses Miller d236689e6a Allow the user to select more gui scales (#399) 2024-03-25 09:19:35 -07:00
Caedis d15bbb56ee Add void fog option (default false) (#398) 2024-03-24 19:48:09 -07:00
Jason Mitchell f4355bd4c4 More readable 2024-03-23 21:14:11 -07:00
makamys 5dbd244d72 Readme tweaks (#391)
* [skip ci] Add logo to readme

* [skip ci] README: add CurseForge and Modrinth links
2024-03-20 16:48:06 -07:00
Jason Mitchell 367c82a225 [ci skip] Add CF/MN project info 2024-03-18 08:19:07 -07:00
Jason Mitchell 852bcbb38b Check before casting.
Fixes https://github.com/GTNewHorizons/Angelica/issues/388
2024-03-16 11:24:38 -07:00
ah-OOG-ah 464af945b2 Fix AIOBE in debug screen and NPE on world join (#385)
* Fix AIIOBE

* Fix NPE

* Actually fix
2024-03-15 21:42:38 -04:00
makamys 996b3df9cb Use vanilla field to count number of chunk updates
Fixes D-Tools compat
2024-03-15 15:23:48 -07:00
makamys 22d28abce6 Use ByteBuffer overload when indirect buffer is in client memory
Fixes #373
2024-03-15 15:23:37 -07:00
Jason Mitchell 636b616f64 Stop blacklisting bartworks. (#369)
Needs https://github.com/GTNewHorizons/bartworks/commit/50dfbb44acdd28bc183dc58b9cd40d5ba5121685
2024-03-09 09:27:22 -08:00
Caedis 14b7178419 Initialize toggle keybind when registering (#366)
* Initialize toggle keybind when registering

* Add comment
2024-03-08 15:26:36 -08:00
Caedis 22bf48c093 Potential fix for splash screen crashes (#363)
* Move framebuffer static initializor to getter

* missed one

* Revert "missed one"

This reverts commit 97027c1372.

* Revert "Move framebuffer static initializor to getter"

This reverts commit 6ef65735ff.

* Initialize HudCaching on world join

* run it on the client only

* remove unused imports
2024-03-08 12:40:51 -06:00
Caedis 4600bca2d0 Mixin to override FOV multiplier instead of using the forge event (#361)
* Mixin to speed check instead of using fov event

* scratch that, override return value entirely

* Revert "scratch that, override return value entirely"

This reverts commit 20a379d766.

* Revert "Mixin to speed check instead of using fov event"

This reverts commit 22db36d677.

* Change to lowest priority event so it is ran last (hopefully)
2024-03-08 10:26:34 -06:00
Jason Mitchell fcb9536d93 Don't blacklist gregtech from the render thread (#356) 2024-03-03 15:20:04 -08:00
embeddedt 51a6a72ae5 Only track rendered sprites on specific RenderBlocks instances (#355)
* Only track rendered sprites on specific RenderBlocks instances
2024-03-03 10:10:47 -08:00
Jason Mitchell f41f27e706 Some misbehaving mods *cough GT5u cough* enjoy reallocating textures all the time, so try a normal hash set instead of a reference one... 2024-03-03 09:26:33 -08:00
ah-OOG-ah 346a305f1d Refactor Quad, BlockPos, and QuadProvider API
Also optimize static models
2024-02-29 21:17:46 -05:00
ah-OOG-ah da8f700068 Update LICENSE 2024-02-29 21:17:46 -05:00
ah-OOG-ah f2445fabba Minor patches + license rewording 2024-02-29 21:17:46 -05:00
makamys bc3ca5209f Clean up tags
Also fixes names of enum compound tags missing
2024-02-29 21:17:46 -05:00
makamys 00517079d2 Fix broken links 2024-02-29 21:17:46 -05:00
makamys 7b8a64ec94 Move model-spec.md to docs dir 2024-02-29 21:17:46 -05:00
ah-OOG-ah 794e59b6de Readd CapturingTesselator workaround 2024-02-29 21:17:46 -05:00
ah-OOG-ah 9710801cb1 Fix underwater lighting on QuadProviders 2024-02-29 21:17:46 -05:00
ah-OOG-ah c5bda3b19c Update JsonModel.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah f9678a3793 Batch colorizing 2024-02-29 21:17:46 -05:00
ah-OOG-ah 091290b218 Clean all the things 2024-02-29 21:17:46 -05:00
ah-OOG-ah d991b55af7 Update ClientProxy.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 1530a8f6fe Clean up CubeModel 2024-02-29 21:17:46 -05:00
ah-OOG-ah 98156191fe Update Loader.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 956914efa3 Delete ModelHelper.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 51c3beea9e The purge continues 2024-02-29 21:17:46 -05:00
ah-OOG-ah 657ff921de Fix sided lighting on copied quads 2024-02-29 21:17:46 -05:00
ah-OOG-ah c9539faf44 Update JsonModel.java 2024-02-29 21:17:46 -05:00
ah-OOG-ah 2ca4d5338f Purge FRAPI code
Also use a baked stone model and fix a stupid in JSON
2024-02-29 21:17:46 -05:00
ah-OOG-ah 236a513705 FRAPI materials + NdQuadBuilder performance
Also speed up the offThreadSafety map
2024-02-29 21:17:46 -05:00
ah-OOG-ah 6d49e82a0c Revert "Set aside JSON model code for now"
This reverts commit 31fdf3383195b65a00e999a5634ed3ead8f060b2.
2024-02-29 21:17:46 -05:00
ah-OOG-ah 2fea614a45 Revert "Remove unready code, for now"
This reverts commit b626e3fa8f83013e5b4a68e787ffed9b75d8a679.
2024-02-29 21:17:46 -05:00
ah-OOG-ah 85ed121158 Remove unready code, for now 2024-02-29 21:17:46 -05:00
ah-OOG-ah 9316f42808 Set aside JSON model code for now
Item models my behated
2024-02-29 21:17:46 -05:00
ah-OOG-ah 74b66746eb Dual-license the model package for Fabric 2024-02-29 21:17:46 -05:00
ah-OOG-ah 5abeb9709e Credit FRAPI 2024-02-29 21:17:46 -05:00
ah-OOG-ah 5ec50f22d9 Remove Fabric license headers 2024-02-29 21:17:46 -05:00
ah-OOG-ah dfe3a4220b Add convenience methods 2024-02-29 21:17:46 -05:00
ah-OOG-ah 1e1e95f249 Variant handling 2024-02-29 21:17:46 -05:00
ah-OOG-ah 02b0d1b728 Update JsonModel.java
This fixes things and I don't know why
2024-02-29 21:17:46 -05:00
ah-OOG-ah 9c81c96bb3 Dang, BlockState is hard
YEET
2024-02-29 21:17:46 -05:00
ah-OOG-ah fff5b2cb01 Implement initial BlockState API 2024-02-29 21:17:46 -05:00
ah-OOG-ah 77f1e9b5a2 Support element rotation 2024-02-29 21:17:46 -05:00
ah-OOG-ah 3158a33a65 Texture loading 2024-02-29 21:17:46 -05:00
ah-OOG-ah f6f840235e Does everything but textures 2024-02-29 21:17:46 -05:00
ah-OOG-ah 793f668ef8 Copyright-clear model parsing 2024-02-29 21:17:46 -05:00
Jason Mitchell da01393799 Try an Int2ObjectMap instead of an ObjectList 2024-02-28 23:02:02 -08:00
Jason Mitchell 3030be32f4 Apparently some mods rely on ForgeHooksClient.getWorldRenderPass() (#347)
* Apparently some mods rely on ForgeHooksClient.getWorldRenderPass()
2024-02-28 19:00:26 +00:00
Caedis dbdeba9865 Up required gtnhlib version to 0.2.9 (#340)
* Update README.MD

* Update AngelicaMod.java
2024-02-27 16:49:23 +00:00
Caedis 80ff6af14e Replace config with gtnhlib's config (#337)
* Remove own config

* update bs + deps

* update gtnhlib

* Replace config with gtnhlib's config
2024-02-27 08:37:17 -08:00
Jason Mitchell c34290d182 Ignore the iris/mcpf configs, hardcode angelica-modules.cfg filename 2024-02-26 12:57:47 -08:00
Jason Mitchell 6e3235a985 Gate some advanced/beta features behind java properties 2024-02-26 10:31:54 -08:00
Caedis 419fa9f0c0 Add Dynamic FOV toggle (#331) 2024-02-26 09:19:32 -08:00
Raven Szewczyk c996e5e58c Use a RFB plugin for GLSM transforms when available (#329) 2024-02-25 12:58:19 -08:00
mts2200 6d28df74a6 Fix #320 (#325)
* Fix https://github.com/GTNewHorizons/Angelica/issues/320

* Fix tests on AMD
2024-02-25 01:00:32 -08:00
Jason Mitchell ce97ef876d Switch up the signature to take ints instead of a blockpos and stop allocating one (#324) 2024-02-21 21:29:56 -08:00
Jason Mitchell 8898a6f252 Switcharoo on detecting ThreadSafeISBRHFactory... (#318)
other method apparently wasn't working
2024-02-20 22:17:00 -08:00
Jason Mitchell 37f638ac34 scheduleRebuildOffThread (#316)
* scheduleRebuildOffThread
2024-02-20 08:58:03 -08:00
Jason Mitchell f73c698a5a Don't crash wit invalid lightquality/particalmode options 2024-02-17 22:46:31 -08:00
Jason Mitchell 029da0e7fa Fix glLoadMatrix and add a test for it
Fixes https://github.com/GTNewHorizons/Angelica/issues/299
2024-02-17 18:15:58 -08:00
Darren Eberly e40ee19ac8 Move JOML dependency to GTNHLib (#301)
* Move JOML dependency to GTNHLib

* Update GTNHLib version in README
2024-02-15 10:51:44 -08:00
jss2a98aj 33832fe547 Sync with NotFine (#296)
* Sync with NotFine

* Fix mistake in package name

* Re-separate stars mode and stars total settings
2024-02-15 10:20:13 -08:00
Jason Mitchell 671a776952 Test Matrix operations (#295)
* Test Matrix operations
2024-02-13 23:20:01 -08:00
Matthew William Noel 445b6a3e68 Partially fix entity shaders (#294)
* Partially fix entity shaders
2024-02-13 20:57:44 +00:00
Jason Mitchell ff65370cc5 Blacklist bartworks from the main thread (#286)
Fixes #181
2024-02-12 22:34:24 -08:00
Jason MitchellandCaedis ff290c19e2 GLSM Tests & AMD Driver Workaround (#290)
* Store graphics vendor
* AMD driver workarounds

* Test TRANSFORM_BIT

* Test GL_TEXTURE_BIT
* Fix handling of bound textures on glDeleteTextures

* Switch up the LOGGER in RenderSystem so we don't trigger a Forge Configuration load; AMD driver default matrix mode workaround

* Switch BatchingFontRenderer to use the gl methods via GLSM to better respect cache bypassing
Fix a few instances of GLSM not respecting the bypass

* Start with "runningSplash" true always to disable the cache until loaded into the world

---------

Co-authored-by: Caedis <[email protected]>
2024-02-12 22:33:23 -08:00
Jason Mitchell d1e505308c Ask for graphics card vendor on bugs 2024-02-12 08:36:24 -08:00
Caedis 594799103b Exclude AMD in testPushPopEnableBit 2024-02-11 20:01:53 -08:00
Jason Mitchell 8a65f471a0 Make getBlockType and getBlockMetadata atomic
* Sidesteps/fixes a race condition in the WIP carpenter block thread safe ISBRH implementation
2024-02-11 19:29:17 -08:00
Jason Mitchellandembeddedt d52e2b0454 Do not return null results in translucency sort task if not cancelled (#284)
* Do not return null results in translucency sort task if not cancelled

Co-authored-by: embeddedt <[email protected]>
2024-02-11 22:55:16 +00:00
Raven Szewczyk 9b31bae1c8 Log more information in the no-result task exception (#283) 2024-02-11 22:12:05 +00:00
Ginsway 7cbb905bd7 Update Chinese translation (#261)
* 固有的

* 自己翻译的

* Update src/main/resources/assets/angelica/lang/zh_CN.lang
2024-02-11 13:32:18 -08:00
Jason Mitchell 8a50ed036d More GLSM Tests (#282)
* Properly Cache GL_SHADE_MODEL and make it a stack

* Add opengl_32_core to docs, so we can easily see what is needed to be deprecated/emulated
Add some stub functions to be fleshed out later
2024-02-11 12:13:51 -08:00
Jason Mitchell f1394382ab Make note of required versions of mods if present 2024-02-11 10:45:20 -08:00
Raven Szewczyk 74e6c80aad A few buildscript and test tweaks (#281)
* Kotlin buildscript for better IDE integration

* Fix transitive Bauble dep, move CoreTweaks to a fake-ivy dependency

* Don't scan fullscreen modes for window creation

* Update GTNHGradle
2024-02-11 05:24:08 -08:00
ah-OOG-ah da9d6bad56 Fix typo in issue template (#280) 2024-02-10 20:57:40 -08:00
Jason Mitchell 58a6fabf3c Enough with the bug reports about disabled features 2024-02-10 20:51:18 -08:00
Jason MitchellandDarren Eberly f8c11967d1 Glsm tests (#275)
* Tests for GL_DEPTH_BUFFER_BIT
* Swizzle DepthState.mask ~> enabled
* Use AssertAll so we can clearly see gl/glsm state differences
* Reset test state leakage from ColorBufferBit
* Add start of test for GL_CURRENT_BIT
* Initial basic display list tests
* Print mismatched array index for array comparisions
* Add message for all tests
* Test GL_CURRENT_BIT
* Implement GLSM stub functions
* Test GL_ENABLE_BIT
* Add verifyNotDefaultState when we don't care about the values, just that they're not the default
* GL_MULTISAMPLE seems to be broken on Nvidia
* Test GL_FOG_BIT
* Check glGetError() after every test
* Exclude some tests based on vendor
* Test most of GL_LIGHTING_BIT

---------

Co-authored-by: Darren Eberly <[email protected]>
2024-02-10 16:51:12 -08:00
Jason Mitchell 6d1c4bf39c Revert "fix release workaround"
This reverts commit 018a47e400.
2024-02-10 09:43:48 -08:00
Jason Mitchell 018a47e400 fix release workaround 2024-02-09 17:53:26 -08:00
ah-OOG-ahandmakamys 509017551a Initial QuadProvider API (#256)
* Initial model testing

* Fix UV

* More quad work

* Update BlockRenderer.java

* QuadProvider renders right!

* Clean up

* Update CubeModel.java

* Initial colorization work

* (Badly) color grass

Unbreaks vanilla blocks

* Leaves are easier

* Add separate AO back

* Relocate to Angelica

* Cleanup + pool quads

* Add TODOs for future reference

* Update LightDataAccess.java

* Replace code comment with TODO

* Update WorldSlice.java

Co-authored-by: makamys <[email protected]>

* Default quads to UP

* Only coerce facing in Quad#getFace

Mirrors 1.16's face handling more accurately.
Fixes face culling not working properly for blocks like tall grass

* Iterate over unaligned quads too

* Don't cull unaligned faces

* Release QP quads

---------

Co-authored-by: makamys <[email protected]>
2024-02-09 17:41:15 -08:00
Jason Mitchell cf454f287c GLSM Improvements (#272)
* GLSM Improvements
* Add an IntegerStateStack
* Use IntegerStateStack to track the active texture unit
* Track activeTextureUnit with GL_TEXTURE_BIT
* Bugfix - Don't include color with GL_COLOR_BUFFER_BIT
* Fully test glPush/PopAttrib for GL_COLOR_BUFFER_BIT
* Split GLStateManager init into two pieces
2024-02-09 17:35:58 -08:00
Darren Eberly 0e3e4283af Compat with NotEnoughIDs 16-bit Metadata (#271)
* Compat with NotEnoughIDs 16-bit Metadata

* Less bad(maybe) version parsing
2024-02-09 00:33:42 -05:00
Bogdan 8176e1cd1c Don't put excessive buffer size (#267) 2024-02-04 13:57:04 -08:00
ah-OOG-ah d2cba7c321 Update settings.gradle (#268) 2024-02-04 13:56:22 -08:00
Raven Szewczyk f791b0dab3 [ci skip] upgraded build system 2024-02-04 19:56:28 +00:00
Jason Mitchell 5093531811 Cleanup 2024-02-03 16:04:19 -08:00
Jason Mitchellandmakamys c942df386a OpenGL State Debugging (#262)
* OpenGL State Debugging
* Add OpenGLDebugging
* Enhance GLSM to be aware of single vs multiple return values for glGet

* Capacity vs Remaining (needs NPE saftey?)
Int -> float
glLoadMatrix

* Update src/main/java/com/gtnewhorizons/angelica/glsm/debug/OpenGLDebugging.java

Co-authored-by: makamys <[email protected]>

* Update src/main/java/com/gtnewhorizons/angelica/glsm/debug/OpenGLDebugging.java

Co-authored-by: makamys <[email protected]>

* tweaks

* Fixes
* Have checkGLSM compare matricies differently than other things
* Each Texture Unit has it's own TextureMatrix stack
* Switch to a ClientTickEvent and directly query the Keyboard so we can run the checkGLSM in GUIs and other places
* Remove default keybind

* Don't trigger quite so often

---------

Co-authored-by: makamys <[email protected]>
2024-02-03 15:00:21 -08:00
mist475 1d24789362 Minor cleanup (#264)
* add missing remap = false

* deobfParams

* applyDecompilerCleanupToMain
2024-02-03 09:13:40 -08:00
Jason Mitchell b8b445322c Fix some missing state for push/pop attrib (#260)
* Fix some missing state for push/pop attrib

* Add Color as well
2024-02-02 11:19:26 -08:00
Jason Mitchell 38c72b7af0 Bypass getting anything from the GLSM cache until after world load, but ensure we set everything. 2024-02-02 09:19:25 -08:00
Jason Mitchell 466b0544e3 Add a Vector3dStack - Fix nested translations being stored 2024-02-02 09:19:12 -08:00
Jason Mitchell 26da0c2b64 Update buildscript 2024-02-01 08:04:51 -08:00
Jason Mitchell 8c3ac9e310 null check (#255) 2024-01-31 21:30:59 -08:00
Jason Mitchellandmakamys 6a7c2520d0 Opt in thread saftey (#254)
* Evolution of thread safe ISBRH
* Add API package

Co-authored-by: makamys <[email protected]>
2024-01-31 16:53:45 -08:00
makamys a0d782a1a5 Add dependency hints (#253)
* Crash with a helpful error if FastUtil is missing

* Add UniMixins dep to readme
2024-01-31 08:22:22 -08:00
makamys aebaab8d6f Make RedirectorTransformer handle block subclasses correctly (#249)
Fixes #248
2024-01-30 11:47:28 -08:00
Matthew William Noel 05158317e8 Fix PBR (#252) 2024-01-30 11:46:53 -08:00
embeddedt 4d39c90ba6 Only return null if job is explicitly cancelled (#251) 2024-01-30 09:27:58 -08:00
Jason Mitchell 83cf0801ef Remaining instead of capacity 2024-01-29 08:00:14 -08:00
jss2a98aj db49a613a0 Fix leaf rendering issue (#247)
* Fix and simplify leaf code

* Add SettingsManager.graphicsUpdated() call

Fixes an additional leaf rendering issue and some other things.
2024-01-28 14:18:30 -08:00
Jason Mitchell 64087f53c5 This wasn't supposed to be private 🤦 (#246) 2024-01-28 09:26:51 -08:00
Jason Mitchell efb039ff38 Remove unused option 2024-01-27 16:26:46 -08:00
Jason Mitchell 388929cc0c Fewer Allocations (#243) 2024-01-27 16:17:06 -08:00
Jason Mitchell 6691511e17 More Caching (#242)
* More Caching
* Pull TextureTracker & TextureInfoCache out of Iris and into GLSM
* Cache more TextureInfo state
* GLSM: glTexParameter, glGetTexParameter(i|f), glGetTexLevelParameteri
* Move IrisRenderSystem -> GLSM.RenderSystem
* Ensure DSA works properly with GLSM
 * Further updates to DSA for texParameter/getTexParameter
* A few more cached fields for TextureInfo
* Properly handle deleteTextures
* Ensure anyone crazy enough to use an Int/FloatBuffer for single value params get redirected
* Add optional runtime disabling of GLSM
* Switch checkGLError from an inject to a redirect, hopefully fewer allocations
* Fewer allocations for clearBufferState
* Microoptimization for (setup|clear)BufferState
2024-01-27 15:52:57 -08:00
Michael Zhao b956a44857 fix texture state leak in BatchedFontRenderer (#240) 2024-01-27 14:27:01 -08:00
Jason Mitchell 8863826d0e More aggressive caching (#239)
* More aggressive caching
2024-01-27 10:19:37 -08:00
Pistonight 65d9bf8f2f copy depth buffer from MC for HUD caching 2024-01-26 10:34:46 -08:00
Jason Mitchell 3ee82e7157 OpenGL Debugging
* Move GLDebug and gl capabilitiesinto angelica/glsm instead of Iris
* Wire up GLDebug.pushGroup && popGroup via mixins if lwjgl debug is enabled (useful for api trace)
2024-01-24 20:33:09 -08:00
Pistonight 3b61bb74a2 fix hud caching alpha handling and boss health 2024-01-24 07:59:54 -08:00
Jason Mitchell f378b6e7ba VBO related Tweaks (#227)
* Expose original translation for tesselator, so we can reset it after doing VBO stuff

other small VBO cleanup

* Properly manage the tessellator's state...
2024-01-23 07:54:30 -08:00
Jason Mitchellandmakamys aff05e1812 Add Reese's Sodium Options (#219)
* Add Reese's Sodium Options

Co-authored-by: makamys <[email protected]>
2024-01-21 15:54:03 -08:00
Jason Mitchell 806bcf2d6b Config updates (#225)
* Make in game config for Angelica work
* Backport https://github.com/embeddedt/embeddium/commit/7476bf9b13fcb9a302722b350ef4e6e7d2b8a8c8 to rename angelica-options.json
2024-01-21 13:47:45 -08:00
makamys 3755e2595f Fix campfire backport animations (#224)
* Mark animations of crossed squares

Fixes Angelica's equivalent of https://github.com/GTNewHorizons/Hodgepodge/issues/264
Fixes Campfire Backport campfire flames not animating (but the embers and the
mixed NEI flames are still broken)

* Add Campfire Backport compatibility to animation speedup

Fixes Angelica's equivalent of https://github.com/GTNewHorizons/Hodgepodge/issues/204
Fixes embers and NEI mixed flames not animating
2024-01-21 09:12:30 -08:00
makamys 0d79f5e193 Make NotFine's sky toggle more granular (#222)
Separated "Sky" toggle into "Sky", "Sun & Moon", and "Stars", like in OptiFine.
This also fixes NF's sky toggle turning off MCPF's skybox
2024-01-21 08:33:10 -08:00
Jason Mitchellandmakamys 9210cd3283 ArchaicFix compat (#220)
* ArchaicFix compat

Fixes https://github.com/GTNewHorizons/Angelica/issues/216

* Update src/main/java/com/gtnewhorizons/angelica/mixins/TargetedMod.java

Co-authored-by: makamys <[email protected]>

---------

Co-authored-by: makamys <[email protected]>
2024-01-20 17:19:57 -08:00
makamys 733ffff81f Redirect negative display list calls to VBOs globally (fixes Smart Moving) (#217)
* Redirect negative display list calls to VBOs globally

Fixes Smart Moving not rendering player models

* Remove now redundant glCallList redirects

* Make VertexBuffer keep track of its own draw mode
2024-01-20 12:21:33 -08:00
Michael Zhao 32e2efc1e5 fix hud caching vignette and crosshair color issues (#212) 2024-01-20 10:17:48 -08:00
bombcar d9a688f1d8 fix runclient17 (#211) 2024-01-19 16:43:15 +00:00
Jason Mitchell ba66a0602b Update README.MD - No BetterFPS 2024-01-18 20:00:41 -08:00
Jason Mitchell d53a85e013 Remove silly early initial implementation and fix star VBO (#206)
* Remove silly early initial implementation and fix star VBO
2024-01-18 22:55:52 +00:00
mist475 5f6c418315 disable sodium weather quality redirect if dynamic surroundings is present as it overwrites the entire method (#200) 2024-01-16 09:29:22 -08:00
jss2a98aj 15569aadc7 Enable NotFine leaf modes when enableNotFineFeatures is true (#194)
* Use NotFine leaf modes if enableNotFineFeatures

* Sync NotFine langs
2024-01-15 15:23:44 -08:00
Jason Mitchell 0f97c09fda Render all Wavefront objects as VBO (#192)
* Tris actually seem to work w/ thaumcraft
2024-01-14 14:57:47 -08:00
Jason Mitchell fd43fbd9c9 Update README.MD 2024-01-14 10:12:04 -08:00
embeddedt 2b4ea9fd96 Don't activate item textures if there is no client world (#189) 2024-01-13 21:30:36 -08:00
tth05andJason Mitchell 1837dcec72 Replace fastutil dependency with GTNHLib (#187)
* Replace fastutil dependency with GTNHLib

* Add gtnhlib to mod dependencies

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-14 01:48:32 +00:00
Cyl18 84e1fa284b fix some of iris problems (#183) 2024-01-13 16:29:25 -08:00
Jason Mitchell c211d90faf Off thread safe blocks (#177)
* Whitelist carpentersblocks for off main thread rendering

* Add bounds checking to WorldSlice,

* Add preliminary `IThreadSafeISBRH` support

* Update TODO

* Adjust min y

* remove unnecessary try/catch

* * Keep track of what should be rendered on the main thread
* Update AngelicaBlockSafetyRegistry to handle vanilla blocks, and ISBHR's

* of -> set
2024-01-12 18:31:01 -08:00
Jason Mitchell 537eb06b66 Respect animation speedup config (#180) 2024-01-11 08:05:26 -08:00
Darren Eberly 93b03847df Only use BatchedFontRenderer when not in a display list compilation (#174) 2024-01-09 09:28:31 -05:00
Darren EberlyandJason Mitchell 85e44369bb Handle state changes for display lists correctly in GLSM (#168)
* Handle state changes in display lists correctly in GLSM

* Add some documentation so it's slightly more clear as to what's happening

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-08 21:48:15 +00:00
Raven Szewczyk fbc1b1b440 [ci skip] upgraded build system 2024-01-08 21:23:33 +00:00
embeddedt 97152a6ace Clear event phase before reusing object (#170) 2024-01-08 16:11:35 -05:00
makamysandJason Mitchell 3cde764d33 Update BS (#165)
* Update BS

Ran `updateBuildscript` and manually copied in the new `settings.gradle`

* Update build.gradle

---------

Co-authored-by: Jason Mitchell <[email protected]>
2024-01-08 03:25:38 +00:00
Jason Mitchell 45b20efc45 Change where the offset is reset (#159)
* Change where the offset is reset
* Debug log and rm dead code
2024-01-07 18:58:48 -08:00
Mist475 869f843e3e turn sortAndRender redirect into WrapOperation 2024-01-07 09:56:29 -08:00
Jason Mitchell ad533bcae9 Don't remap, and throw early 2024-01-06 20:50:49 -08:00
Jason Mitchell b100652a7d Fix VBO crash (#151)
* Fix VBO crash
* Use integer.min_value for VBOized display list IDs, and prevent a NPE when trying to delete a VBOized display list
* Offset when accessing the vertexBuffers list
* DragonAPI compat - Only run checkSettings when the world is loaded
2024-01-07 03:30:28 +00:00
Darren Eberly d497c301c9 Fix for GUI lighting states (#148)
* Fix for GUI lighting states

* Lighting fix after RenderTickEvent because mods love to abuse it

* Remove unnecessary glEnable

* Remove unused import
2024-01-06 17:47:58 -08:00
embeddedt 17dddb6691 Rebuild chunk graph if fog distance changes 2024-01-06 17:47:16 -08:00
embeddedt 818f4d3cca Reload renderer if view distance changes
Backport from Sodium 0.3
2024-01-06 17:47:16 -08:00
embeddedt 9141137606 Avoid constructing ChunkMeshData for unused passes 2024-01-06 17:47:16 -08:00
embeddedt 9b6e781a7c Propagate exceptions on meshing thread to main thread for unimportant builds 2024-01-06 17:47:16 -08:00
embeddedt 8229ed9aa0 Prevent sorts from replacing rebuilds for a section 2024-01-06 17:47:16 -08:00
embeddedt 71ea27ee3a Apply epsilons to block face culling checks
Inspired by https://github.com/CaffeineMC/sodium-fabric/commit/c344269368d6ea04d8f9affd1d6aec287aec09c2

The change also makes sense, because block geometry can extend
some distance out of a chunk's strict bounds
2024-01-06 17:47:16 -08:00
Jason Mitchell f760a3e011 Store state changes generated during a display list, and apply them after calling the display list 2024-01-06 17:46:08 -08:00
embeddedt 14c09770eb Integrate Sodium animation system with Angelica's (#147) 2024-01-06 18:46:59 -05:00
Jason Mitchell a0646456d3 So binding a texture in a display list compile won't change it, but it'll capture the change..... (#146)
* So binding a texture in a display list compile won't change it, but it'll capture the change.....
2024-01-06 22:43:53 +00:00
Jason Mitchell 7a783b9d45 Only officially released versions please... 2024-01-06 13:48:36 -08:00
Jason Mitchell b0828fb96a Make sure the correct discard/reset is being called (#144)
* Make sure the correct discard/reset is being called
2024-01-06 12:16:35 -08:00
Jason Mitchell 369893cfa3 Set the hasXXX flags so quads get generated properly (#139)
* Set the hasXXX flags so quads get generated properly
* Add forge to credits
* Change remapping for MixinRenderGlobal
2024-01-06 01:52:25 -05:00
embeddedt a96a973d44 More TESR fixes, make VBO mixins toggleable 2024-01-05 19:45:53 -08:00
embeddedt 2c767f2970 Use ConcurrentHashMap to store tile entity renderers 2024-01-05 19:45:53 -08:00
Jason Mitchell 2839e892e0 Update README.MD
Add links for required updates
2024-01-05 19:38:03 -08:00
makamys a16ed9460a Fix Camera#blockPos rounding and apply third person offset (#137)
Fixes translucent chunk sorting being off near chunk boundaries.
2024-01-05 19:24:23 -05:00
Jason Mitchell 921545ca1f Add archaicfix version requirement, if present (#136) 2024-01-05 22:42:10 +00:00
Jason Mitchell 717c918bd4 VBO Clouds (#135)
* Backport VBO Clouds from Forge 1.12
* Add a 1.12+ style tessellator/buffer builder API to CapturingTessellator
* Update VBOManager to handle adding items out of order, and switch to ObjectArrayList
2024-01-05 14:38:51 -08:00
mist475 98b707e3e3 MCPF config/mixins cleanup (#130)
* cleanup ctm/ cc mixins

* use @Share more

* migrate to forge based config
2024-01-04 19:25:57 -08:00
MrSlimeDude 73c7ca94e1 Fix drawString returing wrong value with 0 length string 2024-01-04 19:25:06 -08:00
Jason Mitchell cf3cfd806f VBO Manager
* Add a VBO manager
* Stop allocating display lists for the vanilla chunk renderer when sodium is enabled
* Move RenderGlobal * ModelRenderer to VBO Manager
* Stop preventing display list allocation for displayListEntities
2024-01-04 19:24:00 -08:00
Jason Mitchell c58870fdeb DisplayList -> VBO for stars, skies, and ModelRenderer (#129) 2024-01-04 10:49:27 -05:00
embeddedt a8ccc8903a Performance & allocation rate optimizations (#128) 2024-01-03 22:35:05 -05:00
embeddedt adb582cd1e Fix chunk updates not unparking main thread upon completion (#127) 2024-01-03 17:20:06 -05:00
Jason Mitchell 364f3a9c00 meh - fix silly (this or do math) 2024-01-03 13:45:16 -08:00
Jason Mitchell c19c812c10 Remove tessellator to buffer (#123)
* Update buildscript
* Swap out uploading a tesselator and tesselatorToBuffer with a Capturing Tesselator
2024-01-03 13:22:52 -08:00
makamys 0460f6dbcd Quad cleanup (#124)
* Remove useless code from Quad

* Remove unnecessary resetting

* Reorder fields to follow tessellator layout

* Fix flags getting ored instead of assigned
2024-01-03 12:57:13 -08:00
Jason Mitchell 4fabe45ae7 CapturingTessellator and VBO support (#120)
* Adds a CapturingTessellator
* VBO support
* Remove some silly badly translated Iris vertex implementation from HFPModelVertexType
* Support Normals
* Move normal rendering to the CapturingTessellator, and remove off thread non-capturing tessellators
* Add quad writer support to VertexFormat
2024-01-03 11:34:11 -08:00
mist475 ab54359f03 fix sodium fluid renderer not using biome colors (#122)
* fix sodium fluid renderer not using biome colors
2024-01-03 16:11:46 +01:00
Jason Mitchell 0c9ec5b23a Defer chunk updates by default
* At least until we can figure out the cause of the stuttering with them enabled
2023-12-30 15:56:56 -08:00
Darren Eberly 20ae68aa62 Re-enable lighting after rendering Thaumcraft aspects 2023-12-30 15:02:29 -08:00
Jason Mitchell 46164ebac7 Normalize Rotation vector
Also add cache bypass to matrix caching
2023-12-30 14:12:45 -08:00
Jason Mitchell de0a600163 Only enable threaded block transformations when sodium is enabled 2023-12-30 13:24:40 -08:00
Jason Mitchell 956f9e344e Update the tesselator checks to allow for non main instance tesselators while still on the main thread (#106) 2023-12-30 13:00:59 -08:00
Darren Eberly acc1f58778 Round texture coordinates instead of truncating (#105)
Backported fix from embeddium: https://github.com/embeddedt/embeddium/commit/a82950cf8e77ce78d9c3dacbfa509900f3a224ca
2023-12-30 12:25:33 -08:00
Caedis 1a38bd1a00 Move mod checks to their own static class (#103) 2023-12-30 13:21:58 -06:00
Jason Mitchell cfc19bb35e Repo cleanup
* Remove (currently) unused covers maven
* Limit FP maven to com.falsepattern to limit requests going that way
2023-12-30 10:51:54 -08:00
mist475 446c8e74ee replace lotr blockrendering hashmap with concurrent version (#98) 2023-12-30 10:39:34 -08:00
FalsePatternandDarren Eberly 74cdc561e6 Preliminary ChunkAPI/EndlessIDs compatibility (#94)
* Preliminary ChunkAPI compatibility
* endlessids biome array crash fix
* Ensure skylight array is not null when hasSky is set

---------

Co-authored-by: Darren Eberly <[email protected]>
2023-12-30 10:26:03 -08:00
Caedis 67fbcc8ff0 Add debug logging option (#97)
* add debug logging option

* remove the deobf check
2023-12-29 01:54:58 -06:00
Jason Mitchell d19b8d5302 Handle bad matrix modes (#93)
* Handle common incorrect modes for glMatrixMode
* Handle matrix stack over/under flow
2023-12-28 21:05:11 -05:00
embeddedt ae0e03bead Do not include transformed mods in runtime classpath by default (#91) 2023-12-28 21:23:40 +00:00
embeddedt 7d7d73a48f Fix constant pool parser early-exiting instead of checking all strings (#90)
Use a helper variable instead of the label-break pattern, the latter
is ugly and error-prone, in my opinion
2023-12-28 13:21:00 -08:00
Jason Mitchell 6dcc4649db Update Hodgepodge required version 2023-12-28 09:42:38 -08:00
Jason Mitchell 5db5c7f683 Update README.MD 2023-12-28 09:36:51 -08:00
Jason Mitchellandembeddedt 21b9b8cb3f Dynamic cstPoolParser (#89)
* Dynamic cats... err cstPoolParser
* Prevent block classes that redeclare vanilla fields from being redirected
* Obviously blocks don't shadow their own fields

---------

Co-authored-by: embeddedt <[email protected]>
2023-12-28 09:08:49 -08:00
Jason Mitchell fc520de642 Dirty no more 2023-12-28 08:20:08 -08:00
Jason Mitchell 9916075569 Catch the specific error, rather than generic Exception (which the error doesn't seem to subclass anyway) (#88) 2023-12-28 08:15:50 -08:00
Jason Mitchell 6624a9adb3 Fully track GL State changes (#83)
* Fully track GL State changes
* Now compatible with glPushAttrib, and glPopAttrib
* Cache mask -> features using an Int2ObjectMap
2023-12-28 07:55:16 -08:00
Jason Mitchell c3216007c1 Add missed IC2 mixin 2023-12-28 07:42:27 -08:00
Jason Mitchell 92b22b1827 No shader issues for now 2023-12-28 06:27:28 -08:00
embeddedt f32c14f795 Add missing import 2023-12-27 12:05:47 -08:00
embeddedt ef15577b15 Fix Block bounds fields redirects not applying to subclasses 2023-12-27 12:05:47 -08:00
embeddedt ac60c01788 Delete vanilla block bounds fields 2023-12-27 09:06:16 -08:00
Caedis 9410902937 Add FalseTweaks and SmoothFont to temp incompatibilities (#70)
* Update README.MD

Add FalseTweaks to temp incompatibilities

* and add SmoothFont
2023-12-27 03:59:27 -06:00
Jason Mitchell 52776530d8 Handle GL_COMPILE separately from GL_COMPILE_AND_EXECUTE
* Should fix OpenComputer issues
2023-12-26 17:19:35 -08:00
Jason Mitchell 9cebb352ad Opt in debug
* Less stutter with buggy stuff
2023-12-26 15:12:44 -08:00
embeddedt d810eaf876 Use client world for main thread renders 2023-12-26 12:45:45 -08:00
Jason Mitchell 1a1ca32721 Update 000-report-bug.yml 2023-12-26 09:10:00 -08:00
Jason Mitchell a3d689e806 Because of course someone uses DoubleBuffer 2023-12-26 08:45:26 -08:00
embeddedt d4e22b6c0c Avoid restoring GL buffers we didn't modify 2023-12-26 07:35:29 -08:00
Jason Mitchell 7e24f6a395 Reduce stuttering on Nvidia - Track the model view and projection matrix (#56)
* Track the model view and projection matrix
* Cache ViewportState as well
* Add mixin to speedup Jabba's saveBoundTexture
2023-12-25 20:16:43 -08:00
embeddedt c8e6a6f34f Make glPushAttrib match native behavior if bypassing state manager cache 2023-12-25 17:19:59 -08:00
Jason Mitchell f7a79cf02f Switch up how we're grabbing the projection & model view matrix to avoid needing to call glGetFloat() again 2023-12-25 16:14:35 -08:00
mist475 21b0de542c base mcpf merge (#45) 2023-12-25 11:44:38 -08:00
Jason Mitchell 7ae4e14a3e Add some more guards around GL capabilities 2023-12-25 11:35:24 -08:00
Jason Mitchell bfd6c25a03 Update README.MD 2023-12-25 09:20:35 -08:00
+4 992644c20f The Mergening (#13)
* ThreadedTessellator -> RenderBlocks instance Tessellator
* Plus a CME workaround until I can figure out why it's happening
* One inject with multiple methods instead of two injects
* Add AF's Tessellator#reset mixin
Fixes screen flashing when chunks are being built
* Thread Saftey
* Make each tesselator use its own ByteBuffer
* Don't make RecyclingList a static variable 🤦
* Add some additions via ITessellatorInstance
* Stop using builtin updateRenderers
* Remove a few unused things in MixinTessellator
* Remove useless casting due to implementing the interface
* Overwrite some more rendering methods to ensure they're not used
* Implement IBlockAccess on WorldSlice
* Currently just proxies to the World... need to get it to use the local cache
* Make WorldSlice use its copied values instead of using the world
* block, meta, and light.  Still need TODO biome
* Finish making WorldSlice thread safe
* Remove last unsafe this.world accesses
* Copy biomeData
* Implement getTileEntity(), and getBiomeGenForCoords()
* Remove unused 1.16+ classes - Biome, Colorizer, and ColorBlender related
* Cache worldHeight instead of asking the provider every time
* Debug Screen updates
* Disable Culling for now (until it works)
* Tessellator Updates
* Use one instance on the main thread, and individual instances on every other thread
* Prevent draw() and buffer.reset() on non singleton instance
* Misc cleanup, maybe better growBuffer?
* Fixing splash screen and GUI issues by excluding SplashProgress from GLStateManager transformer
* Update docs
* Fixing a one line in SodiumWorldRenderer that allows the game setting for the distance at which entities will render. Hope it's not too bad mitch :)
* TileEntites now render
* Less silly transparency
* Removing clamp implementation because I missed the one in mathhelper
* Initial sodium entity smooth lighting
* Fix entity smooth lighting
* Fix lerp uses and use render layers properly (#17)
* Remove some uses of blockstate + patch FluidState
* Fix lerp
* Enable Sodium fluid rendering
* Update FluidRenderer.java
* Rewind buffers when copying
* Fix multidraw
* Force cutout on all non-translucent blocks
* Let vanilla handle render pass state
* Rewrite render layer check to use Forge 1.7 hook
* Fix skylight handling
* Fix flickering
* Clone TEs correctly
* Fixing entityDistMulti (I think)
* Fix TEs rendering on the wrong pass
* Buff max render distance to 32
Pretty useless since the integrated server stalls instantly, but our renderer supports it
* Fix fog
* Fix render distance changes being ignored
* Implement entity culling
* Block face culling
* Re-enable occlusion culling
* Fix x/z coordinate mixup when indexing biome arrays
Partially fixes wrong biome colors, but at chunk edges it's still wrong because
neighboring chunks aren't accessed
* Make a copy of biome data
The old code seemed to work fine but this should be safer
* Make CompatMemoryUtil#memReallocDirect preserve buffer position
LWJGL3's MemoryUtil#memRealloc does this, see its javadoc.
Fixes screen flashing and this error getting printed when indirect buffer grows:
GL_INVALID_OPERATION error generated. Bound draw indirect buffer is not large enough.
* Use biome data of neighboring chunk sections
Fixes wrong colors at chunk edges
* Re-enable fog culling
* Tile entity culling
* Remove some unneeded Sodium code
* Massive code cleanup
* Avoids errors when usin lwjglxdebug
* Bump hodgepodge dep
* Add AngelicaConfig
* Add Mixin to disable MC's builtin checkGLError
* Add configs for iris/sodium
* Iris work
* Move some StateNotifiers to GLStateManager
* Remove some redundant mixins based on sodium/angelica work and rendering state captures
* Add Iris DebugScreenHandler
* rm archaicfix's occlusion renderer and threaded updates
* Implemented Sodium's GUI and a couple of setting fixes (#20)
* Ported Sodium's GUI
* Correct AO
* Fixed Vignette
* Re-enable DirectMemoryAccess
* Adds some code from lwjgl3 in CompatMemoryUtil.java
* Re-add *Unsafe classes
* Remove MixinWorldRenderer
* Add NEID (mixin pr) support
* Only shadow runtime module of antlr4
Reduces jar size by 11 mb
* Update NotFine
* Make LongHashMap actually perform like a hash map
* Options GUI Fixes and some option implementations (#22)
* Correct useNoErrorGLContext option
* Added translucency sorting option
* Implemented Particle Culling
gives real fps boost, however, it's not as big as i thought

* Begin implementing animateOnlyVisibleTextures
* Correct Donation page opening
* Fixed Shift + P
Now it uses NotFine's GUI, but it think that NotFine's GUI should be rewrited for using other config options
* Correct URL's for Linux
* second code cleanup in particle culling
* Fix incorrect TE map population
* Add optional assertMainThread behind `-Dangelica.assertMainThread=true`
* Add back air optimization, but only apply to vanilla air
* Implement more options (#23)
* Combine free regions in GlBufferArena
* Clear global block entity list when initializing renderer
* AF, CompileStubs, and SplashProgress
Remove most of ArchaicFix
* Move a few mixins over to angelica
* Disable if org.lwjgl.util.Debug is set
* Only enable Iris/lwjgl debug callbacks if org.lwjgl.util.Debug is set
* Rewrite Tessellator hacks - now using a ThreadLocal instead of only patching RenderBlocks
* Reenable AF mixins, switch to cached debug var, disable incompatible mixins
* Remove AF deps and a late mixin that was missed
* Add Iris Sodium Compat impl
* Fix Sodium GLProgram to use ResourceLocation instead of Identifier
* Start applying Iris -> Sodium Mixins
* Make NotFine menu open if holding shift
* Fixed Tessellators in production env
* Finish Sodium Fluid Renderer (#24)
* Init and pass Sodium LightPipelines
* Remove registry lookup and refactor WorldUtil
* Hook up lighting pipeline
* Patch fluid velocity
* It's alive! Sodium Fluid Renderer is alive!
* Fix face culling not taking third person camera offset into account
* rewrite ACTEntityRenderer to stop transforming ALL the classes
* use ClassConstantPoolParser in TessellatorTransformer to speed up search for Tessellator references
* use ClassConstantPoolParser in GLStateManagerTransformer to speed up search for class references
* rewrite GLStateManagerTransformer and TessellatorTransformer
* merge GLStateManagerTransfor and TessellatorTransformer into one Transformer
* Fixed smooth lighting rendering
* Iris block_id Mixins & BlockStateIdMap initial impl for 1.7.10
* Fix running with lwjgl debug flag & Cleanup old ShadersMod transformers
* Initialize GLStateManager via Mixins instead of all in the static block
* Clean up chunk load/unload tracking, fix chunks rendering without neighbors sometimes
* Fix occlusion culler not re-running after important uploads

Backport of https://github.com/CaffeineMC/sodium-fabric/pull/755

* Add chunks to queues without going through occlusion culler

Partially reverts the previous chunk tracking commit, because
that logic will reintroduce https://github.com/CaffeineMC/sodium-fabric/issues/605

As long as we only rebuild with neighbors present, we shouldn't
see the visual seams
* Extremely primitive synchronization approach for ISBRH
* Use factory for Spdium menu createElement outputs
This will allow NotFine to use Sodium menu elements and vice versa in a future commit.
* Splash Screen Compat
* Separate remaining NamedState enums
* NotFine but it loads Sodium pages
* Hook up NotFine optimizations
* Hook up some NotFine features
* copy over hud caching code from hodgepodge
* backport glstatemanager mixin
* Track thread that currently owns the GL Context in addition to the main thread.
* First pass over FontRenderer, 1300->1400 FPS on my GPU when showing F3
Done:
 - A batching vertex buffer builder for font output
 - Reduction in drawcalls from 1-3 per character to 1 per font atlas switch
 - Mixin to draw the entire F3 screen in one batch, instead of separate batches per line
TODO:
 - Switch drawing to a VBO
 - Cache string meshes across frames
 - Cache string width calculations used for layouts
 - Multidraw to reduce draw calls even further
* Add JVM flag to bypass GL state caching
* Push/Pop Attrib Hacks -- to be evolved later
* Fix FontRenderer+SplashScreen combo
* HUDCaching tweaks
* Add license
* Jabba Compat, and reset tesselator state even if the chunk render thread blows up
* Initial Xaero's World Map + Minimap Support
* Disable Fastcraft & Optifine if present
* Iris Progress
* Wire up more Iris mixins, informing pipeline stages.  Still not rendering anything visible.
* Don't try to transform the server
* Avoid running biome generator on client in singleplayer
* Call world biome retrieval methods instead of copying array directly (#25)
* Shaders now do something!
* Shadow Pass work
* First shadow pass renders; however it moves all around when moving the camera...
* Second shadow pass not running because it makes everything very very dark instead of just rendering translucents
* Actually use the ShadowRenderer Model View when running the shadow pass...
* Enable Sodium SmoothLightPipeline & Iris useSeparateAo
* Avoid repeatedly copying biome data on each Y level (#27)
* Celestial Rotation fixes
* Water progress
* Uniforms audit
* Lightmap workaround
* PBR compiling, stuck on Normal and Specular textures being added in
* Shaderpack selection "works"; ShaderOptions TODO
* Hud caching angelica (#28)
* Potential hud-caching fix
* Shader Options almost working
** Clicking on everything doesn't yet work, and the visuals are slightly off
* Entity shadows seem to be working
* Move glint fix to Mixin
* Rework mouse handling for ShaderPackConfig
* Stop centering shader options vertically
* Angelica pbr (#31)
* Only use Sodium light pipeline if useSeparateAo is on
Sodium pipeline is still very buggy, so isolate it to Iris-only
for now
* Fix region sorting for translucency
* Open Shaderpack now works on Linux
* RM Shadersmod
* Initial iris scrollbar clicking
* Punt unsupported ISBRHs to the main thread
* Delete the ISBRH lock, shouldn't be needed anymore
* Render GT blocks on main thread
* Require CCC 1.2.0+
* Depend on CCC 1.2
* Fix TESRs not being tracked for blocks rendered on main thread
* Cut down number of runtime dependencies, enable CoreTweaks in dev by default
* Add modern F3 background
* Pull over some hodgepodge mixins


---------

Co-authored-by: makamys <[email protected]>
Co-authored-by: embeddedt <[email protected]>
Co-authored-by: rjnasers <[email protected]>
Co-authored-by: ah-OOG-ah <[email protected]>
Co-authored-by: Ryan Nasers <[email protected]>
Co-authored-by: Rad <[email protected]>
Co-authored-by: Bogdan <[email protected]>
Co-authored-by: Caedis <[email protected]>
Co-authored-by: jss2a98aj <[email protected]>
Co-authored-by: Alexdoru <[email protected]>
Co-authored-by: Raven Szewczyk <[email protected]>
Co-authored-by: mist475 <[email protected]>
Co-authored-by: Ryan Nasers <[email protected]>
2023-12-24 21:49:28 -08:00
Jason Mitchell 96036a67eb Update 000-report-bug.yml
no more reporting about a report
2023-12-24 16:20:32 -08:00
Jason Mitchell 95d3332675 Update 000-report-bug.yml 2023-12-24 16:08:32 -08:00
Jason Mitchell 62ed17757b Update 000-report-bug.yml 2023-12-24 16:08:11 -08:00
Jason Mitchell f69d2bb9f8 .... 2023-12-17 10:01:31 -08:00
Jason Mitchell d4310a6163 .... 2023-12-17 10:00:05 -08:00
Jason Mitchell 0a37dc6a9a Update issue templates 2023-12-17 09:59:25 -08:00
Jason Mitchell a3fefe413e Issue Templates 2023-12-17 09:58:40 -08:00
glowredman fa8be308de Fully port ASM to Mixins (#11)
* Update buildscript

* Enable genericInjection

* Re-enable remapping for certain mixins

* Update buildscript

* Small fixes

- Add generic types
- Add diamond operators
- Fix typo in "NormalMap"
- Remove redundant assignments
- Access static field via class instead of instance
- Use List as type instead of ArrayList
- Add serialVersionUID

* Rename MixinEntityRender -> MixinRender

* Rewrite EntityRenderer ASM as Mixins

* Replace `@Accessor` mixins in favor of ATs

* Move compat to mixins

* Logger cleanup

* Rewrite ItemRenderer ASM as Mixins

* Unify names

* Rewrite RendererLivingEntity ASM as Mixins

* Use Log4J Logger

* Delete ACTRenderManager

* Rewrite ACTRenderSpider as Mixins

* Rewrite AbstractTexture ASM as Mixins

* Port TextureAtlasSprite ASM as Mixins

* Rewrite ThreadDownloadImageData ASM as Mixins

* Rewrite DynamicTexture ASM as Mixins

* Rewrite LayeredTexture ASM as Mixins

* Rewrite TextureManager ASM as Mixins

* Rewrite ITextureObject ASM as mixins

* Rewrite ITextureObject ASM as Mixins

* Clean up compileStubs

* Delete unused stuff

* Finishing touches
2023-08-23 16:39:00 -07:00
Jason Mitchell 2329be3d2d spotless 2023-08-23 16:39:00 -07:00
Jason Mitchell d5eadf8e22 Add MixinEntityRenderer
* Port over (most of) renderHand
2023-08-23 16:39:00 -07:00
Raven Szewczyk f559e032bb Fix recursive and relative #include handling 2023-08-23 16:39:00 -07:00
Raven Szewczyk 940037bc27 Fix NPE in ModelRenderer 2023-08-23 16:39:00 -07:00
Raven Szewczyk c7d721aa5c Update gradle and dependencies 2023-08-23 16:39:00 -07:00
Raven Szewczyk 40a987d81a Mixin Tessellator 2023-08-23 16:39:00 -07:00
Caedis 6840ff5c64 also delete the old transformer 2023-08-23 16:39:00 -07:00
Caedis dd6bbccd32 Spotless 2023-08-23 16:39:00 -07:00
Caedis bdb473a1ee Mixin SimpleTexture 2023-08-23 16:39:00 -07:00
Caedis 26cf4c7e5a Update build.gradle 2023-08-23 16:39:00 -07:00
Caedis 746f6b11eb Mixin TextureClock and TextureCompass 2023-08-23 16:39:00 -07:00
Raven Szewczyk 6134e7ac6b Update buildscript to use unimixins 2023-08-23 16:39:00 -07:00
Jason Mitchell c2c42ffdc9 Mixin-ify RenderGlobal transformer 2023-08-23 16:39:00 -07:00
Jason Mitchell 82f2180888 Progress
* Remove some compilerStubs, access adjustment ASM and replace with Mixin Accessors
* Renderer Mixins
2023-08-23 16:39:00 -07:00
Jason Mitchell 63cc799966 Renderer Mixins & Lighting Level Mixins 2023-08-23 16:39:00 -07:00
Jason Mitchell bf467a3b96 Mixin Shaders Button 2023-08-23 16:39:00 -07:00
992d5e08b9 Start using mixins (#8)
* SMCLog -> ALog

* Start using Mixins!
* Shader startup ACTMinecraft -> MixinMinecraft

* spotlessApply (#9)

Co-authored-by: GitHub GTNH Actions <>

* Update buildscript, add mixingasm and nei

* Remove unneeded transformer exclusions

* Fix broken stack frames

* Fix mcp namer for rfg

* Inject the asm transformer manually in the correct order to avoid mixin-induced issues

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Raven Szewczyk <[email protected]>
2023-02-23 18:24:05 +00:00
Raven Szewczyk 102938304c Working obfuscated run, switch to FMLLoadingPlugin properly 2023-02-20 20:07:20 +00:00
Raven Szewczyk 9af8478236 Update gradle properties for RFG 2023-02-20 19:54:24 +00:00
Raven Szewczyk 3cc367bf0d Update buildscript 2023-02-20 19:46:58 +00:00
Raven Szewczyk 416b967e8a [ci skip] upgraded build system 2023-01-31 09:50:48 +00:00
Jason Mitchell 5f4739cc78 [ci skip] Add git-blame-ignore-revs for spotlessApply 2023-01-29 12:49:10 -08:00
Jason Mitchell f64f7f366a [ci skip] spotlessApply with the new settings 2023-01-29 12:49:10 -08:00
Jason Mitchell c47661b619 [ci skip] Update buildscript to RetroFuturaGradle 2023-01-29 12:48:47 -08:00
1340 changed files with 100091 additions and 13209 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Ignore spotlessApply reformat
f64f7f366af8fc32dddfe9c9acd1259eb7d65787
+36 -27
View File
@@ -1,35 +1,44 @@
* text eol=lf
*.jar binary
*.[jJ][aA][rR] binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.tif binary
*.tiff binary
*.ico binary
*.svg text
*.eps binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.kar binary
*.m4a binary
*.mid binary
*.midi binary
*.mp3 binary
*.ogg binary
*.ra binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7z binary
*.gz binary
*.tar binary
*.tgz binary
*.zip binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.patch -text
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
*.[pP][aA][tT][cC][hH] -text
*autogenerated binary
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+81
View File
@@ -0,0 +1,81 @@
name: Report Bug
description: "Report a bug."
body:
- type: markdown
attributes:
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Fake#1234"
- type: input
id: version
attributes:
label: Mod Version
description: "What version of the Mod are you using?"
placeholder: "Example: 1.0.0-alpha1"
validations:
required: true
- type: dropdown
id: java
attributes:
label: Java Version
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
options:
- Java 8
- Java 9
- Java 11
- Java 17
- Java 19
- Java 20
- Java 21
- Other (Please Specify)
validations:
required: true
- type: dropdown
id: graphics
attributes:
label: Graphics Card Vendor
description: What graphics card vendor are you using?
options:
- Other (Please Specify)
- NVidia
- AMD/ATI
- Intel iGPU
- AMD iGPU
- Mesa/Software
validations:
required: true
- type: textarea
id: report
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: textarea
id: modlist
attributes:
label: Mod List or GTNH Pack Version
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist."
placeholder: "List of mods or GTNH Pack version goes here"
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
- label: "I have read the known incompatibilities and this is not related to one of those."
required: true
- label: "I am running an officially released version. (Or, if I've compiled it myself I plan to fix the issue)"
required: true
- label: "This issue is not related to a feature that is disabed by default - Shaders, MCPF, etc. [They'll be enabled when they're ready for testing]"
required: true
@@ -0,0 +1,33 @@
name: Feature Request
description: "Request a feature."
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: "Please use this form to request features. We ask you check if it was already requested though"
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Wumpus#1234"
- type: textarea
id: request
attributes:
label: Feature Request
description: "Relevant information, as well as relevant images"
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
- label: "I have read the known incompatibilities and this is not related to one of those."
required: true
- label: "This issue is not related to a feature that is disabed by default - Shaders, MCPF, etc. [They'll be enabled when they're ready for testing]"
required: true
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+1 -1
View File
@@ -26,7 +26,7 @@ whitelist.json
*.iml
*.ipr
*.iws
src/main/resources/mixins.*.json
src/main/resources/mixins.*([!.]).json
*.bat
*.DS_Store
!gradlew.bat
+70 -17
View File
@@ -1,19 +1,72 @@
# Angelica
the little angle that supports shaders while saving your fps from a certain death - boubou
# Angelica<img src="img/logo-readme.png" align="right">
Not yet in an usable state
<sup>**[CurseForge](https://www.curseforge.com/minecraft/mc-mods/angelica) | [Modrinth](https://modrinth.com/mod/angelica)**</sup>
* The little Angle [sic] that supports shaders while saving your fps from a certain death -boubou
* Is it obtuse, or accute? -Caedis
* It's a cute angle -mitchej123
**Alpha Quality - Here there be Dragons**
# Required Dependencies
* [UniMixins](https://github.com/LegacyModdingMC/UniMixins/releases) >= 0.1.14
* [GTNHLib](https://github.com/GTNewHorizons/GTNHLib/releases) >= 0.2.9
* NOTE: Some mods are not required, but a specific version is required if present - see: `Permanent Incompatibilities` below.
# Known (temporary) Incompatibilities
* Forge Relocation - Currently non Thread Safe; safe if not in use
* ProjectRed Frames - Currently non Thread Safe; safe if not in use
# Known - Incompatibilities
* EndlessIDs - Not currently planned (Looking for volunteers)
* FalseTweaks - Not currently planned (Looking for volunteers)
* SmoothFont - Not currently planned (Looking for volunteers)
* RPLE - Not currently planned (Looking for volunteers)
# Permanent Incompatibilities
* Optifine [Disabled, won't fix]
* Fastcraft [Disable, won't fix]
* BetterFPS [Won't fix]
* LWJGL3ify 1.5.4 and below - Use the latest version available, 1.5.7+
* ArchaicFix 0.6.2 and below - Use 0.7.0 or above
* Hodgepodge 2.4.3 and below - [Use 2.4.4 or above](https://github.com/GTNewHorizons/Hodgepodge/releases)
* CodeChicken[Core](https://github.com/GTNewHorizons/CodeChickenCore/releases)/[Lib](https://github.com/GTNewHorizons/CodeChickenLib/releases) <1.2.0 - Threading issues, use 1.2.0+
* Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config)
# Credits
* ShadersMod
* Original ShadersMods: karyonix, sonic ether, id_miner, daxnitro
* eigenraven, Caedis, glowredman, and mitchej123 for the conversion of ASM to Mixin
* eigenraven and vlaetansky for getting the original ShadersMod compiling again
* ArchaicFix
* Includes graphic enhancements from [ArchaicFix](https://github.com/embeddedt/ArchaicFix/tree/4afb943751883b27a1f0aa7c5ba71698bc897e95) by embeddedt under the [LGPL](https://github.com/embeddedt/ArchaicFix/blob/main/LICENSE.md)
* NotFine
* Includes modified version of [NotFine](https://github.com/jss2a98aj/NotFine/tree/a2652e24b5654f437fb7138f6d1f5e947a7d7125) by jss2a98aj under the LGPL
* Iris Shaders
* The [Iris](https://github.com/IrisShaders/Iris) Team: coderbot, IMS212, Justsnoopy30, FoundationGames
* Asek3 for the Iris Forge port [Oculus](https://github.com/Asek3/Oculus/tree/839ce8eca8cf0c4f6b7a1322b906e5c99125ca69)
* Backported code under the LGPL
* Sodium
* JellySquid & the CaffeineMC team, for making Sodium in the first place
* Embeddedt for [Embeddium](https://github.com/embeddedt/embeddium/tree/dc59ca357c25beefd6288f0d1d40b4cd8e670ab8) under the [LGPL 3.0](https://github.com/embeddedt/embeddium/blob/16.x/forge/LICENSE)
* Reese's Sodium Options
* FlashyReese for [Reese's Sodium Options](https://github.com/FlashyReese/reeses-sodium-options/tree/aa4ea67047cf53e54976e93c6bb1ab5ba16b142b) under the [MIT license](https://github.com/FlashyReese/reeses-sodium-options/blob/aa4ea67047cf53e54976e93c6bb1ab5ba16b142b/LICENSE.txt)
* Neodymium
* Makamys for [Neodymium](https://github.com/makamys/Neodymium) - Various Tessellator -> Quad functionality taken under the LGPL 3
* MCPatcherForge
* Original [MCPatcher](https://bitbucket.org/prupe/mcpatcher/src/master/): Paul Rupe
* [Forge version](https://bitbucket.org/prupe/mcpatcher/src/master/): Mist475 under LGPL 3.0 with default ctm textures for glass and bookshelves by DarkBum under CC-BY-SA
* HUDCaching
* Created by [Moulberry](https://github.com/Moulberry/MCHUDCaching), backported from [Patcher](https://github.com/Sk1erLLC/Patcher) mod by Alexdoru under the CC-BY-SA-NC 4.0 license
* Angelica
* mitchej123, Omni, Makamys, Embeddedt, NanoLive, Caedis, Cardinalstar, Alexdoru, Eigenraven, mist475, Clepto for helping get Angelica up and running!
* IMS, jss2a98aj, || dbp ||, roadhog360 for advice and moral support
* Forge 1.12+
* Some files have been taken from Minecraft Forge under the LGPL 2.1 license and are marked as such
* FRAPI and Indigo
* Model building API heavily inspired by/copied from Fabric's; upstream may use it under the original Apache 2.0
license, see LICENSE in `com.gtnewhorizons.angelica.models`
* Dynamic Lights
* LambdAurora for [LambDynamicLights](https://github.com/LambdAurora/LambDynamicLights) under the MIT license, and the Forge port anthxnymc for [DynamicLightsReforged](https://github.com/anthxnymc/DynamicLightsReforged), also under the MIT license
Original build instructions obtained via minecraftforums archeology:
```
Developing environment
- Extract forge src to forge folder. Run "gradlew setupDecompWorkspace setupDevWorkspace" until it succeeded, then "gradlew build", then "gradlew eclipse".
- Delete everything in src\main folder inside forge folder.
- Extract smc-2.3.18-mc1.7.10-src.7z to src\main folder.
- Read patch file shadersmod-mcf.patch
- Find %userprofile%\.gradle\caches\minecraft\net\minecraftforge\forge\*\forgeSrc-*-sources.jar and extract it somewhere.
-- Select files that need to be patched and copy them to src\main with correct folder structure.
- Apply patch shadersmod-mcf.patch
- In eclipse, add java_dev folder as another source folder.
- In eclipse, exclude InitNames in src folder from build path. Use InitNames in java_dev folder instead.
- Find %userprofile%\.gradle\caches\modules-2\files-2.1\net.minecraftforge\forge\*\*\forge-*-userdev.jar and extract conf\*.csv and conf\*.srg in it to forge\conf and rename packaged.srg to joined.srg.
```
-21
View File
@@ -1,21 +0,0 @@
configurations {
compileStubs
}
sourceSets {
compileStubsStubs
compileStubs {
compileClasspath += configurations.compileStubs
}
}
jar {
manifest {
attributes([
"Manifest-Version" : 1.0,
"TweakClass" : "com.gtnewhorizons.angelica.loading.ATweaker",
"TweakOrder" : 1100,
])
}
}
-968
View File
@@ -1,968 +0,0 @@
//version: 1661114848
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.TimeUnit
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
buildscript {
repositories {
mavenCentral()
maven {
name 'forge'
url 'https://maven.minecraftforge.net'
}
maven {
// GTNH ForgeGradle Fork
name = "GTNH Maven"
url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
}
maven {
name 'sonatype'
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
maven {
name 'Scala CI dependencies'
url 'https://repo1.maven.org/maven2/'
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2.9'
}
}
plugins {
id 'java-library'
id 'idea'
id 'eclipse'
id 'scala'
id 'maven-publish'
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false
id 'com.google.devtools.ksp' version '1.5.30-1.0.0' apply false
id 'org.ajoberstar.grgit' version '4.1.1'
id 'com.github.johnrengelman.shadow' version '4.0.4'
id 'com.palantir.git-version' version '0.13.0' apply false
id 'de.undercouch.download' version '5.0.1'
id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false
id 'com.diffplug.spotless' version '6.7.2' apply false
}
boolean settingsupdated = verifySettingsGradle()
settingsupdated = verifyGitAttributes() || settingsupdated
if (settingsupdated)
throw new GradleException("Settings has been updated, please re-run task.")
dependencies {
implementation 'com.diffplug:blowdryer:1.6.0'
}
apply plugin: 'com.diffplug.blowdryer'
if (project.file('.git/HEAD').isFile()) {
apply plugin: 'com.palantir.git-version'
}
def out = services.get(StyledTextOutputFactory).create('an-output')
apply plugin: 'forge'
def projectJavaVersion = JavaLanguageVersion.of(8)
java {
toolchain {
languageVersion.set(projectJavaVersion)
}
}
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false
if (!disableSpotless) {
apply plugin: 'com.diffplug.spotless'
apply from: Blowdryer.file('spotless.gradle')
}
if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
}
checkPropertyExists("modName")
checkPropertyExists("modId")
checkPropertyExists("modGroup")
checkPropertyExists("autoUpdateBuildScript")
checkPropertyExists("minecraftVersion")
checkPropertyExists("forgeVersion")
checkPropertyExists("replaceGradleTokenInFile")
checkPropertyExists("gradleTokenModId")
checkPropertyExists("gradleTokenModName")
checkPropertyExists("gradleTokenVersion")
checkPropertyExists("gradleTokenGroupName")
checkPropertyExists("apiPackage")
checkPropertyExists("accessTransformersFile")
checkPropertyExists("usesMixins")
checkPropertyExists("mixinPlugin")
checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly")
checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName")
boolean noPublishedSources = project.hasProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
boolean usesMixinDebug = project.hasProperty('usesMixinDebug') ?: project.usesMixins.toBoolean()
boolean forceEnableMixins = project.hasProperty('forceEnableMixins') ? project.forceEnableMixins.toBoolean() : false
String channel = project.hasProperty('channel') ? project.channel : 'stable'
String mappingsVersion = project.hasProperty('mappingsVersion') ? project.mappingsVersion : '12'
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
if (apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
}
if (accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if (!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
}
if (usesMixins.toBoolean()) {
if (mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) {
throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!")
}
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if (!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt"
if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
if (coreModClass) {
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt"
if (!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
configurations.all {
resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
// Make sure GregTech build won't time out
System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String)
System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String)
}
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
try {
'git config core.fileMode false'.execute()
}
catch (Exception ignored) {
out.style(Style.Failure).println("git isn't installed at all")
}
// Pulls version first from the VERSION env and then git tag
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
}
catch (Exception ignored) {
out.style(Style.Failure).text(
'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' +
'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' +
'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)'
)
versionOverride = 'NO-GIT-TAG-SET'
identifiedVersion = versionOverride
}
version = minecraftVersion + '-' + identifiedVersion
ext {
modVersion = identifiedVersion
}
if (identifiedVersion == versionOverride) {
out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7')
}
group = modGroup
if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
} else {
archivesBaseName = modId
}
def arguments = []
def jvmArguments = []
if (usesMixins.toBoolean() || forceEnableMixins) {
arguments += [
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
if (usesMixinDebug.toBoolean()) {
jvmArguments += [
"-Dmixin.debug.countInjections=true",
"-Dmixin.debug.verbose=true",
"-Dmixin.debug.export=true"
]
}
}
minecraft {
version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion
runDir = 'run'
if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile
if (gradleTokenModId) {
replace gradleTokenModId, modId
}
if (gradleTokenModName) {
replace gradleTokenModName, modName
}
if (gradleTokenVersion) {
replace gradleTokenVersion, modVersion
}
if (gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
clientIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
if (developmentEnvironmentUserName) {
args("--username", developmentEnvironmentUserName)
}
}
serverIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
}
}
if (file('addon.gradle').exists()) {
apply from: 'addon.gradle'
}
apply from: 'repositories.gradle'
configurations {
implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
implementation.extendsFrom(shadowCompile)
implementation.extendsFrom(shadeCompile)
}
repositories {
maven {
name 'Overmind forge repo mirror'
url 'https://gregtech.overminddl1.com/'
}
if (usesMixins.toBoolean() || forceEnableMixins) {
maven {
name 'sponge'
url 'https://repo.spongepowered.org/repository/maven-public'
}
maven {
url 'https://jitpack.io'
}
}
}
dependencies {
if (usesMixins.toBoolean()) {
annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
annotationProcessor('com.google.guava:guava:24.1.1-jre')
annotationProcessor('com.google.code.gson:gson:2.8.6')
annotationProcessor('org.spongepowered:mixin:0.8-SNAPSHOT')
}
if (usesMixins.toBoolean() || forceEnableMixins) {
// using 0.8 to workaround a issue in 0.7 which fails mixin application
compile('com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
compile('com.github.GTNewHorizons:SpongeMixins:1.5.0')
}
}
apply from: 'dependencies.gradle'
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
task generateAssets {
if (usesMixins.toBoolean()) {
def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json");
if (!mixinConfigFile.exists()) {
mixinConfigFile.text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8",
"mixins": [],
"client": [],
"server": []
}
"""
}
}
}
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
}
shadowJar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [
project.configurations.shadowImplementation,
project.configurations.shadowCompile
]
dependsOn(relocateShadowJar)
}
jar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest {
attributes(getManifestAttributes())
}
if (usesShadowedDependencies.toBoolean()) {
dependsOn(shadowJar)
enabled = false
}
}
reobf {
if (usesMixins.toBoolean()) {
addExtraSrgFile mixinSrg
}
}
afterEvaluate {
if (usesMixins.toBoolean()) {
tasks.compileJava {
options.compilerArgs += [
"-AreobfSrgFile=${tasks.reobf.srg}",
"-AoutSrgFile=${mixinSrg}",
"-AoutRefMapFile=${refMap}",
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
"-XDenableSunApiLintControl",
"-XDignore.symbol.file"
]
}
}
}
runClient {
if (developmentEnvironmentUserName) {
arguments += [
"--username",
developmentEnvironmentUserName
]
}
args(arguments)
jvmArgs(jvmArguments)
}
runServer {
args(arguments)
jvmArgs(jvmArguments)
}
tasks.withType(JavaExec).configureEach {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion = projectJavaVersion
}
)
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
exclude("spotless.gradle")
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace modVersion and minecraftVersion
expand "minecraftVersion": project.minecraft.version,
"modVersion": modVersion,
"modId": modId,
"modName": modName
}
if (usesMixins.toBoolean()) {
from refMap
}
// copy everything else that's not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
exclude 'spotless.gradle'
}
}
def getManifestAttributes() {
def manifestAttributes = [:]
if (!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
}
if (accessTransformersFile) {
manifestAttributes += ["FMLAT": accessTransformersFile.toString()]
}
if (coreModClass) {
manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass]
}
if (usesMixins.toBoolean()) {
manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
"MixinConfigs" : "mixins." + modId + ".json",
"ForceLoadAsMod": !containsMixinsAndOrCoreModOnly.toBoolean()
]
}
return manifestAttributes
}
task sourcesJar(type: Jar) {
from(sourceSets.main.allSource)
from(file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
task shadowDevJar(type: ShadowJar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [
project.configurations.shadowImplementation,
project.configurations.shadowCompile
]
}
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
target = tasks.shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar(type: Jar) {
dependsOn(relocateShadowDevJar)
dependsOn(shadowDevJar)
enabled = false
}
task devJar(type: Jar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output
getArchiveClassifier().set("dev")
manifest {
attributes(getManifestAttributes())
}
if (usesShadowedDependencies.toBoolean()) {
dependsOn(circularResolverJar)
enabled = false
}
}
task apiJar(type: Jar) {
from(sourceSets.main.allSource) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from(sourceSets.main.output) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from(sourceSets.main.resources.srcDirs) {
include("LICENSE")
}
getArchiveClassifier().set('api')
}
artifacts {
if (!noPublishedSources) {
archives sourcesJar
}
archives devJar
if (apiPackage) {
archives apiJar
}
}
// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
// and isn't strictly needed with the POM so just disable it.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
publishing {
publications {
maven(MavenPublication) {
from components.java
if (usesShadowedDependencies.toBoolean()) {
artifact source: shadowJar, classifier: ""
}
if (!noPublishedSources) {
artifact source: sourcesJar, classifier: "sources"
}
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
if (apiPackage) {
artifact source: apiJar, classifier: "api"
}
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons"
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
// Using the identified version, not project.version as it has the prepended 1.7.10
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
// remove extra garbage from minecraft and minecraftDeps configuration
pom.withXml {
def badArtifacts = [:].withDefault { [] as Set<String> }
for (configuration in [
projectConfigs.minecraft,
projectConfigs.minecraftDeps
]) {
for (dependency in configuration.allDependencies) {
badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name
}
}
// example for specifying extra stuff to ignore
// badArtifacts["org.example.group"] += "artifactName"
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
badArtifacts[it.groupId.text()].contains(it.artifactId.text())
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven {
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
credentials {
username = System.getenv("MAVEN_USER") ?: "NONE"
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
}
}
}
}
// Updating
task updateBuildScript {
doLast {
if (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!")
}
}
if (!project.getGradle().startParameter.isOffline() && isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
}
}
static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/build.gradle")
}
static URL exampleSettingsGradleUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/settings.gradle.example")
}
static URL exampleGitAttributesUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/master/.gitattributes")
}
boolean verifyGitAttributes() {
def gitattributesFile = getFile(".gitattributes")
if (!gitattributesFile.exists()) {
println("Downloading default .gitattributes")
exampleGitAttributesUrl().withInputStream { i -> gitattributesFile.withOutputStream { it << i } }
exec {
workingDir '.'
commandLine 'git', 'add', '--renormalize', '.'
}
return true
}
return false
}
boolean verifySettingsGradle() {
def settingsFile = getFile("settings.gradle")
if (!settingsFile.exists()) {
println("Downloading default settings.gradle")
exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
return true
}
return false
}
boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
boolean settingsupdated = verifySettingsGradle()
settingsupdated = verifyGitAttributes() || settingsupdated
if (settingsupdated)
throw new GradleException("Settings has been updated, please re-run task.")
return true
}
return false
}
boolean isNewBuildScriptVersionAvailable(String projectDir) {
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript)
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
return !isUpToDate
}
static String getVersionHash(String buildScriptContent) {
String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
if (versionLine != null) {
return versionLine.split(": ").last()
}
return ""
}
configure(updateBuildScript) {
group = 'forgegradle'
description = 'Updates the build script to the latest version'
}
// Parameter Deobfuscation
task deobfParams {
doLast {
String mcpDir = "$project.gradle.gradleUserHomeDir/caches/minecraft/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion"
String mcpZIP = "$mcpDir/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
String paramsCSV = "$mcpDir/params.csv"
download.run {
src "https://maven.minecraftforge.net/de/oceanlabs/mcp/mcp_$channel/$mappingsVersion-$minecraftVersion/mcp_$channel-$mappingsVersion-${minecraftVersion}.zip"
dest mcpZIP
overwrite false
}
if (!file(paramsCSV).exists()) {
println("Extracting MCP archive ...")
unzip(mcpZIP, mcpDir)
}
println("Parsing params.csv ...")
Map<String, String> params = new HashMap<>()
Files.lines(Paths.get(paramsCSV)).forEach { line ->
String[] cells = line.split(",")
if (cells.length > 2 && cells[0].matches("p_i?\\d+_\\d+_")) {
params.put(cells[0], cells[1])
}
}
out.style(Style.Success).println("Modified ${replaceParams(file("$projectDir/src/main/java"), params)} files!")
out.style(Style.Failure).println("Don't forget to verify that the code still works as before!\n It could be broken due to duplicate variables existing now\n or parameters taking priority over other variables.")
}
}
static int replaceParams(File file, Map<String, String> params) {
int fileCount = 0
if (file.isDirectory()) {
for (File f : file.listFiles()) {
fileCount += replaceParams(f, params)
}
return fileCount
}
println("Visiting ${file.getName()} ...")
try {
String content = new String(Files.readAllBytes(file.toPath()))
int hash = content.hashCode()
params.forEach { key, value ->
content = content.replaceAll(key, value)
}
if (hash != content.hashCode()) {
Files.write(file.toPath(), content.getBytes("UTF-8"))
return 1
}
} catch (Exception e) {
e.printStackTrace()
}
return 0
}
// Credit: bitsnaps (https://gist.github.com/bitsnaps/00947f2dce66f4bbdabc67d7e7b33681)
static unzip(String zipFileName, String outputDir) {
byte[] buffer = new byte[16384]
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName))
ZipEntry zipEntry = zis.getNextEntry()
while (zipEntry != null) {
File newFile = new File(outputDir + File.separator, zipEntry.name)
if (zipEntry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
throw new IOException("Failed to create directory $newFile")
}
} else {
// fix for Windows-created archives
File parent = newFile.parentFile
if (!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("Failed to create directory $parent")
}
// write file content
FileOutputStream fos = new FileOutputStream(newFile)
int len = 0
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len)
}
fos.close()
}
zipEntry = zis.getNextEntry()
}
zis.closeEntry()
zis.close()
}
configure(deobfParams) {
group = 'forgegradle'
description = 'Rename all obfuscated parameter names inherited from Minecraft classes'
}
// Dependency Deobfuscation
def deobf(String sourceURL) {
try {
URL url = new URL(sourceURL)
String fileName = url.getFile()
//get rid of directories:
int lastSlash = fileName.lastIndexOf("/")
if (lastSlash > 0) {
fileName = fileName.substring(lastSlash + 1)
}
//get rid of extension:
if (fileName.endsWith(".jar") || fileName.endsWith(".litemod")) {
fileName = fileName.substring(0, fileName.lastIndexOf("."))
}
String hostName = url.getHost()
if (hostName.startsWith("www.")) {
hostName = hostName.substring(4)
}
List parts = Arrays.asList(hostName.split("\\."))
Collections.reverse(parts)
hostName = String.join(".", parts)
return deobf(sourceURL, "$hostName/$fileName")
} catch (Exception e) {
return deobf(sourceURL, "deobf/${sourceURL.hashCode()}")
}
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
def deobf(String sourceURL, String rawFileName) {
String bon2Version = "2.5.1"
String fileName = URLDecoder.decode(rawFileName, "UTF-8")
String cacheDir = "$project.gradle.gradleUserHomeDir/caches"
String bon2Dir = "$cacheDir/forge_gradle/deobf"
String bon2File = "$bon2Dir/BON2-${bon2Version}.jar"
String obfFile = "$cacheDir/modules-2/files-2.1/${fileName}.jar"
String deobfFile = "$cacheDir/modules-2/files-2.1/${fileName}-deobf.jar"
if (file(deobfFile).exists()) {
return files(deobfFile)
}
String mappingsVer
String remoteMappings = project.hasProperty('remoteMappings') ? project.remoteMappings : 'https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/'
if (remoteMappings) {
String id = "${forgeVersion.split("\\.")[3]}-$minecraftVersion"
String mappingsZIP = "$cacheDir/forge_gradle/maven_downloader/de/oceanlabs/mcp/mcp_snapshot_nodoc/$id/mcp_snapshot_nodoc-${id}.zip"
zipMappings(mappingsZIP, remoteMappings, bon2Dir)
mappingsVer = "snapshot_$id"
} else {
mappingsVer = "${channel}_$mappingsVersion"
}
download.run {
src "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases/com/github/parker8283/BON2/$bon2Version-CUSTOM/BON2-$bon2Version-CUSTOM-all.jar"
dest bon2File
quiet true
overwrite false
}
download.run {
src sourceURL
dest obfFile
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', minecraftVersion, '--mappingsVer', mappingsVer, '--notch'
workingDir bon2Dir
standardOutput = new FileOutputStream("${deobfFile}.log")
}
return files(deobfFile)
}
def zipMappings(String zipPath, String url, String bon2Dir) {
File zipFile = new File(zipPath)
if (zipFile.exists()) {
return
}
String fieldsCache = "$bon2Dir/data/fields.csv"
String methodsCache = "$bon2Dir/data/methods.csv"
download.run {
src "${url}fields.csv"
dest fieldsCache
quiet true
}
download.run {
src "${url}methods.csv"
dest methodsCache
quiet true
}
zipFile.getParentFile().mkdirs()
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))
zos.putNextEntry(new ZipEntry("fields.csv"))
Files.copy(Paths.get(fieldsCache), zos)
zos.closeEntry()
zos.putNextEntry(new ZipEntry("methods.csv"))
Files.copy(Paths.get(methodsCache), zos)
zos.closeEntry()
zos.close()
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (!project.hasProperty(propertyName)) {
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
}
+33
View File
@@ -0,0 +1,33 @@
plugins {
id("com.gtnewhorizons.gtnhconvention")
}
minecraft {
extraRunJvmArguments.add("-Dangelica.enableTestBlocks=true")
}
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
}
dependsOn(tasks.extractNatives2)
jvmArgs("-Djava.library.path=${tasks.extractNatives2.get().destinationFolder.asFile.get().path}")
}
tasks.processResources {
inputs.property("version", project.version.toString())
filesMatching("META-INF/rfb-plugin/*") {
expand("version" to project.version.toString())
}
}
tasks.register<Copy>("copyDependencies") {
group = "Angelica"
description = "Collect dependencies into the testDependencies folder"
from(configurations.default)
into("testDependencies")
}
+108 -2
View File
@@ -1,5 +1,111 @@
/*
* Add your dependencies here. Supported configurations:
* - api("group:name:version:classifier"): if you use the types from this dependency in the public API of this mod
* Available at runtime and compiletime for mods depending on this mod
* - implementation("g:n:v:c"): if you need this for internal implementation details of the mod, but none of it is visible via the public API
* Available at runtime but not compiletime for mods depending on this mod
* - compileOnly("g:n:v:c"): if the mod you're building doesn't need this dependency during runtime at all, e.g. for optional mods
* Not available at all for mods depending on this mod, only visible at compiletime for this mod
* - compileOnlyApi("g:n:v:c"): like compileOnly, but also visible at compiletime for mods depending on this mod
* Available at compiletime but not runtime for mods depending on this mod
* - runtimeOnlyNonPublishable("g:n:v:c"): if you want to include a mod in this mod's runClient/runServer runs, but not publish it as a dependency
* Not available at all for mods depending on this mod, only visible at runtime for this mod
* - devOnlyNonPublishable("g:n:v:c"): a combination of runtimeOnlyNonPublishable and compileOnly for dependencies present at both compiletime and runtime,
* but not published as Maven dependencies - useful for RFG-deobfuscated dependencies or local testing
* - runtimeOnly("g:n:v:c"): if you don't need this at compile time, but want it to be present at runtime
* Available at runtime for mods depending on this mod
* - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
* - testCONFIG("g:n:v:c") - replace CONFIG by one of the above (except api), same as above but for the test sources instead of main
*
* - shadowImplementation("g:n:v:c"): effectively the same as API, but the dependency is included in your jar under a renamed package name
* Requires you to enable usesShadowedDependencies in gradle.properties
*
* - compile("g:n:v:c"): deprecated, replace with "api" (works like the old "compile") or "implementation" (can be more efficient)
*
* You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed,
* but use this sparingly as it can break using your mod as another mod's dependency if you're not careful.
*
* To depend on obfuscated jars you can use `devOnlyNonPublishable(rfg.deobf("dep:spec:1.2.3"))` to fetch an obfuscated jar from maven,
* or `devOnlyNonPublishable(rfg.deobf(project.files("libs/my-mod-jar.jar")))` to use a file.
*
* Gradle names for some of the configuration can be misleading, compileOnlyApi and runtimeOnly both get published as dependencies in Maven, but compileOnly does not.
* The buildscript adds runtimeOnlyNonPublishable to also have a runtime dependency that's not published.
*
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
configurations {
transformedMod // Mods that can be transformed - used for compiling angelica, but not necessary at runtime
transformedMod.canBeConsumed = false
transformedModCompileOnly
transformedModCompileOnly.canBeConsumed = false
// Add the transformed mod dependencies to the compilation classpaths, but don't publish them in the Maven metadata
compileClasspath.extendsFrom(transformedMod, transformedModCompileOnly)
testCompileClasspath.extendsFrom(transformedMod, transformedModCompileOnly)
// Can be enabled for testing if desired
// runtimeClasspath.extendsFrom(transformedMod)
// testRuntimeClasspath.extendsFrom(transformedMod)
}
dependencies {
compileOnly(sourceSets.compileStubs.output)
compileStubs(sourceSets.compileStubsStubs.output)
compileOnly("com.github.GTNewHorizons:Hodgepodge:2.4.31")
compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:0.4.0") { transitive = false }
compileOnly("org.projectlombok:lombok:1.18.22") { transitive = false }
annotationProcessor("org.projectlombok:lombok:1.18.22")
// Iris Shaders
compileOnly('org.jetbrains:annotations:24.0.1')
api("com.github.GTNewHorizons:GTNHLib:0.2.9:dev")
shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0
implementation("io.github.douira:glsl-transformer:1.0.0")
shadowImplementation("io.github.douira:glsl-transformer:1.0.0") { // glsl-transformer Noncommercial License 1.0.0
exclude module: "antlr4" // we only want to shadow the runtime module
}
compileOnly "org.apache.ant:ant:1.8.2"
// Because who doesn't want NEI
devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.4.9-GTNH:dev')
devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.2.0:dev')
// Notfine Deps
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")
compileOnly("com.github.GTNewHorizons:twilightforest:2.5.16:dev") { transitive = false }
compileOnly(rfg.deobf('curse.maven:witchery-69673:2234410'))
compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.0-GTNH:dev")
compileOnly("com.github.GTNewHorizons:Natura:2.6.1:dev")
compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.5.0:api") { transitive = false }
compileOnly("com.falsepattern:endlessids-mc1.7.10:1.5-beta0002:dev") { transitive = false }
compileOnly(rfg.deobf("curse.maven:extrautils-225561:2264383"))
compileOnly(rfg.deobf("curse.maven:dynamiclights-227874:2337326"))
compileOnly("com.github.GTNewHorizons:NotEnoughIds:2.0.3:dev") // Mixin Version
compileOnly("com.github.GTNewHorizons:NotEnoughIds-Legacy:1.4.7:dev") // ASM Version
compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675"))
// HMMMMM
compileOnly(rfg.deobf("curse.maven:journeymap-32274:2367915"))
compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684"))
compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.4-GTNH:dev")
runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2"))
// Hodgepodge
transformedMod("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev")
// Better Crashes
compileOnly("com.github.GTNewHorizons:BetterCrashes:1.4.0-GTNH:dev")
// Tests
testImplementation(platform('org.junit:junit-bom:5.9.2'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation("org.mockito:mockito-core:3.+")
testImplementation("org.lwjgl.lwjgl:lwjgl:2.9.4-nightly-20150209")
}
Binary file not shown.
+34
View File
@@ -0,0 +1,34 @@
# A specification for models
This is borrowed from [the unofficial Minecraft wiki](https://minecraft.wiki/w/Tutorials/Models) under the CC BY-NC-SA 3.0.
The folder `assets/<namespace>/models/block` holds the model files for all the specified variants. The names of the files can be changed, but must always correspond with the names used in the variant files.
* `[TAG_compound]` The root tag
* `[TAG_string]` **parent**: Loads a different model from the given path, in form of a [resource location](https://minecraft.wiki/w/Tutorials/Models#File_path). If both `"parent"` and `"elements"` are set, the `"elements"` tag overrides the `"elements"` tag from the previous model.
* Can be set to `"builtin/generated"` to use a model that is created out of the specified icon. Note that only the first layer is supported, and rotation can be achieved only by using block states files.
* `[TAG_byte]` **ambientocclusion**: Whether to use [ambient occlusion](http://en.wikipedia.org/wiki/Ambient_occlusion) (`true` - default), or not (`false`). Note:only works on Parent file
* `[TAG_object]` **display**: Holds the different places where item models are displayed.
* `[TAG_compound]` ***Position***: Named `thirdperson_righthand`, `thirdperson_lefthand`, `firstperson_righthand`, `firstperson_lefthand`, `gui`, `head`, `ground`, or `fixed`. Place where an item model is displayed. Holds its rotation, translation and scale for the specified situation. '''fixed''' refers to item frames, while the rest are as their name states. Note that translations are applied to the model before rotations.
* `[TAG_list]` **rotation**: Specifies the rotation of the model according to the scheme `[x, y, z]`.
* `[TAG_list]` **translation**: Specifies the position of the model according to the scheme `[x, y, z]`. The values are clamped between -80 and 80.
* `[TAG_list]` **scale**: Specifies the scale of the model according to the scheme `[x, y, z]`. If the value is greater than 4, it is displayed as 4.
* `[TAG_compound]` **textures**: Holds the textures of the model, in form of a [resource location](https://minecraft.wiki/w/Tutorials/Models#File_path) or can be another texture variable.
* `[TAG_string]` **particle**: What texture to load particles from. This texture is also used as an overlay if you are in a [nether portal](https://minecraft.wiki/w/Nether_portal), and used for [water](https://minecraft.wiki/w/water) and [lava](https://minecraft.wiki/w/Lava)'s still textures.<sup>[[1]](https://bugs.mojang.com/browse/MC-240042)</sup> This texture is also considered a texture variable that can be referenced as `"#particle"`. Note: All breaking particles from non-model blocks are hard-coded, such as for [barriers](https://minecraft.wiki/w/Barrier).
* `[TAG_string]` ***Texture variable***: Defines a texture variable with `name` and assigns it to a texture or another variable.
* `[TAG_list]` **elements**: Contains all the elements of the model. They can have only cubic forms. If both `"parent"` and `"elements"` are set, the `"elements"` tag overrides the `"elements"` tag from the previous model.
* `[TAG_compound]` An element.
* `[TAG_list]` **from**: Start point of a cuboid according to the scheme `[x, y, z]`. Values must be between -16 and 32.
* `[TAG_list]` **to**: Stop point of a cuboid according to the scheme `[x, y, z]`. Values must be between -16 and 32.
* `[TAG_compound]` **rotation**: Defines the rotation of an element.
* `[TAG_list]` **origin**: Sets the center of the rotation according to the scheme `[x, y, z]`.
* `[TAG_string]` **axis**: Specifies the direction of rotation, can be `"x"`, `"y"` or `"z"`.
* `[TAG_float]` **angle**: Specifies the angle of rotation. Can be 45 through -45 degrees in 22.5 degree increments.
* `[TAG_byte]` **rescale**: Specifies whether or not to scale the faces across the whole block. Can be true or false. Defaults to false.
* `[TAG_byte]` **shade**: Defines if shadows are rendered (`true` - default), not (`false`).
* `[TAG_compound]` **faces**: Holds all the faces of the cuboid. If a face is left out, it does not render.
* `[TAG_compound]` ***Face***: Named `down`, `up`, `north`, `south`, `west` or `east`. Contains the properties of the specified face.
* `[TAG_list]` **uv**: Defines the area of the texture to use according to the scheme `[x1, y1, x2, y2]`. The texture behavior is inconsistent if UV extends below 0 or above 16. If the numbers of `x1` and `x2` are swapped (e.g. from `0, 0, 16, 16` to `16, 0, 0, 16`), the texture flips. UV is optional, and if not supplied it automatically generates based on the element's position.
* `[TAG_string]` **texture**: Specifies the texture in form of the texture variable prepended with a `#`.
* `[TAG_string]` **cullface**: Specifies whether a face does not need to be rendered when there is a block touching it in the specified position. The position can be: `down`, `up`, `north`, `south`, `west`, or `east`. It also determines the side of the block to use the light level from for lighting the face, and if unset, defaults to the side.
* `[TAG_int]` **rotation**: Rotates the texture clockwise by the specified number of degrees. Can be 0, 90, 180, or 270. Defaults to 0. Rotation does not affect which part of the texture is used. Instead, it amounts to permutation of the selected texture vertexes (selected implicitly, or explicitly though `uv`).
* `[TAG_int]` **tintindex**: Determines whether to tint the texture using a hardcoded tint index. The default value, -1, indicates not to use the tint. Any other number is provided to BlockColors to get the tint value corresponding to that index. However, most blocks do not have a tint value defined (in which case white is used). Furthermore, no vanilla block currently uses multiple tint values, and thus the tint index value is ignored (as long as it is set to something other than -1); it could be used for modded blocks that need multiple distinct tint values in the same block though.
File diff suppressed because it is too large. Load diff
+146 -38
View File
@@ -1,65 +1,104 @@
# ExampleMod tag to use as Blowdryer (Spotless, etc.) settings version, leave empty to disable.
# LOCAL to test local config updates.
gtnh.settings.blowdryerTag = 0.2.2
# Human-readable mod name, available for mcmod.info population.
modName = Angelica
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
# Conventionally lowercase.
modId = angelica
# Root package of the mod, used to find various classes in other properties,
# mcmod.info substitution, enabling assertions in run tasks, etc.
modGroup = com.gtnewhorizons.angelica
# WHY is there no version field?
# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
# Whether to use modGroup as the maven publishing group.
# Due to a history of using JitPack, the default is com.github.GTNewHorizons for all mods.
useModGroupForPublishing = false
# Will update your build.gradle automatically whenever an update is available
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
# Version of Minecraft to target
minecraftVersion = 1.7.10
# Version of Minecraft Forge to target
forgeVersion = 10.13.4.1614
# Specify a MCP channel and mappings version for dependency deobfuscation and the deobfParams task.
# Specify an MCP channel for dependency deobfuscation and the deobfParams task.
channel = stable
# Specify an MCP mappings version for dependency deobfuscation and the deobfParams task.
mappingsVersion = 12
# Define other MCP mappings for dependency deobfuscation
remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username each time you
# restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = Developer
# Define a source file of your project with:
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = true
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = true
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass = com.gtnewhorizons.angelica.Tags
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = VERSION
# [DEPRECATED] Mod ID replacement token.
gradleTokenModId =
# [DEPRECATED] Mod name replacement token.
gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
replaceGradleTokenInFile = Tags.java
gradleTokenModId = GRADLETOKEN_MODID
gradleTokenModName = GRADLETOKEN_MODNAME
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenGroupName = GRADLETOKEN_GROUPNAME
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile =
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
apiPackage =
# Example value: (apiPackage = api) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.api
apiPackage = api
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile =
# There can be multiple files in a space-separated list.
# Example value: mymodid_at.cfg nei_at.cfg
accessTransformersFile = angelica_at.cfg notfine_at.cfg archaicfix_at.cfg mcpatcherforge_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Adds some debug arguments like verbose output and export
usesMixins = true
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
mixinsPackage = mixins
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass =
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
coreModClass = loading.AngelicaTweaker
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false
@@ -67,18 +106,87 @@ containsMixinsAndOrCoreModOnly = false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
# responsibility check the licence and request permission for distribution, if required.
usesShadowedDependencies = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your
# responsibility to check the license and request permission for distribution if required.
usesShadowedDependencies = true
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds the GTNH maven, CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId = angelica
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
modrinthRelations = required-project\:gtnhlib
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId = 988067
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations = requiredDependency\:gtnhlib
# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
#customArchiveBaseName =
# customArchiveBaseName =
# Optional parameter to prevent the source code from being published
# noPublishedSources =
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
# Uncomment this to disable spotless checks
# Uncomment to prevent the source code from being published.
# noPublishedSources = true
# Uncomment this to disable Spotless checks.
# This should only be uncommented to keep it easier to sync with upstream/other forks.
# That is, if there is no other active fork/upstream, NEVER change this.
# disableSpotless = true
disableSpotless = true
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
# disableCheckstyle = true
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# (force use delegated build).
# This is meant to be set in $HOME/.gradle/gradle.properties.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be native build.
# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
# ideaOverrideBuildType = idea
# Whether IDEA should run spotless checks when pressing the Build button.
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
Binary file not shown.
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Regular → Executable
+178 -117
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,78 +17,111 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+25 -33
View File
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,10 +25,14 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@@ -37,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -51,48 +55,36 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
magick convert logo-1x.png -scale 200% \( +clone -background black -shadow 60x6+0+0 \) +swap -background none -layers merge logo-readme.png
+25 -1
View File
@@ -1,5 +1,29 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
name = 'mavenpattern'
url = 'https://mvn.falsepattern.com/releases'
content {
includeGroup 'com.falsepattern'
}
}
exclusiveContent {
forRepository {
ivy {
name = 'CoreTweaks releases'
url = 'https://github.com/makamys/CoreTweaks/releases/download/'
patternLayout {
artifact '[revision]/[module]-1.7.10-[revision]+nomixin(-[classifier])(.[ext])'
}
metadataSources {
artifact()
}
}
}
filter {
includeGroup('CoreTweaks')
}
}
mavenLocal()
}
+18 -8
View File
@@ -1,10 +1,20 @@
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "https://nexus.gtnewhorizons.com/repository/public/"
mavenContent {
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
}
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
plugins {
id 'com.diffplug.blowdryerSetup' version '1.6.0'
}
apply plugin: 'com.diffplug.blowdryerSetup'
blowdryerSetup {
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.1.5')
//devLocal '.' // Use this when testing config updates locally
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.21'
}
@@ -1,7 +0,0 @@
package net.minecraft.client.model;
import java.util.List;
public class ModelBase {
public List boxList;
}
@@ -1,10 +0,0 @@
package net.minecraft.client.model;
import java.util.List;
public class ModelRenderer {
public List childModels;
public void resetDisplayList() {}
}
@@ -1,14 +0,0 @@
package net.minecraft.client.renderer;
public class EntityRenderer {
public static int anaglyphField;
public static boolean anaglyphEnable;
/**
* Render player hand
*/
public void renderHand(float p_78476_1_, int p_78476_2_) {}
public void renderWorld(float f, long l) {}
}
@@ -1,8 +0,0 @@
package net.minecraft.client.renderer;
public class RenderGlobal {
public WorldRenderer[] worldRenderers;
public void loadRenderers() {}
}
@@ -1,180 +0,0 @@
package net.minecraft.client.renderer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import net.minecraft.client.shader.TesselatorVertexState;
public class Tessellator {
private static int nativeBufferSize;
private static int trivertsInBuffer;
public static boolean renderingWorldRenderer;
public boolean defaultTexture;
private int rawBufferSize;
public int textureID;
/** The byte buffer used for GL allocation. */
public ByteBuffer byteBuffer;
/** The same memory as byteBuffer, but referenced as an integer buffer. */
public IntBuffer intBuffer;
/** The same memory as byteBuffer, but referenced as an float buffer. */
public FloatBuffer floatBuffer;
/** The same memory as byteBuffer, but referenced as an short buffer. */
public ShortBuffer shortBuffer;
/** Raw integer array. */
public int[] rawBuffer;
/** The number of vertices to be drawn in the next draw call. Reset to 0 between draw calls. */
public int vertexCount;
/** The first coordinate to be used for the texture. */
public double textureU;
/** The second coordinate to be used for the texture. */
public double textureV;
public int brightness;
/** The color (RGBA) value to be used for the following draw call. */
public int color;
/** Whether the current draw object for this tessellator has color values. */
public boolean hasColor;
/** Whether the current draw object for this tessellator has texture coordinates. */
public boolean hasTexture;
public boolean hasBrightness;
/** Whether the current draw object for this tessellator has normal values. */
public boolean hasNormals;
/** The index into the raw buffer to be used for the next data. */
public int rawBufferIndex;
/**
* The number of vertices manually added to the given draw call. This differs from vertexCount because it adds extra
* vertices when converting quads to triangles.
*/
public int addedVertices;
/** Disables all color information for the following draw call. */
public boolean isColorDisabled;
/** The draw mode currently being used by the tessellator. */
public int drawMode;
/** An offset to be applied along the x-axis for all vertices in this draw call. */
public double xOffset;
/** An offset to be applied along the y-axis for all vertices in this draw call. */
public double yOffset;
/** An offset to be applied along the z-axis for all vertices in this draw call. */
public double zOffset;
/** The normal to be applied to the face being drawn. */
public int normal;
/** The static instance of the Tessellator. */
public static final Tessellator instance = new Tessellator();
/** Whether this tessellator is currently in draw mode. */
public boolean isDrawing;
/** The size of the buffers used (in integers). */
public int bufferSize;
public float midTextureU;
public float midTextureV;
public float normalX;
public float normalY;
public float normalZ;
public float[] vertexPos = new float[16];
private Tessellator(int p_i1250_1_) {}
public Tessellator() {}
/**
* Draws the data set up in this tessellator and resets the state to prepare for new drawing.
*/
public int draw() {
return 0;
}
public TesselatorVertexState getVertexState(float p_147564_1_, float p_147564_2_, float p_147564_3_) {
return null;
}
public void setVertexState(TesselatorVertexState p_147565_1_) {}
/**
* Clears the tessellator state in preparation for new drawing.
*/
public void reset() {}
/**
* Sets draw mode in the tessellator to draw quads.
*/
public void startDrawingQuads() {}
/**
* Resets tessellator state and prepares for drawing (with the specified draw mode).
*/
public void startDrawing(int p_78371_1_) {}
/**
* Sets the texture coordinates.
*/
public void setTextureUV(double p_78385_1_, double p_78385_3_) {}
public void setBrightness(int p_78380_1_) {}
/**
* Sets the RGB values as specified, converting from floats between 0 and 1 to integers from 0-255.
*/
public void setColorOpaque_F(float p_78386_1_, float p_78386_2_, float p_78386_3_) {}
/**
* Sets the RGBA values for the color, converting from floats between 0 and 1 to integers from 0-255.
*/
public void setColorRGBA_F(float p_78369_1_, float p_78369_2_, float p_78369_3_, float p_78369_4_) {}
/**
* Sets the RGB values as specified, and sets alpha to opaque.
*/
public void setColorOpaque(int p_78376_1_, int p_78376_2_, int p_78376_3_) {}
/**
* Sets the RGBA values for the color. Also clamps them to 0-255.
*/
public void setColorRGBA(int p_78370_1_, int p_78370_2_, int p_78370_3_, int p_78370_4_) {}
public void func_154352_a(byte p_154352_1_, byte p_154352_2_, byte p_154352_3_) {}
/**
* Adds a vertex specifying both x,y,z and the texture u,v for it.
*/
public void addVertexWithUV(
double p_78374_1_, double p_78374_3_, double p_78374_5_, double p_78374_7_, double p_78374_9_) {}
/**
* Adds a vertex with the specified x,y,z to the current draw call. It will trigger a draw() if the buffer gets
* full.
*/
public void addVertex(double p_78377_1_, double p_78377_3_, double p_78377_5_) {}
/**
* Sets the color to the given opaque value (stored as byte values packed in an integer).
*/
public void setColorOpaque_I(int p_78378_1_) {}
/**
* Sets the color to the given color (packed as bytes in integer) and alpha values.
*/
public void setColorRGBA_I(int p_78384_1_, int p_78384_2_) {}
/**
* Disables colors for the current draw call.
*/
public void disableColor() {}
/**
* Sets the normal for the current draw call.
*/
public void setNormal(float p_78375_1_, float p_78375_2_, float p_78375_3_) {}
/**
* Sets the translation for all vertices in the current draw call.
*/
public void setTranslation(double p_78373_1_, double p_78373_3_, double p_78373_5_) {}
/**
* Offsets the translation for all vertices in the current draw call.
*/
public void addTranslation(float p_78372_1_, float p_78372_2_, float p_78372_3_) {}
}
@@ -1,13 +0,0 @@
package net.minecraft.client.renderer;
import net.minecraft.client.renderer.culling.ICamera;
public class WorldRenderer {
public boolean isInFrustum;
public boolean skipAllRenderPasses() {
return false;
}
public void updateInFrustum(ICamera frustrum) {}
}
@@ -1,6 +0,0 @@
package net.minecraft.client.renderer.culling;
public class Frustrum implements ICamera {
public void setPosition(double x, double y, double z) {}
}
@@ -1,3 +0,0 @@
package net.minecraft.client.renderer.culling;
public interface ICamera {}
@@ -1,3 +0,0 @@
package net.minecraft.client.renderer.entity;
public abstract class Render {}
@@ -1,10 +0,0 @@
package net.minecraft.client.renderer.entity;
import net.minecraft.client.model.ModelBase;
public abstract class RendererLivingEntity extends Render {
public ModelBase mainModel;
/** The model to be used during the render passes. */
public ModelBase renderPassModel;
}
@@ -1,17 +0,0 @@
package net.minecraft.client.renderer.texture;
import com.gtnewhorizons.angelica.client.MultiTexID;
public abstract class AbstractTexture implements ITextureObject {
public int glTextureId = -1;
public MultiTexID multiTex;
public int getGlTextureId() {
return 0;
}
public MultiTexID getMultiTexID() {
return null;
}
}
@@ -1,13 +0,0 @@
package net.minecraft.client.renderer.texture;
public class DynamicTexture extends AbstractTexture {
public DynamicTexture(int i, int i1) {
super();
}
public int[] getTextureData() {
return null;
}
public void updateDynamicTexture() {}
}
@@ -1,10 +0,0 @@
package net.minecraft.client.renderer.texture;
import com.gtnewhorizons.angelica.client.MultiTexID;
public interface ITextureObject {
MultiTexID getMultiTexID();
int getGlTextureId();
}
@@ -1,8 +0,0 @@
package net.minecraft.client.renderer.texture;
public class TextureAtlasSprite {
public boolean useAnisotropicFiltering;
public void updateAnimation() {}
}
@@ -1,18 +0,0 @@
package net.minecraft.client.renderer.texture;
import net.minecraft.util.ResourceLocation;
public class TextureMap extends AbstractTexture {
public static ResourceLocation locationBlocksTexture;
public int atlasWidth;
public int atlasHeight;
public int getTextureType() {
return 0;
}
public ResourceLocation completeResourceLocation(ResourceLocation resourceLocation, int i) {
return null;
}
}
-1
View File
@@ -1 +0,0 @@
Stubs for the compile stubs
@@ -1,3 +0,0 @@
package com.gtnewhorizons.angelica.client;
public class MultiTexID {}
@@ -1,3 +0,0 @@
package net.minecraft.client.shader;
public class TesselatorVertexState {}
@@ -1,3 +0,0 @@
package net.minecraft.util;
public class ResourceLocation {}
@@ -0,0 +1,22 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizon.gtnhmixins.ILateMixinLoader;
import com.gtnewhorizon.gtnhmixins.LateMixin;
import com.gtnewhorizons.angelica.mixins.Mixins;
import java.util.List;
import java.util.Set;
@LateMixin
public class AngelicaLateMixins implements ILateMixinLoader {
@Override
public String getMixinConfig() {
return "mixins.angelica.late.json";
}
@Override
public List<String> getMixins(Set<String> loadedMods) {
return Mixins.getLateMixins(loadedMods);
}
}
@@ -0,0 +1,45 @@
package com.gtnewhorizons.angelica;
import com.gtnewhorizons.angelica.compat.ModStatus;
import com.gtnewhorizons.angelica.proxy.CommonProxy;
import com.gtnewhorizons.angelica.utils.AnimationMode;
import com.gtnewhorizons.angelica.utils.ManagedEnum;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
@Mod(
modid = "angelica",
name = "Angelica",
version = Tags.VERSION,
dependencies = " before:lwjgl3ify@[1.5.3,);" + " after:hodgepodge@[2.4.4,);" + " after:CodeChickenCore@[1.2.0,);"
+ " after:archaicfix@[0.7.0,);" + " required-after:gtnhlib@[0.2.9,);",
acceptedMinecraftVersions = "[1.7.10]",
acceptableRemoteVersions = "*",
guiFactory = "com.gtnewhorizons.angelica.config.AngelicaGuiConfigFactory")
public class AngelicaMod {
@SidedProxy(clientSide = "com.gtnewhorizons.angelica.proxy.ClientProxy", serverSide = "com.gtnewhorizons.angelica.proxy.CommonProxy")
public static CommonProxy proxy;
public static final boolean lwjglDebug = Boolean.parseBoolean(System.getProperty("org.lwjgl.util.Debug", "false"));
public static final ManagedEnum<AnimationMode> animationsMode = new ManagedEnum<>(AnimationMode.VISIBLE_ONLY);
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
ModStatus.preInit();
proxy.preInit(event);
}
@Mod.EventHandler
public void init(FMLInitializationEvent event) {
proxy.init(event);
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent event) {
proxy.postInit(event);
}
}
@@ -0,0 +1,10 @@
- [x] Frustum (Seems related to Frustrum)
- [X] NativeImage
- [ ] PoseStack
- [ ] RenderType
- [ ] MultiBufferSource.BufferSource
- [ ] VertexBuffer
- [ ] VertexConsumer
- [ ] VertextFormat
- [ ] TextureAtlas (Seems related to TextureManager) - PBR related
- [ ] GUI
@@ -1,12 +0,0 @@
package com.gtnewhorizons.angelica;
// Use this class for Strings only. Do not import any classes here. It will lead to issues with Mixins if in use!
public class Tags {
// GRADLETOKEN_* will be replaced by your configuration values at build time
public static final String MODID = "GRADLETOKEN_MODID";
public static final String MODNAME = "GRADLETOKEN_MODNAME";
public static final String VERSION = "GRADLETOKEN_VERSION";
public static final String GROUPNAME = "GRADLETOKEN_GROUPNAME";
}
@@ -0,0 +1,49 @@
package com.gtnewhorizons.angelica.api;
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
import net.minecraft.util.MathHelper;
import net.minecraftforge.common.util.ForgeDirection;
import java.math.RoundingMode;
import static com.google.common.math.IntMath.log2;
public interface BlockPos {
int SIZE_BITS_X = 1 + log2(MathHelper.roundUpToPowerOfTwo(30000000), RoundingMode.UNNECESSARY);
int SIZE_BITS_Z = SIZE_BITS_X;
int SIZE_BITS_Y = 64 - SIZE_BITS_X - SIZE_BITS_Z;
long BITS_X = (1L << SIZE_BITS_X) - 1L;
long BITS_Y = (1L << SIZE_BITS_Y) - 1L;
long BITS_Z = (1L << SIZE_BITS_Z) - 1L;
int BIT_SHIFT_Z = SIZE_BITS_Y;
int BIT_SHIFT_X = SIZE_BITS_Y + SIZE_BITS_Z;
int getX();
int getY();
int getZ();
BlockPosImpl offset(ForgeDirection d);
BlockPosImpl down();
BlockPosImpl up();
long asLong();
static long asLong(int x, int y, int z) {
long l = 0L;
l |= ((long) x & BITS_X) << BIT_SHIFT_X;
l |= ((long) y & BITS_Y) << 0;
l |= ((long) z & BITS_Z) << BIT_SHIFT_Z;
return l;
}
public static int unpackLongX(long packedPos) {
return (int)(packedPos << 64 - BIT_SHIFT_X - SIZE_BITS_X >> 64 - SIZE_BITS_X);
}
public static int unpackLongY(long packedPos) {
return (int)(packedPos << 64 - SIZE_BITS_Y >> 64 - SIZE_BITS_Y);
}
public static int unpackLongZ(long packedPos) {
return (int)(packedPos << 64 - BIT_SHIFT_Z - SIZE_BITS_Z >> 64 - SIZE_BITS_Z);
}
}
@@ -0,0 +1,8 @@
package com.gtnewhorizons.angelica.api;
public interface MutableBlockPos extends BlockPos {
MutableBlockPos set(int x, int y, int z);
MutableBlockPos set(long packedPos);
}
@@ -0,0 +1,43 @@
package com.gtnewhorizons.angelica.api;
import net.minecraft.block.Block;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
public interface QuadProvider {
int R_MASK = 0xFF << 16;
int G_MASK = 0xFF << 8;
int B_MASK = 0xFF;
/**
* Returns the color packed as ABGR. If you want to vary colors within a block, just ignore the color passed into
* {@link #getQuads} and use whatever you want. You might want to override this to return a constant if you're
* extending a block with an expensive color call, like leaves.
*/
default int getColor(IBlockAccess world, BlockPos pos, Block block, int meta, Random random) {
final int cin = block.colorMultiplier(world, pos.getX(), pos.getY(), pos.getZ());
return (0xFF << 24) | ((cin & B_MASK) << 16) | (cin & G_MASK) | ((cin & R_MASK) >>> 16);
}
/**
* If you need to allocate new quads, set this to true. If true, the quads returned by {@link #getQuads} are
* recycled, and you should not keep a reference to them. Example: stone can return a static list every time, but a
* modded block which adds or removes quads based on location would need dynamic quads.
*/
default boolean isDynamic() {
return false;
}
/**
* Provide quads to render. If you need new quads, they should be obtained with the passed supplier and
* {@link #isDynamic} overridden to return true. If so, all quads in the list are recycled and references to them
* should not be kept.
*/
List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool);
}
@@ -0,0 +1,22 @@
package com.gtnewhorizons.angelica.api;
import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable;
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
import net.minecraftforge.common.util.ForgeDirection;
import javax.annotation.Nullable;
public interface QuadView extends ModelQuadViewMutable {
boolean isShade();
boolean isDeleted();
ForgeDirection getFace();
void copyFrom(QuadView src);
void setRaw(int[] data, boolean shade, @Nullable ForgeDirection face, int colorIndex, int flags);
int[] getRawVertexes();
/**
* Present for compatibility with the Tesselator, not recommended for general use.
*/
void setState(int[] rawBuffer, int offset, BlockRenderer.Flags flags, int drawMode, float offsetX, float offsetY, float offsetZ);
}
@@ -0,0 +1,35 @@
package com.gtnewhorizons.angelica.api;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Marks an ISBRH as thread-safe, allowing Angelica to run it off-thread.
*
* <p>Note: Any tessellator access <i>must</i> be done within the methods of the ISBRH and not cached in the class.</p>
*/
@Documented
@Target({ TYPE })
@Retention(RUNTIME)
public @interface ThreadSafeISBRH {
/**
* Specifies whether Angelica should create a thread local instance of the class for each thread.
* <ul>
* <li>If this is set to <tt>true</tt>, a new instance will be created using the default constructor on each thread.</li>
* <ul>
* <li>Note: If your renderer requires arguments to the constructor, do <i>not</i> use this annotation;
* instead use the {@link ThreadSafeISBRHFactory} interface and implement the {@link ThreadSafeISBRHFactory#newInstance} method. </li>
* </ul>
* <li>If this is set to <tt>false</tt>, the main thread instance will be used on all threads.
* Use this option if your renderer class has no state, and can be safely used from multiple threads as is.</li>
* <ul>
* <li>No state/non final variables should be stored in the ISBRH as it is not guaranteed to be thread safe.</li>
* </ul>
* </ul>
*/
boolean perThread();
}
@@ -0,0 +1,22 @@
package com.gtnewhorizons.angelica.api;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* Marks an ISBRH as thread-safe using a thread local instance, allowing Angelica to run it off-thread.
* Use this when your ISBRH uses a non-default constructor.
* <p>To avoid a hard dependency on Angelica, you will likely want to mark this as an optional interface using:</p>
* <pre>
* @Optional.Interface(modid = "angelica", iface = "com.gtnewhorizons.angelica.api.ThreadSafeISBRHFactory")
* </pre>
*
* <p><b>Notes</b></p>
* <ul>
* <li>Any tessellator access <i>must</i> be done within the methods of the ISBRH and not cached in the class.</li>
* <li>If your class uses a default constructor or is thread-safe by default, consider using the simpler {@link ThreadSafeISBRH}
* annotation instead.
* </ul>
*/
public interface ThreadSafeISBRHFactory extends ISimpleBlockRenderingHandler {
ThreadSafeISBRHFactory newInstance();
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.resources.IResourceManager;
public class DefaultTexture extends AbstractTexture {
public DefaultTexture() {
loadTexture(null);
}
public void loadTexture(IResourceManager resourcemanager) {
int[] aint = ShadersTex.createAIntImage(1, 0xFFFFFFFF);
ShadersTex.setupTexture(this.getMultiTexID(), aint, 1, 1, false, false);
}
}
@@ -1,354 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.settings.GameSettings;
import org.lwjgl.Sys;
public class GuiShaders extends GuiScreen {
/** This GUI's parent GUI. */
protected GuiScreen parentGui;
private int updateTimer = -1;
public boolean needReinit;
/*
private class GuiListShaderpacks {
int posX,posY,sizeX,sizeY;
int viewPosY;
int itemHeight = 20;
int selection;
ArrayList<String> listShaderpacks;
public void draw() {
Tessellator tess = Tessellator.instance;
int listSize = listShaderpacks.size();
int i,j;
for (i=viewPosY/itemHeight, j=Math.min((viewPosY+sizeY)/itemHeight,listSize); i<j; ++i)
{
int itemY = posY-viewPosY+itemHeight*i;
boolean selected = i==selection;
tess.startDrawingQuads();
tess.setColorRGBA(0,0,selected?128:0,128);
tess.addVertex(posX,itemY,0);
tess.addVertex(posX,itemY+itemHeight,0);
tess.addVertex(posX+sizeX,itemY+itemHeight,0);
tess.addVertex(posX+sizeX,itemY,0);
tess.draw();
field_146289_q.drawString(listShaderpacks.get(i), posX, itemY, 0xFFFFFFFF, true);
}
}
}
private GuiListShaderpacks guiListShaderpacks;
*/
private GuiSlotShaders shaderList;
/** This GUI's 'Done' button. */
// private GuiSmallButton doneButton;
public GuiShaders(GuiScreen par1GuiScreen, GameSettings par2GameSettings) {
this.parentGui = par1GuiScreen;
}
private static String toStringOnOff(boolean value) {
return value ? "On" : "Off";
}
@Override
/**
* Adds the buttons (and other controls) to the screen in question.
*/
public void initGui() {
if (Shaders.shadersConfig == null) Shaders.loadConfig();
List buttonList = this.buttonList;
int width = this.width;
int height = this.height;
buttonList.add(new GuiButton(
17, width * 3 / 4 - 60, 30, 160, 18, "NormapMap: " + toStringOnOff(Shaders.configNormalMap)));
buttonList.add(new GuiButton(
18, width * 3 / 4 - 60, 50, 160, 18, "SpecularMap: " + toStringOnOff(Shaders.configSpecularMap)));
buttonList.add(new GuiButton(
15,
width * 3 / 4 - 60,
70,
160,
18,
"RenderResMul: " + String.format("%.04f", Shaders.configRenderResMul)));
buttonList.add(new GuiButton(
16,
width * 3 / 4 - 60,
90,
160,
18,
"ShadowResMul: " + String.format("%.04f", Shaders.configShadowResMul)));
buttonList.add(new GuiButton(
10,
width * 3 / 4 - 60,
110,
160,
18,
"HandDepth: " + String.format("%.04f", Shaders.configHandDepthMul)));
buttonList.add(new GuiButton(
9, width * 3 / 4 - 60, 130, 160, 18, "CloudShadow: " + toStringOnOff(Shaders.configCloudShadow)));
// buttonList.add(new GuiButton(14, width *3 /4 -60, 150, 160, 18, "ShadowClipFrustrum: "
// +toStringOnOff(Shaders.configShadowClipFrustrum)));
buttonList.add(new GuiButton(
4,
width * 3 / 4 - 60,
170,
160,
18,
"tweakBlockDamage: " + toStringOnOff(Shaders.configTweakBlockDamage)));
buttonList.add(new GuiButton(
19, width * 3 / 4 - 60, 190, 160, 18, "OldLighting: " + toStringOnOff(Shaders.configOldLighting)));
// buttonList.add(new GuiButton(11, width *3 /4 -60, 210, 160, 18, "Tex Min: "
// +Shaders.texMinFilDesc[Shaders.configTexMinFilB]));
// buttonList.add(new GuiButton(12, width *3 /4 -60, 230, 160, 18, "Tex_n Mag: "
// +Shaders.texMagFilDesc[Shaders.configTexMagFilN]));
// buttonList.add(new GuiButton(13, width *3 /4 -60, 250, 160, 18, "Tex_s Mag: "
// +Shaders.texMagFilDesc[Shaders.configTexMagFilS]));
buttonList.add(new GuiButton(6, width * 3 / 4 - 60, height - 25, 160, 20, "Done"));
buttonList.add(new GuiButton(5, width / 4 - 80, height - 25, 160, 20, "Open shaderpacks folder"));
this.shaderList = new GuiSlotShaders(this);
this.shaderList.registerScrollButtons(7, 8); // registerScrollButtons(7, 8);
this.needReinit = false;
}
@Override
/** actionPerformed
* Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
*/
protected void actionPerformed(GuiButton par1GuiButton) {
if (par1GuiButton.enabled) // enabled
{
switch (par1GuiButton.id) // id
{
case 4: /* New block breaking */
Shaders.configTweakBlockDamage = !Shaders.configTweakBlockDamage;
// displayString
par1GuiButton.displayString = "tweakBlockDamage: " + toStringOnOff(Shaders.configTweakBlockDamage);
break;
case 9: /* Cloud shadow */
Shaders.configCloudShadow = !Shaders.configCloudShadow;
par1GuiButton.displayString = "CloudShadow: " + toStringOnOff(Shaders.configCloudShadow);
break;
case 10: /* Hand Depth */ {
float val = Shaders.configHandDepthMul;
float[] choices = {0.0625f, 0.125f, 0.25f, 0.5f, 1.0f};
int i;
if (!isShiftKeyDown()) { // isShiftKeyDown
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configHandDepthMul = choices[i];
par1GuiButton.displayString = "HandDepth: " + String.format("%.4f", Shaders.configHandDepthMul);
break;
}
case 15: /* Render Resolution Multiplier */ {
float val = Shaders.configRenderResMul;
float[] choices = {0.25f, 0.3333333333f, 0.5f, 0.7071067812f, 1.0f, 1.414213562f, 2.0f};
int i;
if (!isShiftKeyDown()) {
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configRenderResMul = choices[i];
par1GuiButton.displayString = "RenderResMul: " + String.format("%.4f", Shaders.configRenderResMul);
Shaders.scheduleResize();
break;
}
case 16: /* Shadow Resolution Multiplier */ {
float val = Shaders.configShadowResMul;
float[] choices = {0.25f, 0.3333333333f, 0.5f, 0.7071067812f, 1.0f, 1.414213562f, 2.0f, 3.0f, 4.0f};
int i;
if (!isShiftKeyDown()) {
for (i = 0; i < choices.length && choices[i] <= val; ++i) {}
if (i == choices.length) i = 0;
} else {
for (i = choices.length - 1; i >= 0 && val <= choices[i]; --i) {}
if (i < 0) i = choices.length - 1;
}
Shaders.configShadowResMul = choices[i];
par1GuiButton.displayString = "ShadowResMul: " + String.format("%.4f", Shaders.configShadowResMul);
Shaders.scheduleResizeShadow();
break;
}
case 17: /* Normal Map */ {
Shaders.configNormalMap = !Shaders.configNormalMap;
// displayString
par1GuiButton.displayString = "NormapMap: " + toStringOnOff(Shaders.configNormalMap);
mc.scheduleResourcesRefresh(); // schedule refresh texture
break;
}
case 18: /* Normal Map */ {
Shaders.configSpecularMap = !Shaders.configSpecularMap;
// displayString
par1GuiButton.displayString = "SpecularMap: " + toStringOnOff(Shaders.configSpecularMap);
mc.scheduleResourcesRefresh(); // schedule refresh texture
break;
}
case 19: /* old Lighting */ {
Shaders.configOldLighting = !Shaders.configOldLighting;
// displayString
par1GuiButton.displayString = "OldLighting: " + toStringOnOff(Shaders.configOldLighting);
Shaders.updateBlockLightLevel();
mc.renderGlobal.loadRenderers();
break;
}
case 11: /* texture filter */ {
Shaders.configTexMinFilB = (Shaders.configTexMinFilB + 1) % Shaders.texMinFilRange;
Shaders.configTexMinFilN = Shaders.configTexMinFilS = Shaders.configTexMinFilB;
par1GuiButton.displayString = "Tex Min: " + Shaders.texMinFilDesc[Shaders.configTexMinFilB];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 12: /* texture filter */ {
Shaders.configTexMagFilN = (Shaders.configTexMagFilN + 1) % Shaders.texMagFilRange;
par1GuiButton.displayString = "Tex_n Mag: " + Shaders.texMagFilDesc[Shaders.configTexMagFilN];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 13: /* texture filter */ {
Shaders.configTexMagFilS = (Shaders.configTexMagFilS + 1) % Shaders.texMagFilRange;
par1GuiButton.displayString = "Tex_s Mag: " + Shaders.texMagFilDesc[Shaders.configTexMagFilS];
ShadersTex.updateTextureMinMagFilter();
break;
}
case 14: /* shadow frustum clipping */ {
Shaders.configShadowClipFrustrum = !Shaders.configShadowClipFrustrum;
par1GuiButton.displayString =
"ShadowClipFrustrum: " + toStringOnOff(Shaders.configShadowClipFrustrum);
ShadersTex.updateTextureMinMagFilter();
break;
}
case 5: /* Open shaderpacks folder */
switch (net.minecraft.util.Util.getOSType()) {
case OSX:
{
try {
Runtime.getRuntime().exec(new String[] {
"/usr/bin/open", Shaders.shaderpacksdir.getAbsolutePath()
});
return;
} catch (IOException var7) {
var7.printStackTrace();
}
}
break;
case WINDOWS:
{
String var2 = String.format(
"cmd.exe /C start \"Open file\" \"%s\"",
new Object[] {Shaders.shaderpacksdir.getAbsolutePath()});
try {
Runtime.getRuntime().exec(var2);
return;
} catch (IOException var6) {
var6.printStackTrace();
}
}
break;
default:
break;
}
boolean var8 = false;
try {
Class var3 = Class.forName("java.awt.Desktop");
Object var4 = var3.getMethod("getDesktop", new Class[0]).invoke((Object) null, new Object[0]);
var3.getMethod("browse", new Class[] {URI.class})
.invoke(var4, new Object[] {(new File(mc.mcDataDir, Shaders.shaderpacksdirname)).toURI()
});
} catch (Throwable var5) {
var5.printStackTrace();
var8 = true;
}
if (var8) {
System.out.println("Opening via system class!");
Sys.openURL("file://" + Shaders.shaderpacksdir.getAbsolutePath());
}
break;
case 6: /* Done */
File confshader = new File(Shaders.shadersdir, "current.cfg");
try {
Shaders.storeConfig();
} catch (Exception ex) {
}
if (needReinit) {
needReinit = false;
Shaders.loadShaderPack();
Shaders.uninit();
this.mc.renderGlobal.loadRenderers();
}
this.mc.displayGuiScreen(this.parentGui); // displayGuiScreen
break;
default:
this.shaderList.actionPerformed(par1GuiButton); // actionPerformed
}
}
}
@Override
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3) {
drawDefaultBackground(); // background
this.shaderList.drawScreen(par1, par2, par3); // drawScreen
if (this.updateTimer <= 0) {
this.shaderList.updateList();
this.updateTimer += 20;
}
this.drawCenteredString(this.fontRendererObj, "Shaders ", this.width / 2, 16, 0xffffff);
this.drawCenteredString(this.fontRendererObj, " v" + Shaders.versionString, this.width - 40, 10, 0x808080);
// this.drawCenteredString(this.fontRenderer, "( Place zipped Shader files here. )", this.width / 4 + 10,
// this.height - 26, 0x808080);
super.drawScreen(par1, par2, par3);
}
@Override
/**
* Called from the main game loop to update the screen.
*/
public void updateScreen() {
super.updateScreen();
--this.updateTimer;
}
public Minecraft getMc() {
return this.mc;
}
public void drawCenteredString(String par1, int par2, int par3, int par4) {
this.drawCenteredString(this.fontRendererObj, par1, par2, par3, par4);
}
}
@@ -1,75 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.util.ArrayList;
import net.minecraft.client.gui.GuiSlot;
import net.minecraft.client.renderer.Tessellator;
class GuiSlotShaders extends GuiSlot {
private ArrayList shaderslist;
final GuiShaders shadersGui;
public GuiSlotShaders(GuiShaders par1GuiShaders) {
// super(par1GuiShaders.getMc(), par1GuiShaders.width / 2 + 20, par1GuiShaders.height, 40, par1GuiShaders.height
// - 70, 16);
super(
par1GuiShaders.getMc(),
par1GuiShaders.width / 2 + 20,
par1GuiShaders.height,
40,
par1GuiShaders.height - 70,
16);
this.shadersGui = par1GuiShaders;
this.shaderslist = Shaders.listofShaders();
}
public void updateList() {
this.shaderslist = Shaders.listofShaders();
}
@Override
/** getSize */
protected int getSize() {
return this.shaderslist.size();
}
@Override
/** elementClicked */
protected void elementClicked(int par1, boolean par2, int par3, int par4) {
Shaders.setShaderPack((String) shaderslist.get(par1));
shadersGui.needReinit = false;
Shaders.loadShaderPack();
Shaders.uninit();
}
@Override
/** isSelected */
protected boolean isSelected(int par1) {
return ((String) this.shaderslist.get(par1)).equals(Shaders.currentshadername);
}
@Override
/** getScrollBarX */
protected int getScrollBarX() {
return this.width - 6;
}
@Override
/** getContentHeight */
protected int getContentHeight() {
return this.getSize() * 18;
}
@Override
/** drawBackground */
protected void drawBackground() {
// this.shadersGui.drawDefaultBackground();
}
@Override
/** drawSlot */
protected void drawSlot(int par1, int par2, int par3, int par4, Tessellator par5, int par6, int par7) {
this.shadersGui.drawCenteredString(
(String) this.shaderslist.get(par1), this.shadersGui.width / 4 + 10, par3 + 1, 0xffffff);
}
}
@@ -1,76 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.nio.ByteBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
/**
*
* @author Nathanael Lane
*/
public class HFNoiseTexture {
public int texID;
public int textureUnit;
public HFNoiseTexture(int width, int height) {
texID = GL11.glGenTextures();
textureUnit = 15;
byte[] image = genHFNoiseImage(width, height);
ByteBuffer data = BufferUtils.createByteBuffer(image.length);
data.put(image);
data.flip();
// GL13.glActiveTexture(GL13.GL_TEXTURE0 + this.textureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, data);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
// GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
public int getID() {
return texID;
}
public void destroy() {
GL11.glDeleteTextures(texID);
texID = 0;
}
// from George Marsaglia's paper on XORshift PRNGs
private int random(int seed) {
seed ^= (seed << 13);
seed ^= (seed >> 17);
seed ^= (seed << 5);
return seed;
}
private byte random(int x, int y, int z) {
int seed = (random(x) + random(y * 19)) * random(z * 23) - z;
return (byte) (random(seed) % 128);
}
/*
* Just a random value for each pixel to get maximum frequency
*/
private byte[] genHFNoiseImage(int width, int height) {
byte[] image = new byte[width * height * 3];
int index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int z = 1; z < 4; z++) {
image[index++] = random(x, y, z);
}
}
}
return image;
}
}
@@ -1,10 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public interface IShaderPack {
void close();
InputStream getResourceAsStream(String resName);
}
@@ -1,13 +0,0 @@
package com.gtnewhorizons.angelica.client;
public class MultiTexID {
public int base;
public int norm;
public int spec;
public MultiTexID(int baseTex, int normTex, int specTex) {
base = baseTex;
norm = normTex;
spec = specTex;
}
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public class ShaderPackDefault implements IShaderPack {
public ShaderPackDefault() {}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
return ShaderPackDefault.class.getResourceAsStream(resName);
}
}
@@ -1,30 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class ShaderPackFolder implements IShaderPack {
protected File packFile;
public ShaderPackFolder(String name, File file) {
packFile = file;
}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
try {
File resFile = new File(packFile, resName.substring(1));
if (resFile != null) {
return new BufferedInputStream(new FileInputStream(resFile));
}
} catch (Exception excp) {
}
return null;
}
}
@@ -1,16 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.InputStream;
public class ShaderPackNone implements IShaderPack {
public ShaderPackNone() {}
@Override
public void close() {}
@Override
public InputStream getResourceAsStream(String resName) {
return null;
}
}
@@ -1,48 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.io.File;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ShaderPackZip implements IShaderPack {
protected File packFile;
protected ZipFile packZipFile;
public ShaderPackZip(String name, File file) {
packFile = file;
packZipFile = null;
}
@Override
public void close() {
if (packZipFile != null) {
try {
packZipFile.close();
} catch (Exception excp) {
}
packZipFile = null;
}
}
@Override
public InputStream getResourceAsStream(String resName) {
if (packZipFile == null) {
try {
packZipFile = new ZipFile(packFile);
} catch (Exception excp) {
}
}
if (packZipFile != null) {
try {
ZipEntry entry = packZipFile.getEntry(resName.substring(1));
if (entry != null) {
return packZipFile.getInputStream(entry);
}
} catch (Exception excp) {
}
}
return null;
}
}
File diff suppressed because it is too large. Load diff
@@ -1,87 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.nio.IntBuffer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockIce;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.culling.Frustrum;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import org.lwjgl.opengl.GL11;
public class ShadersRender {
public static void setFrustrumPosition(Frustrum frustrum, double x, double y, double z) {
frustrum.setPosition(x, y, z);
}
public static void clipRenderersByFrustrum(RenderGlobal renderGlobal, Frustrum frustrum, float par2) {
Shaders.checkGLError("pre clip");
if (!Shaders.isShadowPass) {
WorldRenderer[] worldRenderers = renderGlobal.worldRenderers;
for (int i = 0; i < worldRenderers.length; ++i) {
if (!worldRenderers[i].skipAllRenderPasses()) {
worldRenderers[i].updateInFrustum(frustrum);
}
}
} else {
WorldRenderer[] worldRenderers = renderGlobal.worldRenderers;
for (int i = 0; i < worldRenderers.length; ++i) {
if (!worldRenderers[i].skipAllRenderPasses()) {
worldRenderers[i].isInFrustum = true;
}
}
}
}
public static void renderHand0(EntityRenderer er, float par1, int par2) {
if (!Shaders.isShadowPass) {
Item item = (Shaders.itemToRender != null) ? Shaders.itemToRender.getItem() : null;
Block block = (item instanceof ItemBlock) ? ((ItemBlock) item).field_150939_a : null;
// ItemCloth is for semitransparent block : stained glass, wool
if (!(item instanceof ItemBlock) && !(block instanceof BlockIce)) {
Shaders.readCenterDepth();
Shaders.beginHand();
er.renderHand(par1, par2);
Shaders.endHand();
Shaders.isHandRendered = true;
}
}
}
public static void renderHand1(EntityRenderer er, float par1, int par2) {
if (!Shaders.isShadowPass) {
if (!Shaders.isHandRendered) {
Shaders.readCenterDepth();
GL11.glEnable(GL11.GL_BLEND);
Shaders.beginHand();
er.renderHand(par1, par2);
Shaders.endHand();
Shaders.isHandRendered = true;
}
}
}
public static void renderItemFP(ItemRenderer itemRenderer, float par1) {
// clear depth buffer locally
GL11.glDepthFunc(GL11.GL_GEQUAL);
GL11.glPushMatrix();
IntBuffer drawBuffers = Shaders.activeDrawBuffers;
Shaders.setDrawBuffers(Shaders.drawBuffersNone);
itemRenderer.renderItemInFirstPerson(par1);
Shaders.setDrawBuffers(drawBuffers);
GL11.glPopMatrix();
GL11.glDepthFunc(GL11.GL_LEQUAL);
// really render item or hand
itemRenderer.renderItemInFirstPerson(par1);
}
public static void renderFPOverlay(EntityRenderer er, float par1, int par2) {
Shaders.beginFPOverlay();
er.renderHand(par1, par2);
Shaders.endFPOverlay();
}
}
@@ -1,243 +0,0 @@
package com.gtnewhorizons.angelica.client;
import static org.lwjgl.opengl.ARBVertexShader.glDisableVertexAttribArrayARB;
import static org.lwjgl.opengl.ARBVertexShader.glEnableVertexAttribArrayARB;
import static org.lwjgl.opengl.ARBVertexShader.glVertexAttribPointerARB;
import com.gtnewhorizons.angelica.transform.ALog;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.Arrays;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
public class ShadersTess {
public static final int vertexStride = 16;
public static int draw(Tessellator tess) {
if (!tess.isDrawing) {
throw new IllegalStateException("Not tesselating!");
} else {
tess.isDrawing = false;
if (tess.drawMode == GL11.GL_QUADS && tess.vertexCount % 4 != 0) {
ALog.warning("%s", "bad vertexCount");
}
int voffset = 0;
int realDrawMode = tess.drawMode;
while (voffset < tess.vertexCount) {
int vcount;
vcount = Math.min(tess.vertexCount - voffset, tess.byteBuffer.capacity() / (vertexStride * 4));
if (realDrawMode == GL11.GL_QUADS) vcount = vcount / 4 * 4;
tess.floatBuffer.clear();
tess.shortBuffer.clear();
tess.intBuffer.clear();
tess.intBuffer.put(tess.rawBuffer, voffset * vertexStride, vcount * vertexStride);
tess.byteBuffer.position(0);
tess.byteBuffer.limit(vcount * (vertexStride * 4));
voffset += vcount;
if (tess.hasTexture) {
tess.floatBuffer.position(3);
GL11.glTexCoordPointer(2, (vertexStride * 4), tess.floatBuffer);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if (tess.hasBrightness) {
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
tess.shortBuffer.position(6 * 2);
GL11.glTexCoordPointer(2, (vertexStride * 4), tess.shortBuffer);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
}
if (tess.hasColor) {
tess.byteBuffer.position(5 * 4);
GL11.glColorPointer(4, true, (vertexStride * 4), tess.byteBuffer);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
}
if (tess.hasNormals) {
tess.floatBuffer.position(9);
GL11.glNormalPointer((vertexStride * 4), tess.floatBuffer);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
}
tess.floatBuffer.position(0);
GL11.glVertexPointer(3, (vertexStride * 4), tess.floatBuffer);
ShadersTess.preDrawArray(tess);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDrawArrays(realDrawMode, 0, vcount);
}
// end loop
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
ShadersTess.postDrawArray(tess);
if (tess.hasTexture) {
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if (tess.hasBrightness) {
OpenGlHelper.setClientActiveTexture(OpenGlHelper.lightmapTexUnit);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
OpenGlHelper.setClientActiveTexture(OpenGlHelper.defaultTexUnit);
}
if (tess.hasColor) {
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
}
if (tess.hasNormals) {
GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
}
int n = tess.rawBufferIndex * 4;
tess.reset();
return n;
}
}
public static void preDrawArray(Tessellator tess) {
// Shaders.checkGLError("preDrawArray");
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glTexCoordPointer(2, (vertexStride * 4), (FloatBuffer) tess.floatBuffer.position(12));
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glVertexAttribPointerARB(
Shaders.midTexCoordAttrib, 2, false, vertexStride * 4, (FloatBuffer) tess.floatBuffer.position(12));
glEnableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useEntityAttrib) {
glVertexAttribPointerARB(Shaders.entityAttrib, 3, false, false, vertexStride * 4, (ShortBuffer)
tess.shortBuffer.position(7 * 2));
glEnableVertexAttribArrayARB(Shaders.entityAttrib);
}
// Shaders.checkGLError("preDrawArray");
}
public static void preDrawArrayVBO(Tessellator tess) {
// Shaders.checkGLError("preDrawArray");
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, (vertexStride * 4), 12 * 4L);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glVertexAttribPointerARB(Shaders.midTexCoordAttrib, 2, GL11.GL_FLOAT, false, vertexStride * 4, 12 * 4L);
glEnableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useEntityAttrib) {
glVertexAttribPointerARB(Shaders.entityAttrib, 3, GL11.GL_SHORT, false, vertexStride * 4, 7 * 4L);
glEnableVertexAttribArrayARB(Shaders.entityAttrib);
}
// Shaders.checkGLError("preDrawArray");
}
public static void postDrawArray(Tessellator tess) {
// Shaders.checkGLError("postDrawArray");
if (Shaders.useEntityAttrib) {
glDisableVertexAttribArrayARB(Shaders.entityAttrib);
}
if (Shaders.useMidTexCoordAttrib && tess.hasTexture) {
glDisableVertexAttribArrayARB(Shaders.midTexCoordAttrib);
}
if (Shaders.useMultiTexCoord3Attrib && tess.hasTexture) {
GL13.glClientActiveTexture(GL13.GL_TEXTURE3);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}
// Shaders.checkGLError("postDrawArray");
}
public static void addVertex(Tessellator tess, double parx, double pary, double parz) {
int[] rawBuffer = tess.rawBuffer;
int rbi = tess.rawBufferIndex;
float fx = (float) (parx + tess.xOffset);
float fy = (float) (pary + tess.yOffset);
float fz = (float) (parz + tess.zOffset);
// Check if buffer is nearly full
if (rbi >= tess.bufferSize - vertexStride * 4) {
if (tess.bufferSize >= 0x1000000) {
// Max size reached. Just draw.
if (tess.addedVertices % 4 == 0) {
tess.draw();
tess.isDrawing = true;
}
} else if (tess.bufferSize > 0) {
// Expand
tess.bufferSize *= 2;
tess.rawBuffer = rawBuffer = Arrays.copyOf(tess.rawBuffer, tess.bufferSize);
System.out.format("Expand tesselator buffer %d\n", tess.bufferSize);
} else {
// Initialize
tess.bufferSize = 0x10000;
tess.rawBuffer = rawBuffer = new int[tess.bufferSize];
}
}
// shaders mod calculate normal and mid UV
if (tess.drawMode == 7) {
int i = tess.addedVertices % 4;
float[] vertexPos = tess.vertexPos;
vertexPos[i * 4 + 0] = fx;
vertexPos[i * 4 + 1] = fy;
vertexPos[i * 4 + 2] = fz;
if (i == 3) {
// calculate normal
float x1 = vertexPos[8 + 0] - vertexPos[+0];
float y1 = vertexPos[8 + 1] - vertexPos[+1];
float z1 = vertexPos[8 + 2] - vertexPos[+2];
float x2 = vertexPos[12 + 0] - vertexPos[4 + 0];
float y2 = vertexPos[12 + 1] - vertexPos[4 + 1];
float z2 = vertexPos[12 + 2] - vertexPos[4 + 2];
float vnx = y1 * z2 - y2 * z1;
float vny = z1 * x2 - z2 * x1;
float vnz = x1 * y2 - x2 * y1;
float lensq = vnx * vnx + vny * vny + vnz * vnz;
float mult = (lensq != 0.0) ? (float) (1f / Math.sqrt(lensq)) : 1f;
rawBuffer[rbi + (9 - vertexStride * 3)] = rawBuffer[rbi + (9 - vertexStride * 2)] =
rawBuffer[rbi + (9 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalX = vnx * mult);
rawBuffer[rbi + (10 - vertexStride * 3)] = rawBuffer[rbi + (10 - vertexStride * 2)] =
rawBuffer[rbi + (10 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalY = vny * mult);
rawBuffer[rbi + (11 - vertexStride * 3)] = rawBuffer[rbi + (11 - vertexStride * 2)] =
rawBuffer[rbi + (11 - vertexStride * 1)] = Float.floatToRawIntBits(tess.normalZ = vnz * mult);
tess.hasNormals = true;
// mid UV
tess.midTextureU = (Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 3)])
+ Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 2)])
+ Float.intBitsToFloat(rawBuffer[rbi + (3 - vertexStride * 1)])
+ (float) tess.textureU)
/ 4;
tess.midTextureV = (Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 3)])
+ Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 2)])
+ Float.intBitsToFloat(rawBuffer[rbi + (4 - vertexStride * 1)])
+ (float) tess.textureV)
/ 4;
rawBuffer[rbi + (12 - vertexStride * 3)] = rawBuffer[rbi + (12 - vertexStride * 2)] =
rawBuffer[rbi + (12 - vertexStride * 1)] = Float.floatToRawIntBits(tess.midTextureU);
rawBuffer[rbi + (13 - vertexStride * 3)] = rawBuffer[rbi + (13 - vertexStride * 2)] =
rawBuffer[rbi + (13 - vertexStride * 1)] = Float.floatToRawIntBits(tess.midTextureV);
}
}
// end normal and mid UV calculation
++tess.addedVertices;
rawBuffer[rbi + 0] = Float.floatToRawIntBits((float) fx);
rawBuffer[rbi + 1] = Float.floatToRawIntBits((float) fy);
rawBuffer[rbi + 2] = Float.floatToRawIntBits((float) fz);
rawBuffer[rbi + 3] = Float.floatToRawIntBits((float) tess.textureU);
rawBuffer[rbi + 4] = Float.floatToRawIntBits((float) tess.textureV);
rawBuffer[rbi + 5] = tess.color;
rawBuffer[rbi + 6] = tess.brightness;
rawBuffer[rbi + 7] = Shaders.getEntityData();
rawBuffer[rbi + 8] = Shaders.getEntityData2();
rawBuffer[rbi + 9] = Float.floatToRawIntBits((float) tess.normalX);
rawBuffer[rbi + 10] = Float.floatToRawIntBits((float) tess.normalY);
rawBuffer[rbi + 11] = Float.floatToRawIntBits((float) tess.normalZ);
rawBuffer[rbi + 12] = Float.floatToRawIntBits((float) tess.midTextureU);
rawBuffer[rbi + 13] = Float.floatToRawIntBits((float) tess.midTextureV);
tess.rawBufferIndex = rbi += vertexStride;
++tess.vertexCount;
}
}
@@ -1,988 +0,0 @@
package com.gtnewhorizons.angelica.client;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.ITextureObject;
import net.minecraft.client.renderer.texture.LayeredTexture;
import net.minecraft.client.renderer.texture.Stitcher;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL30.*;
public class ShadersTex {
public static final int initialBufferSize = 1048576;
public static ByteBuffer byteBuffer = BufferUtils.createByteBuffer(initialBufferSize * 4);
public static IntBuffer intBuffer = byteBuffer.asIntBuffer();
public static int[] intArray = new int[initialBufferSize];
public static final int defBaseTexColor = 0x00000000;
public static final int defNormTexColor = 0xFF7F7FFF;
public static final int defSpecTexColor = 0x00000000;
public static Map<Integer, MultiTexID> multiTexMap = new HashMap();
public static TextureMap updatingTextureMap = null;
public static TextureAtlasSprite updatingSprite = null;
public static MultiTexID updatingTex = null;
public static MultiTexID boundTex = null;
public static int updatingPage = 0;
public static String iconName = null;
public static IntBuffer getIntBuffer(int size) {
if (intBuffer.capacity() < size) {
int bufferSize = roundUpPOT(size);
byteBuffer = BufferUtils.createByteBuffer(bufferSize * 4);
intBuffer = byteBuffer.asIntBuffer();
}
return intBuffer;
}
public static int[] getIntArray(int size) {
if (intArray.length < size) {
intArray = null;
intArray = new int[roundUpPOT(size)];
}
return intArray;
}
public static int roundUpPOT(int x) {
int i = x - 1;
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i + 1;
}
public static IntBuffer fillIntBuffer(int size, int value) {
int[] aint = getIntArray(size);
IntBuffer intBuf = getIntBuffer(size);
Arrays.fill(intArray, 0, size, value);
intBuffer.put(intArray, 0, size);
return intBuffer;
}
public static int[] createAIntImage(int size) {
int[] aint = new int[size * 3];
Arrays.fill(aint, 0, size, defBaseTexColor);
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
return aint;
}
public static int[] createAIntImage(int size, int color) {
int[] aint = new int[size * 3];
Arrays.fill(aint, 0, size, color);
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
return aint;
}
public static MultiTexID getMultiTexID(AbstractTexture tex) {
MultiTexID multiTex = tex.multiTex;
if (multiTex == null) {
int baseTex = tex.getGlTextureId();
multiTex = multiTexMap.get(Integer.valueOf(baseTex));
if (multiTex == null) {
multiTex = new MultiTexID(baseTex, GL11.glGenTextures(), GL11.glGenTextures());
multiTexMap.put(baseTex, multiTex);
}
tex.multiTex = multiTex;
}
return multiTex;
}
public static void deleteTextures(AbstractTexture atex) {
int texid = atex.glTextureId;
if (texid != -1) {
GL11.glDeleteTextures(texid);
atex.glTextureId = -1;
}
MultiTexID multiTex = atex.multiTex;
if (multiTex != null) {
atex.multiTex = null;
multiTexMap.remove(Integer.valueOf(multiTex.base));
GL11.glDeleteTextures(multiTex.norm);
GL11.glDeleteTextures(multiTex.spec);
if (multiTex.base != texid) {
System.err.println("Error : MultiTexID.base mismatch.");
GL11.glDeleteTextures(multiTex.base);
}
}
}
/** Remove MultiTexID object reference and delete textures */
public static int deleteMultiTex(ITextureObject tex) {
if (tex instanceof AbstractTexture) {
deleteTextures((AbstractTexture) tex);
} else {
GL11.glDeleteTextures(tex.getGlTextureId());
}
return 0;
}
public static void bindNSTextures(int normTex, int specTex) {
// Shaders.checkGLError("pre bindNSTextures");
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
// Shaders.checkGLError("bindNSTextures");
}
public static void bindNSTextures(MultiTexID multiTex) {
bindNSTextures(multiTex.norm, multiTex.spec);
}
public static void bindTextures(int baseTex, int normTex, int specTex) {
// Shaders.checkGLError("pre bindTextures");
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, normTex);
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, specTex);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, baseTex);
// Shaders.checkGLError("bindTextures");
}
public static void bindTextures(MultiTexID multiTex) {
boundTex = multiTex;
if (Shaders.isRenderingWorld && Shaders.activeTexUnit == GL13.GL_TEXTURE0) {
if (Shaders.configNormalMap) {
GL13.glActiveTexture(GL13.GL_TEXTURE2);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
}
if (Shaders.configSpecularMap) {
GL13.glActiveTexture(GL13.GL_TEXTURE3);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
}
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
public static void bindTexture(ITextureObject tex) {
if (tex instanceof TextureMap) {
Shaders.atlasSizeX = ((TextureMap) tex).atlasWidth;
Shaders.atlasSizeY = ((TextureMap) tex).atlasHeight;
} else {
Shaders.atlasSizeX = 0;
Shaders.atlasSizeY = 0;
}
bindTextures(tex.getMultiTexID());
}
/** not used */
public static void bindTextures(int baseTex) {
MultiTexID multiTex = multiTexMap.get(Integer.valueOf(baseTex));
bindTextures(multiTex);
}
public static void allocTexStorage(int width, int height, int maxLevel) {
Shaders.checkGLError("pre allocTexStorage");
int level;
for (level = 0; (width >> level) > 0 && (height >> level) > 0 /*&& level<=maxLevel*/; ++level) {
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
level,
GL11.GL_RGBA,
(width >> level),
(height >> level),
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
(IntBuffer) null);
}
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, level - 1);
Shaders.checkGLError("allocTexStorage");
// clear unused level otherwise glTexSubImage2D will crash on AMD when reallocation texture of different size.
// for ( ; level < 16 ; ++level) {
// GL11.glTexImage2D(GL11.GL_TEXTURE_2D, level, GL11.GL_RGBA, 0, 0, 0, GL12.GL_BGRA,
// GL12.GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null);
// }
GL11.glGetError(); // It usually returns error 0x0501 Invalid value for width 0 height 0. Ignore it.
}
// for Dynamic Texture
public static void initDynamicTexture(int texID, int width, int height, DynamicTexture tex) {
MultiTexID multiTex = tex.getMultiTexID();
int[] aint = tex.getTextureData();
int size = width * height;
Arrays.fill(aint, size, size * 2, defNormTexColor);
Arrays.fill(aint, size * 2, size * 3, defSpecTexColor);
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// norm texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// spec texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
allocTexStorage(width, height, 0);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
public static ITextureObject createDefaultTexture() {
DynamicTexture tex = new DynamicTexture(1, 1);
tex.getTextureData()[0] = 0xffffffff;
tex.updateDynamicTexture();
return tex;
}
// for TextureMap
public static void allocateTextureMap(
int texID, int mipmapLevels, int width, int height, float anisotropy, Stitcher stitcher, TextureMap tex) {
System.out.println("allocateTextureMap " + tex.getTextureType() + " " + mipmapLevels + " " + width + " "
+ height + " " + anisotropy + " ");
updatingTextureMap = tex;
tex.atlasWidth = width;
tex.atlasHeight = height;
MultiTexID multiTex = getMultiTexID(tex);
updatingTex = multiTex;
TextureUtil.allocateTextureImpl(multiTex.base, mipmapLevels, width, height, anisotropy);
if (Shaders.configNormalMap)
TextureUtil.allocateTextureImpl(multiTex.norm, mipmapLevels, width, height, anisotropy);
if (Shaders.configSpecularMap)
TextureUtil.allocateTextureImpl(multiTex.spec, mipmapLevels, width, height, anisotropy);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
}
public static TextureAtlasSprite setSprite(TextureAtlasSprite tas) {
return updatingSprite = tas;
}
public static String setIconName(String name) {
return iconName = name;
}
public static void uploadTexSubForLoadAtlas(
int[][] data, int width, int height, int xoffset, int yoffset, boolean linear, boolean clamp) {
TextureUtil.uploadTextureMipmap(data, width, height, xoffset, yoffset, linear, clamp);
boolean border = updatingSprite.useAnisotropicFiltering;
int[][] aaint;
//
if (Shaders.configNormalMap) {
aaint = readImageAndMipmaps(iconName + "_n", width, height, data.length, border, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.norm);
TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp);
}
//
if (Shaders.configSpecularMap) {
aaint = readImageAndMipmaps(iconName + "_s", width, height, data.length, border, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
TextureUtil.uploadTextureMipmap(aaint, width, height, xoffset, yoffset, linear, clamp);
}
//
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.base);
}
public static int[][] readImageAndMipmaps(
String name, int width, int height, int numLevels, boolean border, int defColor) {
int[][] aaint = new int[numLevels][];
int[] aint;
aaint[0] = aint = new int[width * height];
boolean goodImage = false;
BufferedImage image = readImage(updatingTextureMap.completeResourceLocation(new ResourceLocation(name), 0));
if (image != null) {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
if (imageWidth + (border ? 16 : 0) == width) {
goodImage = true;
image.getRGB(0, 0, imageWidth, imageWidth, aint, 0, imageWidth);
if (border) TextureUtil.prepareAnisotropicData(aint, imageWidth, imageWidth, 8);
}
}
if (!goodImage) {
Arrays.fill(aint, defColor);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
aaint = genMipmapsSimple(aaint.length - 1, width, aaint);
return aaint;
}
public static BufferedImage readImage(ResourceLocation resLoc) {
BufferedImage image = null;
InputStream istr = null;
if (resManager != null) {
try {
istr = resManager.getResource(resLoc).getInputStream();
image = ImageIO.read(istr);
} catch (IOException e) {
}
if (istr != null) {
try {
istr.close();
} catch (IOException e) {
}
istr = null;
}
}
return image;
}
public static int[][] genMipmapsSimple(int maxLevel, int width, int[][] data) {
int level;
for (level = 1; level <= maxLevel; ++level) {
if (data[level] == null) {
int cw = width >> level;
int pw = cw * 2;
int[] aintp = data[level - 1];
int[] aintc = data[level] = new int[cw * cw];
int x, y;
for (y = 0; y < cw; ++y) {
for (x = 0; x < cw; ++x) {
int ppos = y * 2 * pw + x * 2;
aintc[y * cw + x] =
blend4Simple(aintp[ppos], aintp[ppos + 1], aintp[ppos + pw], aintp[ppos + pw + 1]);
}
}
}
}
return data;
}
public static void uploadTexSub(
int[][] data, int width, int height, int xoffset, int yoffset, boolean linear, boolean clamp) {
TextureUtil.uploadTextureMipmap(data, width, height, xoffset, yoffset, linear, clamp);
}
public static int blend4Alpha(int c0, int c1, int c2, int c3) {
int a0 = (c0 >>> 24) & 255;
int a1 = (c1 >>> 24) & 255;
int a2 = (c2 >>> 24) & 255;
int a3 = (c3 >>> 24) & 255;
int as = a0 + a1 + a2 + a3;
int an = (as + 2) / 4;
// int an = Math.min(Math.min(Math.min(a0,a1),a2),a3);
int dv;
if (as != 0) {
dv = as;
} else {
dv = 4;
a3 = a2 = a1 = a0 = 1;
}
int frac = (dv + 1) / 2;
// return (((Math.min(Math.min(Math.min(a0,a1),a2),a3)/ 4) << 24) |
int color = (an << 24)
| (((((c0 >>> 16) & 255) * a0
+ ((c1 >>> 16) & 255) * a1
+ ((c2 >>> 16) & 255) * a2
+ ((c3 >>> 16) & 255) * a3
+ frac)
/ dv)
<< 16)
| (((((c0 >>> 8) & 255) * a0
+ ((c1 >>> 8) & 255) * a1
+ ((c2 >>> 8) & 255) * a2
+ ((c3 >>> 8) & 255) * a3
+ frac)
/ dv)
<< 8)
| (((((c0 >>> 0) & 255) * a0
+ ((c1 >>> 0) & 255) * a1
+ ((c2 >>> 0) & 255) * a2
+ ((c3 >>> 0) & 255) * a3
+ frac)
/ dv)
<< 0);
return color;
}
public static int blend4Simple(int c0, int c1, int c2, int c3) {
int color = (((((c0 >>> 24) & 255) + ((c1 >>> 24) & 255) + ((c2 >>> 24) & 255) + ((c3 >>> 24) & 255) + 2) / 4)
<< 24)
| (((((c0 >>> 16) & 255) + ((c1 >>> 16) & 255) + ((c2 >>> 16) & 255) + ((c3 >>> 16) & 255) + 2) / 4)
<< 16)
| (((((c0 >>> 8) & 255) + ((c1 >>> 8) & 255) + ((c2 >>> 8) & 255) + ((c3 >>> 8) & 255) + 2) / 4) << 8)
| (((((c0 >>> 0) & 255) + ((c1 >>> 0) & 255) + ((c2 >>> 0) & 255) + ((c3 >>> 0) & 255) + 2) / 4) << 0);
return color;
}
public static void genMipmapAlpha(int[] aint, int offset, int width, int height) {
int minwh = Math.min(width, height);
int level;
int w1, w2, h1, h2, o1, o2;
w1 = w2 = width;
h1 = h2 = height;
o1 = o2 = offset;
// generate mipmap from big to small
o2 = offset;
w2 = width;
h2 = height;
o1 = 0;
w1 = 0;
h1 = 0;
for (level = 0; w2 > 1 && h2 > 1; ++level, w2 = w1, h2 = h1, o2 = o1) {
o1 = o2 + w2 * h2;
w1 = w2 / 2;
h1 = h2 / 2;
for (int y = 0; y < h1; ++y) {
int p1 = o1 + y * w1;
int p2 = o2 + y * 2 * w2;
for (int x = 0; x < w1; ++x) {
aint[p1 + x] = blend4Alpha(
aint[p2 + (x * 2)],
aint[p2 + (x * 2 + 1)],
aint[p2 + w2 + (x * 2)],
aint[p2 + w2 + (x * 2 + 1)]);
}
}
}
// fix black pixels from small to big
while (level > 0) {
--level;
w2 = width >> level;
h2 = height >> level;
o2 = o1 - w2 * h2;
int p2 = o2;
for (int y = 0; y < h2; ++y) {
for (int x = 0; x < w2; ++x) {
// p2 = o2 + y*w2 + x;
if (aint[p2] == 0) {
aint[p2] = aint[o1 + (y / 2) * w1 + (x / 2)] & 0x00ffffff;
}
++p2;
}
}
o1 = o2;
w1 = w2;
h1 = h2;
}
}
public static void genMipmapSimple(int[] aint, int offset, int width, int height) {
int minwh = Math.min(width, height);
int level;
int w1, w2, h1, h2, o1, o2;
w1 = w2 = width;
h1 = h2 = height;
o1 = o2 = offset;
// generate mipmap from big to small
o2 = offset;
w2 = width;
h2 = height;
o1 = 0;
w1 = 0;
h1 = 0;
for (level = 0; w2 > 1 && h2 > 1; ++level, w2 = w1, h2 = h1, o2 = o1) {
o1 = o2 + w2 * h2;
w1 = w2 / 2;
h1 = h2 / 2;
for (int y = 0; y < h1; ++y) {
int p1 = o1 + y * w1;
int p2 = o2 + y * 2 * w2;
for (int x = 0; x < w1; ++x) {
aint[p1 + x] = blend4Simple(
aint[p2 + (x * 2)],
aint[p2 + (x * 2 + 1)],
aint[p2 + w2 + (x * 2)],
aint[p2 + w2 + (x * 2 + 1)]);
}
}
}
// fix black pixels from small to big
while (level > 0) {
--level;
w2 = width >> level;
h2 = height >> level;
o2 = o1 - w2 * h2;
int p2 = o2;
for (int y = 0; y < h2; ++y) {
for (int x = 0; x < w2; ++x) {
// p2 = o2 + y*w2 + x;
if (aint[p2] == 0) {
aint[p2] = aint[o1 + (y / 2) * w1 + (x / 2)] & 0x00ffffff;
}
++p2;
}
}
o1 = o2;
w1 = w2;
h1 = h2;
}
}
public static boolean isSemiTransparent(int[] aint, int width, int height) {
int size = width * height;
// grass side texture ?;
if (aint[0] >>> 24 == 255 && aint[size - 1] == 0) return true;
for (int i = 0; i < size; ++i) {
int alpha = aint[i] >>> 24;
if (alpha != 0 && alpha != 255) return true;
}
return false;
}
public static void updateSubImage1(int[] src, int width, int height, int posX, int posY, int page, int color) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
int[] aint = getIntArray((size * 4 + 2) / 3);
if (src.length >= size * (page + 1)) {
System.arraycopy(src, size * page, aint, 0, size);
} else {
Arrays.fill(aint, color);
}
//
// if (page == 0)
genMipmapAlpha(aint, 0, width, height);
// else
// genMipmapSimple(aint,0,width,height);
//
for (int level = 0, offset = 0, lw = width, lh = height, px = posX, py = posY; lw > 0 && lh > 0; ++level) {
int lsize = lw * lh;
intBuf.clear();
intBuf.put(aint, offset, lsize).position(0).limit(lsize);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, level, px, py, lw, lh, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf);
offset += lsize;
lw /= 2;
lh /= 2;
px /= 2;
py /= 2;
}
intBuf.clear();
}
public static void updateSubTex1(int[] src, int width, int height, int posX, int posY) {
int level;
int cw;
int ch;
int cx;
int cy;
for (level = 0, cw = width, ch = height, cx = posX, cy = posY;
cw > 0 && ch > 0;
++level, cw /= 2, ch /= 2, cx /= 2, cy /= 2) {
GL11.glCopyTexSubImage2D(GL11.GL_TEXTURE_2D, level, cx, cy, 0, 0, cw, ch);
}
}
/* updateSubImage for single Texture with mipmap */
public static void updateSubImage1(int[][] src, int width, int height, int posX, int posY, int page, int color) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
int numLevel = src.length;
for (int level = 0, // offset=0,
lw = width,
lh = height,
px = posX,
py = posY;
lw > 0 && lh > 0 && level < numLevel;
++level) {
int lsize = lw * lh;
intBuf.clear();
intBuf.put(src[level], 0 /*offset*/, lsize).position(0).limit(lsize);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D, level, px, py, lw, lh, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, intBuf);
// offset += lsize;
lw /= 2;
lh /= 2;
px /= 2;
py /= 2;
}
intBuf.clear();
}
public static void setupTextureMipmap(TextureMap tex) {
/*
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
*/
}
public static void updateDynamicTexture(int texID, int[] src, int width, int height, DynamicTexture tex) {
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
updateSubImage1(src, width, height, 0, 0, 1, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
updateSubImage1(src, width, height, 0, 0, 2, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
updateSubImage1(src, width, height, 0, 0, 0, defBaseTexColor);
}
public static void updateSubImage(
int[] src, int width, int height, int posX, int posY, boolean linear, boolean clamp) {
if (updatingTex != null) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.norm);
updateSubImage1(src, width, height, posX, posY, 1, defNormTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.spec);
updateSubImage1(src, width, height, posX, posY, 2, defSpecTexColor);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, updatingTex.base);
}
updateSubImage1(src, width, height, posX, posY, 0, defBaseTexColor);
}
// not used
public static void updateAnimationTextureMap(TextureMap tex, List tasList) {
Iterator<TextureAtlasSprite> iterator;
MultiTexID multiTex = tex.getMultiTexID();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
for (iterator = tasList.iterator(); iterator.hasNext(); ) {
TextureAtlasSprite tas = iterator.next();
tas.updateAnimation();
}
}
public static void setupTexture(
MultiTexID multiTex, int[] src, int width, int height, boolean linear, boolean clamp) {
int mmfilter = linear ? GL11.GL_LINEAR : GL11.GL_NEAREST;
int wraptype = clamp ? GL11.GL_CLAMP : GL11.GL_REPEAT;
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
//
intBuf.clear();
intBuf.put(src, 0, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
intBuf.put(src, size, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
intBuf.put(src, size * 2, size).position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexImage2D(
GL11.GL_TEXTURE_2D,
0,
GL11.GL_RGBA,
width,
height,
0,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, mmfilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wraptype);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wraptype);
//
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
}
/* currently not used */
public static void updateSubImage(
MultiTexID multiTex, int[] src, int width, int height, int posX, int posY, boolean linear, boolean clamp) {
int size = width * height;
IntBuffer intBuf = getIntBuffer(size);
//
intBuf.clear();
intBuf.put(src, 0, size);
intBuf.position(0).limit(size);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
if (src.length == size * 3) {
intBuf.clear();
intBuf.put(src, size, size).position(0);
intBuf.position(0).limit(size);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
if (src.length == size * 3) {
intBuf.clear();
intBuf.put(src, size * 2, size);
intBuf.position(0).limit(size);
}
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexSubImage2D(
GL11.GL_TEXTURE_2D,
0,
posX,
posY,
width,
height,
GL12.GL_BGRA,
GL12.GL_UNSIGNED_INT_8_8_8_8_REV,
intBuf);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
}
public static ResourceLocation getNSMapLocation(ResourceLocation location, String mapName) {
String basename = location.getResourcePath();
String[] basenameParts = basename.split(".png");
String basenameNoFileType = basenameParts[0];
return new ResourceLocation(location.getResourceDomain(), basenameNoFileType + "_" + mapName + ".png");
}
public static void loadNSMap(
IResourceManager manager, ResourceLocation location, int width, int height, int[] aint) {
if (Shaders.configNormalMap)
ShadersTex.loadNSMap1(
manager, getNSMapLocation(location, "n"), width, height, aint, width * height, defNormTexColor);
if (Shaders.configSpecularMap)
ShadersTex.loadNSMap1(
manager, getNSMapLocation(location, "s"), width, height, aint, width * height * 2, defSpecTexColor);
}
public static void loadNSMap1(
IResourceManager manager,
ResourceLocation location,
int width,
int height,
int[] aint,
int offset,
int defaultColor) {
boolean good = false;
try {
IResource res = manager.getResource(location);
BufferedImage bufferedimage = ImageIO.read(res.getInputStream());
if (bufferedimage.getWidth() == width && bufferedimage.getHeight() == height) {
bufferedimage.getRGB(0, 0, width, height, aint, offset, width);
good = true;
}
} catch (IOException ex) {
}
if (!good) {
java.util.Arrays.fill(aint, offset, offset + width * height, defaultColor);
}
}
/** init and upload from BufferedImage */
/* Replacement for TextureUtil.func_110989_a call in SimpleTexture.func_110551_a.
Keep par0...par5 the same as func_110989_a for easy patching.
More parameters added for reading N-S-Map. */
public static int loadSimpleTexture(
int textureID,
BufferedImage bufferedimage,
boolean linear,
boolean clamp,
IResourceManager resourceManager,
ResourceLocation location,
MultiTexID multiTex) {
int width = bufferedimage.getWidth();
int height = bufferedimage.getHeight();
int size = width * height;
int[] aint = getIntArray(size * 3);
bufferedimage.getRGB(0, 0, width, height, aint, 0, width);
loadNSMap(resourceManager, location, width, height, aint);
setupTexture(multiTex, aint, width, height, linear, clamp);
return textureID;
}
public static void mergeImage(int[] aint, int dstoff, int srcoff, int size) {}
public static int blendColor(int color1, int color2, int factor1) {
int factor2 = 255 - factor1;
return (((((color1 >>> 24) & 255) * factor1 + ((color2 >>> 24) & 255) * factor2) / 255) << 24)
| (((((color1 >>> 16) & 255) * factor1 + ((color2 >>> 16) & 255) * factor2) / 255) << 16)
| (((((color1 >>> 8) & 255) * factor1 + ((color2 >>> 8) & 255) * factor2) / 255) << 8)
| (((((color1 >>> 0) & 255) * factor1 + ((color2 >>> 0) & 255) * factor2) / 255) << 0);
}
public static void loadLayeredTexture(LayeredTexture tex, IResourceManager manager, List list) {
int width = 0;
int height = 0;
int size = 0;
int[] image = null;
Iterator<String> iterator;
for (iterator = list.iterator(); iterator.hasNext(); ) {
String s = iterator.next();
if (s != null) {
try {
ResourceLocation location = new ResourceLocation(s);
InputStream inputstream = manager.getResource(location).getInputStream();
BufferedImage bufimg = ImageIO.read(inputstream);
if (size == 0) {
width = bufimg.getWidth();
height = bufimg.getHeight();
size = width * height;
image = createAIntImage(size, 0x00000000);
}
int[] aint = getIntArray(size * 3);
bufimg.getRGB(0, 0, width, height, aint, 0, width);
loadNSMap(manager, location, width, height, aint);
// merge
for (int i = 0; i < size; ++i) {
int alpha = (aint[i] >>> 24) & 255;
image[size * 0 + i] = blendColor(aint[size * 0 + i], image[size * 0 + i], alpha);
image[size * 1 + i] = blendColor(aint[size * 1 + i], image[size * 1 + i], alpha);
image[size * 2 + i] = blendColor(aint[size * 2 + i], image[size * 2 + i], alpha);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
// init and upload
setupTexture(tex.getMultiTexID(), image, width, height, false, false);
}
/* update block texture filter +/- items texture */
static void updateTextureMinMagFilter() {
TextureManager texman = Minecraft.getMinecraft().getTextureManager();
ITextureObject texObj = texman.getTexture(TextureMap.locationBlocksTexture);
if (texObj != null) {
MultiTexID multiTex = texObj.getMultiTexID();
// base texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.base);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilB]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilB]);
// norm texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.norm);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilN]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilN]);
// spec texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, multiTex.spec);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, Shaders.texMinFilValue[Shaders.configTexMinFilS]);
GL11.glTexParameteri(
GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, Shaders.texMagFilValue[Shaders.configTexMagFilS]);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
}
static IResourceManager resManager = null;
static ResourceLocation resLocation = null;
static int imageSize = 0;
public static IResource loadResource(IResourceManager manager, ResourceLocation location) throws IOException {
resManager = manager;
resLocation = location;
return manager.getResource(location);
}
public static int[] loadAtlasSprite(
BufferedImage bufferedimage, int startX, int startY, int w, int h, int[] aint, int offset, int scansize) {
imageSize = w * h;
bufferedimage.getRGB(startX, startY, w, h, aint, offset, scansize);
loadNSMap(resManager, resLocation, w, h, aint);
return aint;
}
public static int[] extractFrame(int[] src, int width, int height, int frameIndex) {
int srcSize = imageSize;
int frameSize = width * height;
int[] dst = new int[frameSize * 3];
int srcPos = frameSize * frameIndex;
int dstPos = 0;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
srcPos += srcSize;
dstPos += frameSize;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
srcPos += srcSize;
dstPos += frameSize;
System.arraycopy(src, srcPos, dst, dstPos, frameSize);
return dst;
}
public static void fixTransparentColor(TextureAtlasSprite tas, int[] aint) {}
}
@@ -0,0 +1,591 @@
package com.gtnewhorizons.angelica.client.font;
import com.gtnewhorizons.angelica.compat.lwjgl.CompatMemoryUtil;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.FontRendererAccessor;
import it.unimi.dsi.fastutil.chars.Char2ShortOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import jss.util.RandomXoshiro256StarStar;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import static org.lwjgl.opengl.GL11.*;
/**
* A batching replacement for {@code FontRenderer}
*
* @author eigenraven
*/
public class BatchingFontRenderer {
/** The underlying FontRenderer object that's being accelerated */
protected FontRenderer underlying;
/** Cached locations for each unicode page atlas */
private final ResourceLocation[] unicodePageLocations;
/** Array of width of all the characters in default.png */
protected int[] charWidth = new int[256];
/** Array of the start/end column (in upper/lower nibble) for every glyph in the /font directory. */
protected byte[] glyphWidth;
/**
* Array of RGB triplets defining the 16 standard chat colors followed by 16 darker version of the same colors for
* drop shadows.
*/
private int[] colorCode;
/** Location of the primary font atlas to bind. */
protected final ResourceLocation locationFontTexture;
/** The RenderEngine used to load and setup glyph textures. */
private final TextureManager renderEngine;
private final RandomXoshiro256StarStar fontRandom = new RandomXoshiro256StarStar();
/** The full list of characters present in the default Minecraft font, excluding the Unicode font */
@SuppressWarnings("UnnecessaryUnicodeEscape")
private static final String MCFONT_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
private static final short[] MCFONT_ASCII_LUT = new short[512];
private static final Char2ShortOpenHashMap MCFONT_UNI_LUT = new Char2ShortOpenHashMap();
static {
Arrays.fill(MCFONT_ASCII_LUT, (short) -1);
for (short i = 0; i < MCFONT_CHARS.length(); i++) {
char ch = MCFONT_CHARS.charAt(i);
if (ch < MCFONT_ASCII_LUT.length) {
MCFONT_ASCII_LUT[ch] = i;
} else {
MCFONT_UNI_LUT.put(ch, i);
}
}
}
public static int lookupMcFontPosition(char ch) {
if (ch < MCFONT_ASCII_LUT.length) {
return MCFONT_ASCII_LUT[ch];
} else {
return MCFONT_UNI_LUT.getOrDefault(ch, (short) -1);
}
}
public BatchingFontRenderer(FontRenderer underlying, ResourceLocation[] unicodePageLocations, int[] charWidth,
byte[] glyphWidth, int[] colorCode, ResourceLocation locationFontTexture, TextureManager renderEngine) {
this.underlying = underlying;
this.unicodePageLocations = unicodePageLocations;
this.charWidth = charWidth;
this.glyphWidth = glyphWidth;
this.colorCode = colorCode;
this.locationFontTexture = locationFontTexture;
this.renderEngine = renderEngine;
for (int i = 0; i < 64; i++) {
batchCommandPool.add(new FontDrawCmd());
}
}
// === Batched rendering
private int batchDepth = 0;
private int vtxWriterIndex = 0;
private int idxWriterIndex = 0;
private static final int INITIAL_BATCH_SIZE = 256;
private static final ResourceLocation DUMMY_RESOURCE_LOCATION = new ResourceLocation("angelica$dummy",
"this is invalid!");
private FloatBuffer batchVtxPositions = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private ByteBuffer batchVtxColors = BufferUtils.createByteBuffer(INITIAL_BATCH_SIZE * 4);
private FloatBuffer batchVtxTexCoords = BufferUtils.createFloatBuffer(INITIAL_BATCH_SIZE * 2);
private IntBuffer batchIndices = BufferUtils.createIntBuffer(INITIAL_BATCH_SIZE / 2 * 3);
private final ObjectArrayList<FontDrawCmd> batchCommands = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
private final ObjectArrayList<FontDrawCmd> batchCommandPool = ObjectArrayList.wrap(new FontDrawCmd[64], 0);
/** */
private void pushVtx(float x, float y, int rgba, float u, float v) {
final int oldCap = batchVtxPositions.capacity() / 2;
if (vtxWriterIndex >= oldCap) {
final int newCap = oldCap * 2;
batchVtxPositions = CompatMemoryUtil.memReallocDirect(batchVtxPositions, newCap * 2);
batchVtxColors = CompatMemoryUtil.memReallocDirect(batchVtxColors, newCap * 4);
batchVtxTexCoords = CompatMemoryUtil.memReallocDirect(batchVtxTexCoords, newCap * 2);
final int oldIdxCap = batchIndices.capacity();
final int newIdxCap = oldIdxCap * 2;
batchIndices = CompatMemoryUtil.memReallocDirect(batchIndices, newIdxCap);
}
final int idx = vtxWriterIndex;
final int idx2 = idx * 2;
final int idx4 = idx * 4;
batchVtxPositions.put(idx2, x);
batchVtxPositions.put(idx2 + 1, y);
// 0xAARRGGBB
batchVtxColors.put(idx4, (byte) ((rgba >> 16) & 0xFF));
batchVtxColors.put(idx4 + 1, (byte) ((rgba >> 8) & 0xFF));
batchVtxColors.put(idx4 + 2, (byte) (rgba & 0xFF));
batchVtxColors.put(idx4 + 3, (byte) ((rgba >> 24) & 0xFF));
batchVtxTexCoords.put(idx2, u);
batchVtxTexCoords.put(idx2 + 1, v);
vtxWriterIndex++;
}
private void pushUntexRect(float x, float y, float w, float h, int rgba) {
final int vtxId = vtxWriterIndex;
pushVtx(x, y, rgba, 0, 0);
pushVtx(x, y + h, rgba, 0, 0);
pushVtx(x + w, y, rgba, 0, 0);
pushVtx(x + w, y + h, rgba, 0, 0);
pushQuadIdx(vtxId);
}
private int pushQuadIdx(int startV) {
final int idx = idxWriterIndex;
batchIndices.put(idx, startV);
batchIndices.put(idx + 1, startV + 1);
batchIndices.put(idx + 2, startV + 2);
//
batchIndices.put(idx + 3, startV + 2);
batchIndices.put(idx + 4, startV + 1);
batchIndices.put(idx + 5, startV + 3);
idxWriterIndex += 6;
return idx;
}
private void pushDrawCmd(int startIdx, int idxCount, ResourceLocation texture) {
if (!batchCommands.isEmpty()) {
final FontDrawCmd lastCmd = batchCommands.get(batchCommands.size() - 1);
final int prevEndVtx = lastCmd.startVtx + lastCmd.idxCount;
if (prevEndVtx == startIdx && lastCmd.texture == texture) {
// Coalesce into one
lastCmd.idxCount += idxCount;
return;
}
}
if (batchCommandPool.isEmpty()) {
for (int i = 0; i < 64; i++) {
batchCommandPool.add(new FontDrawCmd());
}
}
final FontDrawCmd cmd = batchCommandPool.pop();
cmd.reset(startIdx, idxCount, texture);
batchCommands.add(cmd);
}
private static final class FontDrawCmd {
public int startVtx;
public int idxCount;
public ResourceLocation texture;
public void reset(int startVtx, int vtxCount, ResourceLocation texture) {
this.startVtx = startVtx;
this.idxCount = vtxCount;
this.texture = texture;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
var that = (FontDrawCmd) obj;
return this.startVtx == that.startVtx && this.idxCount == that.idxCount && Objects.equals(this.texture,
that.texture);
}
@Override
public int hashCode() {
return Objects.hash(startVtx, idxCount, texture);
}
@Override
public String toString() {
return "FontDrawCmd["
+ "startVtx="
+ startVtx
+ ", "
+ "vtxCount="
+ idxCount
+ ", "
+ "texture="
+ texture
+ ']';
}
public static final Comparator<FontDrawCmd> DRAW_ORDER_COMPARATOR = Comparator.comparing((FontDrawCmd fdc) -> fdc.texture,
Comparator.nullsLast(Comparator.comparing(ResourceLocation::getResourceDomain)
.thenComparing(ResourceLocation::getResourcePath))).thenComparing(fdc -> fdc.startVtx);
}
/**
* Starts a new batch of font rendering operations. Can be called from within another batch with a matching end, to
* allow for easier optimizing of blocks of font rendering code.
*/
public void beginBatch() {
if (batchDepth == Integer.MAX_VALUE) {
throw new StackOverflowError("More than Integer.MAX_VALUE nested font rendering batch operations");
}
batchDepth++;
}
public void endBatch() {
if (batchDepth <= 0) {
batchDepth = 0;
return;
}
batchDepth--;
if (batchDepth == 0) {
// We finished any nested batches
flushBatch();
}
}
private void flushBatch() {
// Sort&Draw
batchCommands.sort(FontDrawCmd.DRAW_ORDER_COMPARATOR);
final boolean isTextureEnabledBefore = GLStateManager.glIsEnabled(GL11.GL_TEXTURE_2D);
final int boundTextureBefore = GLStateManager.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
boolean textureChanged = false;
ResourceLocation lastTexture = DUMMY_RESOURCE_LOCATION;
GLStateManager.enableTexture();
GLStateManager.enableAlphaTest();
GLStateManager.enableBlend();
GLStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
GLStateManager.glShadeModel(GL_FLAT);
glTexCoordPointer(2, 0, batchVtxTexCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, batchVtxColors);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, 0, batchVtxPositions);
glEnableClientState(GL_VERTEX_ARRAY);
GLStateManager.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Use plain for loop to avoid allocations
final FontDrawCmd[] cmdsData = batchCommands.elements();
final int cmdsSize = batchCommands.size();
for (int i = 0; i < cmdsSize; i++) {
final FontDrawCmd cmd = cmdsData[i];
if (!Objects.equals(lastTexture, cmd.texture)) {
if (lastTexture == null) {
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
} else if (cmd.texture == null) {
GLStateManager.glDisable(GL11.GL_TEXTURE_2D);
}
if (cmd.texture != null) {
((FontRendererAccessor) underlying).angelica$bindTexture(cmd.texture);
textureChanged = true;
}
lastTexture = cmd.texture;
}
batchIndices.limit(cmd.startVtx + cmd.idxCount);
batchIndices.position(cmd.startVtx);
glDrawElements(GL_TRIANGLES, batchIndices);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
if (isTextureEnabledBefore) {
GLStateManager.glEnable(GL11.GL_TEXTURE_2D);
}
if (textureChanged) {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, boundTextureBefore);
}
// Clear for the next batch
batchCommandPool.addAll(batchCommands);
batchCommands.clear();
vtxWriterIndex = 0;
idxWriterIndex = 0;
batchIndices.limit(batchIndices.capacity());
batchIndices.position(0);
}
// === Actual text mesh generation
public static boolean charInRange(char what, char fromInclusive, char toInclusive) {
return (what >= fromInclusive) && (what <= toInclusive);
}
private ResourceLocation getUnicodePageLocation(int page) {
final ResourceLocation lookup = unicodePageLocations[page];
if (lookup == null) {
final ResourceLocation rl = new ResourceLocation(String.format(
"textures/font/unicode_page_%02x.png",
page));
unicodePageLocations[page] = rl;
return rl;
} else {
return lookup;
}
}
private static final char FORMATTING_CHAR = 167; // §
public float drawString(final float anchorX, final float anchorY, final int color, final boolean enableShadow,
final boolean unicodeFlag, final CharSequence string, int stringOffset, int stringLength) {
// noinspection SizeReplaceableByIsEmpty
if (string == null || string.length() == 0) {
return anchorX + (enableShadow ? 1.0f : 0.0f);
}
final int shadowColor = (color & 0xfcfcfc) >> 2 | color & 0xff000000;
this.beginBatch();
float curX = anchorX;
try {
final int totalStringLength = string.length();
stringOffset = MathHelper.clamp_int(stringOffset, 0, totalStringLength);
stringLength = MathHelper.clamp_int(stringLength, 0, totalStringLength - stringOffset);
if (stringLength <= 0) {
return 0;
}
final int stringEnd = stringOffset + stringLength;
int curColor = color;
int curShadowColor = shadowColor;
boolean curItalic = false;
boolean curRandom = false;
boolean curBold = false;
boolean curStrikethrough = false;
boolean curUnderline = false;
final float underlineY = anchorY + underlying.FONT_HEIGHT - 1.0f;
float underlineStartX = 0.0f;
float underlineEndX = 0.0f;
final float strikethroughY = anchorY + (float) (underlying.FONT_HEIGHT / 2);
float strikethroughStartX = 0.0f;
float strikethroughEndX = 0.0f;
for (int charIdx = stringOffset; charIdx < stringEnd; charIdx++) {
char chr = string.charAt(charIdx);
if (chr == FORMATTING_CHAR && (charIdx + 1) < stringEnd) {
final char fmtCode = Character.toLowerCase(string.charAt(charIdx + 1));
charIdx++;
if (curUnderline && underlineStartX != underlineEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(underlineStartX, underlineY, underlineEndX - underlineStartX, 1.0f, curColor);
pushDrawCmd(ulIdx, 6, null);
underlineStartX = underlineEndX;
}
if (curStrikethrough && strikethroughStartX != strikethroughEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(
strikethroughStartX,
strikethroughY,
strikethroughEndX - strikethroughStartX,
1.0f,
curColor);
pushDrawCmd(ulIdx, 6, null);
strikethroughStartX = strikethroughEndX;
}
final boolean is09 = charInRange(fmtCode, '0', '9');
final boolean isAF = charInRange(fmtCode, 'a', 'f');
if (is09 || isAF) {
curRandom = false;
curBold = false;
curStrikethrough = false;
curUnderline = false;
curItalic = false;
final int colorIdx = is09 ? (fmtCode - '0') : (fmtCode - 'a' + 10);
final int rgb = this.colorCode[colorIdx];
curColor = (curColor & 0xFF000000) | (rgb & 0x00FFFFFF);
final int shadowRgb = this.colorCode[colorIdx + 16];
curShadowColor = (curShadowColor & 0xFF000000) | (shadowRgb & 0x00FFFFFF);
} else if (fmtCode == 'k') {
curRandom = true;
} else if (fmtCode == 'l') {
curBold = true;
} else if (fmtCode == 'm') {
curStrikethrough = true;
strikethroughStartX = curX - 1.0f;
strikethroughEndX = strikethroughStartX;
} else if (fmtCode == 'n') {
curUnderline = true;
underlineStartX = curX - 1.0f;
underlineEndX = underlineStartX;
} else if (fmtCode == 'o') {
curItalic = true;
} else if (fmtCode == 'r') {
curRandom = false;
curBold = false;
curStrikethrough = false;
curUnderline = false;
curItalic = false;
curColor = color;
curShadowColor = shadowColor;
}
continue;
}
int lutIndex = lookupMcFontPosition(chr);
if (curRandom && lutIndex != -1) {
int randomReplacementIndex;
do {
randomReplacementIndex = fontRandom.nextInt(this.charWidth.length);
} while (this.charWidth[lutIndex] != this.charWidth[randomReplacementIndex]);
lutIndex = randomReplacementIndex;
chr = MCFONT_CHARS.charAt(lutIndex);
}
final float shadowOffset = unicodeFlag ? 0.5F : 1.0F;
// Check ASCII space, NBSP, NNBSP
if (chr == ' ' || chr == '\u00A0' || chr == '\u202F') {
curX += 4;
continue;
}
final float uStart;
final float vStart;
final float xAdvance;
final float glyphW;
final float uSz;
final float vSz;
final float itOff = curItalic ? 1.0F : 0.0F; // italic offset
final ResourceLocation texture;
if (lutIndex == -1 || unicodeFlag) {
if (glyphWidth[chr] == 0) {
continue;
}
// Draw unicode char
final int uniPage = chr / 256;
texture = getUnicodePageLocation(uniPage);
final int startColumn = this.glyphWidth[chr] >>> 4;
final int endColumn = this.glyphWidth[chr] & 15;
final float startColumnF = (float) startColumn;
final float endColumnF = (float) (endColumn + 1);
uStart = ((float) (chr % 16 * 16) + startColumnF) / 256.0f;
vStart = ((float) ((chr & 255) / 16 * 16)) / 256.0f;
final float chrWidth = endColumnF - startColumnF - 0.02F;
glyphW = chrWidth / 2.0f + 1.0f;
xAdvance = (endColumnF - startColumnF) / 2.0F + 1.0F;
uSz = chrWidth / 256.0f;
vSz = 15.98f / 256.0f;
} else {
// Draw "ASCII" char
uStart = ((lutIndex % 16) * 8) / 128.0F;
vStart = (float) ((lutIndex / 16) * 8) / 128.0F;
xAdvance = this.charWidth[lutIndex];
if (xAdvance == 0) {
continue;
}
glyphW = xAdvance - 0.01F;
uSz = (glyphW - 1.0F) / 128.0F;
vSz = 7.99F / 128.0F;
texture = locationFontTexture;
}
final int vtxId = vtxWriterIndex;
final int idxId = idxWriterIndex;
int vtxCount = 0;
if (enableShadow) {
pushVtx(curX + itOff + shadowOffset, anchorY + shadowOffset, curShadowColor, uStart, vStart);
pushVtx(
curX - itOff + shadowOffset,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart,
vStart + vSz);
pushVtx(curX + glyphW - 1.0F + itOff + shadowOffset,
anchorY + shadowOffset,
curShadowColor,
uStart + uSz,
vStart);
pushVtx(curX + glyphW - 1.0F - itOff + shadowOffset,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
if (curBold) {
final float shadowOffset2 = 2.0f * shadowOffset;
pushVtx(curX + itOff + shadowOffset2, anchorY + shadowOffset, curShadowColor, uStart, vStart);
pushVtx(
curX - itOff + shadowOffset2,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart,
vStart + vSz);
pushVtx(
curX + glyphW - 1.0F + itOff + shadowOffset2,
anchorY + shadowOffset,
curShadowColor,
uStart + uSz,
vStart);
pushVtx(curX + glyphW - 1.0F - itOff + shadowOffset2,
anchorY + 7.99F + shadowOffset,
curShadowColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
}
}
pushVtx(curX + itOff, anchorY, curColor, uStart, vStart);
pushVtx(curX - itOff, anchorY + 7.99F, curColor, uStart, vStart + vSz);
pushVtx(curX + glyphW - 1.0F + itOff, anchorY, curColor, uStart + uSz, vStart);
pushVtx(curX + glyphW - 1.0F - itOff, anchorY + 7.99F, curColor, uStart + uSz, vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
if (curBold) {
pushVtx(shadowOffset + curX + itOff, anchorY, curColor, uStart, vStart);
pushVtx(shadowOffset + curX - itOff, anchorY + 7.99F, curColor, uStart, vStart + vSz);
pushVtx(shadowOffset + curX + glyphW - 1.0F + itOff, anchorY, curColor, uStart + uSz, vStart);
pushVtx(shadowOffset + curX + glyphW - 1.0F - itOff,
anchorY + 7.99F,
curColor,
uStart + uSz,
vStart + vSz);
pushQuadIdx(vtxId + vtxCount);
vtxCount += 4;
}
pushDrawCmd(idxId, vtxCount / 2 * 3, texture);
curX += xAdvance + (curBold ? shadowOffset : 0.0f);
underlineEndX = curX;
strikethroughEndX = curX;
}
if (curUnderline && underlineStartX != underlineEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(underlineStartX, underlineY, underlineEndX - underlineStartX, 1.0f, curColor);
pushDrawCmd(ulIdx, 6, null);
}
if (curStrikethrough && strikethroughStartX != strikethroughEndX) {
final int ulIdx = idxWriterIndex;
pushUntexRect(
strikethroughStartX,
strikethroughY,
strikethroughEndX - strikethroughStartX,
1.0f,
curColor);
pushDrawCmd(ulIdx, 6, null);
}
} finally {
this.endBatch();
}
return curX + (enableShadow ? 1.0f : 0.0f);
}
}
@@ -0,0 +1,29 @@
package com.gtnewhorizons.angelica.client.gui;
import com.gtnewhorizons.angelica.compat.mojang.Element;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Mouse;
import java.util.List;
public abstract class ScrollableGuiScreen extends GuiScreen {
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
handleMouseScroll(mouseX, mouseY, partialTicks);
}
public abstract List<? extends Element> children();
protected void handleMouseScroll(int mouseX, int mouseY, float partialTicks) {
for (; !this.mc.gameSettings.touchscreen && Mouse.next(); this.mc.currentScreen.handleMouseInput()) {
int dWheel = Mouse.getEventDWheel();
if (dWheel != 0) {
for(Element child : children()) {
child.mouseScrolled(mouseX, mouseY, dWheel);
}
}
}
}
}
@@ -0,0 +1,247 @@
package com.gtnewhorizons.angelica.client.renderer;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.compat.mojang.BlockPosImpl;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormat;
import me.jellysquid.mods.sodium.client.model.quad.Quad;
import com.gtnewhorizons.angelica.glsm.stacks.Vector3dStack;
import com.gtnewhorizons.angelica.mixins.interfaces.ITessellatorInstance;
import com.gtnewhorizons.angelica.utils.ObjectPooler;
import cpw.mods.fml.relauncher.ReflectionHelper;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import me.jellysquid.mods.sodium.client.render.pipeline.BlockRenderer;
import net.minecraft.client.renderer.Tessellator;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.List;
import static net.minecraft.util.MathHelper.clamp_int;
/*
* To be used in conjunction with the TessellatorManager
*
* Used to capture the quads generated by the Tessellator across multiple draw calls and make the quad
* list available for usage.
*
* NOTE: This will _not_ (currently) capture, integrate, or stop any GL calls made around the tessellator draw calls.
*
*/
@SuppressWarnings("unused")
public class CapturingTessellator extends Tessellator implements ITessellatorInstance {
// Access Transformers don't work on Forge Fields :rage:
private static final MethodHandle sRawBufferSize;
private static final MethodHandle gRawBufferSize;
private final BlockRenderer.Flags FLAGS = new BlockRenderer.Flags(true, true, true, true);
private final ObjectPooler<QuadView> quadBuf = new ObjectPooler<>(Quad::new);
private final List<QuadView> collectedQuads = new ObjectArrayList<>();
// Any offset we need to the Tesselator's offset!
private final BlockPosImpl offset = new BlockPosImpl();
private final Vector3dStack storedTranslation = new Vector3dStack();
public void setOffset(BlockPosImpl pos) {
this.offset.set(pos);
}
public void resetOffset() {
this.offset.zero();
}
static {
final Field rbs = ReflectionHelper.findField(Tessellator.class, "rawBufferSize");
rbs.setAccessible(true);
try {
sRawBufferSize = MethodHandles.lookup().unreflectSetter(rbs);
gRawBufferSize = MethodHandles.lookup().unreflectGetter(rbs);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void setRawBufferSize(int size) {
try {
sRawBufferSize.invokeExact((Tessellator)this, size);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
public int getRawBufferSize() {
try {
return (int) gRawBufferSize.invokeExact((Tessellator)this);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
@Override
public int draw() {
// Adapted from Neodymium
FLAGS.hasBrightness = this.hasBrightness;
FLAGS.hasColor = this.hasColor;
FLAGS.hasNormals = this.hasNormals;
final int verticesPerPrimitive = this.drawMode == GL11.GL_QUADS ? 4 : 3;
for(int quadI = 0; quadI < this.vertexCount / verticesPerPrimitive; quadI++) {
final QuadView quad = quadBuf.getInstance();
quad.setState(this.rawBuffer, quadI * (verticesPerPrimitive * 8), FLAGS, this.drawMode, -offset.x, -offset.y, -offset.z);
if(quad.isDeleted()) {
quadBuf.releaseInstance(quad);
} else {
this.collectedQuads.add(quad);
}
}
final int i = this.rawBufferIndex * 4;
this.discard();
return i;
}
@Override
public void discard() {
isDrawing = false;
reset();
}
public List<QuadView> getQuads() {
return collectedQuads;
}
public void clearQuads() {
//noinspection ForLoopReplaceableByForEach
for(int i = 0; i < this.collectedQuads.size(); i++) {
this.quadBuf.releaseInstance(this.collectedQuads.get(i));
}
this.collectedQuads.clear();
}
public static ByteBuffer quadsToBuffer(List<QuadView> quads, VertexFormat format) {
if(!format.canWriteQuads()) {
throw new IllegalStateException("Vertex format has no quad writer: " + format);
}
final ByteBuffer byteBuffer = BufferUtils.createByteBuffer(format.getVertexSize() * quads.size() * 4);
// noinspection ForLoopReplaceableByForEach
for (int i = 0, quadsSize = quads.size(); i < quadsSize; i++) {
format.writeQuad(quads.get(i), byteBuffer);
}
byteBuffer.rewind();
return byteBuffer;
}
public void storeTranslation() {
storedTranslation.push();
this.storedTranslation.set(xOffset, yOffset, zOffset);
}
public void restoreTranslation() {
xOffset = storedTranslation.x;
yOffset = storedTranslation.y;
zOffset = storedTranslation.z;
storedTranslation.pop();
}
public static int createBrightness(int sky, int block) {
return sky << 20 | block << 4;
}
// API from newer MC
public CapturingTessellator pos(double x, double y, double z) {
ensureBuffer();
this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float)(x + this.xOffset));
this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float)(y + this.yOffset));
this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float)(z + this.zOffset));
return this;
}
public CapturingTessellator tex(double u, double v) {
this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float)u);
this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float)v);
this.hasTexture = true;
return this;
}
public CapturingTessellator color(float red, float green, float blue, float alpha) {
return this.color((int)(red * 255.0F), (int)(green * 255.0F), (int)(blue * 255.0F), (int)(alpha * 255.0F));
}
public CapturingTessellator color(int red, int green, int blue, int alpha) {
if(this.isColorDisabled) return this;
red = clamp_int(red, 0, 255);
green = clamp_int(green, 0, 255);
blue = clamp_int(blue, 0, 255);
alpha = clamp_int(alpha, 0, 255);
final int color;
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
color = alpha << 24 | blue << 16 | green << 8 | red;
} else {
color = red << 24 | green << 16 | blue << 8 | alpha;
}
this.rawBuffer[this.rawBufferIndex + 5] = color;
this.hasColor = true;
return this;
}
public CapturingTessellator normal(float x, float y, float z) {
final byte b0 = (byte)((int)(x * 127.0F));
final byte b1 = (byte)((int)(y * 127.0F));
final byte b2 = (byte)((int)(z * 127.0F));
this.rawBuffer[this.rawBufferIndex + 6] = b0 & 255 | (b1 & 255) << 8 | (b2 & 255) << 16;
this.hasNormals = true;
return this;
}
public CapturingTessellator lightmap(int skyLight, int blockLight) {
return brightness(createBrightness(skyLight, blockLight));
}
public CapturingTessellator brightness(int brightness) {
this.rawBuffer[this.rawBufferIndex + 7] = brightness;
this.hasBrightness = true;
return this;
}
public CapturingTessellator endVertex() {
this.rawBufferIndex += 8;
++this.vertexCount;
return this;
}
public void ensureBuffer() {
int rawBufferSize = getRawBufferSize();
if (rawBufferIndex >= rawBufferSize - 32) {
if (rawBufferSize == 0) {
rawBufferSize = 0x10000;
setRawBufferSize(rawBufferSize);
rawBuffer = new int[rawBufferSize];
} else {
rawBufferSize *= 2;
setRawBufferSize(rawBufferSize);
rawBuffer = Arrays.copyOf(rawBuffer, rawBufferSize);
}
}
}
}
@@ -0,0 +1,102 @@
package com.gtnewhorizons.angelica.common;
import com.gtnewhorizons.angelica.api.BlockPos;
import com.gtnewhorizons.angelica.api.QuadProvider;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.models.json.JsonModel;
import com.gtnewhorizons.angelica.models.json.Loader;
import com.gtnewhorizons.angelica.models.json.Variant;
import it.unimi.dsi.fastutil.objects.ObjectImmutableList;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Random;
import java.util.function.Supplier;
public class BlockTest extends Block implements QuadProvider {
public static final Variant[] modelId = {
new Variant(
new ResourceLocation("blocks/lectern"),
0,
0,
false
),
new Variant(
new ResourceLocation("blocks/lectern"),
180,
0,
false
),
new Variant(
new ResourceLocation("blocks/lectern"),
90,
0,
false
),
new Variant(
new ResourceLocation("blocks/lectern"),
270,
0,
false
),
};
private static final List<QuadView> EMPTY = ObjectImmutableList.of();
private static final JsonModel[] model = new JsonModel[4];
public BlockTest() {
super(Material.rock);
}
public static void loadModel() {
for (int i = 0; i < 4; ++i)
model[i] = Loader.getModel(modelId[i]);
}
@Override
public boolean isOpaqueCube() {
return false;
}
@Override
public void registerBlockIcons(IIconRegister reg) {
reg.registerIcon("angelica:test_block");
reg.registerIcon("lectern_base");
reg.registerIcon("lectern_front");
reg.registerIcon("lectern_sides");
reg.registerIcon("lectern_top");
reg.registerIcon("oak_planks");
}
@Override
public List<QuadView> getQuads(IBlockAccess world, BlockPos pos, Block block, int meta, ForgeDirection dir, Random random, int color, Supplier<QuadView> quadPool) {
if (meta < 2 || meta > 5) meta = 2;
return (model[meta - 2] != null) ? model[meta - 2].getQuads(world, pos, block, meta, dir, random, color, quadPool) : EMPTY;
}
/**
* Called when a block is placed using its ItemBlock. Args: World, X, Y, Z, side, hitX, hitY, hitZ, block metadata
*/
@Override
public int onBlockPlaced(@NotNull World worldIn, int x, int y, int z, int side, float subX, float subY, float subZ, int meta) {
// Face NORTH if placed up or down
final ForgeDirection s = ForgeDirection.values()[side];
if (s == ForgeDirection.UP || s == ForgeDirection.DOWN)
return 2;
// Face the placed side
return side;
}
}
@@ -0,0 +1,82 @@
package com.gtnewhorizons.angelica.compat;
import com.falsepattern.chunk.api.DataRegistry;
import com.gtnewhorizons.angelica.mixins.early.sodium.MixinExtendedBlockStorage;
import com.gtnewhorizons.angelica.mixins.interfaces.ExtendedNibbleArray;
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.NibbleArray;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import ru.fewizz.idextender.Hooks;
public class ExtendedBlockStorageExt extends ExtendedBlockStorage {
public boolean hasSky;
public ExtendedBlockStorageExt(int yBase, boolean hasSky) {
super(yBase, hasSky);
this.hasSky = hasSky;
}
public ExtendedBlockStorageExt(Chunk chunk, ExtendedBlockStorage storage) {
super(((MixinExtendedBlockStorage) storage).getYBase(), storage.getSkylightArray() != null);
if (ModStatus.isChunkAPILoaded) {
if (storage.getSkylightArray() != null) {
hasSky = true;
}
DataRegistry.cloneSubChunk(chunk, storage, this);
} else {
int arrayLen;
if (ModStatus.isNEIDLoaded){
final short[] block16BArray = ((IExtendedBlockStorageMixin)(Object)this).getBlock16BArray();
System.arraycopy(((IExtendedBlockStorageMixin)(Object)storage).getBlock16BArray(), 0, block16BArray, 0, block16BArray.length);
if(storage.getBlockMSBArray() != null) {
this.setBlockMSBArray(new NibbleArray(block16BArray.length, 4));
copyNibbleArray((ExtendedNibbleArray) storage.getBlockMSBArray(), (ExtendedNibbleArray) this.getBlockMSBArray());
}
arrayLen = block16BArray.length;
if (ModStatus.isNEIDMetadataExtended) {
final short[] block16BMetaArray = ((IExtendedBlockStorageMixin)(Object)this).getBlock16BMetaArray();
System.arraycopy(((IExtendedBlockStorageMixin)(Object)storage).getBlock16BMetaArray(), 0, block16BMetaArray, 0, block16BMetaArray.length);
}
}
else if (ModStatus.isOldNEIDLoaded){
final short[] blockLSBArray = Hooks.get(this);
System.arraycopy(Hooks.get(storage), 0, blockLSBArray, 0, blockLSBArray.length);
// getBlockMSBArray is nuked in asm version
arrayLen = blockLSBArray.length;
}
else {
final byte[] blockLSBArray = this.getBlockLSBArray();
System.arraycopy(storage.getBlockLSBArray(), 0, blockLSBArray, 0, blockLSBArray.length);
if(storage.getBlockMSBArray() != null) {
this.setBlockMSBArray(new NibbleArray(blockLSBArray.length, 4));
copyNibbleArray((ExtendedNibbleArray) storage.getBlockMSBArray(), (ExtendedNibbleArray) this.getBlockMSBArray());
}
arrayLen = blockLSBArray.length;
}
if (!ModStatus.isNEIDMetadataExtended) copyNibbleArray((ExtendedNibbleArray) storage.getMetadataArray(), (ExtendedNibbleArray)this.getMetadataArray());
copyNibbleArray((ExtendedNibbleArray) storage.getBlocklightArray(), (ExtendedNibbleArray)this.getBlocklightArray());
if(storage.getSkylightArray() != null) {
hasSky = true;
if(this.getSkylightArray() == null) {
this.setSkylightArray(new NibbleArray(arrayLen, 4));
}
copyNibbleArray((ExtendedNibbleArray) storage.getSkylightArray(), (ExtendedNibbleArray) this.getSkylightArray());
}
}
((MixinExtendedBlockStorage) this).setBlockRefCount(((MixinExtendedBlockStorage) storage).getBlockRefCount());
}
private static void copyNibbleArray(ExtendedNibbleArray srcArray, ExtendedNibbleArray dstArray) {
if (srcArray == null || dstArray == null) {
throw new RuntimeException("NibbleArray is null src: " + (srcArray == null) + " dst: " + (dstArray == null));
}
final byte[] data = srcArray.getData();
System.arraycopy(data, 0, dstArray.getData(), 0, data.length);
}
}
@@ -0,0 +1,53 @@
package com.gtnewhorizons.angelica.compat;
import com.gtnewhorizons.angelica.helpers.LoadControllerHelper;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import cpw.mods.fml.common.versioning.DefaultArtifactVersion;
import net.dries007.holoInventory.HoloInventory;
public class ModStatus {
/**
* Mixin Version
*/
public static boolean isNEIDLoaded;
/**
* ASM Version
*/
public static boolean isOldNEIDLoaded;
public static boolean isBetterCrashesLoaded;
public static boolean isNEIDMetadataExtended;
public static boolean isLotrLoaded;
public static boolean isChunkAPILoaded;
public static boolean isEIDBiomeLoaded;
public static boolean isXaerosMinimapLoaded;
public static boolean isHoloInventoryLoaded;
public static void preInit(){
isBetterCrashesLoaded = Loader.isModLoaded("bettercrashes");
isNEIDLoaded = Loader.isModLoaded("neid");
isOldNEIDLoaded = Loader.isModLoaded("notenoughIDs");
isLotrLoaded = Loader.isModLoaded("lotr");
isChunkAPILoaded = Loader.isModLoaded("chunkapi");
isEIDBiomeLoaded = Loader.isModLoaded("endlessids_biome");
isXaerosMinimapLoaded = Loader.isModLoaded("XaeroMinimap");
isHoloInventoryLoaded = Loader.isModLoaded("holoinventory");
if (isHoloInventoryLoaded){
isHoloInventoryLoaded = new DefaultArtifactVersion("2.4.4-GTNH")
.compareTo(
LoadControllerHelper.getOwningMod(HoloInventory.class).getProcessedVersion()
) <= 0;
}
isNEIDMetadataExtended = false;
if (isNEIDLoaded) {
int majorVersion = Integer.parseInt(Loader.instance().getIndexedModList().get("neid").getVersion().split("\\.")[0]);
if (majorVersion >= 2) {
isNEIDMetadataExtended = true;
}
}
}
}
@@ -0,0 +1,34 @@
package com.gtnewhorizons.angelica.compat.bettercrashes;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import com.gtnewhorizons.angelica.mixins.interfaces.IRenderGlobalExt;
import cpw.mods.fml.common.Optional;
import net.minecraft.client.Minecraft;
import vfyjxf.bettercrashes.utils.StateManager;
import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER;
@Optional.Interface(modid = "angelica", iface = "vfyjxf.bettercrashes.utils.StateManager.IResettable")
public class BetterCrashesCompat implements StateManager.IResettable {
private static BetterCrashesCompat INSTANCE;
public static void init() {
if (INSTANCE == null) {
INSTANCE = new BetterCrashesCompat();
}
}
public BetterCrashesCompat() {
LOGGER.info("BetterCrashesCompat initialized");
this.register();
}
@Override
public void resetState() {
LOGGER.info("Reloading SodiumRenderer");
((IRenderGlobalExt) Minecraft.getMinecraft().renderGlobal).reload();
LOGGER.info("Resetting GLStateManager");
GLStateManager.reset();
}
}
@@ -0,0 +1,102 @@
package com.gtnewhorizons.angelica.compat.lwjgl;
import org.lwjgl.BufferUtils;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class CompatMemoryUtil {
public static ByteBuffer memReallocDirect(ByteBuffer old, int capacity) {
ByteBuffer newBuf = BufferUtils.createByteBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static IntBuffer memReallocDirect(IntBuffer old, int capacity) {
IntBuffer newBuf = BufferUtils.createIntBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
public static FloatBuffer memReallocDirect(FloatBuffer old, int capacity) {
FloatBuffer newBuf = BufferUtils.createFloatBuffer(capacity);
int oldPos = old.position();
old.rewind();
newBuf.put(old);
newBuf.position(Math.min(capacity, oldPos));
return newBuf;
}
/**
* Backported from LWJGL3 under the BSD 3-Clause "New" or "Revised" License license
*
* <p>This class provides functionality for managing native memory.
*
* <p>All methods in this class will make use of {@link sun.misc.Unsafe} if it's available, for performance. If Unsafe is not available, the fallback
* implementations make use of reflection and, in the worst-case, JNI.</p>
*
* <p>Method names in this class are prefixed with {@code mem} to avoid ambiguities when used with static imports.</p>
*/
static final sun.misc.Unsafe UNSAFE;
static {
UNSAFE = getUnsafeInstance();
}
private static sun.misc.Unsafe getUnsafeInstance() {
java.lang.reflect.Field[] fields = sun.misc.Unsafe.class.getDeclaredFields();
/*
Different runtimes use different names for the Unsafe singleton,
so we cannot use .getDeclaredField and we scan instead. For example:
Oracle: theUnsafe
PERC : m_unsafe_instance
Android: THE_ONE
*/
for (java.lang.reflect.Field field : fields) {
if (!field.getType().equals(sun.misc.Unsafe.class)) {
continue;
}
int modifiers = field.getModifiers();
if (!(java.lang.reflect.Modifier.isStatic(modifiers) && java.lang.reflect.Modifier.isFinal(modifiers))) {
continue;
}
try {
field.setAccessible(true);
return (sun.misc.Unsafe)field.get(null);
} catch (Exception ignored) {
}
break;
}
throw new UnsupportedOperationException("LWJGL requires sun.misc.Unsafe to be available.");
}
public static void memPutByte(long ptr, byte value) { UNSAFE.putByte(null, ptr, value); }
public static void memPutShort(long ptr, short value) { UNSAFE.putShort(null, ptr, value); }
public static void memPutInt(long ptr, int value) { UNSAFE.putInt(null, ptr, value); }
public static void memPutLong(long ptr, long value) { UNSAFE.putLong(null, ptr, value); }
public static void memPutFloat(long ptr, float value) { UNSAFE.putFloat(null, ptr, value); }
public static void memPutDouble(long ptr, double value) { UNSAFE.putDouble(null, ptr, value); }
public static boolean memGetBoolean(long ptr) { return UNSAFE.getByte(null, ptr) != 0; }
public static byte memGetByte(long ptr) { return UNSAFE.getByte(null, ptr); }
public static short memGetShort(long ptr) { return UNSAFE.getShort(null, ptr); }
public static int memGetInt(long ptr) { return UNSAFE.getInt(null, ptr); }
public static long memGetLong(long ptr) { return UNSAFE.getLong(null, ptr); }
public static float memGetFloat(long ptr) { return UNSAFE.getFloat(null, ptr); }
public static double memGetDouble(long ptr) { return UNSAFE.getDouble(null, ptr); }
}
@@ -0,0 +1,15 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.glsm.GLStateManager;
import net.minecraft.client.renderer.texture.AbstractTexture;
import org.lwjgl.opengl.GL11;
public abstract class AutoClosableAbstractTexture extends AbstractTexture implements AutoCloseable {
@Override
public void close() throws Exception {}
// TODO: Is this needed?
public void bind() {
GLStateManager.glBindTexture(GL11.GL_TEXTURE_2D, getGlTextureId());
}
}
@@ -0,0 +1,51 @@
package com.gtnewhorizons.angelica.compat.mojang;
import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing;
import net.minecraftforge.common.util.ForgeDirection;
public enum Axis {
X,
Y,
Z;
public static Axis fromDirection(ModelQuadFacing dir) {
return switch (dir) {
case DOWN, UP -> Y;
case NORTH, SOUTH -> Z;
case WEST, EAST -> X;
case UNASSIGNED -> null;
};
}
public static Axis fromDirection(ForgeDirection dir) {
return switch (dir) {
case DOWN, UP -> Y;
case NORTH, SOUTH -> Z;
case WEST, EAST -> X;
case UNKNOWN -> null;
};
}
public static Axis fromName(String dir) {
return switch (dir) {
case "y" -> Y;
case "z" -> Z;
case "x" -> X;
default -> null;
};
}
public enum Direction {
POSITIVE,
NEGATIVE;
public static Direction fromDirection(ForgeDirection dir) {
return switch (dir) {
case DOWN, NORTH, WEST -> NEGATIVE;
case UP, SOUTH, EAST -> POSITIVE;
case UNKNOWN -> null;
};
}
}
}
@@ -0,0 +1,70 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.api.BlockPos;
import com.gtnewhorizons.angelica.api.MutableBlockPos;
import net.minecraft.world.ChunkPosition;
import net.minecraftforge.common.util.ForgeDirection;
import org.joml.Vector3i;
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongX;
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongY;
import static com.gtnewhorizons.angelica.api.BlockPos.unpackLongZ;
// Should we keep this?
public class BlockPosImpl extends Vector3i implements MutableBlockPos {
public BlockPosImpl() {
super();
}
public BlockPosImpl(int x, int y, int z) {
super(x, y, z);
}
public BlockPosImpl(ChunkPosition chunkPosition) {
super(chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ);
}
@Override
public int getX() {
return this.x;
}
@Override
public int getY() {
return this.y;
}
@Override
public int getZ() {
return this.z;
}
@Override
public BlockPosImpl offset(ForgeDirection d) {
return new BlockPosImpl(this.x + d.offsetX, this.y + d.offsetY, this.z + d.offsetZ);
}
@Override
public BlockPosImpl down() {
return offset(ForgeDirection.DOWN);
}
@Override
public BlockPosImpl up() {
return offset(ForgeDirection.UP);
}
@Override
public long asLong() {
return BlockPos.asLong(this.x, this.y, this.z);
}
@Override
public BlockPosImpl set(int x, int y, int z) {
super.set(x, y, z);
return this;
}
@Override
public BlockPosImpl set(long packedPos) {
return set(unpackLongX(packedPos), unpackLongY(packedPos), unpackLongZ(packedPos));
}
}
@@ -0,0 +1,35 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
public class ByteBufferBackedInputStream extends InputStream {
ByteBuffer buf;
public ByteBufferBackedInputStream(ByteBuffer buf) {
this.buf = buf;
}
public int read() throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
return buf.get() & 0xFF;
}
@Override
public int read(byte @NotNull [] bytes, int off, int len) throws IOException {
if (!buf.hasRemaining()) {
return -1;
}
len = Math.min(len, buf.remaining());
buf.get(bytes, off, len);
return len;
}
}
@@ -0,0 +1,42 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.gtnewhorizons.angelica.rendering.RenderingState;
import lombok.Getter;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.MathHelper;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector4f;
@Getter
public class Camera {
final Vector3d pos = new Vector3d();
final BlockPosImpl blockPos = new BlockPosImpl();
float pitch;
float yaw;
EntityLivingBase entity;
boolean thirdPerson;
final float partialTicks;
public Camera(EntityLivingBase entity, float partialTicks) {
this.partialTicks = partialTicks;
final Vector4f offset = new Vector4f(); // third person offset
final Matrix4f inverseModelView = new Matrix4f(RenderingState.INSTANCE.getModelViewMatrix()).invert();
inverseModelView.transform(offset);
final double camX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks + offset.x;
final double camY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks + offset.y;
final double camZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks + offset.z;
this.entity = entity;
pos.set(camX, camY, camZ);
blockPos.set(MathHelper.floor_double(camX), MathHelper.floor_double(camY), MathHelper.floor_double(camZ));
pitch = entity.cameraPitch;
yaw = entity.rotationYaw;
thirdPerson = Minecraft.getMinecraft().gameSettings.thirdPersonView == 1;
}
}
@@ -0,0 +1,39 @@
package com.gtnewhorizons.angelica.compat.mojang;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.BitSet;
import java.util.Set;
public class ChunkOcclusionData {
private static final int DIRECTION_COUNT = ForgeDirection.values().length;
private final BitSet visibility;
public ChunkOcclusionData() {
this.visibility = new BitSet(DIRECTION_COUNT * DIRECTION_COUNT);
}
public void addOpenEdgeFaces(Set<ForgeDirection> faces) {
for (ForgeDirection dirFrom : faces) {
for (ForgeDirection dirTo : faces) {
this.setVisibleThrough(dirFrom, dirTo, true);
}
}
for (ForgeDirection direction : faces) {
this.visibility.set(direction.ordinal() * DIRECTION_COUNT + direction.ordinal());
}
}
public void setVisibleThrough(ForgeDirection from, ForgeDirection to, boolean visible) {
this.visibility.set(from.ordinal() + to.ordinal() * DIRECTION_COUNT, visible);
this.visibility.set(to.ordinal() + from.ordinal() * DIRECTION_COUNT, visible);
}
public boolean isVisibleThrough(ForgeDirection from, ForgeDirection to) {
return this.visibility.get(from.ordinal() + to.ordinal() * DIRECTION_COUNT);
}
public void fill(boolean visible) {
this.visibility.set(0, this.visibility.size(), visible);
}
}
@@ -0,0 +1,155 @@
package com.gtnewhorizons.angelica.compat.mojang;
import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue;
import it.unimi.dsi.fastutil.ints.IntPriorityQueue;
import me.jellysquid.mods.sodium.common.util.DirectionUtil;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.Set;
/**
* WARNING: Minecraft 1.16 code rip!!
*/
public class ChunkOcclusionDataBuilder {
private static final int STEP_X = (int)Math.pow(16.0, 0.0);
private static final int STEP_Z = (int)Math.pow(16.0, 1.0);
private static final int STEP_Y = (int)Math.pow(16.0, 2.0);
private static final ForgeDirection[] DIRECTIONS = DirectionUtil.ALL_DIRECTIONS;
private final BitSet closed = new BitSet(4096);
private static final int[] EDGE_POINTS = new int[1352];
static {
int k = 0;
for(int l = 0; l < 16; ++l) {
for(int m = 0; m < 16; ++m) {
for(int n = 0; n < 16; ++n) {
if (l == 0 || l == 15 || m == 0 || m == 15 || n == 0 || n == 15) {
EDGE_POINTS[k++] = pack(l, m, n);
}
}
}
}
}
private int openCount = 4096;
public void markClosed(BlockPosImpl pos) {
this.closed.set(pack(pos), true);
--this.openCount;
}
private static int pack(BlockPosImpl pos) {
return pack(pos.getX() & 15, pos.getY() & 15, pos.getZ() & 15);
}
private static int pack(int x, int y, int z) {
return x << 0 | y << 8 | z << 4;
}
public ChunkOcclusionData build() {
final ChunkOcclusionData lv = new ChunkOcclusionData();
if (4096 - this.openCount < 256) {
lv.fill(true);
} else if (this.openCount == 0) {
lv.fill(false);
} else {
for(int i : EDGE_POINTS) {
if (!this.closed.get(i)) {
lv.addOpenEdgeFaces(this.getOpenFaces(i));
}
}
}
return lv;
}
private Set<ForgeDirection> getOpenFaces(int pos) {
final Set<ForgeDirection> set = EnumSet.noneOf(ForgeDirection.class);
final IntPriorityQueue intPriorityQueue = new IntArrayFIFOQueue();
intPriorityQueue.enqueue(pos);
this.closed.set(pos, true);
while(!intPriorityQueue.isEmpty()) {
final int j = intPriorityQueue.dequeueInt();
this.addEdgeFaces(j, set);
for(ForgeDirection lv : DIRECTIONS) {
final int k = this.offset(j, lv);
if (k >= 0 && !this.closed.get(k)) {
this.closed.set(k, true);
intPriorityQueue.enqueue(k);
}
}
}
return set;
}
private void addEdgeFaces(int pos, Set<ForgeDirection> openFaces) {
final int j = pos >> 0 & 15;
if (j == 0) {
openFaces.add(ForgeDirection.WEST);
} else if (j == 15) {
openFaces.add(ForgeDirection.EAST);
}
final int k = pos >> 8 & 15;
if (k == 0) {
openFaces.add(ForgeDirection.DOWN);
} else if (k == 15) {
openFaces.add(ForgeDirection.UP);
}
final int l = pos >> 4 & 15;
if (l == 0) {
openFaces.add(ForgeDirection.NORTH);
} else if (l == 15) {
openFaces.add(ForgeDirection.SOUTH);
}
}
private int offset(int pos, ForgeDirection arg) {
return switch (arg) {
case DOWN -> {
if ((pos >> 8 & 15) == 0) {
yield -1;
}
yield pos - STEP_Y;
}
case UP -> {
if ((pos >> 8 & 15) == 15) {
yield -1;
}
yield pos + STEP_Y;
}
case NORTH -> {
if ((pos >> 4 & 15) == 0) {
yield -1;
}
yield pos - STEP_Z;
}
case SOUTH -> {
if ((pos >> 4 & 15) == 15) {
yield -1;
}
yield pos + STEP_Z;
}
case WEST -> {
if ((pos >> 0 & 15) == 0) {
yield -1;
}
yield pos - STEP_X;
}
case EAST -> {
if ((pos >> 0 & 15) == 15) {
yield -1;
}
yield pos + STEP_X;
}
default -> -1;
};
}
}
@@ -0,0 +1,57 @@
package com.gtnewhorizons.angelica.compat.mojang;
// See if we can merge/mixin/extend ChunkCoordIntPair?
public class ChunkPos {
public static long INT_MASK = (1L << Integer.SIZE) - 1;
public final int x;
public final int z;
public ChunkPos(int x, int z) {
this.x = x;
this.z = z;
}
public ChunkPos(BlockPosImpl pos) {
this.x = pos.getX() >> 4;
this.z = pos.getZ() >> 4;
}
public ChunkPos(long pos) {
this.x = (int)pos;
this.z = (int)(pos >> 32);
}
public static int getPackedX(long pos) {
return (int)(pos & INT_MASK);
}
public static int getPackedZ(long pos) {
return (int)(pos >>> 32 & INT_MASK);
}
public long toLong() {
return toLong(this.x, this.z);
}
public static long toLong(int x, int z) {
return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
}
public int hashCode()
{
final int i = 1664525 * this.x + 1013904223;
final int j = 1664525 * (this.z ^ -559038737) + 1013904223;
return i ^ j;
}
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof ChunkPos lv) {
return this.x == lv.x && this.z == lv.z;
}
return false;
}
}
@@ -0,0 +1,88 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.joml.Vector3i;
// See if we can merge/mixin/extend ChunkPosition maybe?
public class ChunkSectionPos extends Vector3i {
public static int getSectionCoord(int coord) {
return coord >> 4;
}
public static int getBlockCoord(int sectionCoord) {
return sectionCoord << 4;
}
private ChunkSectionPos(int x, int y, int z) {
super(x, y, z);
}
public static ChunkSectionPos from(int x, int y, int z) {
return new ChunkSectionPos(x, y, z);
}
public static ChunkSectionPos from(BlockPosImpl pos) {
return new ChunkSectionPos(getSectionCoord(pos.getX()), getSectionCoord(pos.getY()), getSectionCoord(pos.getZ()));
}
public static long asLong(int x, int y, int z) {
long l = 0L;
l |= ((long)x & 4194303L) << 42;
l |= ((long)y & 1048575L) << 0;
l |= ((long)z & 4194303L) << 20;
return l;
}
public static int getLocalCoord(int coord) {
return coord & 15;
}
public static short packLocal(int x, int y, int z) {
final int i = getLocalCoord(x);
final int j = getLocalCoord(y);
final int k = getLocalCoord(z);
return (short)(i << 8 | k << 4 | j << 0);
}
public long asLong() {
return asLong(this.x, this.y, this.z);
}
public int getSectionX() {
return this.x;
}
public int getSectionY() {
return this.y;
}
public int getSectionZ() {
return this.z;
}
public int getMinX() {
return this.x << 4;
}
public int getMinY() {
return this.y << 4;
}
public int getMinZ() {
return this.z << 4;
}
public int getMaxX() {
return (this.x << 4) + 15;
}
public int getMaxY() {
return (this.y << 4) + 15;
}
public int getMaxZ() {
return (this.z << 4) + 15;
}
public ChunkPos toChunkPos() {
return new ChunkPos(this.getSectionX(), this.getSectionZ());
}
}
@@ -0,0 +1,27 @@
package com.gtnewhorizons.angelica.compat.mojang;
public class CompatMathHelper {
public static int smallestEncompassingPowerOfTwo(int value) {
int j = value - 1;
j |= j >> 1;
j |= j >> 2;
j |= j >> 4;
j |= j >> 8;
j |= j >> 16;
return j + 1;
}
public static int roundUpToMultiple(int value, int divisor) {
if (divisor == 0) {
return 0;
} else if (value == 0) {
return divisor;
} else {
if (value < 0) {
divisor *= -1;
}
int k = value % divisor;
return k == 0 ? value : value + divisor - k;
}
}
}
@@ -0,0 +1,5 @@
package com.gtnewhorizons.angelica.compat.mojang;
public class Constants {
public static final float DEGREES_TO_RADIANS = (float)Math.PI / 180.0F;
}
@@ -0,0 +1,37 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Type;
import com.gtnewhorizons.angelica.compat.mojang.VertexFormatElement.Usage;
import com.gtnewhorizons.angelica.compat.nd.writers.ItemVBOQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionColorTextureQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureColorQuadWriter;
import com.gtnewhorizons.angelica.compat.nd.writers.PositionTextureQuadWriter;
public class DefaultVertexFormat {
public static final VertexFormatElement POSITION_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.POSITION, 3);
public static final VertexFormatElement COLOR_ELEMENT = new VertexFormatElement(0, Type.UBYTE, Usage.COLOR, 4);
public static final VertexFormatElement TEXTURE_ELEMENT = new VertexFormatElement(0, Type.FLOAT, Usage.UV, 2);
public static final VertexFormatElement LIGHT_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
// TODO: The overlay element index is wrong, need to find a 1.7.10 equivalent
public static final VertexFormatElement OVERLAY_ELEMENT = new VertexFormatElement(1, Type.SHORT, Usage.UV, 2);
public static final VertexFormatElement NORMAL_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.NORMAL, 3);
public static final VertexFormatElement PADDING_ELEMENT = new VertexFormatElement(0, Type.BYTE, Usage.PADDING, 1);
public static final VertexFormat POSITION_TEXTURE_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build(), new ItemVBOQuadWriter());
public static final VertexFormat POSITION_COLOR_TEXTURE_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(OVERLAY_ELEMENT).add(LIGHT_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).build(), new PositionQuadWriter());
public static final VertexFormat POSITION_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).build());
public static final VertexFormat POSITION_COLOR_LIGHT = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionTextureQuadWriter());
public static final VertexFormat POSITION_COLOR_TEXTURE = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).build(), new PositionColorTextureQuadWriter());
public static final VertexFormat POSITION_TEXTURE_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).build(), new PositionTextureColorQuadWriter());
public static final VertexFormat POSITION_COLOR_TEX_LIGHTMAP = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(COLOR_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_LIGHT_COLOR = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(LIGHT_ELEMENT).add(COLOR_ELEMENT).build());
public static final VertexFormat POSITION_TEXTURE_COLOR_NORMAL = new VertexFormat(new ImmutableList.Builder<VertexFormatElement>().add(POSITION_ELEMENT).add(TEXTURE_ELEMENT).add(COLOR_ELEMENT).add(NORMAL_ELEMENT).add(PADDING_ELEMENT).build());
}
@@ -0,0 +1,5 @@
package com.gtnewhorizons.angelica.compat.mojang;
public interface Drawable {
default void render(int mouseX, int mouseY, float delta) {}
}
@@ -0,0 +1,29 @@
package com.gtnewhorizons.angelica.compat.mojang;
public interface Element {
default boolean mouseClicked(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseDragged(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseReleased(double mouseX, double mouseY, int button) {
return false;
}
default boolean mouseScrolled(double mouseX, double mouseY, double amount) {
return false;
}
default boolean keyTyped(char typedChar, int keyCode) { return false; }
default boolean isMouseOver(double mouseX, double mouseY) {
return false;
}
default boolean changeFocus(boolean lookForwards) {
return false;
}
}
@@ -0,0 +1,10 @@
package com.gtnewhorizons.angelica.compat.mojang;
public enum InteractionHand {
MAIN_HAND,
OFF_HAND;
InteractionHand() {
}
}
@@ -0,0 +1,121 @@
package com.gtnewhorizons.angelica.compat.mojang;
import lombok.Getter;
import net.coderbot.iris.Iris;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
// TBD
public class NativeImage extends BufferedImage {
@Getter
private final Format format;
@Getter
private final int width;
@Getter
private final int height;
@Getter
private final int size;
public NativeImage(int width, int height, boolean useStb) {
this(NativeImage.Format.RGBA, width, height, useStb);
}
public NativeImage(Format format, int width, int height, boolean useStb) {
super(width, height, BufferedImage.TYPE_INT_ARGB);
this.format = format;
this.width = width;
this.height = height;
this.size = width * height * format.components;
}
public NativeImage(Format format, int width, int height, BufferedImage image) {
super(image.getColorModel(), image.getRaster(), image.isAlphaPremultiplied(), null);
this.format = format;
this.width = width;
this.height = height;
this.size = width * height * format.components;
}
public static NativeImage read(ByteBuffer buf) throws IOException {
return read(new ByteBufferBackedInputStream(buf));
}
public static NativeImage read(InputStream inputStream) throws IOException {
BufferedImage image = ImageIO.read(inputStream);
return new NativeImage(Format.RGBA, image.getWidth(), image.getHeight(), image);
}
public void downloadTexture(int level, boolean bl) {
// this.checkAllocated();
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, format.components);
// GlStateManager._getTexImage(3553, level, format.glFormat, GL11.GL_UNSIGNED_BYTE, this.pixels);
// final int width = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_WIDTH);
// final int height = GL11.glGetTexLevelParameteri(GL11.GL_TEXTURE_2D, level, GL11.GL_TEXTURE_HEIGHT);
IntBuffer buffer = BufferUtils.createIntBuffer(size);
int[] data = new int[size];
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, level, format.glFormat, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
buffer.get(data);
setRGB(0, 0, width, height, data, 0, width);
}
public void writeToFile(File file) throws IOException{
try {
ImageIO.write(this, "png", file);
} catch(IOException ioexception) {
Iris.logger.info("[TextureDump] Unable to write: ", ioexception);
}
}
public static int combine(int i, int j, int k, int l) {
return (i & 255) << 24 | (j & 255) << 16 | (k & 255) << 8 | (l & 255);
}
public static int getA(int i) {
return i >> 24 & 255;
}
public static int getR(int i) {
return i >> 0 & 255;
}
public static int getG(int i) {
return i >> 8 & 255;
}
public static int getB(int i) {
return i >> 16 & 255;
}
public int getPixelRGBA(int x, int y) {
return getRGB(x, y);
}
public void setPixelRGBA(int x, int y, int rgb) {
setRGB(x, y, rgb);
}
public enum Format {
RGBA(4, GL11.GL_RGBA, BufferedImage.TYPE_INT_ARGB),
RGB(3, GL11.GL_RGB, BufferedImage.TYPE_INT_RGB);
private final int components;
private final int glFormat;
private final int imageType;
Format(int components, int glFormat, int imageType) {
this.components = components;
this.glFormat = glFormat;
this.imageType = imageType;
}
}
}
@@ -0,0 +1,97 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
public interface ParentElement extends Element {
List<? extends Element> children();
default Optional<Element> hoveredElement(double mouseX, double mouseY) {
for(Element element : this.children()) {
if (element.isMouseOver(mouseX, mouseY)) {
return Optional.of(element);
}
}
return Optional.empty();
}
default boolean mouseClicked(double mouseX, double mouseY, int button) {
for(Element element : this.children()) {
if (element.mouseClicked(mouseX, mouseY, button)) {
this.setFocused(element);
if (button == 0) {
this.setDragging(true);
}
return true;
}
}
return false;
}
default boolean mouseReleased(double mouseX, double mouseY, int button) {
this.setDragging(false);
return this.hoveredElement(mouseX, mouseY).filter((element) -> element.mouseReleased(mouseX, mouseY, button)).isPresent();
}
default boolean mouseDragged(double mouseX, double mouseY, int button) {
return this.getFocused() != null && this.isDragging() && button == 0 && this.getFocused().mouseDragged(mouseX, mouseY, button);
}
boolean isDragging();
void setDragging(boolean dragging);
default boolean mouseScrolled(double mouseX, double mouseY, double amount) {
return this.hoveredElement(mouseX, mouseY).filter((element) -> element.mouseScrolled(mouseX, mouseY, amount)).isPresent();
}
default boolean keyTyped(char typedChar, int keyCode) {
return this.getFocused() != null && this.getFocused().keyTyped(typedChar, keyCode);
}
@Nullable
Element getFocused();
void setFocused(@Nullable Element focused);
default boolean changeFocus(boolean lookForwards) {
final Element element = this.getFocused();
if (element != null && element.changeFocus(lookForwards)) {
return true;
} else {
final List<? extends Element> list = this.children();
final int i = list.indexOf(element);
final int j;
if (element != null && i >= 0) {
j = i + (lookForwards ? 1 : 0);
} else if (lookForwards) {
j = 0;
} else {
j = list.size();
}
final ListIterator<? extends Element> listIterator = list.listIterator(j);
final BooleanSupplier booleanSupplier = lookForwards ? listIterator::hasNext : listIterator::hasPrevious;
final Supplier<? extends Element> supplier = lookForwards ? listIterator::next : listIterator::previous;
Element element2;
do {
if (!booleanSupplier.getAsBoolean()) {
this.setFocused(null);
return false;
}
element2 = supplier.get();
} while(!element2.changeFocus(lookForwards));
this.setFocused(element2);
return true;
}
}
}
@@ -0,0 +1,82 @@
package com.gtnewhorizons.angelica.compat.mojang;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
public class VertexBuffer implements AutoCloseable {
private int id;
private int vertexCount;
private VertexFormat format;
private int drawMode;
public VertexBuffer() {
this.id = GL15.glGenBuffers();
}
public VertexBuffer(VertexFormat format, int drawMode) {
this();
this.format = format;
this.drawMode = drawMode;
}
public void bind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.id);
}
public void unbind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void upload(ByteBuffer buffer, int vertexCount) {
if (this.id == -1) return;
this.vertexCount = vertexCount;
this.bind();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
this.unbind();
}
public VertexBuffer upload(ByteBuffer buffer) {
if(format == null) throw new IllegalStateException("No format specified for VBO upload");
upload(buffer, buffer.remaining() / format.getVertexSize());
return this;
}
public void close() {
if (this.id >= 0) {
GL15.glDeleteBuffers(this.id);
this.id = -1;
}
}
public void draw(FloatBuffer floatBuffer) {
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glMultMatrix(floatBuffer);
draw();
GL11.glPopMatrix();
}
public void draw() {
GL11.glDrawArrays(drawMode, 0, this.vertexCount);
}
public void setupState() {
if(format == null) throw new IllegalStateException("No format specified for VBO setup");
bind();
format.setupBufferState(0L);
}
public void cleanupState() {
format.clearBufferState();
unbind();
}
public void render() {
setupState();
draw();
cleanupState();
}
}
@@ -0,0 +1,88 @@
package com.gtnewhorizons.angelica.compat.mojang;
import com.google.common.collect.ImmutableList;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter;
import net.coderbot.iris.block_rendering.BlockRenderingSettings;
import net.coderbot.iris.vertices.ImmediateState;
import net.coderbot.iris.vertices.IrisVertexFormats;
import java.nio.ByteBuffer;
import java.util.List;
public class VertexFormat {
@Getter
protected final ImmutableList<VertexFormatElement> elements;
protected final IntList offsets = new IntArrayList();
@Getter
protected final int vertexSize;
protected IWriteQuads quadWriter;
public VertexFormat(ImmutableList<VertexFormatElement> elements) {
this(elements, null);
}
public VertexFormat(ImmutableList<VertexFormatElement> elements, IWriteQuads quadWriter) {
this.elements = elements;
int i = 0;
for (VertexFormatElement element : elements) {
offsets.add(i);
i += element.getByteSize();
}
vertexSize = i;
this.quadWriter = quadWriter;
}
public void setupBufferState(long l) {
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
IrisVertexFormats.TERRAIN.setupBufferState(l);
return;
} else if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
IrisVertexFormats.ENTITY.setupBufferState(l);
return;
}
}
final int i = this.getVertexSize();
final List<VertexFormatElement> list = this.getElements();
final int listSize = list.size();
for(int j = 0; j < listSize; ++j) {
list.get(j).setupBufferState(l + this.offsets.getInt(j), i);
}
}
public void clearBufferState() {
if (BlockRenderingSettings.INSTANCE.shouldUseExtendedVertexFormat() && ImmediateState.renderWithExtendedVertexFormat) {
if (this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_LIGHT_NORMAL || this == DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) {
IrisVertexFormats.TERRAIN.clearBufferState();
return;
} else if ( this == DefaultVertexFormat.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
IrisVertexFormats.ENTITY.clearBufferState();
return;
}
}
final List<VertexFormatElement> list = this.getElements();
final int listSize = list.size();
for(int i = 0 ; i < listSize; ++i) {
list.get(i).clearBufferState();
}
}
public boolean canWriteQuads() {
return quadWriter != null;
}
public void writeQuad(QuadView quad, ByteBuffer byteBuffer) {
if(quadWriter == null) {
throw new IllegalStateException("No quad writer set");
}
quadWriter.writeQuad(quad, byteBuffer);
}
}
@@ -0,0 +1,107 @@
package com.gtnewhorizons.angelica.compat.mojang;
import lombok.Getter;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import java.util.function.IntConsumer;
@Getter
public class VertexFormatElement {
protected final Type type;
protected final Usage usage;
protected final int index;
protected final int count;
protected final int byteSize;
public VertexFormatElement(int index, Type type, Usage usage, int count) {
this.index = index;
this.type = type;
this.usage = usage;
this.count = count;
this.byteSize = type.getSize() * count;
}
public void setupBufferState(long offset, int stride) {
this.usage.setupBufferState(this.count, this.type.getGlType(), stride, offset, this.index);
}
public void clearBufferState() {
this.usage.clearBufferState(this.index);
}
public enum Usage {
POSITION("Position", (size, type, stride, pointer, index) -> {
GL11.glVertexPointer(size, type, stride, pointer);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
}, index -> GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY)),
NORMAL("Normal", (size, type, stride, pointer, index) -> {
GL11.glNormalPointer(type, stride, pointer);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
}, index -> GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY)),
COLOR("Vertex Color", (size, type, stride, pointer, index) -> {
GL11.glColorPointer(size, type, stride, pointer);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
}, index -> GL11.glDisableClientState(GL11.GL_COLOR_ARRAY)),
UV("UV", (size, type, stride, pointer, index) -> {
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + index);
GL11.glTexCoordPointer(size, type, stride, pointer);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}, index -> {
GL13.glClientActiveTexture(GL13.GL_TEXTURE0 + index);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL13.glClientActiveTexture(GL13.GL_TEXTURE0);
}),
PADDING("Padding", (size, type, stride, pointer, index) -> {}, index-> {}),
GENERIC("Generic", (size, type, stride, pointer, index) -> {
GL20.glEnableVertexAttribArray(index);
GL20.glVertexAttribPointer(index, size, type, false, stride, pointer);
}, GL20::glDisableVertexAttribArray);
@Getter private final String name;
private final SetupState setupState;
private final IntConsumer clearState;
Usage(String name, SetupState setupState, IntConsumer clearState) {
this.name = name;
this.setupState = setupState;
this.clearState = clearState;
}
private void setupBufferState(int size, int type, int stride, long pointer, int index) {
this.setupState.setupBufferState(size, type, stride, pointer, index);
}
public void clearBufferState(int index) {
this.clearState.accept(index);
}
interface SetupState {
void setupBufferState(int size, int type, int stride, long pointer, int index);
}
}
@Getter
public enum Type {
FLOAT(4, "Float", GL11.GL_FLOAT),
UBYTE(1, "Unsigned Byte", GL11.GL_UNSIGNED_BYTE),
BYTE(1, "Byte", GL11.GL_BYTE),
USHORT(2, "Unsigned Short", GL11.GL_UNSIGNED_SHORT),
SHORT(2, "Short", GL11.GL_SHORT),
UINT(4, "Unsigned Int", GL11.GL_UNSIGNED_INT),
INT(4, "Int", GL11.GL_INT);
private final int size;
private final String name;
private final int glType;
Type(int size, String name, int glType) {
this.size = size;
this.name = name;
this.glType = glType;
}
}
}
@@ -0,0 +1,63 @@
package com.gtnewhorizons.angelica.compat.nd;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
public class BufferWriter {
// Adapted from Neodymium
private final ByteBuffer buf;
private final FloatBuffer floatBuffer;
private final ShortBuffer shortBuffer;
private final IntBuffer intBuffer;
public BufferWriter(ByteBuffer buf) {
this.buf = buf;
this.floatBuffer = buf.asFloatBuffer();
this.shortBuffer = buf.asShortBuffer();
this.intBuffer = buf.asIntBuffer();
}
private void incrementPosition(int add) {
buf.position(buf.position() + add);
floatBuffer.position(buf.position() / 4);
shortBuffer.position(buf.position() / 2);
intBuffer.position(buf.position() / 4);
}
public void writeFloat(float x) {
try {
floatBuffer.put(x);
incrementPosition(4);
} catch(Exception e){
e.printStackTrace();
}
}
public void writeInt(int x) {
intBuffer.put(x);
incrementPosition(4);
}
public void writeByte(byte x) {
buf.put(x); // this increments the buffer position by 1
incrementPosition(0);
}
public int position() {
return buf.position();
}
public void writeShort(short s) {
shortBuffer.put(s);
incrementPosition(2);
}
}
@@ -0,0 +1,9 @@
package com.gtnewhorizons.angelica.compat.nd;
import com.gtnewhorizons.angelica.api.QuadView;
import java.nio.ByteBuffer;
public interface IWriteQuads {
void writeQuad(QuadView quad, ByteBuffer buf);
}
@@ -0,0 +1,47 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import java.nio.ByteBuffer;
public class ItemVBOQuadWriter implements IWriteQuads {
private boolean direct;
public ItemVBOQuadWriter() {
init(false);
}
public void init(boolean direct) {
// This would need to be re-initialized if the direct vs indirect changes
this.direct = direct;
}
@Override
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
writeQuadIndirect(quad, buf);
}
}
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
buf.putFloat(quad.getY(idx));
buf.putFloat(quad.getZ(idx));
// Texture
buf.putFloat(quad.getTexU(idx));
buf.putFloat(quad.getTexV(idx));
// Normals + Padding
buf.putInt(quad.getNormal(idx));
}
}
}
@@ -0,0 +1,47 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import java.nio.ByteBuffer;
public class PositionColorTextureQuadWriter implements IWriteQuads {
private boolean direct;
public PositionColorTextureQuadWriter() {
init(false);
}
public void init(boolean direct) {
// This would need to be re-initialized if the direct vs indirect changes
this.direct = direct;
}
@Override
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
writeQuadIndirect(quad, buf);
}
}
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
buf.putFloat(quad.getY(idx));
buf.putFloat(quad.getZ(idx));
// Color
buf.putInt(quad.getColor(idx));
// Texture
buf.putFloat(quad.getTexU(idx));
buf.putFloat(quad.getTexV(idx));
}
}
}
@@ -0,0 +1,40 @@
package com.gtnewhorizons.angelica.compat.nd.writers;
import com.gtnewhorizons.angelica.api.QuadView;
import com.gtnewhorizons.angelica.compat.nd.IWriteQuads;
import java.nio.ByteBuffer;
public class PositionQuadWriter implements IWriteQuads {
private boolean direct;
public PositionQuadWriter() {
init(false);
}
public void init(boolean direct) {
// This would need to be re-initialized if the direct vs indirect changes
this.direct = direct;
}
@Override
public void writeQuad(QuadView quad, ByteBuffer buf) {
if(direct) {
writeQuadDirect(quad, buf);
} else {
writeQuadIndirect(quad, buf);
}
}
protected void writeQuadDirect(QuadView quad, ByteBuffer buf) {
throw new UnsupportedOperationException("Direct mode not supported yet");
}
protected void writeQuadIndirect(QuadView quad, ByteBuffer buf) {
for(int idx = 0; idx < 4; ++idx) {
// Position
buf.putFloat(quad.getX(idx));
buf.putFloat(quad.getY(idx));
buf.putFloat(quad.getZ(idx));
}
}
}
Loaded 100 of 1340 files, more files were not shown because too many files have changed in this diff. Show more