Compare commits

...
Author SHA1 Message Date
Alug b59a54c61b change version string lul 2025-05-21 10:37:20 +02:00
Alug 42011f23b4 fix type mismatch for netUpdateFudge 2025-05-20 21:59:29 +02:00
Alug 7e6d31627e make savestate bit bigger lel 2025-05-20 21:58:11 +02:00
Alug a39ab80a77 no need to save those 2025-05-20 21:53:34 +02:00
Alug 18adf0ab32 oop 2025-05-20 21:36:57 +02:00
Alug 3ebfb353e1 more stuff 2025-05-20 21:34:22 +02:00
Alug 7769b0e0eb Revert "store last ticcmd in a buffer"
This reverts commit 9474142aca.
2025-05-20 21:18:48 +02:00
Alug b549aa6f53 this breaks horribly 2025-05-20 20:45:13 +02:00
Alug bd4103a2ed fix sound? 2025-05-20 20:42:32 +02:00
Alug 2e07f0be92 delet unused cvars 2025-05-20 20:41:26 +02:00
Alug 87eddd70af Merge remote-tracking branch 'origin/netshit3' into netshit3 2025-05-20 20:34:56 +02:00
Alug 7034bc6fb3 fix some hashtable warnings 2025-05-20 20:34:48 +02:00
indev 28cfdf8c23 Fix hud not ticking even outside of netplus simulations 2025-05-20 21:28:00 +03:00
Alug 00f24b8841 add P_SPMAngle hack 2025-05-20 20:25:08 +02:00
indev 8b706be4ba Port con_muted 2025-05-20 21:18:46 +03:00
Alug eb5d271dc4 this too 2025-05-20 20:20:37 +02:00
Alug fe107331fe delet this 2025-05-20 20:17:40 +02:00
Alug 51bac6418f clean up p_saveg 2025-05-20 20:13:25 +02:00
Alug 598344fb62 ok just dont touch the lua archive ig? 2025-05-20 19:05:43 +02:00
Alug c1690cc3a0 more shit 2025-05-20 19:02:40 +02:00
Alug d6ea4109ec make this actually do smth lel 2025-05-20 18:59:32 +02:00
Alug 9f634046e5 add hashtable shit 2025-05-20 18:53:45 +02:00
Alug 50af7630e9 smol fixes ig 2025-05-20 18:30:19 +02:00
Alug b30ff1db0e make this "work" 2025-05-20 18:00:56 +02:00
Alug a18662ebce we dont need to allocate a savebuffer, we just use the savestate one 2025-05-20 17:32:02 +02:00
Alug 3cd6fe4e34 tic_frequency 2025-05-20 16:14:50 +02:00
Alug 0b9ac05fbe netplus more like netminus
this is such a mess holy fuck
2025-05-20 15:52:05 +02:00
Alug 7b7028be6a we may fixed the double free, but now we fix the ghost hitlist also crashing 2025-05-19 20:00:54 +02:00
Alug 6f8e28bda8 setting gamestate attempts to 0 should disable saturn resynch and setting resynchattempts to 0 should disable vanilla resynch 2025-05-19 16:27:35 +02:00
Alug 11938e343b oop this was always true effectively 2025-05-19 15:59:50 +02:00
Alug 471d7981c4 Merge remote-tracking branch 'origin/votebgscaling' into lugstuff 2025-05-19 15:59:46 +02:00
Alug a729279224 try fixing some crash with bogus netxcmds 2025-05-19 15:59:41 +02:00
Alug c0f7780709 readd player var to lib_pDoSuperTransformation
otherwise this may desynch?
2025-05-19 15:48:20 +02:00
Alug 38cbdac05a lugstuff thing 2025-05-19 15:26:43 +02:00
Alug 128da9b687 even more random cleanup 2 2025-05-19 15:26:19 +02:00
Alug 5bf5172310 delet old tools
they dont work anymore anyways
2025-05-19 00:22:00 +02:00
Alug f422a81d46 delet dummy 2025-05-19 00:21:43 +02:00
Alug 6b0e55d42f random cleanups
note: 2d camera didnt work anyways
2025-05-18 16:44:09 +02:00
Alug 38ce112e5c stoopid gaame 2025-05-17 14:51:24 +02:00
Alug d9c7f55270 pressing the freecam toggle while spectator now moves your camera to startposition
just to quick and easy return to the map if youre really far off
2025-05-17 13:56:09 +02:00
Alug 2b03311fe9 make this switch slighty prettier 2025-05-17 03:47:14 +02:00
Alug 361621a46a fix 3d models rollangle on gravflip
idk if this is correct, but it works lel
2025-05-17 03:47:01 +02:00
Alug d8f75f5cf4 make ogl screenflip stuff directly assignable
those dont need to be seperate bools lel
also simplify the assignment aswell
2025-05-17 03:46:41 +02:00
Alug 36349c2770 ok even more cleanup for animvote check 2025-05-16 14:22:03 +02:00
Alug 2c0d131cab even more tiny cleanup votebg stuff 2025-05-16 14:15:19 +02:00
Alug 9feda4d22d Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-16 13:42:46 +02:00
indev 03264e760f Allow music credit to be drawn in intermission and main menu 2025-05-16 13:36:05 +03:00
Alug 224e3b25e5 Revert "those appear to do nothing"
This reverts commit 5f40ff5a03.
2025-05-16 01:30:28 +02:00
Alug fa20199ead Revert "those appear to do nothing"
This reverts commit 5f40ff5a03.
2025-05-16 01:30:19 +02:00
Alug 03c624a77b make addon warning not print "(null)" if there is no refreshdirname
kinda lazy way but shrug
2025-05-15 21:41:05 +02:00
Alug 1ed76de58a macrofy redundant splitscreen menus
joystick and camera menus to be specific
2025-05-15 21:41:00 +02:00
Alug 36566091aa make addon warning not print "(null)" if there is no refreshdirname
kinda lazy way but shrug
2025-05-15 21:40:48 +02:00
Alug 1a1466ec67 macrofy redundant splitscreen menus
joystick and camera menus to be specific
2025-05-15 04:12:40 +02:00
Alug 5f40ff5a03 those appear to do nothing
free performance ig?
2025-05-15 01:26:57 +02:00
Alug b1baa90b19 move paletterender walllight stuff into HWR_CalcWallLight
just slightly cleaner
2025-05-15 01:26:36 +02:00
Alug f0579de244 HWR_UsePortals 2025-05-15 01:26:33 +02:00
Alug 044836b026 change gamepad powerup led behavior
it will instead always take the players mobj color, this makes it indirectly support things like acrobatics and the colourized banana snipe
also just makes it a value for cv_gamepadled instead of its own cvar
2025-05-15 01:26:27 +02:00
Alug 268bce79bd move paletterender walllight stuff into HWR_CalcWallLight
just slightly cleaner
2025-05-15 01:26:04 +02:00
Alug 19c1d2438e HWR_UsePortals 2025-05-15 01:24:36 +02:00
Alug 2dcb35da21 those appear to do nothing
free performance ig?
2025-05-15 01:23:44 +02:00
Alug 7747af9e9f change gamepad powerup led behavior
it will instead always take the players mobj color, this makes it indirectly support things like acrobatics and the colourized banana snipe
also just makes it a value for cv_gamepadled instead of its own cvar
2025-05-14 19:28:06 +02:00
Alug c2a761c895 delet some clutter in screen.c 2025-05-14 16:37:04 +02:00
Alug 6bdd2b2397 delet some clutter in screen.c 2025-05-14 16:35:36 +02:00
Alug e95db0c7e8 fix copy paste error oops 2025-05-14 16:09:59 +02:00
Alug efcd8dacfe make votebg scaling behaviour changable 2025-05-14 16:06:15 +02:00
Alug 06124deab9 make an adaptive votescreen patch scaler
attempts to first fill the screen horizontally, if the screen is not filled vertically like that, it will then change the scaling to fill the screen vertically
like this effectively every votebg fills up the screen and accomidates most bgs that added padding for the weird vanilla behaviour
TODO: make the behaviour switchable
2025-05-14 15:51:41 +02:00
Alug 0f0195d35b Make votescreen backgrounds resolution and dup independant
also some slight cleanup
currently this scales vertically to fill out the screen vertically
not sure if horizontally would be preferred, but thatd most likely cut off alot of parts from some votebgs
2025-05-14 02:09:32 +02:00
Alug 0695806ee9 dont allow changing grid sorting with item if item button is also enter 2025-05-13 22:38:03 +02:00
Alug a1c34cab1a Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-13 05:33:19 +02:00
Alug 0fa702c471 disable this 2025-05-13 04:56:15 +02:00
Alug 70f41cf221 clamp screentexture size to maximum supported texture resolution
also moves everything into GL_SetModelView again
also means screen texture sizes wont be recalculated every frame anymore
2025-05-13 04:07:48 +02:00
Alug 78547ba931 fix replay saving during intermission with manual save 2025-05-12 06:12:11 +02:00
Alug 49de45d736 fix minimap angle display in encoremode 2025-05-11 18:47:19 +02:00
Alug 7085ac3392 fix smol oopsie for colourized speedlines 2025-05-11 17:40:17 +02:00
Alug fce86135c0 fix oob write when map has playerstarts for 32 players
playerstarts is MAXPLAYERS big, which is 16 for us
2025-05-11 17:12:00 +02:00
Alug d9052fff97 add "nofork" parameter
to disable process forking
might be useful for gdb and perf
2025-05-11 17:11:51 +02:00
Alug 03fff05f6c change colourized speeline behaviour slightly
"driftonly" will tone the lines completely instead of alternating between blue and driftcharge
"normal" will completely colourize speedlines in the player colour
2025-05-11 17:11:47 +02:00
Gustaf Alhäll 1a91adc5c1 Fix off-by-one buffer overflow when getting LUT 255 2025-05-11 17:11:21 +02:00
Alug f626e9e06b fix 3d models tanking performance to hell 2025-05-11 01:22:44 +02:00
Alug 983974821c make this check like vanilla did 2025-05-11 00:33:39 +02:00
Alug f4af9fd394 unlock everything when using modkartdata save
doesent make too much sense having to unlock everything again when playing mods
2025-05-10 23:42:53 +02:00
Alug b34dd7745b delet the discord stuff
was abandoned anyways
2025-05-10 22:04:42 +02:00
Alug 2728fbdd46 delet this 2025-05-10 21:59:05 +02:00
Alug 6bfb448de1 dont check for how many controllers just attempt to reset "all"
JoyInfo->dev will be null
The crash before was most likely due to an oob read
2025-05-10 21:37:16 +02:00
Alug b8839896c6 fix saturn menu 2025-05-10 19:17:39 +02:00
Alug df66651356 fix typo in rumble reset 2025-05-10 18:59:27 +02:00
Alug 6653b5ab6c Revert "skinlocal deez nuts"
This reverts commit 12ec3d11a2.
2025-05-10 18:56:24 +02:00
Alug 7373ebe0b2 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-10 16:39:14 +02:00
Alug 5ac2dc29b1 delet netticbuffer hax 2025-05-09 16:46:58 +02:00
Alug 8bed3915e4 kill this kill this with fire 2025-05-09 16:27:38 +02:00
Alug 296cec0b0c Fix controls getting stuck when opening the pause menu
https://git.srb2.org/Hanicef/SRB2Classic/-/commit/ed53d96430dedac42b288bd6a5ca8152e6e6acc4
2025-05-09 15:07:49 +02:00
Alug 8a93a79fc7 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-09 01:50:06 +02:00
Alug 0df7c2a1e2 cleanup dpad scroll stuff even more
mostly just to make this more readable
2025-05-08 10:24:03 +02:00
Alug 5d2ea9d7a3 tiny cleanup p_enemy 2025-05-07 20:51:40 +02:00
Alug bd653785c2 dont keepmusic music that is not flagged as keep on death
uuuuuggggghhhhhhhhhhhh
2025-05-06 22:06:33 +02:00
Alug e7b9a28d70 fix music fade crash fix breaking music fades on very new sdl2 versions
man
2025-05-06 21:50:34 +02:00
Alug e4aab9128e dont have acp1 anymore 2025-05-06 19:40:22 +02:00
Alug a69e03310e Revert "optimize MT_TUBEWAYPOINT"
This reverts commit 3d0ac03f06.
2025-05-06 19:35:10 +02:00
Alug eb9fdf1fdc dont free item patches at levelload lol 2025-05-06 17:37:48 +02:00
Alug 63ca42d12c Merge remote-tracking branch 'origin/lugstuff' into lugstuff 2025-05-06 17:08:41 +02:00
Alug a502633f76 call M_ClearMenus in D_StartTitle 2025-05-06 17:08:24 +02:00
Alug 23b194eaa8 why is this still here?? 2025-05-06 12:26:46 +01:00
Alug ce92b30119 fix 32bit windoze compile
everything needs time.h idk why it never errored out before lol
2025-05-06 12:24:13 +01:00
Alug 2adffd32ea test: try prevent synch issues when p_setscale gets called on mobj spawn 2025-05-05 20:30:34 +02:00
Alug 94a5c1fe31 fix the fast pointonsides 2025-05-05 12:50:14 +02:00
Alug 33c9184fed Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-05 12:49:30 +02:00
Alug 7d12ceae74 attempt to cleanup p_mobj a little 2025-05-04 02:49:57 +02:00
Alug 12ec3d11a2 skinlocal deez nuts 2025-05-04 01:35:35 +02:00
Alug b1c94a0885 remove redundant mobj null checks
P_MobjWasRemoved already checks this anyways
2025-05-04 00:52:25 +02:00
Alug 3614867f30 compeltely forgor about this one lel
was here before we had blendmodes
2025-05-04 00:51:10 +02:00
Alug ae19383ee0 simplify this slightly 2025-05-04 00:47:11 +02:00
Alug 75e367372c print previously supressed warnings into log instead of console 2025-05-03 23:16:16 +02:00
Alug 620f5a40d4 dont mindelay when record attacking
theres a few places that do not "lag compensate" at all in RA so this would completely mess things up
2025-05-03 23:10:34 +02:00
Alug a834bc6c05 smol cleanup m_perfstats 2025-05-03 20:44:38 +02:00
Alug 80b35cdefb properly fix mobj action stuff for c23
thx hanicef!
hope i didnt screw anything up in info.c
2025-05-03 20:27:08 +02:00
Alug 196501ae66 fix windoze boolean 2025-05-03 18:56:35 +02:00
Alug 76503edfeb add USELTO and USEASAN make flags
to compile with LTO or Address sanitizer
2025-05-03 17:21:31 +02:00
Alug b1d8930b5a FIXUP make code c24 compliant
this needs to be tested on other platforms
2025-05-02 12:50:41 +02:00
Alug 0ae6f8fa16 forgor casting this 2025-05-02 11:12:04 +02:00
Alug 9ce917feee let squishy speed be player choosable
idk why i just didnt do that lel
also adds stuff to the menus
2025-05-02 10:53:36 +02:00
Alug 7becd7a3d2 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-02 10:36:29 +02:00
Alug acbcdedfa0 fix conlict 2025-05-02 10:29:25 +02:00
Alug 0ab8fa25e2 that needs to come before old_ stuff gets reset 2025-05-02 10:22:58 +02:00
Alug f5b96eead2 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-05-02 10:21:19 +02:00
Alug fcdceb53d7 force c17 with gcc 15 for now
dont feel like porting stuff over to c24 or whatever for v8 so just force c17 so ppl can still compile
2025-05-01 00:33:05 +02:00
indev 2ddb1ab56c Attempt to fix game freezing on windows when moving game window 2025-05-01 00:33:02 +02:00
Alug 0ab0ced3d3 tiny more cleanup screencoord stuff 2025-04-30 14:55:53 +02:00
Alug 47dcf7d1a8 delet this 2025-04-29 22:18:09 +02:00
Alug 51f2dd6275 merge stuff from next 2025-04-29 21:54:38 +02:00
Alug 0b077a9a8d raise cmake minimum requiered to 3.5 2025-04-29 21:13:35 +02:00
Alug 5ab1a65bab delet old high color software stuff 2025-04-29 21:13:31 +02:00
Alug 1d7851d32f add ogl wireframe mode lul
might be useful for some stuff
can finally see the war crimes done by the renderer
2025-04-29 10:13:19 +02:00
Alug 489b4157d2 tiny more cleanup speedometer stuffs
put check for color speedo into a function
and precalc the xtra 3 scale
2025-04-28 17:47:22 +02:00
Alug 2d8d14dcc5 move doaddline block
slightly better branching since maps with portals are very uncommon in kart
2025-04-28 11:29:35 +02:00
Alug 1c8a0006f0 skip rechecking for horizonlines when reloading gamestate
map remains the same during desynch, so safe some time
2025-04-28 11:19:47 +02:00
Alug c722523d40 another tiny cleanup p_setup and p_saveg 2025-04-28 09:55:10 +02:00
Alug b8434e0d1e fix replay ghost double free
kinda rare, but may happen when you resynch on the exact same time you got hit by something
2025-04-27 13:14:52 +02:00
Alug 3ff9a75a8f delet tic resending stuff 2025-04-27 06:50:35 +02:00
Alug e2944412b4 change ticqueue system to be more like srb 2.2
mostly just renaming lel
2025-04-27 06:47:26 +02:00
Alug e7ff735e93 tiny optimization
we dont need to recalc the bpm stuff
we can also divide the bounce in half just once
2025-04-27 00:57:43 +02:00
Alug da0b714c92 make a struct for squishy
this is horrid but should fix this speeding up when multiple players squish
2025-04-27 00:24:52 +02:00
Alug 37146b4c3d no thx i will use memcpy
lel
2025-04-25 21:34:21 +02:00
Alug b56a7bd4ba add a few more branching hints
also fix some indentation
2025-04-25 21:34:02 +02:00
Alug 1c52de67d5 invert skywall offset
also fixes the issue, but doesent draw skywalls over actual walls in rare cases
lets hope this doesent draw walls over actual skywalls now (:
2025-04-25 21:33:08 +02:00
Alug e42e029d61 whitespace crap 2025-04-25 15:02:36 +02:00
indev 6db017ff1a Don't free PU_SPRITE memory, since it invalidates some lua patches if they are using sprite frames 2025-04-25 11:47:15 +02:00
Alug b5a5c7d4f2 take mobjscale into account when skipping small sectors for precip spawn 2025-04-24 13:11:09 +02:00
Alug d79c59f6f3 put precip purge into a function
to reduce code dupe and branching
2025-04-24 13:02:26 +02:00
Alug 40a7c08851 fix spectator key lel
oopsie
2025-04-24 09:42:01 +02:00
Alug 07c090d40d oops didnt think addskins would be used here lel 2025-04-24 09:21:11 +02:00
Alug 9bc010f670 attempt at cleaning up gamecontrol splitscreen shit 2025-04-24 09:13:14 +02:00
Alug 11f7ecba5f cleanup G_Responder
man
2025-04-24 08:58:05 +02:00
Alug 6d458f2960 memset those 2025-04-24 08:27:11 +02:00
Alug aad83a3a9b fix potential crash on startup
thx hanicef
2025-04-24 06:56:57 +02:00
Alug d1ba4c61d7 deprecate "addskins" command
"addskins" is an incredibly ambigous name since its main purpose was to add skins LOCALLY
just prints a notice for now since there may be ppl that still use it
2025-04-24 06:56:35 +02:00
Alug f255374a9d skip checking skin array if localskin was found in localskin array 2025-04-24 06:54:22 +02:00
Alug 635481ea90 just mark it like this 2025-04-24 06:46:41 +02:00
Alug 290deef444 missed removing this 2025-04-24 06:42:50 +02:00
indev baefb4d0b0 Remove I_Assert in GetItemId in lua_hudlib_drawlist.c
It is legal for lua_getpc to be null (thanks GenericHeroGuy for investigating!)
2025-04-23 19:54:22 +02:00
Alug 0ce8c55ab3 check ceiling first in encore flat precaching
no clue why but this fixes the sides of the road on ORR not being encore remapped
2025-04-23 19:54:17 +02:00
Alug e064e4d13d port RRs improved paranoia thinker/mobj prints
https://git.srb2.org/KartKrew/RingRacers/-/commit/509a023329ea1cd583c500a3287c488e5ee3e3a6
https://git.srb2.org/KartKrew/RingRacers/-/commit/17aaf178d587970a3a845aa6c2f3807077996a77
2025-04-23 16:01:27 +02:00
Alug bb26a33889 fix P_RemoveSavegameMobj triggering assert in P_UnlinkThinker 2025-04-23 13:45:47 +02:00
Alug 4c15826848 nooo PARANOIA dont set our thinker next pointer to NULL 2025-04-23 13:21:10 +02:00
Alug 91301ffdcb we have a global to check if config was loaded 2025-04-23 13:10:07 +02:00
Alug baed5fb5de fix cv_set being called for allowsaturnjoin before its registered 2025-04-23 13:09:03 +02:00
Alug 31122a6f34 add P_DivlineCrossedFast
to take more advantage of P_DivlineSideFast
2025-04-23 11:39:54 +02:00
Alug 95ac0796f8 lugstuff needs this 2025-04-23 11:39:27 +02:00
Alug df33fbcdd7 delet bunch of stuff 2025-04-23 11:30:21 +02:00
Alug ac7e298c42 try to fix skywalls zfighting
just apply a small polygonoffset to them
lets hope this is small enough so they dont end up rendering infront of actual textures and such
2025-04-23 00:17:31 +02:00
Alug 9fd20af939 reset palette cvars when toggling paletterendering
everything gets wiped anyways, so this would be just confusing
2025-04-22 22:10:49 +02:00
Alug 8960804f1c fix cloud tops palette not applying 2025-04-22 21:52:46 +02:00
Alug 6437c5a861 smol cleanup z_zone 2025-04-22 20:13:28 +02:00
indev 600e824c63 Don't resume music when game is paused (happens when you pause -> lose window focus -> regain window focus) 2025-04-22 19:26:30 +02:00
Alug 5977574270 simplify cmpack 2025-04-22 19:23:16 +02:00
Alug 1234511304 let saltyhop work without gravstretch 2025-04-22 09:27:40 +02:00
Alug 7784bc6d0d remove Z_ChangeTag hack
needs some testing
but patches have their own purgetag now
2025-04-22 09:27:07 +02:00
Alug 638b3757c8 move playeringame to player struct
credits hanicef for that idea
2025-04-22 09:26:27 +02:00
Alug 9474142aca store last ticcmd in a buffer
https://git.do.srb2.org/Hanicef/SRB2Classic/-/commit/fe663f799e733e9a59a95dfd561e506571838554
2025-04-22 09:21:33 +02:00
Alug cf391fb346 add cv_palette and cv_palettenum
so palettes can be changed midgame
note: subpalettes do not work properly in opengl with paletterendering disabled, so palettenum will NOT work there
2025-04-22 02:52:48 +02:00
Alug 9e684cded1 only check for votescreen replacements if we havent already replaced everything 2025-04-21 14:16:18 +02:00
Alug b642bfb984 add some savety to the hudlib
just error instead of crashing so we can track down any issues more easily
2025-04-21 14:15:35 +02:00
Alug 31e76f8b5f dont free our hud patches when loading an addon lel
appears to work fine in RR so we do it here
fixes some weird issues and crashes with certain hud elements
2025-04-21 14:12:42 +02:00
Alug 2e35a72dec cleanup colormap translation stuff
needs testing
2025-04-21 12:29:31 +02:00
Alug 0d4ad260f0 fix nohw compile lugstuff 2025-04-21 12:21:58 +02:00
Alug 1e66305ce8 add missing pglDisableClientState 2025-04-21 12:21:12 +02:00
Gustaf Alhäll b7a5d715c0 Fix use-after-free when loading addons after searching addons 2025-04-21 12:21:09 +02:00
Alug 20537807e1 Fix server listing refusing to list servers on resolution failure 2025-04-21 12:21:06 +02:00
Alug e63c6cfd1e replace instances of malloc + memset with calloc 2025-04-21 09:53:02 +02:00
Alug ed527a35e2 add mindelay and gentlemens stuff to menu 2025-04-20 23:34:59 +02:00
Alug 3a82442c86 remove lagless camera from the menu
and change cvar name to reset it for everyone
2025-04-20 23:19:15 +02:00
Alug 98dde2f077 Revert "remove erronous checks here"
This reverts commit c2c60f2c69.
2025-04-20 23:00:07 +02:00
Alug 9322a3b1d0 dont let postload make our waitingplayer spritepatches null 2025-04-20 22:59:55 +02:00
Alug 0f0bef2a04 big cleanup "GetZAt" stuff
GetZAt now takes 4 parameters (slope, x, y, normalheight)
and everything now uses their designated getzatfunction
2025-04-20 15:43:17 +02:00
Alug b13f104fde fix P_CameraLineOpening
lel this was always botched
2025-04-20 15:21:39 +02:00
Alug e9d91386d7 remove unecessary settransform call 2025-04-20 06:25:21 +02:00
Alug c2c60f2c69 remove erronous checks here 2025-04-20 06:25:06 +02:00
Alug 836395a6af check for sloperoll first 2025-04-20 06:23:36 +02:00
Alug a7094537cb dont need this anymore 2025-04-20 06:22:58 +02:00
Alug d02a097384 pass hardware patch to HWR_DrawSpriteShadow 2025-04-20 06:22:41 +02:00
Alug a34540f27f unnest timedemo stop stuff 2025-04-19 10:28:04 +02:00
Alug 454311fd28 fix titlescreen demos crashing, again 2025-04-19 10:27:51 +02:00
Alug a260c390ad whoop this is only used by curl 2025-04-19 08:13:07 +02:00
Alug 4de86a1bad cleanup http download stuff a little
unglobalise a bunch of stuffand put into a struct
also hopefully made the progressbar less funky
2025-04-19 08:10:09 +02:00
Alug 59b1d66c39 a 2025-04-19 01:25:37 +02:00
Alug b5521eb709 fix software sprite clipping 2025-04-19 01:19:23 +02:00
Alug 72f193f336 smol software stuffs 2025-04-19 01:06:39 +02:00
Alug 751c72f93c smol fix for R_AddSingleSpriteDef 2025-04-18 23:54:01 +02:00
Alug 5d77754695 fix hwrpatch grabbing the wrong patch
getmapped patch needs to be called before this is referenced to avoid potential issues
2025-04-18 22:03:55 +02:00
Alug e9b2e17b69 readd missing SHORT macro for patch_create 2025-04-18 21:59:24 +02:00
Alug c40d9f3ec4 make a backup of save data before writing to it 2025-04-18 12:52:24 +02:00
Alug 14d2a6f7b6 reword this lel 2025-04-18 12:35:09 +02:00
Alug 65c8bcf3bd reset record attack state in G_ResetDemoPlayback
should fix some wonky issues in a few cases
2025-04-18 11:29:42 +02:00
Alug d7fe799097 fix record attack condition in G_CheckDemoStatus 2025-04-18 11:20:58 +02:00
Alug 52a6812805 reset demo stuff for multiplayer demos when using connect command
so if smth happens and we cannot connect the game wont be stuck in some weird replay limbo state
2025-04-18 11:20:17 +02:00
Alug 96312999c0 fix crash when using connect command from within replays 2025-04-18 11:11:36 +02:00
Alug 3fe45c532d close menus when replay stops 2025-04-18 10:09:42 +02:00
Alug a7ff925038 add mobj null checks
well and remove one
2025-04-18 09:38:44 +02:00
Alug 1d4d1a1400 psure this never worked lel 2025-04-18 09:38:21 +02:00
Alug 4ec735afe1 more unnesting for mobj think stuff 2025-04-18 09:37:25 +02:00
Alug 05086d83f0 Revert "convert fixed to float with multiplication instead of division"
i did not intend to push this to testing lel
2025-04-17 21:49:45 +02:00
Alug 965411519c we dont use MT_WAYPOINT lel
just use starposts
also remove rings cause duh
2025-04-17 14:00:55 +02:00
Alug d328adea5d aaaa != 2025-04-17 13:50:26 +02:00
Alug fb804ea9dd those do not exist anymore lel 2025-04-17 13:48:38 +02:00
Alug 7df37d50f4 fix up the automap again
got the rest of stuff working in a horrible way
automap aswell as minigen stuff looks good now
2025-04-17 13:48:24 +02:00
Alug c36b076b01 fix oopsie in automap bounds calc 2025-04-17 13:32:37 +02:00
Alug ee3a26d8fb fix automap colours
forgor those revert those when i ported RR code over, now they should match up with what they say
2025-04-17 13:30:41 +02:00
Alug 6f86ef2896 why? 2025-04-16 23:21:33 +02:00
Alug ead9e96017 why are these even seperated like that lel 2025-04-16 22:37:22 +02:00
Alug 2b5b7c6292 fix camera vertical look tooltip for green res
Zzz...
2025-04-16 22:31:24 +02:00
Alug 1ee40b5579 add minimap icon dot to saturn hud menu 2025-04-16 22:31:08 +02:00
Alug cc6cb99ac5 add support for drawing a dot on the minimap showing player angle
mostly copy pasted from blankart so thx neppy c:
2025-04-16 22:02:44 +02:00
Alug d9babadd54 fix minimap disappearing when having minimap trans on 10 2025-04-16 21:28:44 +02:00
Alug 14f725a53f fix compile without ROTSPRITE 2025-04-16 20:27:53 +02:00
Alug dc465733c7 move patch rotation stuff into their own files 2025-04-16 20:25:33 +02:00
Alug 58e12d620f just use Z_SetUser
instead of duplicating what RotatedPatch_Create does lul
2025-04-16 19:19:38 +02:00
Alug 0ef5a80d84 turn rotcache into a lumpcache_t
gu hope this is correct lel
2025-04-16 19:06:46 +02:00
Alug 4587f6391a smol cleanup W_CachePatchNumPwad 2025-04-16 18:46:55 +02:00
Alug 280df5d3d6 fix the sprite shadows Zzz... 2025-04-16 16:38:35 +02:00
Alug 9cd8d2fb4e GL_ 2025-04-16 16:27:00 +02:00
Alug f384cf0b86 optimize this a little lel 2025-04-16 16:21:50 +02:00
Alug d1d61119ae smol opitmizations and cleanup 2025-04-16 02:46:40 +02:00
Alug 96eecfe5a0 fix model blendpatches
we already have a functional check in HWR_GetBlendedTexture anyways
2025-04-15 20:27:21 +02:00
Alug e0b58b4da0 add tags for model textures 2025-04-15 19:23:53 +02:00
Alug 021db03eb9 no asan ty 2025-04-15 19:16:42 +02:00
Alug 854ce92d83 Merge branch 'balls' into lugstuff 2025-04-15 19:14:37 +02:00
Alug 0bef27cdf9 fix models lel 2025-04-15 19:14:20 +02:00
Alug 2037420013 dont free our rotsprites aa 2025-04-15 18:37:33 +02:00
Alug 01c3205d5d readd freeing those
dont want kart to use like 4gbs of memory for no reason lel
2025-04-15 17:13:11 +02:00
Alug b9aee1d53e readd hud gfx flushing
now that stuff doesent completely die lmao
2025-04-15 16:55:04 +02:00
indev feb93360a4 If GLENCORE is enabled, free both encore and noencore textures 2025-04-15 17:50:05 +03:00
Alug afd0613199 simplify this 2025-04-15 16:27:03 +02:00
Alug 71e9e040ec cast Zzz... 2025-04-15 15:34:30 +02:00
Alug d54319cd55 revert this part 2025-04-15 15:33:20 +02:00
Alug 0ce790f1bc fix PARANOIA compile 2025-04-15 15:18:58 +02:00
Alug 4cb83de7b3 Merge branch 'lugstuff' into balls 2025-04-15 15:12:19 +02:00
Alug 6ebc6412e4 idk anymore lel 2025-04-15 15:11:52 +02:00
Alug d2f996ebaf change those tags
also add PU_PATCH_DATA
2025-04-15 14:32:42 +02:00
Alug 325eac5b6d add more purge tags refactor patch freeing and stuff
currently dies when adding a wad midgame and the loading into another map
2025-04-15 13:14:23 +02:00
Alug 888d840198 fix PARANOIA compile 2025-04-15 12:46:40 +02:00
Alug 72d5fbe641 fuckit *unshortens your patch dimensions* 2025-04-15 09:27:42 +02:00
Alug 9eb34006c2 port srb2s patch refactor
still needs all the new purge tags
then we should hopefully be free of use after frees and everything
2025-04-15 09:00:21 +02:00
Alug 1ccd50fffa fuck off goddamit 2025-04-15 05:08:19 +02:00
Alug 3a698aab1a noooo dont free out lumppat
for some reason this occasioncally causes an use after free??
our memory management honestly is a fucking mess ngl
2025-04-15 04:57:00 +02:00
Alug b257768f4c change this 2025-04-15 03:47:12 +02:00
Alug b81652bfdd cleanup rotsprite creation
was hoping to fix the rare software crash with this Zzz...
2025-04-15 02:58:43 +02:00
Alug 4f2ffcdea5 cleanup R_ProjectSprite 2025-04-15 01:53:27 +02:00
Alug 2c8c6028f8 revert using modulu for frac calcs for colum drawers
this is fucking slow for some reason
2025-04-14 22:50:39 +02:00
Alug 30d64ad538 Revert "Cache start and end locations for WAD folders"
This reverts commit ef7935e2af.
2025-04-14 12:10:51 +02:00
Alug df888048c4 minor branching stuff 2025-04-14 11:41:09 +02:00
Alug d3427a3074 quiet compiler! 2025-04-14 11:31:46 +02:00
Alug 6378980f0d disable holepunch
never worked for me, and somehow makes my perf slightly worse lel
2025-04-14 11:30:38 +02:00
Alug 31244a5ce1 only holepunch uses this 2025-04-14 11:30:16 +02:00
Alug 517de5d1fe uncomment the banana dust code
it doesent look that great, so i prefer the lua version anyways
2025-04-14 11:28:50 +02:00
Alug 4294536055 delet erronous null checks
idk where those even came from lel
2025-04-14 11:28:23 +02:00
Alug c7526928b7 few more things 2025-04-14 11:15:40 +02:00
Alug f967babe29 kill a bunch of wonky stuff
idk smth in here absolutely trashes my perf in some instances
2025-04-14 11:09:22 +02:00
Alug 41f42c0cb0 missed those 2025-04-14 10:30:26 +02:00
Alug 57388b78c5 disable titlescreen demos if any addon (but musicpacks) are loaded
read comment
not a fan of this, but better than ppl constantly crashing
2025-04-13 22:33:33 +02:00
Alug b589fba6b8 optimize colourcube conditional checks
screw u atoi
2025-04-13 21:46:05 +02:00
Alug f8e63c8a60 Merge pull request #162 from Chearii/dialspeedometer
Add a dial speedometer
2025-04-13 19:07:14 +02:00
Alug 9169c66d03 refactor K_StretchPlayerGravity
mostly just make it more readable lel
2025-04-13 10:38:19 +02:00
Alug 32310c7e39 calloc takes care of those 2025-04-13 09:56:05 +02:00
Alug f8b1d1838c we dont need all this stuff for precip 2025-04-13 09:08:40 +02:00
Alug 7877585135 move this to make it little more clear what this is for 2025-04-13 09:08:16 +02:00
Alug a9e80bf4c4 missed this with localskin stuff 2025-04-13 09:04:19 +02:00
Alug d932d29720 move drawnode stuff into a switch
i like switches uwu
2025-04-13 09:03:24 +02:00
Alug 0985f5f317 readd itembox fuse think that was lost somehow lmao 2025-04-13 09:02:58 +02:00
Alug dcdee7c7f2 move this since it does check for fuse 2025-04-12 18:10:07 +02:00
Alug e0215220b4 unnest and cleanup P_MobjThinker
everything was moved into seperate functions lel
2025-04-12 18:06:38 +02:00
Alug 5cbac8c415 Revert "temp revert nanosleep for nix"
This reverts commit 78cf0d8f9d.
2025-04-12 16:22:41 +02:00
Alug 9f781930ee move line polyseg check out of the lööp if theres no polyobjs on le map
seems to reduce a hotspot there significantly
2025-04-12 16:01:43 +02:00
Alug 43928bbbd2 spr->mobj not thing lel 2025-04-12 15:44:11 +02:00
Alug c7d304349d windoze stimky
well this atleast should work for everyone, but be noted that the normal "localtime" function is apparently not thread safe
2025-04-12 15:43:59 +02:00
Alug 50b3e1ed28 throw mobjcache allocation shit into a inline function 2025-04-12 15:43:43 +02:00
Alug 6ff76802eb convert fixed to float with multiplication instead of division 2025-04-12 15:43:17 +02:00
Alug 4be2c84df0 use mobjcache for savegame mobj load 2025-04-12 15:42:25 +02:00
Alug 2ff37018f9 make a macro for this 2025-04-12 15:41:58 +02:00
Alug 293f91988c attempt at unmangling localskin stuff again
moved almost all the weird ass ternaries into functions
and should also probably fix some remaining issues where stuff was wrong
2025-04-11 20:40:28 +02:00
Alug 32f6309163 dont need to do any of this lel
the calloc takes care of those already
2025-04-11 16:53:52 +02:00
Alug 57ef2acd9c just make the numlaps draw besides the date
idk theres no good place for this otherwise
2025-04-11 14:23:21 +02:00
Alug d0159f9b8d add cvar to change the demo date formatting
bruh
2025-04-11 14:18:10 +02:00
Alug 9178eb5686 bigger buffer for demo version thing 2025-04-11 13:53:19 +02:00
Alug fed354f24f print demo version on "outdated" demos
idk if this is fine lel
2025-04-11 13:47:05 +02:00
Alug 8d201d451b dont need le strncpy 2025-04-11 13:07:14 +02:00
Alug 1e4380f184 apparently we have "nameonly"
ty indev <3
2025-04-11 13:03:57 +02:00
Alug 09e97b07f4 try and get file creation time in some cases on windoze builds
untested as of right now
2025-04-11 12:35:14 +02:00
Alug bbc81e3cc8 try to catch more bad demo dates
i mean this game did not exist in 2010 lmao
but occasionally it actually returned dates other than 1970 depending on what was passed to it lmao
2025-04-11 11:51:58 +02:00
Alug e68d69a38c do pathseperator check like this 2025-04-11 05:07:18 +02:00
Alug d02555b80b extract the date out of replay + display em in replay hut
this is kinda horrid, but essentially, the number at the start of replay names is actually the time when the replay was recorded, so i can extract that and convert it to a readable format
this probably can be done alot cleaner lmao
2025-04-11 05:00:07 +02:00
Alug 2cb338d6f7 add setting for cecho toggle to print to console instead
idk i hate doing string stuff, hope this doesent explode lmao
also ensures even if disabled all cecho stuff is printed to log file again
2025-04-10 22:01:44 +02:00
Alug dadde36ff6 handle highres portraits and statdisplay text more gracefully on low resolutions
below 640x400 the highres portraits become an absolute mess so itll now fallback to the lowres portraits
the statdisplay name text also became completely unreadable so itll use V_DrawThinString instead on low resolutions
2025-04-10 21:16:15 +02:00
Alug 1a28886ce2 simplify those 2025-04-09 23:18:31 +02:00
Alug 0919cc458b remove unused variables from FTransform struct 2025-04-09 22:44:23 +02:00
Alug c3c200c295 this can just be a constant lel 2025-04-09 22:39:36 +02:00
Alug 2e0010ee4e delet this 2025-04-09 22:31:45 +02:00
Alug 653b9ffaa0 Revert "HACK: make translucent fofs not cut cyan pixels"
This reverts commit 0503841939.
2025-04-08 21:39:03 +02:00
Alug 84ddae95ba use precalced value
this never changes, psure impact is negligeble tho
2025-04-08 20:52:43 +02:00
Alug 0503841939 HACK: make translucent fofs not cut cyan pixels
testing this, similar behaviour to software, fixes a few visual inconsistencies, but needs some testing lmao
psure we be leakin memory lmao
2025-04-08 20:52:10 +02:00
Alug dd6dc4d982 let item button also change skin grid sorting type 2025-04-07 19:40:17 +02:00
Alug e8c1afc860 reuse pwidth 2025-04-07 17:54:09 +02:00
Alug aa08c1adef unglobalise holepunchpacket aswell 2025-04-07 17:25:57 +02:00
Alug 1bbfdf6a78 oops this needs be initialized 2025-04-07 17:11:53 +02:00
Alug c3fcece75a sat credits a 2025-04-07 16:20:45 +02:00
Alug f907577094 avoid branching inside the while lööp 2025-04-07 09:10:10 +02:00
Alug 980fbd9b10 use optimized P_DivlineSide instead of R_PointOnSideFast 2025-04-07 08:39:43 +02:00
Alug 9902cac3ee some software optimizations
from:
https://git.do.srb2.org/Hanicef/SRB2Classic/-/merge_requests/6#d4bba40be8388ccd557d03ef4e4a36d0728c7751_645_587

minus the buffer flipping change, karts resolution stuff is hell and even worse due to birdmod things
maybe will look into that sometime
2025-04-07 08:35:33 +02:00
Alug 7cf1e8f15f Refactor netbuffer out of global namespace
https://git.do.srb2.org/Hanicef/SRB2Classic/-/commit/079fd2cef97a9cf22fb5d2b66a9b500914efbc72

+ move some things into functions
2025-04-07 08:13:38 +02:00
Alug a107496f76 free ogl lighttables earlier
ogl lighttable data is owned by extracolormaps apparently, so it has to be freed ealier
2025-04-07 07:45:05 +02:00
Alug ef7935e2af Cache start and end locations for WAD folders
port from https://git.do.srb2.org/Hanicef/SRB2Classic/-/commit/1a9da9dca6168a1cd2f47e06931a99b821596be1

pls git let me apply the og author with patches
2025-04-07 07:37:30 +02:00
Alug 9bfabe3ffd this is unlikely 2025-04-07 06:46:26 +02:00
Alug 28703bc038 whoopy copy paste 2025-04-06 17:13:04 +02:00
Alug f48ce0d94a try to rectify some branch mispredictions
adds "LIKELY" and "UNLIKELY" macros
those can be used to tell the compiler which path is more likely to happen
2025-04-06 17:03:23 +02:00
Alug 418d265f51 dont need this 2025-04-06 16:25:01 +02:00
Alug 2c60a4c353 reorder those a little 2025-04-06 15:14:57 +02:00
Alug 099b1ab81e use the float vid dimensions
forgor here
2025-04-06 15:14:49 +02:00
Alug ae7553ba30 cache the fofflags too 2025-04-06 11:24:38 +02:00
Alug b14b01d5c9 somehow this is slightly faster 2025-04-06 10:59:59 +02:00
Alug 6ebf6a2797 cache this
somehow this was unusually expensive lol
2025-04-06 10:29:28 +02:00
Alug 7b813e142b delet this 2025-04-06 09:58:58 +02:00
Alug d7d610bb99 more smoller optimizations
save some unneeded floattofixed calls
and move the linedef check earlier
2025-04-06 09:36:48 +02:00
Alug 5b9ef80f61 check for horizonlines on mapload on opengl
this saves iterating through a crapton of lines every frame in ogl
2025-04-06 08:45:08 +02:00
Alug 0ec286b9f4 Optimze horizonline check
noticed during profiling due to how it was checked R_PointOnSegSide was called extremely often even if the less expensive check  returned false
2025-04-06 08:43:40 +02:00
Alug 0f3be26c42 Revert "revert "R_ResetViewInterpolation: wait an extra tic if R_UpdateViewInterpolation has not run yet, do not add extra time for subsequent calls""
This reverts commit a560c691ca.
2025-04-05 19:27:48 +02:00
Alug 163122afb1 use R_GetViewNumber here 2025-04-05 19:27:34 +02:00
indev 0b9d56912d Add 'inputdisplay' option for hud.enable, hud.enabled, hud.disable and hud.getOffsets 2025-04-05 17:41:50 +02:00
Alug 721401f85a delet that egg 2025-04-04 18:13:31 +02:00
Alug a4ac85be85 no need to scale the volume for splitscreen if we dont play a sound lol 2025-04-04 18:13:12 +02:00
Alug 8ca0e5f112 didnt mean to change that lel 2025-04-04 08:15:44 +02:00
Alug a99c3b7ae9 fix software crash on date (ceruleavaenaen riviera) 2025-04-04 01:56:46 +02:00
Alug 6406eb5ba6 bruh 2025-04-04 00:29:07 +02:00
Alug 5d2aebc269 fix oopsie in R_Render2sidedMultiPatchColumn 2025-04-04 00:28:16 +02:00
Alug c0fe43ff0c erronous endifma balls 2025-04-03 21:22:16 +02:00
Alug cbb590b4d7 kill SATURNSYNCH and can_receive_gamestate, change the detection of synch method
before we unconditionally sent PT_WILLRESENDGAMESTATE to every connected node that didnt desynch before, in a big lobby this could mean having to send out alot of reliable packets to potentially clients that couldnt use it anyways, like this we just check if a client is saturn, which gets set the moment a saturn client v7.1 and onwards joins (it sends a special packet to the server during connect)
this makes sure we only even attempt the new resynch system with clients WE KNOW can use it anyways
this is backwards compatible until v7.1, v7 when this was introduced did not send the special packet on join and relied on the willreceivegamestate packet, so they wont benefit from the better resynching anymore
2025-04-03 20:41:36 +02:00
Alug 7067d22da0 fix OOB read of "playeringame"
not too sure if this is completely save, but it should technically
2025-04-03 20:25:02 +02:00
Alug 683737a6c7 update saturn credtis
baaaaaaaaaaarely fits now on greenres
had to kill the tooltip too :/
we should prob think of smth else than abusing a menu for this
2025-04-03 00:13:45 +02:00
Alug ca302493f7 drift only option for coloured speelines
man
2025-04-02 19:48:43 +02:00
Alug 6cdce0c95d use max 2025-04-02 10:01:38 +02:00
Alug 9894198028 convert those to float once 2025-04-02 09:58:56 +02:00
Alug b221d22e38 check if texture exists first 2025-04-02 09:58:05 +02:00
Alug b56ce88c27 fix the wonky rendering issues on that one si-ht map
saturn regression introduced by the fof slope cutoff fix
hopefully this has no weiird side effects, but so far everything seemed fine
2025-04-02 09:57:17 +02:00
Alug a7f1ff24cd smol cleanup skyspecial handling for ogl 2025-04-02 09:56:07 +02:00
Alug 1c2e404853 slight cleanup drawOnMinimap 2025-04-02 09:55:35 +02:00
indev 33bb40765c Add pageup and pagedown support in replay hut 2025-04-01 00:23:06 +02:00
Alug 1987a18e68 change scr_depth to gr_texturedepth and allow it to change stuff midgame
its not used for software renderer anymore and before you had to restart the game to be able to see a change in gl
8bits and 24bits options have been removed since they had no effect
and it also allowed me to unglobal things
2025-03-31 22:55:54 +02:00
Alug 62e1109cd4 kill ogl_win
its unused apparently
2025-03-31 22:50:18 +02:00
Alug 3701f7cf9c texfomats without alpha should have maxlod of 5 2025-03-31 22:30:25 +02:00
Alug e14e4b51c7 HAVE_IPV6 2025-03-31 08:29:23 +02:00
Alug efd7cd155e disable compiling with ipv6 support
see commit before
2025-03-31 08:27:43 +02:00
Alug cef448ca23 bugfixes for sock stuff + kinda fix ipv6
thx srb2!
sadly we cannot really make use of ipv6 since vanilla clients cant really handle stuff well ontop of the server browser not supporting them anyways, sad!
its probably better to just disable ipv6 compile completely
however this also has minor cleanups and bugfixes for ipv4 too (server browser now should work proper if you rerfresh it often and then close and open it again etc)
2025-03-31 08:21:46 +02:00
Alug f51cd6977a better check for destinationnode 2025-03-31 08:13:46 +02:00
Alug 7b7d93a2d6 remove unused stuff d_net 2025-03-31 08:11:10 +02:00
Alug d37d97c5fa also dont do this without localdelay 2025-03-29 18:13:01 +01:00
Alug 53aeda3c6b oop still need to update this 2025-03-29 18:00:11 +01:00
Alug f793c4b57f update ping only once per second again
read the comment on why
2025-03-29 17:52:20 +01:00
Alug b72c997789 only do gentlemens anything if we intend to use it
shizo thing
2025-03-29 17:52:09 +01:00
Alug 636feddeb3 128k
well this didnt help but still think 64k might be a bit short
2025-03-29 03:10:25 +01:00
Alug a726646ff3 if 128k network buffer fails then try 64k as last resort 2025-03-29 02:34:36 +01:00
Alug e2e1839829 make the whole tcp stack return errno errors 2025-03-29 02:32:18 +01:00
Alug 2f22f28a4d try to set the socket buffer to 208k
this is what i get on nix, while windoze seems to be stuck on 64k, maybe fixed the occasional network buffer overrun that happens
2025-03-29 00:59:23 +01:00
Alug 541f532988 can just set it to null directly 2025-03-28 17:13:03 +01:00
Alug 2fb572ed4c dont run anything director in dedi
we dont need to even init its stuff
2025-03-28 17:01:43 +01:00
Alug f938d566f7 make a function that returns the newspeedometer style if its availible
makes stuff alot easier to read than constantly checking for if stuff exists everywhere
2025-03-28 07:12:37 +01:00
Alug d3df8708af tiny cleanup inputdisplay
just use V_DrawMappedPatch, it does the same but looks better in code lel
2025-03-28 07:10:26 +01:00
Alug 2b3fefc988 Revert "delet this"
This reverts commit 18352ff6d8.
2025-03-28 04:53:36 +01:00
Alug 568012589d :3 2025-03-28 04:52:50 +01:00
Alug c949589bea can just reset this here 2025-03-28 02:35:53 +01:00
Alug 893de2e047 force switch player after 15 seconds max
not sure if its too strict but it gets really boring just watching the same person for ages
2025-03-28 02:16:32 +01:00
Alug b4dcc7da7d forgor the header file 2025-03-28 02:14:44 +01:00
Alug 3c361654f7 instant switch if the player we watch is finishing
i dont need to watch the finishline for 5 seconds everytime lmao
2025-03-28 02:14:30 +01:00
Alug 29a8075d90 only count actually playing players for director
otherwise you could enable it if theres more than 1 person in the server but only 1 person is actually playing
2025-03-28 02:13:04 +01:00
Alug 4cfeef6300 you cant memset this to -1 lel
prob fixes the director never switching when only one player was left
2025-03-28 01:37:50 +01:00
Alug b2d4039a9f optimize director by checking for finishline waypoint on mapload
instead of every time this is called
2025-03-28 01:12:14 +01:00
Alug 8ede41fde8 simplify this lel 2025-03-28 00:45:17 +01:00
Alug c0a3c4d144 add R_QuickCamDistFixed which returns fixed point value 2025-03-28 00:36:59 +01:00
Alug 37b1ad80e3 nooo dont set srb2waddir to NULL 2025-03-27 23:50:46 +01:00
Alug 4a2f338c85 turn this into a switch for no reason 2025-03-27 23:37:50 +01:00
Alug 910f2d3b8c remove pointless function 2025-03-27 23:33:11 +01:00
Alug ce25dd54b5 add smol P-Meter patches
thx jin for those
2025-03-27 23:27:20 +01:00
Alug 56935ef0c2 seperate the colour hud patches out of here so they can be used without the vanilla colour hud 2025-03-27 22:48:29 +01:00
Alug 010cbd68fd seperate the driftgauge colour patches into extra2 + add some more comments
was an oversight, extra2 should be for all colour hud patches
2025-03-27 22:21:35 +01:00
Alug 2ec90922a2 fix driftgauge value "small" value being overwritten when having extra3 loaded 2025-03-27 22:12:22 +01:00
Alug 9dac5f6dab move saturn extra file checking into its own function
and also properly seperate all patch checks so they only get checked if you have the right file
may actually slightly speedup startup in some cases
2025-03-27 22:01:45 +01:00
Alug e5263121eb fix stick setting showing wheel 2025-03-27 21:36:44 +01:00
Alug b1270fd54d make beta interscreen cvar also affect tab rankings 2025-03-27 21:35:24 +01:00
Alug 648720c8ac just make the input display global toggle for it
mostly done so i can shorten the entry in the menu cause i cba to mangle stuff again
2025-03-27 21:29:50 +01:00
indev 526b254345 Add 'StickGFX' option for showinput cvar if graphics for it exist 2025-03-27 23:19:27 +03:00
Alug 806d8b5e42 actually initalise those lmao 2025-03-27 20:58:17 +01:00
Alug 62b24e9fd4 no need to check for this 2025-03-27 20:44:19 +01:00
Alug 4ca1d40bcc add support for sprite joystick knob
still needs proper toggle
2025-03-27 20:41:14 +01:00
Alug 939c92f1c1 that comment belongs to this lmao 2025-03-27 20:24:56 +01:00
Alug 0000db2f64 fix vertical patch scale not working when horizontal scale is also not changed in opengl patch drawer 2025-03-27 19:48:27 +01:00
Alug 18352ff6d8 delet this 2025-03-26 22:07:39 +01:00
indev 6661d98e5f Fix limit_dist overflowing for some mapobjectscale values 2025-03-26 20:22:16 +01:00
Alug 60ff34d7de fix spacing when compiled withou fbo support 2025-03-26 19:51:52 +01:00
Alug a5b317d552 better slope rotation for shadows
instead of copieng the target mobjs rotation we just use its standingslope instead, this means shadows properly rotate according to which slope theire on
should make them visually more cohesive if a player or other mobj is rotated midair
2025-03-26 19:51:31 +01:00
Alug 7b18694599 add dummy entries so the tooltips dont fucking cutoff stuff in green res
if i only knew of this dumb hack earlier
2025-03-26 19:32:35 +01:00
Alug e6b4f00cb2 muh huh durr hurr is above array bounds of deez nuts 2025-03-26 18:32:02 +01:00
Alug 0c87e207d5 fix advanced video options in green res
god bruh
also removes the directional light entry since its planned to be deprecated
2025-03-26 18:17:29 +01:00
Alug 1fc4437054 fix sprite distort tooltips
Zzzzzzzzzz......
2025-03-26 18:05:17 +01:00
Alug 5792331c10 turn advanced sound ioptions into scoll menu 2025-03-26 18:04:47 +01:00
Alug c06078e4cc turn sprite distortion menu into scoll menu due to green res 2025-03-26 18:00:00 +01:00
Alug d71d9becd8 rename "Custom Options" to "Custom Addon Options"
to make it clear wtf this is even for
2025-03-26 17:45:56 +01:00
Alug 01ea47f59e turn screenshot options into a scoll menu cause of green res 2025-03-26 17:45:31 +01:00
Alug a81cbb9813 fix focus options for green res 2025-03-26 17:31:48 +01:00
Alug 47d3f0e624 move everything around in main options menu to fit stuff for green res 2025-03-26 17:27:09 +01:00
Alug 43c718af37 fix bird menu from crashing (again) finally add an enum so this wont happen again 2025-03-26 17:13:54 +01:00
Alug 4e90b9260b lel 2025-03-26 15:54:18 +01:00
Alug d8282e7b7f add smol text indicating the autoload button 2025-03-26 15:35:13 +01:00
Alug a66b329255 change menu autoload button to "END" instead of right shift
too many ppl accidentally press right shift and end up putting things they didnt intend into their autoload file
which sometimes caused alot of issues in online play
2025-03-26 15:34:57 +01:00
Alug d138a593a6 brazil 2025-03-26 14:54:10 +01:00
Alug 19eda24e57 tab hell 2025-03-25 23:14:10 +01:00
Alug cbd54274f2 grey out mouse grab when use_mouse is enabled 2025-03-25 20:04:59 +01:00
Alug 4181b1dff6 add onchange for "alwaysgrabmouse" 2025-03-25 19:57:02 +01:00
Alug e5a088aee9 put all the "game focus" options into a seperate menu 2025-03-25 19:35:55 +01:00
Alug 6c6e44ec64 fix server lan discovery
which just returned EINVAL and triggered the I_Error in SOCK_Send
more information at: https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2219
2025-03-24 22:42:30 +01:00
Alug 5e1d1f5205 make this not I_Error
no fucking clue what happens with it
2025-03-24 21:10:52 +01:00
Alug db5298a2fc bleh 2025-03-24 20:35:27 +01:00
Alug 7c13b74636 Revert "remove the early returns in SOCK_Send"
This reverts commit dcc3b1294c.
2025-03-24 20:35:10 +01:00
Alug fc2bd63d91 delet this 2025-03-24 19:21:26 +01:00
Alug b9bdfbf790 Revert "clean up some net stuff"
This reverts commit f8903e7ce7.
2025-03-24 19:18:34 +01:00
Alug f54055e69b potentially fix "Received a file not requested" error in poor net conditions
needs a bit of testing
2025-03-24 19:01:02 +01:00
Alug d8e7ed1f1f grey saltroll out in menu if sloperoll disabled 2025-03-24 18:22:07 +01:00
Alug 702e800d3f toggle for saltyhop sloperoll behaviour 2025-03-24 18:20:16 +01:00
indev 4168dbddbb No need to FLOAT_TO_FIXED here :з 2025-03-24 17:19:35 +01:00
Alug 77ba719284 Reset seenplayer on netgame exit 2025-03-24 16:52:47 +01:00
Alug acd23c1002 remove the early returns in SOCK_Send
othewise it may never error out when it should
2025-03-24 16:30:05 +01:00
Alug 4729ca1c40 we dont need sweep and test 2025-03-24 16:25:17 +01:00
Anonimus f2691b4673 Add C++ support to the makefile
Also add new required DLLs for Windows users
2025-03-24 16:24:06 +01:00
Alug db8bc50c17 Do not error out if we don't have a socket for an address family we have disabled
from srb2
2025-03-24 16:23:16 +01:00
Alug 9f1a1cb661 Replace all instances of XD_KICK with a SendKick function 2025-03-24 15:35:26 +01:00
Alug c04fd47637 i hate menus 2025-03-23 18:31:38 +01:00
Alug 4bdcd5b9d5 this does not need be checked here 2025-03-23 18:24:46 +01:00
Alug b08bacede5 lugstuff momento 2025-03-23 18:20:04 +01:00
Alug d89ffbcc0f k_throwdir already returns just -1, 0 and 1 2025-03-23 18:17:59 +01:00
Alug 5ff3973ebb add player blendeffects to menu + change when they apply
most of them now apply during sneakerboost
sparkles may also get add blendmode when you go really fast with them (like the speedlines)
2025-03-23 18:15:35 +01:00
Alug 7331e43207 change "verticallook" and "cameralookbackmom" to be per splitscreen player 2025-03-23 18:15:32 +01:00
Alug 0d7473d104 15 step increment Zzz... 2025-03-23 16:58:53 +01:00
Alug 9c46306b07 simplify the slider stuff slightly 2025-03-23 16:56:56 +01:00
Alug 63517e3de3 make stretchfactor a cv_float again
for easier handling
now that we can use sliders this should hopefully work without issues
2025-03-23 16:54:51 +01:00
Alug 78566f067d make saltyhop height use slider 2025-03-23 16:43:53 +01:00
Alug c48ab0f163 make menu sliders work on CV_FLOAT 2025-03-23 16:38:34 +01:00
Alug 19a6da0ae3 changable saltyhop height
dunno, it looks a bit off on higher values since the animation duration is always the same
also cv_float is weird
2025-03-23 16:18:18 +01:00
Alug a560c691ca revert "R_ResetViewInterpolation: wait an extra tic if R_UpdateViewInterpolation has not run yet, do not add extra time for subsequent calls" 2025-03-23 15:30:45 +01:00
Alug 2306d4b59b Revert "test: revert all the view interp stuff"
This reverts commit 1a836031a7.
2025-03-23 15:28:59 +01:00
Alug 1a836031a7 test: revert all the view interp stuff 2025-03-23 15:07:18 +01:00
Alug 26a741e3fe cap Local_Maketic 2025-03-22 13:06:48 +01:00
Alug 0511c22e6f let this run during "singletics"
renderisnewtic was not really correct
2025-03-22 13:06:31 +01:00
Alug 81120cddce move the early return here 2025-03-21 16:44:14 +01:00
Alug bbe28d6d8f forger P_IsLocalPlayer exists 2025-03-21 15:56:10 +01:00
Alug caaf218dd4 hack for stick input display if you watch some other player Zzz.... 2025-03-21 15:53:10 +01:00
Alug ded46e6197 dont run discord rpc callbacks every frame
ditto
2025-03-20 23:51:59 +01:00
Alug 198cd1a68a dont update sounds every frame
if this would break ppl on 35fps cap wouldve been always screwed lel
2025-03-20 23:47:42 +01:00
Alug d19a455e65 dont call this every frame aswell 2025-03-20 23:44:48 +01:00
Alug 3f51b4389b cap a few things that break otherwise 2025-03-20 23:42:24 +01:00
Alug 55af517a57 uncap netupdate
:chonkbuncle:
2025-03-20 20:24:39 +01:00
Alug 0c209f2439 kill this, i want vanilla behaviour 2025-03-20 18:44:06 +01:00
Alug 27699e91ea delet player_joining 2025-03-20 18:44:03 +01:00
indev eadf16dd14 Only reset replay query in M_ReplayHut if replay hut wasn't open previously 2025-03-19 23:47:48 +01:00
Alug 10ea091471 handle pause better ig?
its still not really what i want lmao
2025-03-19 14:47:27 +01:00
Alug ff32db6e12 readd ACK 2025-03-19 14:31:50 +01:00
Alug ee908baa7a delet the uncap crap from funneh dance
we dont need this to be uncapped, mobj interpolation will take care of anything and this means i can put it into mobj thinker or whatever
2025-03-18 13:16:04 +01:00
Alug 694e7490a6 comments
this is horrible and i made this crap in 5 minutes
2025-03-17 20:14:06 +01:00
Alug 9d4cdbcc32 add horrible squishdance code
lmaao
this is so bad its unreal
2025-03-17 20:09:27 +01:00
Alug eefa41a58e Revert "Use PU_LEVEL for texture caching"
This reverts commit 5ecfc5e09d.
2025-03-17 18:43:55 +01:00
Alug 3b76c4b620 remove this again 2025-03-17 18:41:12 +01:00
Alug cedcccb18e move patch null checks into the patch drawers instead 2025-03-17 18:39:49 +01:00
Alug 0076d1e87a revert this too just in case 2025-03-17 18:26:32 +01:00
GenericHeroGuy b428a5fd1b Fix tonumber leaking doubles when JITted 2025-03-17 16:03:59 +01:00
Alug 20f8e910de make the banana throw speen be seperate from sloperoll toggle
were technically not rolling by slopes here
2025-03-17 15:55:10 +01:00
Alug ae2eb13623 forgor about saltyhop condition 2025-03-17 15:24:49 +01:00
Alug 2aca4dc0c7 add function to check if mobj should sloperoll
makes things slightly cleaner and we can apply sloperoll dist to everything
should probably save some time esp with the trailing item z calc
+ P_MobjPitchAndRoll should be able to be called always since it also does stuff seperate from sloperoll
2025-03-17 15:20:49 +01:00
Alug de2a73149b use quickcamdist for K_RollMobjBySlopes
we dont need this to be accurate at all
and its slightly faster so
2025-03-17 14:21:08 +01:00
Alug 981885dafb fix midair driftsparks
somehow accidentally ended up doing what RR does lmao
hope this doesent do anything funky synchwise
2025-03-17 13:42:31 +01:00
Alug b11348d3e3 kill bunch of redundant calcs for some kart visual effects 2025-03-17 13:06:06 +01:00
Alug f8b3e9cfcb safe some time by returning early in K_RollMobjBySlopes
in case those mobjs are out of our set distance
2025-03-17 12:40:08 +01:00
Alug d9c2add062 dont let saltyhop stop our drift sounds for 1 tic
if you disable its sound effects
2025-03-17 11:15:12 +01:00
Alug 7777946979 noo dont free our realpatch randomly
this used to be Z_Unlock which did nothing
checked against srb2 and rr and this should not be freed normally
2025-03-16 21:05:52 +01:00
indev 3b929b3687 Fix gl_extensions being truncated when there are too many extensions 2025-03-16 15:31:09 +01:00
Alug e1f3447a8b lmao 2025-03-16 13:28:33 +01:00
indev ac1bb9efbf Generalize K_SpawnOrMoveMob, and make adding new vfx that use it slightly easier 2025-03-16 15:01:44 +03:00
Alug cbf02a7741 goddamit 2025-03-16 12:24:38 +01:00
Alug 802514db04 oops 2025-03-16 12:23:51 +01:00
Alug 84ac034fa9 cache player 2025-03-16 12:23:16 +01:00
Alug 6c837f6fb6 bruh 2025-03-16 12:22:45 +01:00
Alug f7f0e02688 Merge remote-tracking branch 'origin/Saturn-Testing' into lugstuff 2025-03-16 12:19:57 +01:00
Alug be3b8cd23e dumb hack for input display in replays
since we cant get playerinput, just use throwdir to get some appoximation
maybe todo: idk maybe squeeze smth into replays?
2025-03-16 00:22:31 +01:00
Alug 868f0acb18 this needs be multiplied by 8 lel oops 2025-03-15 18:41:33 +01:00
Alug 579e7261a3 cache player 2025-03-15 16:47:11 +01:00
Alug 9dc14bda3a add extra check to save a little bit of time 2025-03-15 16:46:37 +01:00
indev 080ae52bce aatree is used both with HWRENDER and ROTSPRITE, so just don't guard its include 2025-03-15 14:50:13 +01:00
Alug 170d4bd57b port of "minimap icon spinouts" by Anonimus
https://codeberg.org/NepDisk/srb2k-neptune/pulls/7

+ some refactoring
2025-03-15 14:40:15 +01:00
Alug a541144d4a safe 2x "va" lel
V_GetSkincolorChar is unused now lel
2025-03-15 14:39:04 +01:00
Alug bcd5d9aa8b just use splitflags 2025-03-14 21:00:00 +01:00
Alug 66c9b05d3d doesent need be an array 2025-03-14 20:56:46 +01:00
Alug 8a410913f3 New input display option for stick display
thy neppy! https://codeberg.org/NepDisk/blankart/commit/52601bdfc2a6dd8916c3c401d70128d2ca11a1ff#diff-baf740b84aa99188fc2e5c1cb93e59fa2e319ff3

+ hellish abomination code cause kart
2025-03-14 20:46:25 +01:00
Alug 474ed722f6 make freecam speed per splitscreenplayer + add to menu 2025-03-12 07:00:50 +01:00
Alug bbd03114ee delet cam rotspeed cvar
lmao forgor this did nothing
2025-03-12 06:52:46 +01:00
Alug b04335f16e fix compile without ROTSPRITE 2025-03-10 17:52:08 +01:00
Alug 353337be24 consolidate those 2025-03-10 17:28:27 +01:00
Alug ed87d759e0 a 2025-03-10 17:28:09 +01:00
Alug c6824a6748 make this slightly less ugly 2025-03-10 14:59:35 +01:00
Alug 3615dd43d6 add cvar to force mouse grab and hide 2025-03-10 14:55:52 +01:00
Alug 865c3cfaec kill bunch of crap 2025-03-10 14:04:16 +01:00
Alug db3435356c Revert "apparently those temp variable are not needed"
This reverts commit 36508c24e3.
2025-03-10 12:31:53 +01:00
Alug 5c2adca262 Revert "use vectors P_ClosestPointOnLine3D and kill vertex z"
This reverts commit e0ae6aa85c.
2025-03-10 12:31:44 +01:00
Alug 801d1a3056 Revert "try simplify blockthings iterator"
This reverts commit 3bae721fa8.
2025-03-10 12:31:40 +01:00
indev 1eea46654b Add SHORT here for consistency with other code 2025-03-08 16:17:24 +01:00
indev c44f78d303 Check for missing patch earlier in W_CachePatchNameRotated 2025-03-08 16:17:20 +01:00
Alug d5587d51c1 p_sight stuff idk 2025-03-08 16:16:39 +01:00
Alug bccad86f50 try shizo thing to reduce netlag 2025-03-07 14:47:18 +01:00
Alug 4d6b5437c8 show smol notice in stat and ra menu when game is modded 2025-03-07 14:45:28 +01:00
Alug ab9aba1de6 remove erronous cv_sloperoll checks
this cvar is meant to be only the toggle for the player slope rotation, however, spriterotation should still be usable in any case with this disabled. the global toggle "cv_spriteroll" has been removed
2025-03-07 09:52:43 +01:00
indev 2a8b54c91b spriteroll doesn't exist now :p 2025-03-07 00:44:58 +01:00
Anonimus 2dedbc25f6 HUD patch rotation 2025-03-07 00:44:23 +01:00
Alug 7401ddca43 explicitly check for x11 sdl videodriver 2025-03-06 11:21:50 +01:00
Alug af470dc7b2 idk why this breaks shit 2025-03-05 00:07:24 +01:00
Alug 7e2469b1f7 fix some blendmode oopsies 2025-03-04 22:56:54 +01:00
Alug ddf21ea753 use memcmp for R_IsEmptyLine
:chonkbuncle:
this actually is quite a little faster too
2025-03-04 20:35:39 +01:00
Alug 8c451f6fee try make this slightly more readable 2025-03-04 19:27:26 +01:00
Alug dbb58f44e5 quick check if sectors are same
so can save on bunch of stuff, also move midtex check earlier
2025-03-04 19:18:27 +01:00
Alug d1981fd566 change syntax
will stay uppercase to not conflict with some crap Zzz...
2025-03-04 19:11:38 +01:00
Alug 73eafbe57c smth smth magic number 2025-03-03 13:12:00 +01:00
Alug 99087629f2 pointless inline 2025-03-03 11:20:03 +01:00
Alug f217914a47 empty function lel 2025-03-03 11:16:06 +01:00
Alug 8034e55050 this returns -1 on fail 2025-03-03 11:15:44 +01:00
Alug db0ffa3ed5 delet memcpy doing nothing 2025-03-03 11:14:09 +01:00
Alug 4318923ad5 tiny cleanup keyboard stuff 2025-03-03 09:56:13 +01:00
Alug 78cf0d8f9d temp revert nanosleep for nix 2025-03-03 00:13:59 +01:00
GenericHeroGuy 8524f3367c Figured out why that doesn't work 2025-03-02 23:30:02 +01:00
GenericHeroGuy 5b18c9837a Properly constant-fold (0 or 123)
But not (0 and 123). Yay bug compatibility!
2025-03-02 23:29:59 +01:00
Alug fa07c4d659 guh 2025-03-02 23:27:19 +01:00
indev ebcb3df9b4 Revert "Convert parsed numbers to doubles first in lj_strscan_scan"
This reverts commit 3f8fb365a0.
2025-03-02 23:13:18 +01:00
indev 9f76ede41e Revert "Restore setnumV for fmt == STRSCAN_NUM in lj_strscan_scan"
This reverts commit 644cd36286.
2025-03-02 23:13:15 +01:00
Alug 69d62b7b12 muh huh truncuate my butt mingw32 2025-03-02 23:13:08 +01:00
Alug 7ea55e2d29 bugger off UPX
dont want compressed executables, they BREAK backtraces
2025-03-02 23:02:43 +01:00
Alug febbc4f2cd inlining failed in call to my butt 2025-03-02 22:11:35 +01:00
indev 7480105a06 Restore setnumV for fmt == STRSCAN_NUM in lj_strscan_scan 2025-03-02 22:06:55 +01:00
Alug 6d604aed28 forgor 2025-03-02 21:44:31 +01:00
Alug 73d57220f0 screw you music system
no fucking clue but this fixes stuff showing the musiccredit too early on reload
2025-03-02 21:41:42 +01:00
Alug de4ee28ccf bleh 2025-03-02 21:29:21 +01:00
Alug 3bbe4842b7 Reapply "better M_Random implementation"
This reverts commit a406b21401.
2025-03-02 19:48:22 +01:00
indev 66198e0159 Convert parsed numbers to doubles first in lj_strscan_scan
Regular blua does something similar to that, and it changes how large
numeric literals are parsed. It's very rare for those to be used but can
still in theory cause synch issues between blua and bluajit clients
2025-03-02 19:10:51 +01:00
Alug 70a479836d lul 2025-03-02 19:10:48 +01:00
indev de4c90b790 Delet goto from bluajit, since regular blua doesn't support that 2025-03-01 13:05:03 +01:00
indev c8cc80a253 Fix water and fog shader missing #version 2025-02-28 20:39:39 +01:00
Alug cd991ca5bb more kart hud cleanup
also removes erronous nametag toggles
2025-02-28 18:54:38 +01:00
indev 8b6ce4e113 Don't reset demo recording if player is still entering replay name in intermission 2025-02-28 17:21:13 +01:00
Alug b356b72781 slight cleanup kart hud 2025-02-28 09:51:36 +01:00
Alug 58d3d66515 add airsparks to saturn options 2025-02-27 19:45:56 +01:00
Alug 94855fbaae color ping numbers for color hud 2025-02-27 19:38:11 +01:00
Alug a406b21401 Revert "better M_Random implementation"
This reverts commit a353dceaa3.
2025-02-27 19:37:41 +01:00
Alug 60018b5561 do this in a less horrifieng manner 2025-02-27 19:11:59 +01:00
Alug 25a5c39252 use floor shader for everything when paletterender disabled
just like vanilla!
not the way to do this properly, but whatever
2025-02-27 18:50:50 +01:00
Alug 8939e2601d actually can just use this directly 2025-02-26 13:04:10 +01:00
Alug fec04089c0 Merge remote-tracking branch 'origin/Saturn-Testing' into lugstuff 2025-02-26 11:11:19 +01:00
Alug 8dea244d1b turn this into a switch
else if stinky
2025-02-26 11:08:53 +01:00
Alug b96dc05a45 use lj_char_isspace 2025-02-21 20:05:35 +01:00
Alug 1ed3cf28b0 use strlen 2025-02-21 20:05:26 +01:00
indev 661d4ee8e1 Allow trailing spaces in lj_strscan_scan 2025-02-20 21:44:14 +01:00
Alug c711bf42c9 readd missing cast 2025-02-20 21:19:51 +01:00
Alug 1afb5e5219 toggle for keeping driftsparks while in air 2025-02-19 12:05:29 +01:00
Alug 98eaaae30e reuse var 2025-02-19 11:10:51 +01:00
Alug 10e303b0a8 few instances of int float conversions i forgor 2025-02-19 11:10:27 +01:00
indev 63391d3763 Fix compilation with old sdl 2025-02-18 23:50:04 +01:00
Alug 8a3d767c08 Reapply "delete acktosend"
This reverts commit 95f797fcda.
2025-02-18 23:49:55 +01:00
Alug d3b786d725 init joyid here
i hate the controller code
2025-02-17 21:58:27 +01:00
Alug ceff2e9be6 properly init numcontrollers 2025-02-17 21:30:36 +01:00
Alug 31dabda1db initialize this 2025-02-17 21:23:55 +01:00
Alug 72322e5f42 dont check number of controllers every frame 2025-02-17 21:16:12 +01:00
Alug 15f97ab8a4 skip a bunch of stuff in dedi/render_none 2025-02-17 20:54:37 +01:00
Alug 95f797fcda Revert "delete acktosend"
This reverts commit a150512122.
2025-02-17 19:45:34 +01:00
Alug a150512122 delete acktosend
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2591
2025-02-17 16:30:57 +01:00
Alug 1b58bdc903 update software precache
spit stuff into functions
handle animated textures and flats too
2025-02-16 16:47:06 +01:00
Alug 095fd0b015 better handling of sprite angles in precache
only cache stuff that we need
2025-02-16 16:38:42 +01:00
Alug 1abf62e929 skip checking sectors and lines multiple times 2025-02-16 15:37:43 +01:00
Alug 00f9eaf67f slightly optimize ogl precaching
cleanup too
2025-02-16 15:37:18 +01:00
Alug 3193081d0e make texture precache toggable 2025-02-16 15:34:54 +01:00
Alug ae7296c586 guard this in sprite precache 2025-02-16 15:33:58 +01:00
Alug 51efdb32e5 precache animated textures too 2025-02-15 16:22:16 +01:00
Alug 50e9721a0d also precache animated flats
i have no clue how tf animated textures work
2025-02-15 14:27:52 +01:00
Alug 2305a3210e dedicated server does not need to call texture precaching
prob leftover from back in the day, it doesent do anything at all anyways
also gives it a less ambigous name
2025-02-15 02:15:04 +01:00
Alug d947f5b4c1 precache (most) sprites on ogl leveload 2025-02-15 02:07:50 +01:00
Alug 18163ec6d7 mhhm ternaries 2025-02-15 02:06:51 +01:00
Alug efaf1eb2a1 move texture precache into own function
unnesting stuff
2025-02-15 01:05:44 +01:00
Alug d6476fde67 oops should be i 2025-02-15 00:35:34 +01:00
Alug c99f2c20b1 load both encore and non encore tex 2025-02-14 23:24:58 +01:00
Alug 989e1a3f56 move precache into hw_cache.c 2025-02-14 23:02:13 +01:00
Alug e2f311f9e0 handle encore in ogl precaching
thx indev for help <3
2025-02-14 22:57:25 +01:00
Alug 45b59fc81e this is incorrect, dont need it anyways 2025-02-14 21:57:57 +01:00
Alug 02fb70e2ae disable ogl precaching on encore mode
noencore things need to be handled
for now just disable it until i figure out how to check for lineflags here
2025-02-14 21:31:22 +01:00
Alug 53dfa07237 precache level flats and textures on mapload in opengl
not entirely sure if this works correctly with encore, have to test a little
TODO: move this into hwr file or smth
2025-02-14 21:22:42 +01:00
Alug bc2b85df0f Revert "do some lööp unrolling for software span drawers"
This reverts commit 782e3172ad.
2025-02-14 19:49:17 +01:00
Alug b21586a698 add toggle for blendmode player effects
otherwise people will yell
enabled by default for now for demonstration purposes
2025-02-13 18:41:26 +01:00
Alug 3797b02143 make P_InitCamera slightly prettier 2025-02-12 17:55:23 +01:00
Alug 796be8d0ff cleanup P_SetupLevel
removed bunch of pointless vars, moved some things into functions
changed some stuff to be boolean
2025-02-12 17:32:07 +01:00
Alug e394056c36 use correct type in P_InitMinimapInfo 2025-02-12 11:56:41 +01:00
Alug 8863b39aa9 split screentexture width and height
most displays are widescreen, so their width and height differ quite significantly, this may make the overall screentexture alot smaller
2025-02-11 19:21:38 +01:00
Alug 9c61691632 revert adding netbuffer to local ping
dont wanna revert the commit, since i keep the new way of determining the ping display, since its less awful than before
2025-02-11 15:01:48 +01:00
Alug 1e71c73a61 fix online player localping display 2025-02-10 21:00:00 +01:00
Alug 4349b6b9cb fix some level userdata not being invalidated
maybe fixed the random issues we had with the server?
2025-02-10 20:47:33 +01:00
Alug 793f3c23a6 dont add buffer delay when local delay is disabled 2025-02-10 19:05:44 +01:00
Alug 5987fd8fda account for netticbuffer in offline ping
this makes it more accurately reflect how it would behave in an online game
2025-02-10 17:43:33 +01:00
Alug c55fb60cc8 add some comments + smol cleanup again for keepmusic 2025-02-10 16:51:17 +01:00
Alug 9fcf4548df extend mapmusic_t struct and rename to music_t
didnt see that all the music stuff was more or less using the same things
2025-02-10 06:35:03 +01:00
Alug 11ea49fd15 clean this up a bit 2025-02-10 06:19:58 +01:00
Alug d09ae5ef5b init JoyInfo stuff on startup
just in case
2025-02-09 17:47:50 +01:00
Alug 78b1476c87 use joystick id here 2025-02-09 17:05:00 +01:00
Alug a2e12767ce reset joystick id when closing 2025-02-09 17:04:49 +01:00
Alug e2ec2ff4de optimize ogl drawer functions
by avoiding excessive interger to float conversions
2025-02-08 23:17:43 +01:00
Alug a5dcea17b6 fix clang uninitialised warning 2025-02-08 23:07:39 +01:00
Alug f803128b16 fix oopsie with mapmusic in glib 2025-02-08 18:09:52 +01:00
Alug 777629d8c3 this should be static 2025-02-08 17:48:00 +01:00
Alug 3de5a2d1d1 throw music vars into a struct "mapmusic_t"
simplifies everything, keepmusic vars use it too
2025-02-08 17:46:58 +01:00
Alug 48c3081fdc handle music reloadreset stuff in seperate function
just tryin make it less ugly
2025-02-08 17:31:01 +01:00
Alug 00e3f48329 rename this 2025-02-08 17:25:01 +01:00
Alug 39744885f2 always save keepmusic stuff
but set keepmusresume in stopmusic Zzz...
2025-02-08 16:47:12 +01:00
Alug c6451208ad attemp to fix playerreborn resetting keepmusic 2025-02-08 16:28:23 +01:00
Alug 0774274e9c change speelines blending condition
uuuhh, so, if you have sneakerboost they always will apply additive blending
otherwise if you go really fast (faster than sneakerboost)
2025-02-08 15:36:33 +01:00
Alug 2dc3ca5f01 did not mean to push this 2025-02-07 18:19:53 +01:00
indev 174a7b5d84 Don't force specific characters in M_HandleConnectIP 2025-02-07 18:18:20 +01:00
Alug cd57ebd763 keep track of joystick index in struct 2025-02-07 15:57:13 +01:00
Alug b14d1f1e0b just pass the controller directly
simplifies this alot
2025-02-07 04:05:10 +01:00
Alug 3f3df9346f Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-02-07 01:00:32 +01:00
Alug b0535da97b smol cleanup 2025-02-06 17:29:35 +01:00
Alug cdc25fddc8 only apply additive blend to speedlines when any kind of boost is happening
to emphasize that ure boosting or smth
2025-02-06 17:25:17 +01:00
Alug 351f043131 update controller led when connecting a controller 2025-02-06 14:43:18 +01:00
Alug 5f7632decf dont pass bogus values to I_GamepadRumble and I_SetGamepadIndicatorColor
- fixes rumble and led stuff not working after hotplugging
- also fixes sdl2-compat breaking
- i hate karts controller code
2025-02-06 02:12:05 +01:00
Alug 235f830621 remove this from action list 2025-02-05 17:08:16 +01:00
indev d49b5af91a Don't start invinc/grow alarm sound when player uses power item
It will still be started in K_UpdateInvincibilitySounds, but now if
player already had invincibility, they won't get 2 overlapping sounds
2025-02-05 16:56:42 +01:00
Alug d245c6eca7 Revert "kill a bunch of uneeded null checks"
This reverts commit 7bc804bccb.
2025-02-05 16:52:45 +01:00
Alug f02bd5513e random shit i had stashed and too lazy since its for testing only anyways 2025-02-05 15:45:06 +01:00
Alug 88dc60648e screw you seenames 2025-02-05 15:33:10 +01:00
Alug 63d6987b93 also add additive to boostflame 2025-02-05 00:35:33 +01:00
Alug 2386877394 test fix software white pixels (thx indev <3) 2025-02-04 19:09:38 +01:00
Alug 65188a6652 add blendmodes to a bunch of effects
lul
2025-02-04 19:08:54 +01:00
Alug 35e1c3370d crappy deb prints for mus stuff 2025-02-04 12:56:18 +01:00
Alug 7904740024 show musiccredit when using tunes 2025-02-04 12:56:05 +01:00
Alug 8af0d2c14c keep track of map music
this is kinda horrible, but allows musicchanges which replace map music/tunes to also work with this system
2025-02-04 12:55:50 +01:00
Alug bfd19512b1 reset keepmusposition in tunes command
mapmusic will be reset the moment the gamestate changes, so whatever was changed with tunes will not be kept sadly
2025-02-04 02:41:31 +01:00
Alug b777e82890 save music position and try to fade back into mapmusic when the music changed from mapmusic when keepmusic is enabled
uhh idk how to explain lel
hope this doesent explode
2025-02-04 02:24:08 +01:00
Alug 8cc09712bc skip intro sounds also with keepmusic lel 2025-02-04 02:12:51 +01:00
Alug 21a1158798 add additive blending to fast speedlines 2025-02-03 20:43:30 +01:00
Alug 207741651a handle ogl sprite lightlevels like rr now that we have all the stuff for it 2025-02-03 20:43:03 +01:00
Alug 098f5c9086 oops didnt mean to move this 2025-02-03 19:54:51 +01:00
Alug 919623157b flag clash moment 2025-02-03 18:39:17 +01:00
Alug 2d1f3b90e4 forgor 2025-02-03 18:39:03 +01:00
Alug 67fb508e8d Update position nums to use additive
https://git.srb2.org/KartKrew/RingRacers/-/commit/4d108930a94f44dbc916d1116eab8421e669e4b6
2025-02-03 18:10:36 +01:00
Alug ec121f5ac7 fix merge conflicts 2025-02-03 18:07:29 +01:00
Alug 73dc9a794f Add line and FOF blending, fix model and shadow blending
also a bit of cleanup in r_things but it's too minor to headline
2025-02-03 18:00:04 +01:00
Alug 3e563df999 Prelim: Linedef alpha variable
realistically this was just because I'm Lazy
this makes figuring out linedef blending less of a brain twister
2025-02-03 17:59:39 +01:00
Alug 7ad25c5f19 Add blending modes 2025-02-03 17:59:18 +01:00
Alug 3bae721fa8 try simplify blockthings iterator 2025-02-03 14:42:44 +01:00
Alug e0ae6aa85c use vectors P_ClosestPointOnLine3D and kill vertex z 2025-02-03 14:42:23 +01:00
Alug 36508c24e3 apparently those temp variable are not needed 2025-02-03 14:41:51 +01:00
Alug 201ead11ea check for realpatch here too 2025-02-03 14:41:10 +01:00
Alug 05354a3352 no need pass this stuff 2025-02-02 15:18:05 +01:00
Alug ed6b6404a3 should revert this completely 2025-02-02 00:19:46 +01:00
Alug e7c68fbeea partly revert this
some of those "mightve" been changed at the point of the check
2025-01-30 13:25:46 +01:00
Alug 9c00b4c32d inline G_CopyTiccmd 2025-01-30 13:11:49 +01:00
Alug bab0f05c3e dont register a crapton of pointless stuff for dedi
should cleanup dedi config significantly lmao
2025-01-30 13:11:30 +01:00
Alug bc62f0632a tiny cleanup i_video 2025-01-30 11:45:35 +01:00
Alug f5c5978f9d dont need to do all this crap if disabled 2025-01-30 00:14:57 +01:00
Alug 8eaa1f6130 "kill" seenames
idk if anyone wants it, its still there, needed to move the netvar out of it tho lol
2025-01-30 00:07:32 +01:00
Alug 9a84d9f1f8 move this after the early returns
save some time when drifting
2025-01-30 00:04:21 +01:00
Alug 4b44af7cf1 lmao 2025-01-29 23:57:42 +01:00
Alug b16472a379 turn driftsparkGrowTimer into a player field
less hacky and avoids 3 loops lol
2025-01-29 23:57:25 +01:00
Alug 8f7d51e57c kill redundant laptime code
just use the newer one
2025-01-29 23:23:54 +01:00
Alug 3cc8f8650d In rehashtab, do counthash before adding asize
Thanks alug!
2025-01-29 22:28:44 +01:00
Alug 3162930634 cause undefined behavior in table resizing calculation. :chonkbuncle:
reverting https://github.com/LuaJIT/LuaJIT/commit/c56811bb7acf40174ac9b63e69f58b42adf85bd7

seems to fix the issue with mismatching tables between jit and kart blua
2025-01-29 21:44:22 +01:00
Alug 45a8f61266 refactor M_DrawSlider
apparently fixes weird framerate issues with gamma slider
also shows the values on sliders
2025-01-29 19:33:57 +01:00
Alug 2f66ba0126 inline V_LocalTransFlag
its very smol
2025-01-29 19:05:42 +01:00
Alug 90bdd24de2 even more replay deb prints lel 2025-01-29 12:16:38 +01:00
Alug 8527d71fa8 also print player name for item desynch 2025-01-29 00:46:16 +01:00
Alug aba60ffd74 smol replay fixes from rr 2025-01-29 00:32:20 +01:00
Alug 3e455ee8ee better replay resynch prints 2025-01-29 00:32:04 +01:00
Alug 5f297136b8 Have replay recording of "hits" use the reference count system
https://git.srb2.org/KartKrew/RingRacers/-/commit/fa8bffabfc51ea1d7be86d833190bb7dcf494fca
2025-01-29 00:08:50 +01:00
Alug 2b6c05839e try and just compare music with mapmusname first 2025-01-28 18:32:19 +01:00
Alug aa5b480a44 inline a bunch of super smol lua things 2025-01-28 18:31:54 +01:00
Alug ba38b69782 inline a few hooklib functions 2025-01-28 18:10:10 +01:00
Alug 8cf889c390 super smol optimization 2025-01-28 17:37:52 +01:00
Alug 398d62e2a6 pass slope to K_RollMobjBySlopes
removing some code dupe in the process and allows some more flexability
2025-01-28 17:33:44 +01:00
Alug c923c6c96a forgor to set those oop 2025-01-28 16:09:56 +01:00
Alug 983410c953 fix issues with models
- Sloperotation was weird, it now uses what we calculate in K_RollMobjsBySlopes
- in general uses srb2s newer system
- alot of cleanup of pointless variables
- sprinfo pivots should now work
- removed roillmodel since it was smth weird and broke rollangle
2025-01-28 16:05:20 +01:00
Alug 4260527170 dont rain on stuff without planes lel 2025-01-27 23:41:54 +01:00
Alug 34603b9128 dont recalc if precip sector didnt move
forgor i can just check this
2025-01-27 23:24:01 +01:00
Alug a4213d0316 only need to recalc this once a tic
precip thinker thinks slightly more often, but we really dont need that tbh
2025-01-27 23:13:34 +01:00
Alug 3f63d89099 only recalc floorz for visible precip mobjs
before it apparently recalced it a crapton for the crapton not visible precipmobjs, which even on vanilla maps led to noticable jitter
2025-01-27 22:25:34 +01:00
Alug 83b6b841c6 just keep a copy of musicchange before the lua hook
keep music can check for what was it stuff changed last to
2025-01-27 16:43:48 +01:00
Alug f84ac6febe grow an invinc music also broke stuff
cant put it into the music exception list, otherwise it will always disable keepmusic when either one was used even once
2025-01-27 16:13:00 +01:00
Alug 89443dfe30 the music system is truly amazing 2025-01-27 15:32:47 +01:00
Alug df33acdd01 i hate conditions 2025-01-27 14:54:49 +01:00
Alug e0579225f3 smol optimization comparePolygon
return slightly earlier for skywalls and horizonlines
2025-01-27 11:21:23 +01:00
Alug 4f64ba6e79 make old ping bar be blue on d1 aswell as purple with mindelay 2025-01-27 09:19:25 +01:00
Alug fd3efc5469 potential fix for clients locking up due to never receiving acks back
apparently, if the client doesent receive an ack back which may happen due to duplicate packets/bad net conditions, it may spam resend the packet until its netxcmd buffer is full and locks up
2025-01-27 08:58:21 +01:00
Alug 64afc7a737 set this to 1 2025-01-27 08:57:55 +01:00
Alug e5de2a0165 disable landing dust for now
idk how to not make it spawn when item was placed instead of thrown Zzz...
2025-01-26 21:15:12 +01:00
Alug 09a2deb6de also rotate eggboxes in air 2025-01-26 21:14:24 +01:00
Alug ef1917dc6b reduce dust momz a little 2025-01-26 21:14:08 +01:00
Alug 94fbd49f40 spawn dust when throwable item lands
also when you drive into a banan
2025-01-26 20:26:29 +01:00
Alug 9c00eedfaf fall through deez 2025-01-26 18:31:17 +01:00
Alug 444e42517f delet if else hell 2025-01-26 18:18:23 +01:00
Alug 33921e79f4 handle vote bg fallbacks more gracefully
if someone doesent provide a widescreen patch it now falls back to the replaced non widescreen one and vice versa instead of just falling back to what vanilla provides
2025-01-26 17:57:27 +01:00
Alug bdafaa014c forgor about the banan spin 2025-01-26 16:17:58 +01:00
Alug dfe9815837 reduce scope of those
makes it look slightly neater
2025-01-25 22:44:22 +01:00
Alug db5b728a97 draw non widescreen anim vote bg before falling back to vanilla bg
how it was before, the game just fallback to the vanila widescreen patch if there was no animated widescreen bg provided, just fall back to the non widescreen anim patch instead if it exists
2025-01-25 22:13:39 +01:00
Alug 10c0c8afab move this
no need to have two conditions for same thing
2025-01-25 21:50:40 +01:00
Alug f14591033d kart is special and changed ping colours
so change this to reflect it
2025-01-25 21:40:28 +01:00
Alug 4e76751372 make ping flash somewhat like vanilla again 2025-01-25 21:36:06 +01:00
Alug 7e8cda4a96 "makes integer from pointer without a cast" deez nuts 2025-01-25 16:59:31 +01:00
Alug cebbcbaf7c remove noshowhelp from bunch of debug cvars
doesent make too much sense those are hidden tbh
2025-01-25 15:39:40 +01:00
Alug 55e90733ec dont banan drag rumble when not driving lel 2025-01-25 09:32:49 +01:00
Alug fd95e6a075 setup maplight stuff earlier
otherwise it doesent init early enough
2025-01-25 08:05:51 +01:00
indev fb9212a8c6 Fix 'total podium' stat display using totalwins 2025-01-25 06:30:52 +01:00
Alug a19260080d inline one line gametype checks 2025-01-24 21:55:47 +01:00
Alug fe8b8d798c inline bunch of one line HWR things 2025-01-24 21:54:36 +01:00
Alug 2b988d404f inline G_TicsTo stuff
theyre smol and get called often
2025-01-24 21:19:50 +01:00
Alug 439a2811b1 j moment 2025-01-24 21:18:17 +01:00
Alug 097b70f069 add funny banan throw rotate thing
like rr
2025-01-24 19:24:56 +01:00
Alug f557ae8bd6 think we should copy this 2025-01-24 18:04:38 +01:00
Alug 4dd80ff328 make trailing items also be able to rotate on slopes
mostly stuff from RR thx!
2025-01-24 17:56:50 +01:00
Alug a011b4e3ee spawn speedlines with non synched rng if ur in eggbox status
and well only if you have colourisation enabled
2025-01-24 17:14:30 +01:00
Alug 69d8dafc8f oop 2025-01-24 06:43:46 +01:00
Alug 10028a4769 proper add server gentlemans
this should be a netvar, but we cant really do that, thought not a huge deal
however id wish to send some kinda message to all players but idk
2025-01-24 06:39:57 +01:00
Alug 86712703d7 dont mess up realpingtable
when serverplayer has mindelay active
this was supposed to show mindelay for serverplayers but that doesent work :chaosleep: so just do not mess with it
2025-01-23 21:55:37 +01:00
Alug 230962c8c2 slight cleanup HU_drawPlayerPing 2025-01-23 21:25:26 +01:00
Alug a3dfa2a930 assign player later 2025-01-23 20:40:05 +01:00
Alug 4ce0a6c63e try speedup P_LoadRawSubsectors 2025-01-23 20:33:11 +01:00
Alug 25b13a89d4 try speedup P_LoadRawSectors 2025-01-23 20:27:56 +01:00
Alug c2611a465a simplify camtoggledelay and spectatedelay
just make em an array and use lööp
2025-01-23 19:45:23 +01:00
Alug bb6e58b5ce kill P_TeleportMove
P_MoveOrigin literally just calls that so replace it with that
2025-01-23 19:33:35 +01:00
Alug 7aa641bbfd colourise ping colour 2025-01-23 18:06:41 +01:00
Alug 3d3ebdefd6 a 2025-01-23 18:06:19 +01:00
Alug ad4be98c8a colourise pingnumber when gentlemens is active 2025-01-23 18:06:06 +01:00
Alug 86a172800d division by zero moment 2025-01-23 17:38:20 +01:00
Alug e1cfbd25fa add gentlemens delay to ping display
+ display ping even offline if you have mindelay active
2025-01-23 16:48:38 +01:00
Alug 0a40a28c3d smol cleanup 2025-01-23 16:16:46 +01:00
Alug ff90a678f1 port clientsided gentlemens delay
cant do the serverside stuff due to netvars
2025-01-23 16:03:12 +01:00
Alug edb7678675 just use D_NumPlayers 2025-01-23 15:50:45 +01:00
Alug d19e3b69fc Prevent dropped ticcmds due to interp timing jutter
kinda figured out what this does, and makes clients on uncapped listen servers alot less prone to drop gametics
2025-01-23 15:05:11 +01:00
Alug 70428d2309 fix freecam not resetting online
idk local player handling is fucking awful in kart
2025-01-22 19:42:01 +01:00
Alug b14b913d0a try just passing the sector + add 50 trillion extra checks
idk anymore but this is literally now how vanilla kart behaved
2025-01-22 19:08:03 +01:00
Alug f0df97589f skip some stuffs when theres no portals
skip some portal checking incases wheres no portals
2025-01-22 18:04:50 +01:00
Alug 58d0b5ffc6 remove redundand FTransform field 2025-01-22 16:46:58 +01:00
Alug fd1ea7ab0a more smol ogl sprite drawer optimizations 2025-01-22 15:45:08 +01:00
Alug 2036dfd83b also fix potential use-after-free in HWR_AddPrecipitationSprites
no clue why ogl didnt do it since its effectivle the same code as software
2025-01-22 15:44:25 +01:00
Alug fa9582cc72 no need to check for invisible precip here
the early returns indirectly handles things since we dont have custom weather support in kart
2025-01-22 15:43:24 +01:00
Alug 4b7a2848e5 split HWR_DrawSprites
saves on ALOT of conditional branching in a lööp when models are disabled
2025-01-22 15:23:30 +01:00
indev 9c16798fdb Check for spectator in K_StatRound 2025-01-21 16:54:53 +01:00
Alug 0d3d958b46 fix level statistics page controls 2025-01-21 16:54:28 +01:00
Alug a899923067 use SRB2.2s general folder structure
- seperate addons folder (download folder remains in home directory unlike RR)
- seperate gif and screenshot folders
2025-01-21 01:35:10 +01:00
Alug 6e0519bbbc use SRB2.2´s logging system
- creates a new logfile each start instead of overwriting it everytime
2025-01-21 00:50:21 +01:00
Alug 26ef5b0dad e better play it safe 2025-01-20 22:26:07 +01:00
Alug 127a7e5ae7 delete nonfunctional second mouse stuff 2025-01-20 22:02:08 +01:00
Alug 7320fdc340 kill even more unused patches
+ nonexistand crosshair stuff
2025-01-20 21:30:37 +01:00
Alug 867bc8197b dont cache all those unused hud graphics 2025-01-20 21:12:06 +01:00
Alug db7ab2d33f Hold up/down for 2 seconds while not moving to pan the camera vertically
from RR
2025-01-20 19:33:47 +01:00
Alug f56de827b5 a 2025-01-20 19:21:33 +01:00
Alug a9cb23be79 oops didnt init this 2025-01-20 19:17:41 +01:00
Alug 07287d056c dont turn 90 degrees when switching to freecam 2025-01-20 19:00:10 +01:00
Alug f3c44b48b9 kill aiming stuff in BuildTiccmd 2025-01-20 18:53:26 +01:00
Alug 5ab348bf30 fix freecam vertical look for the 500th thousand time
truly amazing code
2025-01-20 18:04:05 +01:00
Alug 2715699648 put this thing onto its original place 2025-01-20 15:22:00 +01:00
Alug 355dc07401 code dupe P_CyclePlayerMobjState 2025-01-20 15:19:43 +01:00
Alug 7c7e820a94 put this into switch
looks better
2025-01-20 15:09:19 +01:00
indev 2fd8532be0 Put playtime statistics at first page instead of RA medals 2025-01-19 01:10:55 +01:00
indev 83091413e7 New statistics menu (WIP) 2025-01-19 00:59:19 +01:00
indev 14fff2e3a3 Wipe kart stats on game data reload 2025-01-19 00:45:32 +01:00
indev ba26fc8226 That was from testing a 2025-01-19 00:31:32 +01:00
indev 85d68a7b7b Make custom stats fully compatible between different versions, so new fields can be added in future without save corruptions 2025-01-19 00:30:55 +01:00
Alug 2885dbfb12 remove some code dupe in R_AddLine 2025-01-19 00:03:46 +01:00
Alug 9e5341537a ; moment 2025-01-18 21:35:22 +01:00
Alug cedf7beaa1 more sane thing 2025-01-18 21:22:20 +01:00
Alug dd84250c8a actually should always use mobjscale 2025-01-18 21:06:30 +01:00
Alug fe3a7525b3 mobjscale precip sectorheight stuff 2025-01-18 21:04:20 +01:00
Alug 5380ce85d9 fix lessprecip toggle doing nothing
logic error on my part
2025-01-18 21:03:06 +01:00
Alug cc043cb4c8 use MT_NULL instead of number 2025-01-18 14:36:35 +01:00
Alug db6cd6b510 refactor weather switching
from srb2
makes this more sane and makes PRECIP_STORM_NORAIN not spawn a crapton of invisible mobjs
2025-01-18 14:29:44 +01:00
Alug 6670b6f611 idk why we check this 2025-01-18 11:45:20 +01:00
Alug 2d5cf03ceb attempt optimizing P_PointOn stuff again
this time non inversed and wrong lel
2025-01-18 11:44:34 +01:00
Alug 51631dcb40 forgor to check for that flag 2025-01-18 11:44:09 +01:00
Alug ff620c0218 change tooltips slightly 2025-01-17 23:44:17 +01:00
Alug 7cc3f6af7f add stuff to menu 2025-01-17 23:42:50 +01:00
Alug 56007eda9c ok clang 2025-01-17 23:35:33 +01:00
Alug 9b4d275d51 replace byte2float table with direct calc
actually speeds up things for me by around 5-10fps
2025-01-17 23:07:50 +01:00
Alug 405693e1ed shut up clang 2025-01-17 23:07:03 +01:00
Alug 269dbc6fef set sdl audio resampling mode to highest quality 2025-01-17 21:45:07 +01:00
Alug 8346d59a42 try to use double buffer vsync 2025-01-17 21:44:54 +01:00
Alug 4e34b549b5 disable this 2025-01-17 21:44:32 +01:00
Alug fe598266e3 fix nofbocompile 2025-01-17 21:42:19 +01:00
Alug d6579a9e6d :chaosleep: 2025-01-17 19:53:30 +01:00
Alug c057803a17 add toggle for item amount number display 2025-01-17 17:15:00 +01:00
Alug 0bcd840f60 Revert "turn on multiitemicons by default"
This reverts commit 9217cd3832.
2025-01-17 16:48:06 +01:00
Alug c7425a02ac "Fix console text bleeding "
read https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1434
2025-01-17 14:22:56 +01:00
Alug 0f7c91e894 cap console animation if uncappedhud is disabled
since thats "how vanilla done it" before
2025-01-17 14:17:44 +01:00
Alug e9f7f50088 use R_GetHudUncap 2025-01-17 14:12:19 +01:00
Alug b8540f9e21 add fancyroulette toggle 2025-01-17 14:12:07 +01:00
Alug 2196905023 add the fancy hudtrans flags 2025-01-17 13:58:29 +01:00
Alug bc874e5605 dont fancy during respawn 2025-01-17 13:58:14 +01:00
indev f84a78c4e6 Fancy :D 2025-01-17 13:50:11 +01:00
Alug db836ae315 turn on multiitemicons by default 2025-01-17 12:58:26 +01:00
Alug b328b98a2d add banan jitter toggle to menu 2025-01-17 12:37:23 +01:00
Alug 66bfff4f84 change how spritescales and offsets work
- now theres realoffsets aswell
- allows better control of changing things per lua and still do funky stuff in hardcode without conflicts
- spritescales and offsets now get reset centralised before any thinkers run
2025-01-17 00:54:40 +01:00
Alug 32bc9979a0 add toggle for bananjitter 2025-01-16 23:42:21 +01:00
Alug 55f2841c33 only rumble banan when on ground 2025-01-16 23:32:59 +01:00
Alug 127e2bcf27 fix typo lel 2025-01-16 22:33:17 +01:00
Alug e84e186df0 don use multiicon patches in 3/4p splitscreen
since it uses the smoler patches
also removes redundant assignments
2025-01-16 21:58:37 +01:00
Alug d6ad6f85ea simplify keepmusic
honestly no clue why i made stuff check on every music change
2025-01-16 21:00:47 +01:00
Alug f8515f697e clean up d_net 2025-01-16 00:59:38 +01:00
Alug 89856bf5b2 Clear acktosend when initializing node
since it was never reset, values might been taken over from former node
2025-01-16 00:58:52 +01:00
indev 3743303748 Add spb music to list of exceptions for keepmusic 2025-01-16 00:57:45 +01:00
Alug 6b5517ee2c dont keep music if there is no music 2025-01-16 00:57:39 +01:00
indev de8ffbfd60 Fix spectator control text overlapping when showdirectorhud is off 2025-01-15 21:39:02 +01:00
Alug ade0526311 oops 2025-01-15 12:59:00 +01:00
Alug 713fe463b0 ignore invisible fofs again 2025-01-15 12:57:53 +01:00
Alug c18695d194 make freecam strafe be affected by freecamspeed cvar 2025-01-15 12:57:35 +01:00
Alug 4cacac86cd also skip invisible fofs 2025-01-15 12:09:48 +01:00
Alug 719c70a432 dont throw a warning about addons with custom gamedata
just ignore it
2025-01-15 11:54:56 +01:00
indev db567a3d80 G_PlayerReborn didn't work for 'respawns' stats, maybe G_DoReborn will? 2025-01-14 20:05:38 +01:00
indev 61bcab727f Player kartstuff's get reset in G_PlayerFinishLevel, so need to call K_StatRound earlier 2025-01-14 20:05:33 +01:00
Alug 2512a9bc87 no need to strcmp just check for "savemoddata"
that bool only ever gets set to true if the savegame has been switched to the modded one and unlike in srb2 this WILL never be reset to false again
2025-01-13 17:42:22 +01:00
Alug a51540fe06 save vanilla save when switching to modified savegame
also add check so we dont rerun this everytime setgamemodified is called
2025-01-13 16:41:45 +01:00
Alug 26b8b126d2 remove "majormods" checks from stuff that saves to savegame
so its only there to throw a notice when you load an addon
2025-01-13 16:37:56 +01:00
Alug 37ed39840f Merge remote-tracking branch 'origin/kartstats' into lugstuff 2025-01-13 16:00:55 +01:00
Alug 6fa1ec8a07 Revert "make game use seperate save when addons are loaded"
This reverts commit 07e1c9e993.
2025-01-13 15:58:28 +01:00
indev 723f5a97f2 Clear menus when running 'map' command 2025-01-13 15:54:20 +01:00
Alug 88761ce4a4 remove this
hooklib refactor already indirectly fixed this so this code is pointless
2025-01-13 15:50:12 +01:00
Alug 07e1c9e993 make game use seperate save when addons are loaded
so you can record attack and it will also keep saving to statistics
also added a few things it now keeps track of
TODO: unfuck the statistics page and add a 2nd one perhaps? due to space reasons
menucode is hell
2025-01-13 10:47:38 +01:00
Alug c3c5a38360 this doesent work out
breaks some textures not appearing on some maps
2025-01-13 07:55:02 +01:00
Alug b36b2379b2 slightly cleanup gravstretch stuff 2025-01-12 17:07:07 +01:00
Alug fdef0127fa change banana default patch to match lua roulette hud behaviour 2025-01-12 17:01:12 +01:00
Alug 56c4d72318 add support for multiitem patches (thx neppy!)
needs new patches, unsure if we just gonna add em to the extra file or make a new one
so it ambigous for now
2025-01-12 17:01:08 +01:00
Alug e64fc61fac oops fix menu stuff 2025-01-12 17:01:04 +01:00
Alug c5ccb2cd2c oops those should be player scale actually 2025-01-12 02:33:59 +01:00
Alug 90eda3b79a fix having saltyhop disabled forcing player spriteyoffset to be forced 0
just clear out everything on toggle
2025-01-12 02:27:32 +01:00
Alug dd8ac9f75c add toggle to colour sneakertrail flames (thx neppy!) 2025-01-12 02:00:31 +01:00
Alug 4d37cfba2a split ra wheel and position number hud offsets
kinda ass due to the preset offset, but will just not apply if either was changed from its original position
2025-01-12 01:51:37 +01:00
Alug 8fac3fa367 toggle for camera turnaround on timeover 2025-01-12 00:59:47 +01:00
Alug fc658f3fe9 forgor about software again 2025-01-12 00:01:57 +01:00
Alug 4c7a204151 TEST: skip prepping 3d floors for fofs without planes
or if they were already checked
2025-01-11 23:27:44 +01:00
Alug fa09ee3c42 split HWR_RenderBSPNode
to reduce function call overhead
its only microscopicly faster lel
2025-01-11 23:04:35 +01:00
Alug 031c1017c1 one line this 2025-01-11 22:34:45 +01:00
Alug e3a4a85833 fix frame flag clash 2025-01-11 19:54:59 +01:00
Alug bf0d4077b0 hmm try making them have absolute lightlevel 2025-01-11 18:10:15 +01:00
Alug 0c5c12adb9 simplify cmpack 2025-01-11 18:09:51 +01:00
Alug ba27cd1c6c put random direction light toggle into advanced video options
also make it a scoll menu
2025-01-11 18:08:14 +01:00
Alug 0bc865395e reinit random maplight on mapchange when toggled
the condition may otherwise not change the light if you restart the same map
2025-01-11 08:52:41 +01:00
Alug f78d5fffdc oops 2025-01-11 08:28:49 +01:00
Alug 0801c18e22 add FF_ABSOLUTELIGHTLEVEL
mobj_t.lightlevel is absolute instead of relative when set
2025-01-11 08:22:30 +01:00
Alug fe3bc867bc add encore variants of maplight 2025-01-11 08:03:59 +01:00
Alug 23dd5aa1d9 forgor this 2025-01-11 07:50:10 +01:00
Alug 52b8a34535 if disabled and no soc overrides light behave like vanilla
always apply wall and slope contrast pls
2025-01-11 07:34:41 +01:00
Alug 4f5d49292c change how randomized light works
so it doesent kill actual soc set randomlight if you toggle it
2025-01-11 07:25:12 +01:00
Alug c991abc64d move this 2025-01-10 22:46:05 +01:00
Alug ca7b397e21 "Invinciblity" 2025-01-10 22:31:31 +01:00
Alug 6b44984549 seperate game turn axis from cam turn axis
both are bound to the same value by default, so vanilla controls remain intact
theres no other good way to have gamepad controls for this sadly
2025-01-10 22:23:28 +01:00
Alug 06ae053783 strafe controls for speccam/freecam
TODO: seperate cam turning axis from gameplay turn axis for gamepads
2025-01-10 18:33:50 +01:00
Alug 178db4baae let "fovchange" work in software 2025-01-10 14:58:58 +01:00
Alug 0ffff2751e clamp to length-1 2025-01-10 02:14:31 +01:00
Alug 9121ec9527 reinit minimap stuff when a wad is added while ingame 2025-01-10 02:11:43 +01:00
Alug 8f251485a3 fix column drawers clamping stuff 2025-01-10 01:54:31 +01:00
Alug 5ea1e2bd71 kill unarchivevaluedemo
just pass if we load from replay or not and do stuff accordingly
2025-01-09 20:05:06 +01:00
Alug 21d1bd3033 make gamestate download show total gamestate size 2025-01-09 18:21:32 +01:00
Alug a79e78644d this should also use unpaused rendertimefrac 2025-01-09 17:25:50 +01:00
Alug 782e3172ad do some lööp unrolling for software span drawers
actually gained me like 5 fps on 1440p for some reason lel
2025-01-09 17:15:30 +01:00
Alug 5fbc1ae911 use lööps for those to look a little better lel 2025-01-09 17:11:02 +01:00
Alug 8c8a597559 dont reset cam using f12 when only one player is ingame 2025-01-09 17:06:45 +01:00
Alug f3f5f364d3 slightly refactor chasecam stuff again 2025-01-08 23:49:26 +01:00
Alug e70342fc19 le funny banan drag jumpy 2025-01-08 18:34:54 +01:00
Alug f168c2f8c4 fix postimg data types mismatch
also remove the "postimgflag_t" typedef since its useless
and use smoler type for everything we dont need much space lol
2025-01-08 18:23:25 +01:00
Alug 89e5ed191c shouldnt this be uint? 2025-01-08 15:42:36 +01:00
Alug e02ad7883c this is not needed anymore 2025-01-08 15:12:31 +01:00
Alug 5bb613dda1 smol cleanup localskin ranking shit 2025-01-08 06:29:17 +01:00
Alug 37b3519a51 grow pp rumble 2025-01-08 06:02:11 +01:00
Alug 95ed1712bf add banandrag rumble lol 2025-01-08 05:51:00 +01:00
Alug 1d5502a17e add slight fadeout to spinout rumble 2025-01-08 05:50:41 +01:00
Alug eee6e4e020 driftcharge toggle + menu entry 2025-01-08 05:04:54 +01:00
Alug 7cdacc7bdd add a toggle for colourspeedlines 2025-01-08 04:58:36 +01:00
Alug 64d447298b move this
to preserve order as best as possible due to synched rng zzz...
2025-01-08 04:48:37 +01:00
Alug 5433a9d31d reorder saturn hud menu a little
also remove uncapped hud from it, since why would you ever wanna turn it off?
2025-01-08 04:31:11 +01:00
Alug d30934fa4d move saturn hud cvars to k_kart and fix driftgauge extra showing
if there is no patch for it
its kinda dumb, since technically would allow to not load all of em
but im lazy and dont wanna change possiblevalues around
2025-01-08 04:01:48 +01:00
Alug eed42d9b18 toggle for smol positionnum and posnum animation 2025-01-08 04:00:57 +01:00
Alug 44c016fd2c fix "connect" command not saving to last server 2025-01-08 03:17:14 +01:00
Alug f0f1a16982 oops forgor those 2025-01-08 01:48:55 +01:00
Alug 4b6587e8ba clean up gamepad led stuff 2025-01-08 01:46:56 +01:00
Alug f427dce73b dont rumble in freecam + player fix 2025-01-08 01:33:37 +01:00
Alug a4ddbff64d oops fix software lel 2025-01-08 00:13:27 +01:00
Alug aa937f2f7b clean up this mess a little 2025-01-07 22:47:35 +01:00
Alug bc1cde262c a 2025-01-07 22:04:52 +01:00
Alug 56014403b2 aight try this 2025-01-07 21:15:40 +01:00
Alug 48566ea8eb fix fbo crap once again 2025-01-07 20:16:28 +01:00
Alug e44bec1b8c check if subsector has sector before assigning 2025-01-07 19:49:36 +01:00
Alug a8bfd89b01 fix freecam aim getting stuck and other issues
- gamepads now aim like they used to and at same speed as keyboard
- aim reset has been changed so it resets automatically, but also can be manually reset with centerview
- aiming is locked during cam reset
2025-01-07 18:47:12 +01:00
indev 0f245f52b1 If available, add map title into crash log 2025-01-07 16:30:37 +01:00
Alug ae8629ecba replace common damage magic numbers with named macros
that stuff always confused me before lol
2025-01-07 16:30:32 +01:00
Alug f0f69e873a readd check for banan
this time without mobjwasremoved
just check if banan exists
2025-01-07 16:29:33 +01:00
Alug e9c35d269d check for cam subsector
since we can move it around and i added this to freecam mode, subsector may be null for reason so better be safe than sorry
2025-01-07 16:28:38 +01:00
Alug ee8f937866 idk but this func crashes often enough 2025-01-07 03:48:14 +01:00
Alug 1a0bb18de7 make this more complicated due to a "-" 2025-01-06 22:50:15 +01:00
Alug f4fa1fbd8c check for 0 to avoid division by 0 2025-01-06 22:40:56 +01:00
Alug 50593dbfc2 change director toggling handling
- now not changable over console anymore, bind only!
- it doesent save anymore so its always disabled at game start
- moving while in spec state will disable director when active so stand still
- disable it in splitscreen completely
- only adjust view when toggling it on
2025-01-06 22:40:36 +01:00
Alug 65b5415216 let postimg stuff also apply to freecam 2025-01-06 22:02:34 +01:00
Alug bbe9d29d5c add a little extra safety here ig
this crashed on levelload once so idk maybe player was null ig
2025-01-06 19:49:29 +01:00
Alug b77673550e save a whopping 2ms from gamestart to race start on texture updating 2025-01-06 19:05:42 +01:00
Alug d82acd060c double the slack for slep 2025-01-06 19:01:58 +01:00
GenericHeroGuy 3f139d83ca Add cleanjit target
Recompiling the whole game after changing a single flag is pretty tiring
2025-01-06 17:12:32 +01:00
GenericHeroGuy a8743d50b8 Fix some functions leaking doubles in INTONLY 2025-01-06 17:12:29 +01:00
Alug 9c105db8da any of those may be NULL in MakePatch
no idea but this crap keeps crashing in some other place every single time i add a check somewhere else
2025-01-05 23:02:27 +01:00
Alug 25bcd2b866 thats not timedemo lel 2025-01-05 21:24:48 +01:00
Alug 31726b05e6 turn off any active menus when using demo play commands 2025-01-05 21:23:45 +01:00
Alug 2f1e591d06 disable pause vhs effect when in freecam mode 2025-01-05 20:37:39 +01:00
Alug 8cb4349950 slight slep optimization
https://git.do.srb2.org/STJr/SRB2/-/commit/1da55066d43ed6a0cb666999c20316bef463024b?merge_request_iid=2583
2025-01-05 20:12:19 +01:00
Alug 38653dd22f disable director while in replay freecam 2025-01-05 19:01:54 +01:00
Alug e6e179453c no u may be used uninitialised 2025-01-05 18:53:49 +01:00
Alug 849cfbfbfa Adjust slack based on precision
https://git.do.srb2.org/STJr/SRB2/-/commit/d20552c49d9fd6a2075ebd7d46b0b133c69f1dbe?merge_request_iid=2583
2025-01-05 17:41:02 +01:00
Alug d9b04cd7d8 --------- 2025-01-05 15:11:09 +01:00
Alug 678e2f604c remove this again
seems like it basically doesent change anything
2025-01-05 15:03:39 +01:00
Alug 7bc804bccb kill a bunch of uneeded null checks
P_MobjWasRemoved already checks if mobj is null lol
2025-01-05 14:50:23 +01:00
Alug 56177e06bf slight cleanup buildticcmd 2025-01-05 14:17:44 +01:00
Alug 2b1b1fd882 put refreshdirmenu back here 2025-01-05 14:14:34 +01:00
Alug 3e976415f0 this somehow got lost lel 2025-01-05 01:11:26 +01:00
Alug f5ee615b2d dont cast "infinity" to int lel 2025-01-05 00:41:41 +01:00
Alug beaf44040d Further improve sleep accuracy on UNIX systems
hanichad https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2583
2025-01-05 00:32:23 +01:00
Alug 807eff3168 revert "Faster z position checks for mobjs without collision" 2025-01-04 22:17:15 +01:00
Alug ba394303b1 reduce ternary hell a little lel 2025-01-04 21:54:45 +01:00
Alug 9bbd33ad48 make float and sink use accel and brake again but also keep rebindable controls
keeps intended behaviour since we now dont need to worry about player controls anymore
but keeps the rebindable buttons incase someone wants to do a crazy control setup for some reason
2025-01-04 21:03:22 +01:00
Alug 77ff2b986d more hAx: dont move player during freecam state besides hop and honk
useful if you wanna take pics and dont feel like driving away
2025-01-04 19:37:52 +01:00
Alug b8e9cd0a42 dont do this while not in replay
this is kinda awkward tbh, but its useful for replay stuff
2025-01-04 19:33:43 +01:00
GenericHeroGuy d6d9839985 Use references instead of upvalues for original I/O functions
No more unrestricted I/O through debug.getupvalue
2025-01-04 02:28:53 +01:00
GenericHeroGuy 68e0f40b86 Update to BLUAJIT 449b76f 2025-01-04 02:28:49 +01:00
Alug 3085e49e87 forgor about lookback ig 2025-01-04 01:55:40 +01:00
Alug f733bf140e check for consoleplayer since displayplayer is who youre watching 2025-01-04 01:55:40 +01:00
Alug ef94e1051f remove redundant stuff
can just set this all the time, its only used when menu is active anyways so it doesent matter if we set it
2025-01-03 20:09:28 +01:00
Alug 7687e6effc simplify this 2025-01-03 19:35:29 +01:00
Alug d705bd3fb7 oops smol error 2025-01-03 18:29:21 +01:00
Alug ea484e4aec move postimg flags to camera struct
- also dont let water and heat be applied on top of each other since it does not look good (water postimg takes priority over heat)
- also save a little time in opengl splitscreen since it does not support heat or wöter effects
2025-01-03 18:18:20 +01:00
Alug a77aa11e36 fix encore mirroring not applyingg to freecam/democam 2025-01-03 16:40:43 +01:00
Alug b1f6263537 didnt mean to revert this one 2025-01-03 15:53:08 +01:00
Alug 4c38961efa do NOT repeatedly call M_Responder!!
"thread safety" or smth
also put stuff into two seperate functions, since i started hating nesting
2025-01-03 15:51:38 +01:00
Alug dc6904fad2 clean shit up even more + fix cam aiming reset
dont really care about which input anyways.
2025-01-03 07:33:28 +01:00
Alug e9b1329f15 try and clean up this mess
+ fix cam angle being wrong when you switch to freecam from viewing someone
2025-01-03 07:01:04 +01:00
Alug bd989239ea add another local ticcmd builder so it can guess if we "moved" and put us into freecam state and shit 2025-01-03 01:18:30 +01:00
Alug 3dd0313d53 only ever touch this if player has a mobjs
angleturn is dumb in kart and rarely really is what we want
2025-01-03 01:14:01 +01:00
Alug b91f2e91f1 smol fix 2025-01-02 22:18:52 +01:00
Alug dd267a725b apparently this is slower for everything but rendering 2025-01-02 21:50:02 +01:00
Alug 7a5c255956 let windoze detect 64bit mingw in makefile
lets us use just "make" cmd without specifieng any other crap on mingw64
2025-01-02 20:55:47 +01:00
Alug a33b225c0b move camera noclip stuff into its own function
its not used in kart anyways and moving it makes crap more readable
2025-01-02 17:07:41 +01:00
Alug dfdea068ef let playercmd lua hook run during "spectator" input crap lmao 2025-01-02 16:55:20 +01:00
Alug 0c0f52c38c fix unitialised use of controller stuff 2025-01-02 16:54:54 +01:00
Alug f017db6be0 do some actualy casting for angle and aiming cmd stuff 2025-01-02 16:45:02 +01:00
Alug 2b0e3104a6 move spectator hack after pause/desynch code
this should take priority over everything
2025-01-02 16:44:30 +01:00
Alug f7dad2c580 giga shizo spec synch "fix"
ok so, for whatever dumb reason, spectatormovement will desynch at random, even on localhost.
with this we just literally fucking ignore almost every button input locally and just wont move our spectator player at all.
but since we are indeed still runiing specatotr movement code, and this is localcmd shit, the server just thinks we dont want to move and thus is "synchsave".
sadly this does not fix desynchs from vanilla players
the only code we keep is for button inputs that do certain actions like "item" so we can still join from spec with it and other crap
2025-01-02 06:49:54 +01:00
Alug 087fbca227 this doesent work for us 2025-01-02 06:49:51 +01:00
Alug 6024405de4 add speccam playerflag
the other thing was weird and dumb lol
2025-01-02 06:49:47 +01:00
Alug 574ff2cb84 this may not be synchsafe 2025-01-02 01:52:25 +01:00
Alug 823b0eeaa2 save subsector checks for dedi 2025-01-01 23:30:16 +01:00
Alug fa21a9621e speed up camera position checks 2025-01-01 23:28:48 +01:00
Alug 1f8203b155 logic error lmao oops 2025-01-01 21:52:54 +01:00
Alug 2c55e28ea5 use FRACUNIT in rumbleticker + some changes
- brakedrift will now add to any rumble thats currently going on
- both hyu and invul now rumble less heavy on offroad
2025-01-01 21:34:02 +01:00
Alug 878b1d60da Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2025-01-01 18:13:34 +01:00
Alug 87a14fa263 slightly cleanup rumble and led ticker 2025-01-01 17:36:47 +01:00
Alug 32a35eb2e7 try a continue in P_NetArchiveThinkers lööp
nothing huuuuge, but on some maps with alot of thinkers this saves a tiny bit of time when creating a save
2025-01-01 17:19:12 +01:00
Alug 81c1f2d1a8 always close any menus when using "connect" command 2025-01-01 17:06:03 +01:00
Alug 2cfc1a7980 those will never be changed ever 2025-01-01 06:18:05 +01:00
Alug 248e47118f hack: only let freecam for spec move when youre actually able to move as spec
cause kart weird, and we cant remove the spec movement due to synch reasons
and letting the cam move instantly instead of waiting, may put you in a weird cam position
2025-01-01 05:37:30 +01:00
Alug e18d973d5e move early return even earlier
so theres no need to constantly init scale and drawdist
2025-01-01 05:10:52 +01:00
Alug da3ffafc90 we dont really need to check for precipthinkers in the precip thinkerlist
also makes precip handling in P_NetUnArchiveThinkers a little safer
2025-01-01 05:07:56 +01:00
Alug cf32ce90b6 dont iterate through precip blockmap if there is no precip 2025-01-01 05:06:52 +01:00
Alug 970657eb74 attempt to optimize column drawers a little 2024-12-31 00:57:32 +01:00
Alug 65ab0c21d4 reset refreshdirmenu at diff place
idk maybe this finally actually fixes the crappy addon menu
2024-12-31 00:12:09 +01:00
Alug 4633a55c97 dont try to chase after your spec mobj lel 2024-12-30 23:10:51 +01:00
Alug a27642faee readd this check lel 2024-12-30 22:21:26 +01:00
Alug 8368c668df fix potential Fix segfault when aborting HTTP download 2024-12-30 17:34:13 +01:00
Alug b932edb983 fix potential cash with perfstats
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2576
2024-12-30 17:29:27 +01:00
Alug 1cf4db9148 hide director control stuff for others than player 1 2024-12-30 11:29:49 +01:00
Alug d12320bbb5 dont disable this.... if its disabled kek 2024-12-30 11:24:14 +01:00
Alug 213b3124fa slight cleanup director 2024-12-30 11:11:16 +01:00
Alug 10a306110b aaaaa 2024-12-30 11:03:38 +01:00
Alug da9b6f80f1 forgor 2024-12-30 11:02:13 +01:00
Alug ca9f2aa9c0 kill splitscreen director again 2024-12-30 11:00:05 +01:00
Alug d88ececbea no need to check for all this crap 2024-12-29 20:00:35 +01:00
Alug 01a325736d dont need this anymore 2024-12-29 19:46:14 +01:00
Alug bec1420591 remove this turning off director
director will only work when in spec anyways
2024-12-29 19:33:50 +01:00
Alug a1a644aa48 fix some potential issues with viewinterp
now unpaused disabled interp on netlag
also fixes screencoord stuff not being interpolated during pause
2024-12-29 19:29:12 +01:00
Alug ec68b885d7 fix driftgauge showing with freecam while ingame 2024-12-29 19:21:40 +01:00
Alug 57d01415e2 readd cam cmd stuff
cause it may break the cam in replays or smth a
2024-12-29 19:21:23 +01:00
Alug 8a3b934518 allocate some extra buffer for demobuffer
incase this might overflow that we dont write to unvalid memory
thx indev <3
2024-12-29 17:56:35 +01:00
Alug f775bb54a5 change error msg 2024-12-29 17:45:20 +01:00
Alug 9cc96f9d70 reset demo recording in those places 2024-12-29 17:43:09 +01:00
Alug 93da9867b4 add warning for non allocated demobuffer 2024-12-29 17:38:36 +01:00
Alug 9ed6a0af1e fix demo playback 2024-12-29 17:14:47 +01:00
Alug d97f86b3f6 fix wrong cam default controls 2024-12-29 16:51:07 +01:00
Alug 871fa6bb67 fix offbyone issue 2024-12-29 16:48:29 +01:00
Alug d7f31cfea0 add a mipmap check here ig 2024-12-29 15:40:11 +01:00
Alug 6182fd9488 let director switch to splitscreen players lel 2024-12-29 15:34:43 +01:00
Alug dad904967e add a bunch of extra checks into demo stuff
buffer may be NULL in some cases
should fix dedis crashing when replay recording is disabled
2024-12-29 15:34:10 +01:00
Alug 2186fc6ce0 dont need to do this twice 2024-12-29 06:40:13 +01:00
Alug de8c933f1c fix centerview 2024-12-29 06:37:10 +01:00
Alug fda002c736 block freecam toggling when player is in spec 2024-12-29 06:36:36 +01:00
Alug 9c34bb0ae7 clean up cam stuff for good 2024-12-29 06:27:18 +01:00
Alug 5c7d12b60d make function to return button names
to use with new rebindable cam controls
2024-12-29 06:02:35 +01:00
Alug 7ae685565a make debugdirector show stuff for p1 atleast 2024-12-29 05:51:04 +01:00
Alug 4fbfb19b21 Revert "always call fixcamera when toggling freecam"
This reverts commit 3ca07376ac.
2024-12-29 05:44:45 +01:00
Alug dd8aca5773 track views in directorinfo structs
should hopefully fix any potential remaining issues
2024-12-29 05:42:21 +01:00
Alug b903dc1205 fix director toggling + smol cleanup 2024-12-29 05:32:51 +01:00
Alug 3ca07376ac always call fixcamera when toggling freecam 2024-12-29 05:01:09 +01:00
Alug 49518b753e toggle off freecam when f12ing 2024-12-29 05:00:41 +01:00
Alug 413f236a7d missing inlucde 2024-12-28 18:52:49 +01:00
Alug 64a5a4920b cleanup K_DirectorIsAvailable 2024-12-28 18:24:56 +01:00
Alug d2b0fc3b5e add K_DirectorIsAvailable 2024-12-28 18:17:34 +01:00
Alug aa95507478 Update replayfreecam lua global to use camera.freecam for currently viewed player 2024-12-28 17:42:45 +01:00
Alug b0aba7f4a4 cleanup director splitscreen stuff 2024-12-28 17:42:04 +01:00
Alug 7341f77fe1 WIP splitscreen director lel 2024-12-28 17:20:02 +01:00
Alug 76460b9d9c replace all this crap with either stplyrnum or R_GetViewNumber 2024-12-28 05:52:20 +01:00
Alug 2ba291516e remove the remainder or demo.freecam 2024-12-28 04:18:47 +01:00
Alug 30d1747d43 disable replayfreecam lua exposure
need a way to expose crap lel
2024-12-28 04:10:09 +01:00
Alug 113dd4aeae fix jitter when toggling freecam off 2024-12-28 04:09:43 +01:00
Alug 17f79b0260 fix cam interp during pause again 2024-12-28 04:01:09 +01:00
Alug 2526a99726 fix speccam again 2024-12-28 04:00:56 +01:00
Alug 21ec8ea1a4 fix freecam not being steerable when not in spec
ugh this is godawful
its literally almost a complete copy of
2024-12-28 03:44:21 +01:00
Alug 9cac882840 changable freecam speed 2024-12-28 01:41:49 +01:00
Alug 02dfced6c0 make freecam work in splitscreen
banish cameracmd shit
2024-12-28 01:38:08 +01:00
Alug 9f2e80fc3c set default controls for float and sink ig 2024-12-28 00:21:41 +01:00
Alug 57a097ea52 add alternative cam float and sink buttons 2024-12-28 00:04:49 +01:00
Alug e5d8a2e8a9 add bindable freecam toggle 2024-12-27 23:55:19 +01:00
Alug 579b66e1c0 fix freecam not being interpolated when ingame 2024-12-27 23:37:23 +01:00
Alug 2e3c4a45b0 use demo freecam for spec
its more versataile and lets you pass through walls and floors just like in replays
2024-12-27 23:34:09 +01:00
Alug 7f5033f14a actually dont make those beeg 2024-12-27 22:30:40 +01:00
Alug 084574f2f2 sparkle trail effect from rr TEST
most likely not netsafe
also smol trail breaks for some reason lel
2024-12-27 21:51:50 +01:00
Alug 2d5cdd3f19 a 2024-12-27 21:51:07 +01:00
Alug 64897ba6d6 momz stuff for kart vfx
from RR
2024-12-27 21:02:26 +01:00
Alug 87887aa3a0 make function for driftsparkcolour
reduce some code dupe
2024-12-27 20:59:43 +01:00
Alug 8e67e96e6f super smol refactor minimap head drawer 2024-12-27 18:43:27 +01:00
Alug 14f030e9a8 use V_STEELMAP for white skincolours instead
cause white on white be weird
2024-12-27 18:41:50 +01:00
Alug 93dbe7eecb z 2024-12-27 00:44:20 +01:00
Alug dd8f25d43c draw gametype in tabrankings during replay playback
replays already show the mapname in there so
2024-12-27 00:44:10 +01:00
Alug 7f25117c3e make highlight color in scoreboard and tab ranking player coloured
also make it appear in splitscreen
similar to hostmod things
2024-12-27 00:35:38 +01:00
Alug 01525e294f also add playernum var to tabrankings drawer 2024-12-27 00:34:51 +01:00
Alug 07a6ea240b check whiteplayer once 2024-12-26 23:50:49 +01:00
Alug 2e658ac546 more smol refactoring 2024-12-26 23:46:52 +01:00
Alug 930fdc84ec refactor intermission standings drawer
abstract the data stuff too
2024-12-26 23:24:23 +01:00
Alug a42342a4b8 a 2024-12-26 20:52:57 +01:00
Alug 75309ff21b crappy optimization
check first if any of those flats exist lel
2024-12-26 20:50:56 +01:00
Alug 0c58f66fd8 actually check for vanilla speedpads first
they are more likely to appear tbh
2024-12-26 20:05:03 +01:00
Alug e03d13c2b8 simplify this alot
Zzz... somehow overlooked that it already gets a fof sector passed
also adds another condition since we dont need to check anything with 255 brightness
2024-12-26 20:02:46 +01:00
Alug fba943470d another attempt at fixing skipintro mus playing titlescreen music 2024-12-26 17:51:06 +01:00
Alug 595972629d whoops this never did anything lol 2024-12-26 15:49:47 +01:00
Alug 4fb43b798d 1px 2024-12-26 01:07:49 +01:00
Alug 87c499d8c7 make the extra 3 driftgauge not resolution dependant
thx indev <3 you saved me from going insane...
2024-12-26 00:56:40 +01:00
Alug 265e52caab make colorhud check consistent 2024-12-26 00:49:31 +01:00
Alug 1445a75183 super smol optimizations 2024-12-26 00:01:42 +01:00
Alug cc2434fd69 add tweakmap support
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/7fb44bdb0239a8012be73cb9ee384a9fdca9addb
2024-12-25 01:56:58 +01:00
Alug 936b39f7a3 make those const 2024-12-23 18:06:56 +01:00
Alug b8a86ca405 make some cam stuff behave exactly like vanilla again
no clue if this changes anything at all, but cam stuff be causing so many issues id rather just have it behave like it used to
2024-12-23 17:45:43 +01:00
Alug 773df88224 dont remember removing this in s_sound 2024-12-23 17:44:48 +01:00
indev e7a2c83aa5 If player has mobj, use it to assign localangle in G_FixCamera 2024-12-23 15:50:31 +01:00
Alug dc1ae2125c fixeur comptime stuff (thx indev <3) 2024-12-23 00:58:11 +01:00
Alug 8e9036029a try to check for watertrail stuff on mapload too
so it doesent need to check so much always when its called
2024-12-23 00:16:14 +01:00
Alug b14558765a fix driftsparkle sometimes not replacing driftdust 2024-12-23 00:15:22 +01:00
Alug 131b28ff9f bump 2024-12-22 22:51:45 +01:00
Alug 0e1a8b3623 a 2024-12-22 22:35:39 +01:00
Alug ffb8b281d8 add some lightlevel randomization 2024-12-22 22:35:31 +01:00
Alug 07aeb0d94b use P_MobjWasRemoved for HWR_DrawSprite 2024-12-22 21:18:57 +01:00
Alug 725640379e only check fofs if lumpname matches 2024-12-22 21:17:54 +01:00
Alug 340dffab23 make fullbright speedpads work on fofs pls 2024-12-22 21:11:15 +01:00
Alug c1e5cadcc7 settable mobj lightlevel from lua 2024-12-22 20:56:11 +01:00
Alug 898d1e7fc7 fullbright for some player visual effects
sparks and stuff should glow lel
2024-12-22 20:43:58 +01:00
Alug f5058fb5be readd mobj lightlevel field so i dont have to edit frameflags 2024-12-22 20:29:26 +01:00
Alug fbd051f947 make speedines colorized for driftlevels 2024-12-22 20:26:33 +01:00
Alug dc846fc487 just skip missing/broken fields in musiccredit handling
like vanilla kek
still will throw warnings but atleast will show stuff if theres anything left in the musicdef
2024-12-22 19:59:42 +01:00
Alug 402cd310d9 stuff 2024-12-22 18:45:34 +01:00
Alug 2ee68da944 fix compile 2024-12-22 18:38:09 +01:00
Alug 780308fee0 just revert this idk how comptime works 2024-12-22 18:38:00 +01:00
Alug dc256a03b4 Revert "add P_CheckPositionShadow just for shadow mobjs"
This reverts commit 7edce19c9c.
2024-12-22 18:29:53 +01:00
Alug 4e5576351c Revert "add shadows to faster slope z checking"
This reverts commit 4aaa2c6fed.
2024-12-22 18:29:46 +01:00
Alug 33957b5f60 Merge branch 'Saturn-Testing' into lugstuff 2024-12-22 18:29:39 +01:00
Alug c492622102 add some () 2024-12-22 01:47:07 +01:00
Alug f7494fedd5 do the same for R_ProjectPrecipitationSprite 2024-12-22 01:44:25 +01:00
Alug b02d4365ac dont put potential null mobj into interpolation stuff 2024-12-22 01:42:42 +01:00
Alug ba1486f763 dont dereference potential null mobjs in software projectsprite 2024-12-22 01:40:42 +01:00
Alug a495482fc1 compiler pls shut up 2024-12-22 01:31:52 +01:00
Alug 39a5da5036 use P_MobjWasRemoved and null check for thing subsector in projectsprite 2024-12-22 01:31:00 +01:00
Alug 504f15db58 fix fade to menu again oops 2024-12-20 18:25:59 +01:00
Alug 54116b3d3f fix no fbo compile 2024-12-20 18:25:57 +01:00
Alug 6c9c648af1 always reset those just in case 2024-12-20 11:35:22 +01:00
Alug 5da992b63b idk just set to false here too 2024-12-20 11:19:09 +01:00
Alug 9bb5e95f54 whoops 2024-12-20 03:17:12 +01:00
Alug bad4180e63 try to clean up downsampling and resolution checking stuff
- global function that updates variables with current display resolution
-smol boolean function that quickly checks if the game res matches the desktop res
- i_downsample has been simplyfied a bit
2024-12-20 03:12:03 +01:00
Alug 084e364a8a fix fbo shader lel 2024-12-20 03:07:31 +01:00
Alug 2cbc4e580d better nvidia xwayland workaround handling
what in the world was i thinking????
2024-12-20 02:50:30 +01:00
Alug a2e6ec4f5b add another early return 2024-12-20 01:20:51 +01:00
Alug 231a7f1366 simplify this crap and make compiler happy 2024-12-20 00:57:57 +01:00
Alug bee77ec2ad no 2024-12-20 00:57:31 +01:00
Alug 11cc7e63b7 just query this once 2024-12-20 00:57:15 +01:00
Alug 2083daf4c3 return false here 2024-12-20 00:51:05 +01:00
Alug 816e6a0287 makes no sense without screen tex 2024-12-20 00:50:28 +01:00
Alug 6d9541c135 simplify this crap 2024-12-20 00:38:56 +01:00
Alug 0f208617bd fix compile due to missing am_map.h include 2024-12-19 22:42:14 +01:00
Alug e8bbac82f4 fix compile without USE_FBO_OGL 2024-12-19 22:40:08 +01:00
Alug d657afe18b oops 2024-12-19 20:42:52 +01:00
Alug 96f3ac9d9e add "listmapthings" and "listunusedsprites" commands
the former also shows duplicated mapthings
2024-12-19 20:33:04 +01:00
Alug 9290744fca Fix segfault when sending excessively large netcmds
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2568/diffs?commit_id=457b761d9301b1904c414a8e8ba908f74b9ab959
2024-12-18 18:57:02 +01:00
Alug f08f91a9fe use slightly diff maths for skydomevertex calc
from DSDA-Doom
maybe fixes some issues with certain skydomes?
2024-12-18 18:55:58 +01:00
Alug 22e20ed282 delet this only O3 2024-12-17 12:45:48 +01:00
Alug be2952db5d dont show gamemodes in battle + smol cleanup 2024-12-17 00:53:50 +01:00
Alug ff4a27de0e fix the string being truncuated 2024-12-17 00:53:35 +01:00
Alug 991e1a2844 make this crap actually work lol 2024-12-16 23:33:27 +01:00
Alug a2cbec78f9 assballs 2024-12-16 23:51:59 +01:00
Alug d1b3cd4994 init textcmdbuf to NULL
just in case
2024-12-16 20:40:36 +01:00
Alug 431c2c71f5 delay NetXCmd´s instead of dropping them when the buffer is full
credits and many thanks to Hanicef!
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2568
2024-12-16 20:34:28 +01:00
Alug 5fd6437c34 potential fix for clients locking up due to never receiving acks back
apparently, if the client doesent receive an ack back which may happen due to duplicate packets/bad net conditions, it may spam resend the packet until its netxcmd buffer is full and locks up
2024-12-16 18:27:53 +01:00
Alug 47c429c792 prevent potential crash if viewmobj was removed 2024-12-16 16:37:38 +01:00
Alug b69b94f26f smol fix for gamma stuff
-dont apply gamma adjust when gamma is on default value
-fix saturation not being applied on console on OpenGL without paletterendering
2024-12-16 04:35:03 +01:00
Alug b9bb2e5663 Revert "try the semi fast R_PointOnSide FOR gameplay stuff"
This reverts commit d80a02fe42.
2024-12-16 02:00:01 +01:00
Alug 488aecf95c fix changing gamma absolutely trashing performance
not quite sure why it made stuff die so much but uhhh
instead i just check in the cube initialistion function instead and only let it build when needed to not change how the game looks with raised gamma values
2024-12-15 23:26:09 +01:00
Alug d80a02fe42 try the semi fast R_PointOnSide FOR gameplay stuff 2024-12-15 20:22:42 +01:00
Alug 8dff1abc54 oops 2024-12-14 22:47:20 +01:00
Alug 06d85ac65a slight cleanup K_GetScreenCoords and related functions
mostly just reducing scope and adding const clarifyier
also use mobjwasremoved checks everywhere instead of just simple null checks for some safety
2024-12-14 21:14:24 +01:00
Alug b4d49c565f Revert "Draw an icon above players when they are typing in chat or console"
This reverts commit da5136c7c1.
2024-12-14 20:25:33 +01:00
Alug da5136c7c1 Draw an icon above players when they are typing in chat or console
not fully working but didnt want go work to waste
2024-12-14 20:25:27 +01:00
Alug 32c3b7761a fix papersprite lightlevels again kek + remove shit that does nothing 2024-12-14 17:13:28 +01:00
Alug 5445be6645 fix papersprite directional light
uhhh idk??
also passes papersprite bool directly instead of rechecking every frame for it
2024-12-14 16:53:10 +01:00
Alug 7b89f41b77 seems like you CANNOT apply dispoffset to papersprites
well then
2024-12-14 16:27:40 +01:00
Alug 56e1b50260 fix inverted papersprite roll
oopsie
2024-12-14 16:27:06 +01:00
Alug 9fdd7de5b1 only check if polyobjcst are on the map 2024-12-14 16:00:01 +01:00
Alug 960679a3fd forgor about cameracheckposition 2024-12-13 16:50:10 +01:00
Alug e428fdc89a only check for polyobjects in the blockmap if there even are polyobjects
this saves the trouble of iterating through the blockmap every single time P_CheckPosition is called if there are no polyobjects present on the map
2024-12-13 16:46:49 +01:00
Alug fd514d4e1d smol calc optimization P_Checkposition 2024-12-13 16:45:22 +01:00
Alug cec6dfc131 add P_CheckPositionShadow just for shadow mobjs
its basically just R_GetShadowZ from the render based shadows from srb2 lmao
hope this is synchsafe
2024-12-13 16:36:37 +01:00
Alug 20319ad43c add shadows to faster slope z checking 2024-12-13 15:48:15 +01:00
Alug 774bfc7959 delet all the hardware sound crap
psure it doesent even properly work at this point
2024-12-13 15:47:55 +01:00
Alug 3db5f64b5e Revert "kill "Use po2 patches to fix mipmaps ""
This reverts commit 6b904b10f5.
2024-12-12 18:09:17 +01:00
Alug ddc97b662c Revert "HWR_ResizeBlock more like HWR_ResizeCock"
This reverts commit db96d717ce.
2024-12-12 18:09:13 +01:00
Alug 75ad25f961 Revert "const ma"
This reverts commit 98fbd3fa65.
2024-12-12 18:09:09 +01:00
themixedupstuff e604884bd7 Fixed gr_glinfo crash when there are way too many extensions present. 2024-12-12 17:37:04 +01:00
indev 65d487c60b Avoid overflowing CONS_Printf's buffer by using vsnprintf 2024-12-12 16:50:49 +01:00
Alug c489cfb657 zzz 2024-12-12 15:03:08 +01:00
Alug 1608b8388b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-12-12 15:01:54 +01:00
Alug f706548779 disable deb print
this never triggered even once
2024-12-12 14:58:57 +01:00
Alug 67bb704a66 check for the flag first 2024-12-12 02:31:19 +01:00
Alug 516cd19d68 seperate thinkerlist for precip
i sure hope i handled everything right lmao
2024-12-12 01:02:46 +01:00
Alug 94d883e22e remove some precip code dupe 2024-12-12 00:30:37 +01:00
Alug d3fb8e9bac better cv_lessprecip handling
idk what i was thinking lmao
2024-12-12 00:11:42 +01:00
Alug 98fbd3fa65 const ma 2024-12-11 23:46:51 +01:00
Alug db96d717ce HWR_ResizeBlock more like HWR_ResizeCock 2024-12-11 23:42:21 +01:00
Alug 6b904b10f5 kill "Use po2 patches to fix mipmaps "
test
2024-12-11 23:29:21 +01:00
Alug 134b28f2d2 maybe fix fade stuff idk 2024-12-11 23:23:46 +01:00
Alug c66497a1d6 clean up hw_cache stuff + fix accidental wrong cast 2024-12-11 23:23:27 +01:00
Alug 5e625e64ce smol cleanup GL_SetBlend
use early return since i likeit more
2024-12-11 22:14:06 +01:00
Alug c11b6f9fda GL_UpdateTexture can be static 2024-12-11 21:58:45 +01:00
Alug 76fc3c1da7 smoll optimization
dont recalc this everytime just do tha lööp thinge
seems to work fine
2024-12-11 15:17:59 +01:00
Alug 07fc47d995 more cleanup GL_UpdateTexture
also some optimizations
2024-12-11 14:23:28 +01:00
Alug 5b264a35bf clean up GL_UpdateTexture
use switches and reduce code dupe
2024-12-11 04:35:43 +01:00
Alug ff58d21051 cast this 2024-12-11 02:02:43 +01:00
Alug 77583d44ed "extra safety" 2024-12-11 01:25:29 +01:00
Alug b3ff5e30aa test "or" 2024-12-11 00:32:34 +01:00
Alug c0a69065ea clamp splitsprite heights aswell 2024-12-10 23:06:29 +01:00
Alug 077ee0bc12 those should better be clamped oops 2024-12-10 22:20:53 +01:00
Alug 303f6cb1ce clean up this stuff; make splitwall behave more like vanilla
changes some splitwall issues slightly but gives bit better performance in some cases
2024-12-10 22:16:03 +01:00
Alug e458c10aac one line those 2024-12-10 21:18:06 +01:00
Alug 85d58d22b7 Unconditionally interpolate view
even if it may NOT change
but i get the feeling it may cause some issues
2024-12-10 21:18:03 +01:00
Alug 22445958c1 dont pass fwrapv to compiler flags
this technically changes behavior of some things, even if it MAY fix some undefined behaviour
2024-12-10 21:18:00 +01:00
Alug 0fc7d2124a interp.subsector is unused
so dont need to assign it nor call pointinsubsector for nothing
2024-12-09 23:19:58 +01:00
Alug 3f99d9aae9 i love menus 2024-12-09 10:19:54 +01:00
Alug b357a8f503 "P_CheckSightFast" for lua
should be faster than normal P_CheckSight
only to be used for things like nametags etc so nothing gameplaywise as it will desynch
2024-12-09 10:48:50 +01:00
Alug f3e184caf1 smol things 2024-12-08 21:18:39 +01:00
Alug f41fda74b5 check for numer before trying to parse it
thx ghg! c:
2024-12-08 16:45:53 +01:00
Alug ec6e8fa3d5 use le flags 2024-12-08 16:02:37 +01:00
Alug 2f0f11976d rename to "hw_gl" 2024-12-08 15:39:36 +01:00
Alug 82ad5a91ab smol cleanup 2024-12-08 15:31:28 +01:00
Alug cd8f43fa47 optimized checksight for nametags and camera
idk should this be exposed to lua too?
2024-12-08 15:26:10 +01:00
Alug 69a593e09d use early return
no need to check for all this crap if we can use it anyways
2024-12-08 04:38:58 +01:00
Alug 1173ea3301 menu oopsie 2024-12-08 04:06:52 +01:00
Alug 6a1398b788 clear maplight on toggling
so you only have to wait until nextmap for effect to do smth instead of game restart
2024-12-08 04:05:43 +01:00
Alug 2fcb5d628e menu entry 2024-12-08 03:39:58 +01:00
Alug 5d902b8507 make random directionallight toggable 2024-12-08 03:39:55 +01:00
Alug d3edc19de9 Revert "try recursion limit for _RenderBSPNode"
This reverts commit 501b8b7bf5.
2024-12-08 02:10:00 +01:00
Alug 5bad795c60 make those less chaotic 2024-12-08 01:33:06 +01:00
Alug 9b8374665a readd some kart batching thing idk 2024-12-08 01:32:53 +01:00
Alug 0479a3e723 stuff 2024-12-08 01:27:57 +01:00
Alug b54ed5f6e5 proper macros 2024-12-08 01:27:14 +01:00
Alug a127088db1 fix chronoshit speedpad light + use memcmp ig
also check for some stuff to maybe save on memcmp checks idk
2024-12-07 17:37:52 +01:00
Alug 015f583908 no need to set all that stuff manually 2024-12-07 12:52:00 +01:00
Alug b6d1e67cf1 port updated skydome code from srb2
seems to actually fix some visual issues on certain maps with it
2024-12-07 12:29:50 +01:00
Alug 9afd00dda7 int should use abs instead of fabs? 2024-12-06 08:15:42 +01:00
Alug 95379f534d delet this 2024-12-06 08:15:17 +01:00
Alug e67d04c694 bruh 2024-12-05 14:29:48 +01:00
Alug 027016e8a3 try less maths for projectionmatrix
from dsdadoom again lul
2024-12-05 11:36:53 +01:00
Alug 4f30029884 use long M_PI to fix some render issues 2024-12-05 11:36:12 +01:00
Alug 8e48cd1b25 little extra safety 2024-12-05 08:10:05 +01:00
Alug 6fcc40748c reduce the scope of those
only this function needs those
2024-12-05 08:07:52 +01:00
Alug 2bed437313 try fix keepmusic occasionally not working
idk but sometimes DoReborn broke it?
also this ensures keepmusic and skipintromus flags always get reset
2024-12-05 07:58:11 +01:00
Alug 88aafd9df2 TEST: dont keep calling R_PointInSubsector in P_CheckPosition if the postiion never changes
can just reuse the thing subsector
might speed things up quite a bit actually
test: cause idk if it is actually compeltely netsafe
2024-12-04 14:39:57 +01:00
Alug 76bb99422a why does this need a variable?
it just gets assigned kartstuff[k_aizdriftstrat] anyways?
2024-12-04 14:22:14 +01:00
Alug b3e3947fc0 clean up this mess 2024-12-04 14:20:49 +01:00
Alug 3ed1e5b8b0 make those const 2024-12-04 14:20:15 +01:00
Alug 6783ef7ff7 only ever call pointtoangle for sprites that really need it 2024-12-04 01:39:04 +01:00
Alug 199fc184b7 change this a little 2024-12-03 21:47:59 +01:00
Alug 4db0b89e92 1463 lmao change this to be readable
also raise to 40 secs
2024-12-03 21:42:43 +01:00
Alug 103bb7e58d try to make demo data handling a bit safer
- Use Z_Malloc to allocate demobuffer
- Use Z_Free to free demobuffer
- Make functions for freeing and resseting demobuffer
- Always reset demobuffer when not saving
2024-12-03 21:42:36 +01:00
indev 4a9b206d01 Add MENUCAPS to some menu options 2024-12-03 21:32:45 +01:00
Alug 3cd66e75e7 this may be used unitialised lul 2024-12-03 19:55:51 +01:00
Alug e9c43843b3 better fix for unclosable addon warning screen
old one was hacky asf
2024-12-02 19:35:01 +01:00
Alug 577c6f194f better fix for netgame join hoop crash
this actually works and makes em animate
also this IS SAFER since before the hoop stuff got really badly mangled
2024-12-01 22:04:32 +01:00
Alug 8b7c171a67 better fix for G_FixCamera
completely forgor in kart and srb2.1 cmd.angleturn needs to be bitshifted to accomidate localangle
using it again is better, since player mobj angle is not always suitable for localangle and may slightly mismatch where a player is steering
2024-12-01 10:28:58 +01:00
Alug 77b37d6579 seems like player not always have mobjs
titledemo moment
2024-12-01 10:18:10 +01:00
Alug 5ffdadfc41 this only ever applies to ogl
no need in software lol
2024-11-30 23:39:10 +01:00
Alug d9648a4b41 oop 2024-11-30 23:19:11 +01:00
Alug ba059ec1a6 give those better names 2024-11-30 23:17:02 +01:00
Alug 3790782ec7 save one R_PointToAngle call
very smol optimisation lul
2024-11-30 22:31:36 +01:00
Alug f0b7899cf6 missed this 2024-11-30 22:04:47 +01:00
Alug af9ba7ef41 oops this gets directly called in one instance
also why do we keep checking for null mobj when P_MobjWasRemoved checks that anyways?
2024-11-30 21:59:47 +01:00
Alug 840aff38f2 smol cleanup 2024-11-30 21:54:37 +01:00
Alug 7ebbc35f52 whoops 2024-11-30 21:46:56 +01:00
Alug c3e2a71724 sloperoll already has "off" setting, delet spriteroll cvar since redundant 2024-11-30 21:46:41 +01:00
Alug 69e5b7c199 this is null anyways if disabled 2024-11-30 21:44:23 +01:00
Alug 5e46b9de60 forgor sliptide roll 2024-11-30 20:28:19 +01:00
Alug ed67c8fd56 okay? shut up compiler 2024-11-30 20:09:04 +01:00
Alug e36302ea57 optimize sprite rotation / sprite drawing a bit
- make software and ogl use same variable names
- let papersprites also roll in ogl not just software
- throw pitchnroll calc into a function to reduce code dupe
- save some calcs when having sliptide roll disabled
- fix software not calculating camang when just player roll is enabled (did that ever work right before? oops)
- determine early if the sprite is supposed to rotate, and only if it really does, run the rotation stuff
2024-11-30 20:04:58 +01:00
Alug f28355bd82 delete A_RollAngle things
they cant be used, since theyre not synchsafe
and nothing uses those anyways
2024-11-30 19:45:19 +01:00
Alug 5f76010bdc allow demo play commands while watching a demo again 2024-11-29 23:25:50 +01:00
Alug 14a1d7782c loading not sending
just to clarify
2024-11-29 22:23:58 +01:00
Alug 275403d9fc this is also redundant 2024-11-29 13:15:46 +01:00
Alug ea787467ed use continue instead of huge if block 2024-11-29 12:14:15 +01:00
Alug d0738121be dont think we need to reset anything here
kick cmd gets send out which should clear stuff in theory
2024-11-29 10:39:57 +01:00
Alug 1c4817cb08 Fix buffer overrun with players with no associated node
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/810/diffs?commit_id=af9164f336a65634f6908e677b47773d88f583af
2024-11-29 10:14:34 +01:00
Alug aeb31aaabf those are redundant 2024-11-29 10:07:20 +01:00
Alug 6dc304d445 why? 2024-11-29 09:51:58 +01:00
indev 7961428b7c Simplify consistency check a bit 2024-11-29 09:36:21 +01:00
indev 61229fdaa4 Only check nodes that are in game in SV_ResendingSavegameToAnyone 2024-11-29 09:36:19 +01:00
Alug ed8b4c4b6e those dont need to be inlined tbh 2024-11-29 09:36:05 +01:00
Alug ba1b4e868c remove dupes 2024-11-28 08:09:36 +01:00
Alug eda3820e66 eh this looks better 2024-11-28 08:01:24 +01:00
indev dc1dd3e04e Use textinput_t for addon search 2024-11-27 22:56:25 +01:00
Alug bb6632831c forgor 2024-11-27 22:42:06 +01:00
Alug d996bc7793 only apply palrender postprocess shader once 2024-11-27 22:40:20 +01:00
Alug ea0babc5c0 dont draw final screen texture twice if you use native res
no need to
saves some performance
2024-11-27 22:35:49 +01:00
Alug 702dd09d3f Revert "fix ogl screenshots"
This reverts commit 56cd789eea.
2024-11-27 22:35:29 +01:00
Alug 56cd789eea fix ogl screenshots 2024-11-27 17:12:57 +01:00
Alug d8e6e17ee5 make own screentex for vhs effect
idk if its really needed tbh, but also doesent hurt
2024-11-27 17:03:19 +01:00
Alug 70e66b9fed use macros lol 2024-11-27 16:45:41 +01:00
Alug d81e484aa7 memset screentex 2024-11-27 16:45:19 +01:00
Alug 1feeb18a49 why do replay play commands only have netgame check???????
bad things will happen if theyre played ingame regardless of netgame or not
2024-11-27 00:36:19 +01:00
Alug 5d7d99fa3d Revert "hopefully fix some inconsistencies with directional lighting"
This reverts commit d607d7bd7c.
2024-11-27 00:02:34 +01:00
Alug b5cd4ab8cd test make skyfloors also toggle directional light 2024-11-27 00:02:26 +01:00
Alug d607d7bd7c hopefully fix some inconsistencies with directional lighting 2024-11-26 23:33:56 +01:00
Alug 4d3187cc45 sector may be null 2024-11-26 23:24:15 +01:00
Alug a5a919a29e sprite light oopsie 2024-11-26 23:06:09 +01:00
Alug d0df038ad8 funny debug print 2024-11-26 22:32:16 +01:00
Alug f866b86397 init polyobject thinker->references to 0
otherwise they wont get removed alot of the time
2024-11-26 22:31:58 +01:00
Alug eba4601c73 TEST: only call drawscreenfinaltexture once
speeds up gpu perf quite a bit
2024-11-26 22:31:23 +01:00
Alug 8c3bf47a88 we dont even need to check this
this doesent do anything with papersprites so dont even call it kek
2024-11-26 22:30:29 +01:00
Alug baaae908bb kill spritecliphack shader 2024-11-26 22:27:34 +01:00
Alug d6a2fe0993 init polyobj thinker cachable bool
otherwise shit will die lol
2024-11-26 18:21:10 +01:00
Alug 5ceb4d9be6 try mobjcache with very explicit check
karts thinker handling is so bad it made the cachable boolean return things like -1002438656
2024-11-26 17:20:31 +01:00
Alug 56c91eba23 fix early return in comparePolygons
thx durr very cool!
2024-11-26 15:06:16 +01:00
Alug 2a3dfbde83 check for titlescreen music 2024-11-26 05:33:00 +01:00
Alug caf4fd036e make hud hooks clean up after themselves 2024-11-22 16:04:01 +01:00
Alug 7732dd218f Refactor HUD hooks too 2024-11-22 00:39:53 +01:00
indev a3008b7188 Fix mobj hooks called for mobj type 0 being interpreted as regular hooks 2024-11-21 23:32:28 +01:00
Alug 464141837c forgor to remove those 2024-11-21 22:34:00 +01:00
indev f10bc1838e Players that get 'NO CONTEST' can save replays too now 2024-11-21 20:18:13 +01:00
Alug 3a236ca2ad fix lugstuff crash 2024-11-21 20:00:52 +01:00
Alug 6b7fe5ac25 Fix -Warray-bounds warning in lua_hooklib.c 2024-11-21 19:50:35 +01:00
Alug 73acf71f9c fix pre and post thinkframe perfstats pages 2024-11-21 19:49:42 +01:00
Alug ad36471d97 Fix HurtMsg inflictor mobj type discriminator
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1903
2024-11-21 19:46:27 +01:00
Alug a40f9171a3 Fix MusicChange hook crashing when called 2024-11-21 19:41:14 +01:00
Alug 80bf58eb00 MORE MACROS 2024-11-21 19:40:36 +01:00
Alug d0874b2d33 Refactor hook ref allocation 2024-11-21 19:39:26 +01:00
Alug 68461d05d2 Automatically count hook values 2024-11-21 19:37:30 +01:00
Alug 0e421f0468 we dont have key event hooks 2024-11-21 19:17:36 +01:00
Alug 7b27bfc907 this is unused for now 2024-11-21 19:17:26 +01:00
Alug a73059a76a change those to fit rest of style 2024-11-21 19:10:49 +01:00
Alug 81b9a1e0a2 make intermissionthinker use LUA_HookVoid
comment out hookbool since unused
2024-11-21 19:03:39 +01:00
indev bacc793bc7 Fix warning regarding MusicChange hook 2024-11-21 21:01:00 +03:00
indev f83079d2fb Add Should- and Player- Spin/Explode/Squish, and ServerJoin hooks into new hook system 2024-11-21 20:59:08 +03:00
Alug a115963ba2 delet serverjoin stuff i forgor and add old should spin stuff 2024-11-21 18:39:28 +01:00
Alug 5e3309c216 serverjoin hook 2024-11-21 18:35:50 +01:00
Alug ca4bb191a4 port srb2 hooklib refactor (WIP)
lol lmao
2024-11-21 18:08:44 +01:00
Alug 799ed82532 try to make shadows not so offset on slopes with rotation enabled
lmaos
2024-11-21 02:11:40 +01:00
Alug 0e55d4018a those should be SHORT i think? 2024-11-21 02:10:57 +01:00
Alug 9fb5cdbe99 last attempt at fixing those things 2024-11-20 23:44:15 +01:00
Alug 1cd3b43646 me dont like huge ass if block use return instead lol 2024-11-20 23:03:26 +01:00
Alug a680bf196d add R_PointInSubsectorFast for non critical gameplay stuff like sounds and camera
and some parts of rendering
2024-11-20 21:11:37 +01:00
Alug 43ae24be29 use it for R_IsPointInSubsector
this is fine since R_IsPointInSubsector is only used for precip spawn unless you disable noclipcam lol
2024-11-20 21:10:46 +01:00
Alug 05b397e8d6 rename to R_PointOnSideFast 2024-11-20 21:10:28 +01:00
Alug 1e5d809740 revert that part 2024-11-20 21:09:30 +01:00
Alug 0764c335b3 Fix integer overflows on very large numbers 2024-11-20 20:36:22 +01:00
Alug 138feecefc oop 2024-11-20 17:32:20 +01:00
Alug 2e53406b07 also pass papersprite to HWR_RotateSpritePolyToAim 2024-11-20 17:31:39 +01:00
Alug bec5bb12c5 ugh logic issue 2024-11-20 17:26:57 +01:00
Alug 469f4bd223 restructure this again and let shadows use shader 2024-11-20 17:23:01 +01:00
Alug 0309477c9d optimize this a bit
no need to constantly recheck this, just pass it around as a bool
also inline dispoffset function since it used to be a nested thing
2024-11-20 17:03:37 +01:00
Alug 622dce1b1a use shader to mitigate sprite clipping unless its shadows and papersprites
also moved stuff into its own function to not make shit look like hell
2024-11-20 16:45:42 +01:00
Alug bce066f3d0 slightly optimize P_CreateBlockMap 2024-11-20 16:07:22 +01:00
Alug a0bc9e119c fix potential overflow in R_ProjectSprite 2024-11-20 15:20:01 +01:00
Alug 5cc5fe9e55 fixed float to integer conversion problems
from dsda doom
should hopefully make this behave the same everywhere
2024-11-19 20:18:16 +01:00
Alug ae7454f2d4 Revert "use memset here too"
This reverts commit 1bff103e53.
2024-11-17 21:45:51 +01:00
Alug afb7ffc6d0 make replay/time attack menu support lowercase if toggled, also levelselect addon names too 2024-11-17 14:41:41 +01:00
Alug 3fc0deb0bc well was worth a try lol 2024-11-17 13:59:38 +01:00
Alug d81f378271 why is that declared here?? 2024-11-17 13:30:20 +01:00
Alug 423797e414 make menucaps stuff global macro and also apply to downloader text 2024-11-17 13:02:57 +01:00
Alug 898c54f6f0 Test: run NetUpdate every frame again
just not in the renderer code lmao
2024-11-15 21:58:33 +01:00
Alug bb94c8f359 try make this look less like crap lol 2024-11-15 21:55:50 +01:00
Alug 76233104d1 try recursion limit for _RenderBSPNode
its 112 seems like the best compromise, hope it doesent break maps i didnt test visually or smth
2024-11-15 18:29:38 +01:00
GenericHeroGuy d5eeb33212 Unify I/O library modifications 2024-11-15 16:14:43 +01:00
Alug 57fd3e5aa5 gu 2024-11-15 16:14:32 +01:00
GenericHeroGuy dc9887e1bf Disable bytecode (1930cc9) 2024-11-15 14:23:27 +01:00
Alug e5b73c45e2 test this again
now that i understand the flags lol
2024-11-15 09:03:59 +01:00
GenericHeroGuy ac6daeef76 Fix building with NOBLUAJIT 2024-11-15 00:26:03 +01:00
GenericHeroGuy eebf21369c Check division/modulo by zero (a74a4eb) 2024-11-15 00:02:05 +01:00
Alug e06bc2a3b3 inline those 2024-11-14 07:37:40 +01:00
Alug f829265f75 psure it should be like this? 2024-11-14 06:24:46 +01:00
Alug b995a764c4 cleanup localcmd stuff 2024-11-14 06:24:27 +01:00
Alug f1c3b49933 use memset here too 2024-11-14 06:23:51 +01:00
Alug fc6428a0f7 use memsets here and clear pingdata too 2024-11-14 06:22:56 +01:00
GenericHeroGuy 52f7da69ad Standard library wipeout (1d1b7ec) 2024-11-13 17:29:01 +01:00
Alug 7af93a3251 Revert "try +="
This reverts commit 60ad8b12cc.
2024-11-12 20:31:51 +01:00
Alug fcb4fbfb44 prevent some palrender startup crashes
thx srb2 apparently this can be null during init so add some extra safety
2024-11-12 16:22:51 +01:00
Alug 60ad8b12cc try += 2024-11-12 15:43:59 +01:00
Alug 4c2443ff69 add some paranthesis here 2024-11-12 15:43:46 +01:00
indev 9a1b334731 Fix game crashing when increasing number of viewpoints more than by one (again) (needs testing that it didn't break anything else) 2024-11-12 02:45:09 +01:00
GenericHeroGuy 07104e60f4 Fix building on Windows (hopefully) 2024-11-12 02:44:22 +01:00
GenericHeroGuy 34fca9f5a4 Two fixes from master 2024-11-11 00:34:34 +01:00
GenericHeroGuy 42d0ec2a49 Disable FFI 2024-11-10 20:00:11 +01:00
Alug 18b0e12840 Merge remote-tracking branch 'ghg/ljtest' into lugstuff 2024-11-10 19:07:21 +01:00
Alug 074e297850 That didn't work in spectator camera, oops 2024-11-10 18:55:05 +01:00
Alug 997727f370 Fix spectating other players setting wrong angle when returning back to local player 2024-11-10 18:54:44 +01:00
Alug d57bca137d dont do this for papersprites
fickle...
2024-11-09 20:22:07 +01:00
Alug f8185069a0 try this lul 2024-11-08 11:34:18 +01:00
Alug 1ddf5cf81e typod -1 lol 2024-11-08 11:17:01 +01:00
Alug d2aa9faa7b a 2024-11-08 05:21:38 +01:00
Alug de5155a3c2 oops i need that 2024-11-07 23:51:45 +01:00
Alug 9338c3bfe3 death 2024-11-07 23:49:37 +01:00
Alug b9cf085411 destruction 2024-11-07 23:48:58 +01:00
Alug e859324b71 forgor ifdef here 2024-11-03 15:34:55 +01:00
Alug f11460c42a try to simplify this alteast a little
shit is awful
2024-11-03 03:38:48 +01:00
Alug fa27a01dc4 missed this 2024-11-03 03:13:07 +01:00
Alug 77da44cb23 add some more checks for this 2024-11-03 02:58:42 +01:00
Alug f8e9c34353 add just a little more extra safety for fbo 2024-11-03 02:43:19 +01:00
Alug 33ad483b0b initialise this to null aswell
just in case
2024-11-02 14:19:46 +01:00
Alug 7c36b670f3 add accurate fps counter crap to menu + rename it to force it back on
since shit more or less was broken in saturn before and always showed the more accurate one, force it again since stuff caused confusion
2024-11-02 12:57:09 +01:00
Alug b57a150033 oops 2024-11-02 01:13:04 +01:00
Alug a804ee0868 use a "-" here for consistancy 2024-11-02 00:50:23 +01:00
Alug 584de3737c respect cv_showdirectorhud 2024-11-02 00:49:23 +01:00
Alug 0d159674fa spec cam disables director, but you can toggle it from speccam
uhhhhhhh
2024-11-02 00:47:50 +01:00
Alug 6c40c0eda0 fix wanted reticle offsets
Zzz...
2024-11-01 20:29:25 +01:00
Alug 8a8324c841 oops broke encore 2024-11-01 20:01:44 +01:00
Alug fff0adff15 use precalced minimap stuff for v.drawOnMinimap 2024-11-01 19:55:12 +01:00
Alug 28bee7e619 fix some issues with cv_minihead and minimap icon drawing 2024-11-01 19:54:36 +01:00
Alug cd7698ffba fix minimap not being initialised
causes issues when you switch to maps that dont have a minimap
2024-11-01 18:29:23 +01:00
Alug 8f508b6cd8 try speed this up slightly 2024-10-31 11:59:12 +01:00
Alug e2c3dbe9ce tab pls 2024-10-31 11:59:02 +01:00
Alug 2299159722 Revert "test refactor batching stuff again"
This reverts commit cc82da4179.
2024-10-31 11:56:10 +01:00
Alug cc82da4179 test refactor batching stuff again 2024-10-31 11:56:02 +01:00
Alug 4f0b5cb0cf Revert "lets test polygon hashing again"
This reverts commit 2de193b68a.
2024-10-31 11:14:23 +01:00
Alug 2de193b68a lets test polygon hashing again
there were some changes today so idk lets see
2024-10-30 21:34:54 +01:00
indev 3080d3dc3e Add shift+insert shortcut for pasting text 2024-10-30 20:26:02 +01:00
indev e17e47b438 Fix mapmusname global in lua being renamed to (*mapmusname) 2024-10-30 19:22:27 +01:00
Alug e08b6af500 remove some unused stuff in portal struct 2024-10-30 13:52:00 +01:00
Alug b8fdb05f35 improve ogl portal clipping 2024-10-30 13:05:20 +01:00
Alug 36b7bc0ed6 just memcpy palette 2024-10-29 09:01:56 +01:00
Alug 79f46931f4 rename stuff to use "GL_" prefix
might get chaotic without a prefix lol
2024-10-29 08:55:30 +01:00
Alug cd78d6f0c7 TEST call all ogl funcs directly 2024-10-29 00:07:40 +01:00
Alug 7393e752ca huge ass ogl api refactor
idk just screwing around

credits lactozilla
https://git.srb2.org/Lactozilla/SRB2/-/commit/8df6702bfc0cf9d7f9cdc2470b939d01ee37d50b
2024-10-28 23:31:02 +01:00
Alug 83de4399fd fix portal culling 2024-10-28 20:24:46 +01:00
Alug 4c815bd3bf throw this into an inline func 2024-10-28 20:11:05 +01:00
Alug 0545bffacf make this look slightly less terrible 2024-10-28 17:30:31 +01:00
Alug c009866158 Revert "dont pass skybox to r_setupframe"
This reverts commit 78c0f64135.
2024-10-28 17:29:01 +01:00
Alug d0ee4d73f9 those do nothing 2024-10-28 16:34:11 +01:00
Alug d97815620f throw those into functions 2024-10-28 07:38:58 +01:00
Alug 588e52a673 gu 2024-10-28 07:38:43 +01:00
Alug b83016f492 dont always call HWR_Startup again 2024-10-28 07:21:03 +01:00
Alug 8a0129df6a no need to update this witouth water ripples 2024-10-28 06:47:56 +01:00
Alug 470f1fbc73 grey out some stuffs in the ogl and advanced video menus 2024-10-28 06:40:07 +01:00
Alug d5b0d77b9f sort those a bit 2024-10-28 06:36:11 +01:00
Alug cf130189a2 those should be disabled 2024-10-28 06:35:08 +01:00
Alug c56b5fc1a6 move CV_PossibleValue_t to their own section like other files 2024-10-28 06:25:36 +01:00
Alug 53e9303321 add "gl" to secbright and lightdither cvars
theyre only used in ogl so follow the naming convention
2024-10-28 05:40:36 +01:00
Alug e6d90a7d0e reorder all of this to be in same order lol 2024-10-28 05:32:21 +01:00
Alug 06b84f3ba3 check if those are already off before trying to turn them off lol 2024-10-28 05:16:10 +01:00
Alug 11d9df3f0b replace last remaining "gr" 2024-10-28 04:29:30 +01:00
Alug 5a19c26500 forgor 2024-10-28 04:29:17 +01:00
Alug 1b293981fa gr -> gl
this has been annoying me since ages lol
2024-10-28 04:15:30 +01:00
Alug a9759f2740 change cvar register order for ogl stuff 2024-10-27 21:08:51 +01:00
Alug a0cefa9dea Revert "idk why this crashes lol"
This reverts commit 879a13d622.
2024-10-27 20:36:36 +01:00
Alug 879a13d622 idk why this crashes lol 2024-10-27 20:17:15 +01:00
Alug 13ccdcfd23 more cleanup 2024-10-27 07:50:34 +01:00
Alug de23737563 make a bunch of hwr stuff static and cleanup 2024-10-27 07:40:15 +01:00
Alug 34d3e5b760 eh dont check for so much 2024-10-27 07:03:42 +01:00
Alug ea2de6b4e2 fr*nch 2024-10-26 23:23:51 +02:00
Alug d2540ba060 this should be portalcullsector lol 2024-10-26 19:44:12 +02:00
Alug b8a30cef57 reduce the scope of this since not needed 2024-10-26 19:43:57 +02:00
Alug ae71aa6511 rename this to avoid confusion 2024-10-26 19:31:06 +02:00
Alug 8a476b9218 just use the same as software lol
i never saw any differernce except in performance for this
also viewsin and viewcos get calced in r_fps so no need to do here again
2024-10-26 19:28:39 +02:00
Alug 14e91dda44 slight cleanup ogl portals again 2024-10-26 19:19:25 +02:00
Alug 271b8f3a2f rename and slight cleanup 2024-10-26 18:27:06 +02:00
Alug 861356870c smth smth shadows a global declaration 2024-10-26 18:11:17 +02:00
Alug 36b42cce02 throw ogl portals into their own files 2024-10-26 18:10:07 +02:00
Alug 461ca659f8 readd mobj null check here 2024-10-26 16:39:39 +02:00
Alug 7e81337298 inline this since its super smol 2024-10-26 16:36:46 +02:00
Alug 80168e59c1 dont think this is needed for noclipcam? 2024-10-26 16:18:42 +02:00
Alug ab7291bd33 move chasecam postimg stuff into own function + add comments for what stuff does lol
shit got me really confused
2024-10-26 16:09:49 +02:00
Alug 040e969799 forgor to remove this 2024-10-26 00:48:32 +02:00
Alug c965c41c3a clean up portals 2024-10-26 00:45:20 +02:00
Alug 1d9138075a Revert "Add visplane portal creation functionality and use it to replace the skybox rendering."
This reverts commit 122bd69069.
2024-10-26 00:30:55 +02:00
Alug 46738de038 Revert "refactor a bunch of crap and fix skyportals"
This reverts commit d4c36c64fc.
2024-10-26 00:30:51 +02:00
indev dc49e1cbaf Fix A_Lua not removing error handler from lua stack 2024-10-25 22:52:24 +02:00
Alug d4c36c64fc refactor a bunch of crap and fix skyportals 2024-10-25 22:52:19 +02:00
Alug 122bd69069 Add visplane portal creation functionality and use it to replace the skybox rendering.
https://git.do.srb2.org/STJr/SRB2/-/commit/264386f84257a47fe5480bb6300df02d039a2491
2024-10-25 21:03:27 +02:00
Alug 27b77c2db4 port srb2 software portal refactor 2024-10-25 20:49:38 +02:00
Alug 6333fc73e9 move the return ealier in V_DoPostProcessor 2024-10-25 20:21:04 +02:00
Alug 63d4ae5206 this is needed for postimg stuff in first person
lol
also adds break in splitscreen lööp
2024-10-25 20:12:06 +02:00
Alug 9fc4f81fef ok those should be fine 2024-10-25 02:49:46 +02:00
Alug 9fa9261580 aaa 2024-10-25 02:46:35 +02:00
Alug 2f98c5457d add a bunch of more flags to hopefully make this netsafe 2024-10-25 02:44:19 +02:00
Alug f7bca6f868 this crashes 2024-10-25 02:43:58 +02:00
Alug 426dd1489a Reapply "optimize z position checking for mobjs without collision and camera"
This reverts commit 0dca45ca6c.
2024-10-25 02:33:08 +02:00
Alug 740eb5d860 also use K_MomentumAngle for speelines make eggmanexplode color them and inline them since this used to be in the function itself 2024-10-25 02:24:58 +02:00
Alug 5100443457 comment it out tho since we use a lua with the same visual effect 2024-10-25 01:47:59 +02:00
Alug b5c284f526 make some stuff also be able to spawn watertrails 2024-10-25 01:38:21 +02:00
Alug 8c0fa813fe use momentumangle stuff like rr for wöter 2024-10-25 00:53:54 +02:00
Alug ab5aa30068 oops forgor lol 2024-10-24 23:05:20 +02:00
Alug 525ab05549 slight cleanup + make static + smol optimize ogl sprite drawers 2024-10-24 23:03:18 +02:00
Alug f7c831f9d1 dont pass skybox to r_setupframe
why was this even done?
neither srb2 nor v2/rr ever did this?
2024-10-24 22:44:10 +02:00
Alug a195f807d0 speed up ogl floor clip fix slightly 2024-10-24 18:43:42 +02:00
Alug dde1229e54 try to speed up texture updating 2024-10-24 18:43:22 +02:00
Alug 88c4517b72 this only needs to be checked when thing->player
aaaa
2024-10-24 02:56:10 +02:00
Alug f47eed9413 try to optimize a few sectorspecial checks 2024-10-24 02:39:40 +02:00
Alug fe35d5ab55 save one calc lol 2024-10-24 02:08:17 +02:00
Alug 0e17013255 just check for noencore bool in hwr_processseg instead of checked line flags everytime 2024-10-23 21:28:08 +02:00
Alug a44e3515a2 why not reuse those? 2024-10-23 20:37:11 +02:00
Alug 001cd91b62 cleanup HWR_ProcessSeg
stuff was quite the mess
2024-10-23 19:51:55 +02:00
Alug f88931445a dont always calc this twice 2024-10-23 19:02:48 +02:00
Alug 947e6f943f no need to check stuff in already postload marked addons 2024-10-23 15:48:34 +02:00
Alug 1cba35d7aa move this into TC_RAINBOW condtion
its only used with TC_RAINBOW anyways
2024-10-23 15:25:55 +02:00
Alug 675e0f8c4f this does nothing 2024-10-23 15:25:07 +02:00
Alug 30e504810b dont play rain sounds when weather is disabled 2024-10-23 13:00:22 +02:00
Alug 185198593d remove debug print 2024-10-23 01:48:57 +02:00
indev 34cdf39c6b Add W_CheckFileContains for W_CheckPostLoadList 2024-10-23 02:45:16 +03:00
Alug 4f8736300a attempt to check for things in file for postload detection 2024-10-23 01:00:31 +02:00
Alug e40e1c42c3 split auto and postload, let autoload run on gamestart again
prep for smth
2024-10-23 00:26:08 +02:00
Alug a04d7c6b23 redo rain sound overflow fix
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/3eac1fed0f44a8285a9f6b82a12e86997bbb0d34
2024-10-22 20:20:30 +02:00
Alug 40b37e9c31 fix sprite scale and offset interpolation for ghost mobjs
and remove sprite roll interp that never worked
2024-10-22 16:06:08 +02:00
Alug c49bb1bbc6 fix ghost interpolation 2024-10-22 02:27:34 +02:00
Alug ff0f0ee347 make those not look terrible thx 2024-10-22 01:15:52 +02:00
Alug e3eb49e4a2 refactor postimg stuff so it can be combined with each other better
thx much indev! <3
everything now works with encore!
software now also supports screen effects in splitscreen!
2024-10-22 01:11:40 +02:00
Alug 42e463e529 actually remove "renderflags" lol 2024-10-21 22:52:59 +02:00
Alug f781532e1b gaah tabs 2024-10-21 22:51:05 +02:00
Alug ba8958b27a remove renderflags
those literally did nothing
2024-10-21 22:46:51 +02:00
Alug d082bfd8ec fix R_ThingVisible
those are "eflags" in kart smh
2024-10-21 22:38:45 +02:00
Alug 3216b2515d maybe fix mobj interp spawn bugs?
idk maybe has some odd side effects?
2024-10-21 22:22:38 +02:00
Alug 078f198d81 add proper null check here too 2024-10-21 21:28:01 +02:00
Alug 6162d285c9 dont use cv_sloperolldist in splitscreen + save some assignments and one fixedhypot call
also use tabs lul
2024-10-21 21:05:05 +02:00
Alug 56b1ead206 tab pls 2024-10-21 18:43:01 +02:00
Alug 5f11d93d42 make this less terrible lmao 2024-10-21 18:41:27 +02:00
Alug 78a62ba84a use highly optmized (but slightly inaccurate) version of R_PointOnSide for rendering 2024-10-21 18:17:47 +02:00
Alug ad5f288374 Clarify we're calculating a cross product 2024-10-21 18:10:18 +02:00
indev 2aa6f1b8f5 Fix off-by-one error for using '?' as map name 2024-10-21 17:41:06 +02:00
indev 25a5ac2a2d Fix off-by-one error in lib_setSfxInfo 2024-10-21 17:39:42 +02:00
Alug 8a9f44ebaf also check here ig? 2024-10-21 17:01:20 +02:00
Alug e6b77081f7 prevent map command crash from maps with invalid or non existing mapinfo 2024-10-21 15:37:34 +02:00
Alug 9808d123cd replace those two P_MobjWasRemoved with simple null check insteead
since those may actually segfault if null anyways
2024-10-21 06:23:05 +02:00
Alug 4213bffab0 trailing space hell 2024-10-21 06:11:18 +02:00
Alug 516f0c700f remove more P_MobjWasRemoved checks
same as before, those may be not synchsafe
2024-10-21 06:03:47 +02:00
Alug b03939d753 revert some P_MobjWasRemoved checks i forgor about
those may NOT be vanilla netsafe
2024-10-21 05:55:44 +02:00
Alug 0786e3dcf2 lugstuff change 2024-10-20 20:30:38 +02:00
Alug fe4397d746 bruh 2024-10-20 19:53:56 +02:00
Alug b4c52190e2 rotsprite stuff also should be SHORT 2024-10-20 19:11:46 +02:00
Alug 723491fd86 try to take some registers for span drawers too 2024-10-20 15:59:31 +02:00
Alug a1b087938e remove this again 2024-10-20 15:21:58 +02:00
Alug c13cb0b8d9 Reapply "optimize R_PointOnSegSide"
This reverts commit 5b3daac4c8.
2024-10-20 04:15:28 +02:00
Alug c1703de590 terrible brightmap substitute 2024-10-20 04:15:25 +02:00
Alug e08f03cf57 HWR_RenderPlane can be static 2024-10-20 04:14:54 +02:00
Alug 5b3daac4c8 Revert "optimize R_PointOnSegSide"
This reverts commit c1ce93b6b0.
2024-10-20 02:17:35 +02:00
Alug c1ce93b6b0 optimize R_PointOnSegSide
its only used for 2 rendering functions, so being potentially inaccurate is not that dangerous and the speedup in some instances might be worth the tradeoff
2024-10-20 02:02:22 +02:00
Alug 5da1e8bb80 fix some rendering issues and crashes in software renderer
- Increase MINZ from 4 fracunits to 16
- R_StoreWallRange: do not render textures with holes
- fix off-by-one error in R_ProjectSprite
- Avoid rendering unused left/right edges of screen while rolling
- Clamp patch column post drawing bounds
- Vissprites: set dc.texheight
- Add null check for column in R_DrawMaskedColumn
2024-10-20 02:01:02 +02:00
Alug 48a62eeee4 fix a maybe-uninitialized warning 2024-10-20 00:21:48 +02:00
Alug f9788a21f6 fix lightnum calc 2024-10-20 00:18:31 +02:00
Alug db425035a4 dont need to always check this 16 times if we already know theres more than one player ingame 2024-10-19 21:14:45 +02:00
Alug ed7aa81527 dont show encore toggle text in record attack menu
dont think you can even record attack in encore hmm
2024-10-18 20:34:00 +02:00
Alug 8108dec7e3 just remove version string at this point lol 2024-10-18 20:23:06 +02:00
Alug f9363e71d9 dont run director if theres only one player ingame
idk if this is good lol
2024-10-17 22:54:44 +02:00
Alug 98a7e35c55 forgor joyscale 2024-10-16 13:21:47 +02:00
Alug c998bd9c05 huge cleanup controller code
hope i didnt break anything here lel
2024-10-16 13:14:07 +02:00
Alug 7194f44eca those can be registered in lööp 2024-10-16 12:57:27 +02:00
Alug 4654070f9a clean up cvar register a bit 2024-10-16 11:22:08 +02:00
Alug 16db0ba290 do this instead 2024-10-16 00:19:18 +02:00
Alug 58bf1572de Revert "optimize R_PointOnSegSide"
This reverts commit 068afd7eb4.
2024-10-15 23:52:17 +02:00
Alug 4af35d623c attempt to optimize some p_maputl stuff 2024-10-15 23:31:46 +02:00
Alug 3bbafe8fc1 god pls just work 2024-10-14 19:20:19 +02:00
Alug 068afd7eb4 optimize R_PointOnSegSide 2024-10-14 13:15:56 +02:00
Alug f98209a32e remove this print 2024-10-14 13:15:33 +02:00
Alug d62a654a2d forgor about shadows lol 2024-10-13 23:36:21 +02:00
Alug 509341569e whoops forgor 2024-10-13 23:25:17 +02:00
Alug 20b82c1f2a lol 2024-10-13 23:13:14 +02:00
Alug 54170bece7 only do this in software renderer
doesent work even with pal rendering in ogl
2024-10-13 23:07:44 +02:00
Alug 0a7578472e move this 2024-10-13 22:54:20 +02:00
Alug 65cf58dfab remove unused/nonunsable analog cvars 2024-10-13 22:39:26 +02:00
Alug d95828451e fix cam stuff for good + huge cleanup 2024-10-13 22:20:56 +02:00
Alug e21182ccfc fix the cam loops 2024-10-13 21:47:56 +02:00
Alug ba818244df use arrays for all the cam cvars 2024-10-13 19:01:30 +02:00
indev c667fedc1a Fix error handler staying on lua stack after lua commands being called 2024-10-13 14:45:01 +02:00
indev a7d6c0994f Fix game crashing when using P_DoPlayerExit on player without mobj 2024-10-13 14:44:58 +02:00
Alug d601975597 this should be SHORT 2024-10-13 02:58:46 +02:00
Alug 21b57c1009 this uhhh actually makes things crash lol 2024-10-13 02:46:04 +02:00
Alug 16800a2730 fix ogl shearing
no clue wtf kart was doing here lmao
2024-10-13 02:28:07 +02:00
Alug 36448930d6 dont need this splitscreen check 2024-10-13 02:01:02 +02:00
Alug 740c39c3c4 attempt to clean up cam shit even more 2024-10-13 01:55:52 +02:00
Alug 397efe5479 only interp cam during pause for replay freecam to not jitter during pause 2024-10-13 01:11:48 +02:00
Alug f6c9b22adc ignore keepmusic when called from P_RestoreMusic
most of the sound handling just calls this and this may just stop the music entirely on some occasions so just ignore keepmusic for that
2024-10-13 00:40:37 +02:00
Alug ffa053c695 print saturnpak print into debfile instead of console 2024-10-13 00:11:34 +02:00
Alug 5c4fee6cdf Refactor TTY input handling
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2451#b2f76b3273f1780347c35ec752bcde560c5f73a5
2024-10-12 23:26:07 +02:00
Alug 38335e857a fix tty converting everything to lowercase 2024-10-12 23:21:05 +02:00
Alug 9f16fa3e17 Fix insane TTY input latency
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2360
2024-10-12 23:10:01 +02:00
indev d0ad91f277 If corrupted save received, leave netgame 2024-10-12 22:05:25 +02:00
Alug e1d98ea45c Add few checks to prevent game crashing if netgame archive becomes corrupted
https://github.com/alufolie91/saturn-32p/commit/1e47728ea8c60a1f04130170ddfab9b02e1a7e4c#diff-0c6396d5a9ad45f461741cd44ffb2c0d3cf0eb2ec7b0500053005196fe53f1a6R1517
2024-10-12 22:04:50 +02:00
Alug cedab33c13 Attempt to fix a lua panic when unarchiveing extvars (print error to console instead. Not sure if it would be safe for game to read from save afterwards though)
https://github.com/alufolie91/saturn-32p/commit/a770ecdbd4afd56a9d8325eae47f0c69f71661ee#diff-0c6396d5a9ad45f461741cd44ffb2c0d3cf0eb2ec7b0500053005196fe53f1a6R1462
2024-10-12 21:56:08 +02:00
Alug 212667a34f oops 2024-10-12 21:29:39 +02:00
Alug cf5ee4cf27 make s_sound a little prettier 2024-10-12 21:24:37 +02:00
Alug 6953e494cb fix some warnings when compiling with older sdl version 2024-10-12 21:23:58 +02:00
Alug daad7627b8 save 1 G_BuildMapTitle call kek 2024-10-12 20:19:44 +02:00
Alug 0bfed31cae clean bird music stuff again
we dont need to return everywhere but instead stuff can be mostly just set to 0
this also somewhat ensures stuff works after toggling without having to restart the game or map
2024-10-12 19:54:56 +02:00
Alug 9660128123 always assign stutter_threshold 2024-10-12 19:44:15 +02:00
Alug c927d333bd readd music_resync_powerups_only 2024-10-12 19:39:52 +02:00
Alug 75637e361c shut up mingw 2024-10-11 21:12:52 +02:00
Alug cbcfe9d3e9 fix spec cam bug + more cleanup 2024-10-11 21:00:05 +02:00
Alug 7ea07ec3b0 Start bustable FOF sounds at the correct height 2024-10-10 14:40:14 +02:00
Alug df842b981c remove broken and unused netcode stuff
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2523
2024-10-10 05:18:07 +02:00
Alug c98781403d Revert "rendertimefrac_unpaused should be fracunit on netlag"
This reverts commit 6722b43244.
2024-10-09 15:32:51 +02:00
Alug 651e5a4924 proper inline this 2024-10-08 04:17:58 +02:00
Alug 9eec9f7e52 fix some inline stuff 2024-10-07 23:05:01 +02:00
Alug 41244ae522 proper inline P_MobjWasRemoved 2024-10-07 23:01:17 +02:00
Alug f1d0e2834e proper inline M_Memcpy 2024-10-07 23:01:03 +02:00
Alug 7f98bac3ae properly inline those 2024-10-07 22:57:24 +02:00
Alug 9d8fcfeeb6 smol fix 2024-10-07 21:32:25 +02:00
Alug 28847e4adf test smol optimization P_CheckPosition 2024-10-07 20:40:41 +02:00
Alug ee2d078957 keep debug print for now 2024-10-07 13:00:50 +02:00
Alug e51bb250e2 add some brackets lul 2024-10-07 13:00:18 +02:00
Alug e93ea48b96 comment this out for now so v7 clients dont use vanilla resynch system
keep sending PT_WILLRESENDGAMESTATE packets to everyone for now
saturnpak will still mark the right clients so they will use the right consistency check without having to desynch first
2024-10-07 13:00:08 +02:00
Alug 5efe6364ca add debfile prints whenever gamestate counter changes 2024-10-07 12:59:59 +02:00
Alug c6574ee800 make the debug print a little better 2024-10-07 12:59:54 +02:00
Alug df8c39425a use saturn packet to determine if client can receive gamestate
before the server always assumed every client cant receive the gamestate using the vanilla consistency check for everyone.
aswell as before the first resynch it tried to send the gamestate resend packets to everyone
2024-10-07 12:59:51 +02:00
Alug 0e49632006 make this less ugly 2024-10-07 12:53:25 +02:00
Alug 9c60a9298d false 2024-10-07 12:48:29 +02:00
Alug a4792f3058 add crap to menu 2024-10-07 12:45:09 +02:00
Alug 05b65dd7f6 psure this can just be SINT8 2024-10-06 19:04:28 +02:00
Alug 9657dc0f1b prevent this from become super large somehow lol
just like cap it at 19 it works just fine
2024-10-06 18:44:14 +02:00
Alug d5ff7f1274 this doesent make much sense tbh 2024-10-06 18:35:26 +02:00
Alug 5b59e9e740 this shouldnt be here lol 2024-10-06 18:33:25 +02:00
Alug 567b61133e shouldnt that be a bool? 2024-10-06 18:31:40 +02:00
Alug 3427fc3275 rendertimefrac_unpaused should be fracunit on netlag
makes this a little more sane tbh
2024-10-06 18:31:09 +02:00
Alug f3b96b5050 dont think this needs to be reset every frame 2024-10-06 18:28:00 +02:00
Alug 3a3eb2790d fix this 2024-10-06 14:52:35 +02:00
Alug d5225537c4 only do this in replays
otherwise shit will jitter during netlag
2024-10-06 14:30:21 +02:00
Alug fac56d9469 fix main menu interpolation
apparently in main menu, opening the menu pauses the game so rendertimefrac was FRACUNIT and didnt interpolate
2024-10-06 13:32:46 +02:00
Alug cc73aa18c6 Interpolate view, even when paused
https://github.com/KartKrewDev/RingRacers/commit/3320faec8cebecb124882d38c7ec0ad37b79340a#diff-607b68058edc6124b3061267d902aabeddb6ba338c6483df0af8b1a7cf796a01R43
2024-10-06 13:12:27 +02:00
Alug ba2127b00e fix a interp bug where the jitter on tally increase would be for only one rendered frame, not one full tic. 2024-10-06 13:04:43 +02:00
Alug 4e966aa44a HACK: reset interp values in case 412 teleporter without using P_Setorigin
since that function does some wonky stuff and idk if that would be synch safe
2024-10-06 13:00:07 +02:00
Alug 23fe7755f8 add missing break 2024-10-06 12:56:19 +02:00
Alug f81d33acdf more R_ResetViewInterpolation stuff 2024-10-06 12:53:24 +02:00
Alug 305037cae2 R_ResetViewInterpolation: wait an extra tic if R_UpdateViewInterpolation has not run yet, do not add extra time for subsequent calls 2024-10-06 12:49:29 +02:00
Alug 2909b68872 smol fix 2024-10-05 08:35:35 +02:00
Alug bf9cd35e5c throw this into own function too 2024-10-05 08:29:40 +02:00
Alug 30b7fc2f2b make function for quakes, scale with mobjscale 2024-10-05 08:26:06 +02:00
Alug 4213e6a965 this needs gamestate check
sometimes the title music kept playing
2024-10-05 06:56:21 +02:00
Alug b868ff35c2 attempt to cleanup R_SetupFrame 2024-10-05 06:09:48 +02:00
Alug ccb116e910 P_Ticker: update view interpolation at the start of a tic 2024-10-05 06:08:23 +02:00
Alug 0412e8fd8e add G_FixCamera 2024-10-05 06:04:12 +02:00
Alug 3f68006e3c set timeinmap for demo rewind
idk maybe this helps with that feature desynching all the time lol
2024-10-05 05:41:30 +02:00
Alug 4ed7a63806 Do not set hu_stopped on interpolated frame 2024-10-05 05:25:25 +02:00
Alug 4d56c1559f add comment to try and explain this crap 2024-10-03 18:15:12 +02:00
Alug ae99bcfca2 make this more readable 2024-10-02 20:32:26 +02:00
Alug 8f8ec6ef5d smol dupe 2024-10-02 14:39:57 +02:00
Alug 05faa2cbf8 prevent this from overflowing
ye well idk anymore.
2024-10-02 14:20:29 +02:00
Alug 56b942289f fhsfghs 2024-10-02 14:16:43 +02:00
Alug b095ac7620 gu 2024-10-02 14:16:37 +02:00
Alug bc7520f45a ok we need a bunch of this 2024-10-02 14:16:08 +02:00
Alug 82f9de3114 Reapply "Only reseek if we have to"
This reverts commit cbc39ba4f9.
2024-10-02 13:57:52 +02:00
Alug a5de6eccd5 Reapply "New system to prevent multiple fopen"
This reverts commit 0bdf1ca87a.
2024-10-02 13:57:42 +02:00
Alug 7c645c1623 why? 2024-10-02 13:50:06 +02:00
Alug 540d99924e why did we calc all of this in ogl? 2024-10-02 13:34:41 +02:00
Alug 68681a34f2 conflict stuff 2024-10-02 12:43:28 +02:00
Alug d56df7e0fc dont leak pls 2024-10-02 12:42:16 +02:00
Alug eb4eef5260 fix G_BuildMapTitle leaks 2024-10-02 12:42:10 +02:00
Alug 7b62c14a8e Revert "add global maptitle string calced at mapload"
This reverts commit 401597d309.
2024-10-02 12:42:04 +02:00
Alug 0ecc23e52d Revert "init with NULL lol"
This reverts commit 06bcd3ffca.
2024-10-02 12:41:36 +02:00
Alug fdefb1829b Revert "pre alloc MapName on mapload and unarchive"
This reverts commit 1b027e169a.
2024-10-02 12:41:34 +02:00
Alug b775095b67 fix up old fps counter 2024-10-02 12:14:31 +02:00
indev b87074c5f6 Fix selection in replay save prompt 2024-10-02 11:41:53 +02:00
Alug 2be07aee63 a 2024-10-02 11:41:49 +02:00
Alug c45a792ef9 Use textinput_t for replay save prompt too 2024-10-02 11:41:03 +02:00
Alug 1b027e169a pre alloc MapName on mapload and unarchive 2024-10-01 17:45:18 +02:00
Alug 06bcd3ffca init with NULL lol 2024-10-01 16:38:48 +02:00
Alug 401597d309 add global maptitle string calced at mapload 2024-10-01 16:35:10 +02:00
Alug e3773172f3 lol 2024-10-01 16:03:48 +02:00
indev bc37b4c817 Remove debug print 2024-10-01 16:02:52 +02:00
indev df031d1b88 Fix (hopefully) all other menu types that use IT_CV_STRING 2024-10-01 16:02:46 +02:00
Alug 1dc83a0c3c dumb special case for wandering balls Zzz... 2024-10-01 16:02:39 +02:00
indev 1883178c55 Fix IT_CV_STRING crashing game in M_DrawGenericMenu 2024-10-01 15:46:15 +02:00
Alug e0a74be510 fix some stuff 2024-10-01 15:46:09 +02:00
Alug 2725e590ea add "map ?" shortcut for random map 2024-10-01 14:49:37 +02:00
Alug 30aa9b2bc1 use stricmp for this 2024-10-01 14:42:20 +02:00
Alug fe591b6620 cv_showdirectorhud didnt save Zzz... 2024-09-30 23:00:25 +02:00
Alug 6d8ed5897f more 2024-09-30 16:33:29 +02:00
Alug ece9eb3504 cleanup + comments 2024-09-30 16:32:03 +02:00
Alug c6de3040fb work around encore music again
S_InitMapMusic would play before the level actually started thus playing a smol bit of non encore music in encore
2024-09-30 16:27:56 +02:00
Alug 5f1dfecd18 fix encore music again lol 2024-09-30 16:19:54 +02:00
Alug 76d22deddd Use m_textinput for chat too 2024-09-30 15:43:22 +02:00
indev b92fddeabc Use same keyboardlayout code as in chat for textinput, also add a null terminator after ctrl-v just in case string is not always zeroed out already 2024-09-30 15:42:59 +02:00
Alug 2dddc81713 Put all text input logic into separate file and use it for all text input fields 2024-09-30 15:42:55 +02:00
Alug 0fb2992b49 dev print for weather stuff 2024-09-30 15:42:22 +02:00
Alug 8464554a71 work around custom vote theme music + rename a bunch of stuff
please help me
2024-09-30 15:41:19 +02:00
Alug 4034a8227f encoremusic... 2024-09-30 13:05:44 +02:00
Alug ff9d2b0cdc fix up everything and make stuff work
i hope lmao
2024-09-30 12:50:49 +02:00
Alug 95cdc2c5a6 change how keepmusic works
compare map and encore instead of the music itself
2024-09-30 11:45:33 +02:00
Alug f8083e10eb forgor about encore music 2024-09-30 06:38:29 +02:00
Alug 8c6322c04d update comments a little 2024-09-30 06:31:43 +02:00
Alug ef58f61d8e add some basics of what i wanna have for music stuff
- basic keepmusic implementation (currently checks for if the song changes instead of the map, idk if i keep this, since this allows certain maps to change the music on start, ex abstract avenue or wandering balls)
- Toggle to ignore any kind of music change during the level (includes intermission music, depends on how custom intermission music works)
-toggle to start map music instantly on levelload and skip the intro fanfare (also skips any linedef executed sound so some map intros dont interfere with this)
2024-09-30 06:28:02 +02:00
Alug fae42eecbc make a function for the music level start stuff 2024-09-30 05:17:44 +02:00
Alug a81ea3c2cc let SOC also use PRECIP_BLANK/ weather = 4
no idea why it couldnt doesent make any sense
2024-09-29 22:26:49 +02:00
Alug 661984b620 no need to even traverse part of the blockmap when PRECIP_STORM_NORAIN and PRECIP_BLANK 2024-09-29 21:51:31 +02:00
Alug f6b571e022 move this stuff
so dont need check for renderisnewtic multiple  times and dont need to check for menu and dpad stuff every single frame
2024-09-29 15:14:43 +02:00
Alug 1ca2a8865f stop dying pls 2024-09-28 22:16:49 +02:00
Alug a55dacdcc6 remove code dupe and let S_LoadMusicDefs also load MUSCINFO def 2024-09-28 17:03:09 +02:00
Alug d20ebed618 make a funky macro 2024-09-28 15:04:12 +02:00
Alug 5fdc20f997 refactor musicdef stuff
well it fixed the hash find lmao
2024-09-28 03:20:57 +02:00
Alug 968445c12c oops 2024-09-28 03:20:37 +02:00
Alug 45965414b1 Remove p_sight assert 2024-09-28 01:49:21 +02:00
Alug f92034225d super smol optimization to S_FindMusicCredit 2024-09-28 01:47:18 +02:00
Alug 6949efbb7e reset rumble on some conditions 2024-09-28 01:37:54 +02:00
Alug 6e085e302d Replace portalline boolean with g_portal pointer to current portal Beta 2024-09-28 01:30:14 +02:00
Alug 642b196130 do this by default for me 2024-09-28 01:01:33 +02:00
Alug c84ad4aabb smol director stuffs 2024-09-28 00:12:57 +02:00
Alug 93bb7273c2 this needs no dedi check actually 2024-09-27 23:45:52 +02:00
Alug dfca69d59c kill lua_step 2024-09-27 23:41:49 +02:00
Alug 9655c33f48 set those in P_SpawnGhostMobj too 2024-09-27 22:46:54 +02:00
Alug 0c408d09fd let player pointer be const in P_IsLocalPlayer and P_IsDisplayPlayer 2024-09-27 22:40:38 +02:00
Alug 5f6b9ff87c forgor remove this 2024-09-27 22:40:08 +02:00
Alug 1da7a2d401 consolidate this 2024-09-27 22:36:48 +02:00
Alug a3c9812f67 this does nothing 2024-09-27 22:28:57 +02:00
Alug 03fd761179 z 2024-09-27 20:18:36 +02:00
Alug 89a64267fa R_DrawMaskedColumn: do not draw zero length column 2024-09-27 20:18:21 +02:00
Alug 4c25b7c26a Use PU_LEVEL for texture caching 2024-09-27 20:16:46 +02:00
Alug 97c8d06e33 Software: krangle directional lighting in 3P/4P splitscreen 2024-09-27 19:20:57 +02:00
Alug 9747d0bb20 those should be size_t 2024-09-27 18:52:53 +02:00
Alug 3fe3f512e3 update lzf compression to 1.6 2024-09-27 18:21:17 +02:00
Alug b4d4377938 fix encore minimap 2024-09-27 15:04:01 +02:00
Alug f5bf80cc63 use qs22j here again
it is really faster
thought it wasnt in this case
2024-09-27 05:19:52 +02:00
Alug 3e9f9129d8 cleanup + reformatting 2024-09-27 05:00:01 +02:00
Alug 34dd04b9ef forgor this 2024-09-27 04:26:43 +02:00
Alug d286bb43dd reformat this 2024-09-27 04:24:45 +02:00
Alug cab06f92d6 ; 2024-09-26 18:18:34 +02:00
Alug 4297c1b80d gamestate resend counter was never proper reset for nodes
means it would carry over to the next person occupieing that node and made them have less chances to get the gamestate resent
2024-09-25 19:31:18 +02:00
Alug bb6df8b4b8 those can be static 2024-09-24 22:23:23 +02:00
Alug 577380da3b add toggle for water ripples Zzz... 2024-09-24 22:18:17 +02:00
Alug 2f843feabf Kick clients that fail to catch up with server gamelogic
version from rr to accomidate kart netcode a bit better
2024-09-24 19:10:13 +02:00
Alug 9440aa62ff only allow director toggling with button when you spec someone 2024-09-24 16:57:20 +02:00
indev 0daf5e0da9 Expose demo.freecam as replayfreecam 2024-09-24 15:25:41 +02:00
Alug 64c4ad4852 make director text disappear after 13 seconds, and in replays after 4 2024-09-24 15:25:36 +02:00
Alug cf68f56497 dont show director text when in replay freecam 2024-09-24 15:02:32 +02:00
Alug 405ac6f85b hide viewpoint text when in replay freecam 2024-09-24 15:01:02 +02:00
Alug 72768e7d60 dont show driftgauge when in replay freecam 2024-09-24 15:00:45 +02:00
Alug cd3bd8713a dont run director when you use spectator freecam 2024-09-24 14:51:18 +02:00
Alug 399dbcaee9 Revert "dont read map marker files just skip em instead"
This reverts commit 2c0129be47.
2024-09-23 23:21:33 +02:00
indev 3f2889a644 Skip map marker in vres_GetMap 2024-09-23 23:15:07 +02:00
indev 533d2429b3 Add showdownloadprompt cvar, so addon download prompt can be disabled 2024-09-23 23:09:29 +02:00
Alug 2c0129be47 dont read map marker files just skip em instead
thx indev <3
2024-09-23 20:38:52 +02:00
Alug cb0da0d737 check vres data before freeing it 2024-09-23 20:36:56 +02:00
Alug ce9ab6e6c6 forgor some casting 2024-09-23 18:40:24 +02:00
Alug 373adf473a revert this 2024-09-23 01:39:21 +02:00
Alug 1cc461cc60 dont actually call Nullprecipthinker 2024-09-23 01:02:31 +02:00
Alug 89a4a19eed read precip row in perfstats 2 2024-09-23 01:02:14 +02:00
Alug 5ee5eac998 dont count precip towards thinkers in perfstats 2024-09-23 01:02:04 +02:00
Alug 999e5618d7 fix precip performance issuess on certain maps 2024-09-23 01:00:47 +02:00
Alug 056f7a32e8 lets not archive players as mobjs 2024-09-22 23:08:24 +02:00
Alug d1a3549ebc dont check consistency/attempt to resend the gamestate while a client is currently getting the save resend
perhaps that makes mass synchs less bad
2024-09-22 22:16:11 +02:00
Alug 8c58359aac Zzz... 2024-09-22 22:11:17 +02:00
Alug 0dca45ca6c Revert "optimize z position checking for mobjs without collision and camera"
This reverts commit c11d925580.
2024-09-22 17:51:56 +02:00
Alug 11039a4ce6 try to prevent unknown packet type spam when client attempt to connect while levelloading 2024-09-22 16:51:05 +02:00
Alug e16bc759b0 extra check 2024-09-22 16:46:08 +02:00
Alug c745a534de clean up leveload a bit 2024-09-22 16:46:01 +02:00
Alug ed24674b0c Load palette before map data 2024-09-22 16:25:16 +02:00
Alug 91f8705844 cleanup r_draw8 2024-09-22 16:01:23 +02:00
Alug e24fe7a239 update copyright am_map 2024-09-21 20:26:20 +02:00
Alug 970f948844 precalc automap and minimap stuff on mapload instead of every frame 2024-09-21 20:13:53 +02:00
Alug 85c5851539 stuff for potential fixup? 2024-09-21 19:43:22 +02:00
Alug 52c35ea0c5 attempt to fix automap + add minimap generator command "minigen" 2024-09-21 19:28:22 +02:00
Alug 14cc43dd6a beta hud driftgauge
eh needs some stuff for menu still
also should replace driftgauge gfx sometime
2024-09-20 20:31:45 +02:00
Alug 699da62ab1 move this 2024-09-19 12:41:32 +02:00
Alug 4be125d3da always reset cam subsector regardless of splitscreen 2024-09-18 12:11:04 +02:00
Alug 23631e4a0f decrease this a tiny bit 2024-09-17 19:52:20 +02:00
Alug 49c0e04f13 this is the correct value 2024-09-17 19:47:24 +02:00
Alug 16709f5f8e make ticcmds on gamestateresend
resynch will still stop making em
should hopefully fix some weird issues where you might end up somewhere weird if the resend takes a little longer
2024-09-17 16:47:24 +02:00
Alug b4ccca9892 properly reset all splitscreen cameras on resynch
also fix some casting
2024-09-17 16:46:21 +02:00
Alug 4e9086b369 Revert "dont run playerjoin hook on resynch"
This reverts commit 5f7bf4164d.
2024-09-17 16:43:05 +02:00
indev 8114e25056 Ignore case here 2024-09-17 16:42:37 +02:00
indev 7c6e36f8c5 Add proper skin search in skin command 2024-09-17 16:42:34 +02:00
Alug 1a13b83fd7 dont need this 2024-09-16 18:12:46 +02:00
Alug 0729065d16 "player" 2024-09-16 17:52:10 +02:00
Alug e6be07af1f some stuff i forgor 2024-09-16 17:33:17 +02:00
Alug 47aa62092e Revert "Contain end & size into savebuffer_t"
This reverts commit 1a810bc923.
2024-09-16 15:55:22 +02:00
Alug ce6596edde just kick everyone when direct download file not found instead of i error
dumbass hack for now
2024-09-16 15:55:04 +02:00
Alug 0bdf1ca87a Revert "New system to prevent multiple fopen"
This reverts commit cc54d98a39.
2024-09-16 14:32:32 +02:00
Alug cbc39ba4f9 Revert "Only reseek if we have to"
This reverts commit c332d48e9d.
2024-09-16 14:31:18 +02:00
Alug 77b3609cd8 Prevent integer div by 0 in curl progress callback 2024-09-16 13:53:53 +02:00
Alug c41bf8708b Revert "Add functions to initialize savebuffer_t"
This reverts commit 56182a1ef5.
2024-09-16 13:45:57 +02:00
Alug 54cc730414 Use Zone memory functions for sending compressed saves 2024-09-16 13:36:53 +02:00
Alug d138cee30c Only save demo if demobuf.p is ready 2024-09-16 13:36:13 +02:00
Alug 56182a1ef5 Add functions to initialize savebuffer_t 2024-09-16 13:35:46 +02:00
Alug 1f7487ae37 Contain end & size into savebuffer_t 2024-09-16 13:20:44 +02:00
Alug 2db1dcf79f more fixup 2024-09-16 12:56:09 +02:00
Alug 82ac0d3ab0 fix demo checkspace 2024-09-16 12:53:02 +02:00
Alug c0d1214032 rest smol fixes 2024-09-16 12:40:03 +02:00
Alug d0c909c51d fixup demo savebuf 2024-09-16 12:37:25 +02:00
Alug 2587911936 clean up 2024-09-16 12:18:01 +02:00
Alug 42bc7e3c17 unglobalize savebuffer
needs some cleanup
2024-09-16 12:05:44 +02:00
Alug 16ea4c1393 prevent netvar string overflow 2024-09-16 11:03:03 +02:00
Alug 9b6995e267 dont rerun this aswell 2024-09-16 00:54:19 +02:00
Alug 4117c109d8 dont rerun mapload hook on resynch 2024-09-16 00:44:58 +02:00
Alug 2923020273 dont run playerjoin hook on resynch 2024-09-16 00:19:33 +02:00
Alug ab47582f8a fix sound bug lol 2024-09-16 00:07:58 +02:00
Alug 4041a93ae5 revert some mobj stuff i forgor about 2024-09-15 19:27:06 +02:00
Alug 9cf3eb1631 smol fix to downsample shader 2024-09-15 14:08:06 +02:00
Alug 56fba6725e make advanced server menu scroll menu
grrrrr green res
2024-09-15 12:02:56 +02:00
Alug 3c4e552517 ... 2024-09-15 11:47:33 +02:00
Alug cdc284f009 squish options menu a little
im honestly too lazy too move shit around just before release lmao
2024-09-15 11:43:03 +02:00
Alug 961fe4aad4 test optimization 2024-09-15 00:39:26 +02:00
Alug 67eb7bbff8 some cleanup 2024-09-14 19:43:54 +02:00
Alug 5c82e674cc remove code dupe in r_segs 2024-09-14 18:43:00 +02:00
indev dc5a9bb856 should be != here 2024-09-14 18:16:48 +02:00
indev 28d58b9828 Don't default to sonic if skin was changed to unknown skin, use current skin instead 2024-09-14 17:05:52 +02:00
Alug a187b82887 add a touch of skincolor to speedlines when going fast 2024-09-14 14:25:49 +02:00
Alug 2bf60a9a26 colourize speedlines on some occasions
like durr or ssmth
2024-09-14 14:05:58 +02:00
Alug d2c1158d57 forgor about this 2024-09-14 13:14:01 +02:00
Alug c1305904e5 delete half game again but keep the bots and dehacked crap 2024-09-14 13:07:51 +02:00
Alug 094cf21c4c use continues in hooklib loops too
idk if this is any faster, but it makes smth i wanna port over potentally easier
2024-09-14 12:31:10 +02:00
Alug dc7a23db65 better value 2024-09-13 15:46:40 +02:00
Alug 9297620b6a smol m_menu cleanup 2024-09-13 14:17:06 +02:00
Alug 28019b1088 replace tooltip crap with a macro + fix adv video options tooltips 2024-09-13 14:01:02 +02:00
Alug 18714ac542 move credits a tiny bit 2024-09-13 13:37:04 +02:00
Alug 1724765feb whoops wrong tooltip 2024-09-13 13:35:10 +02:00
Alug 97ee57ff9c add smol comment 2024-09-13 13:30:23 +02:00
Alug 4bc1224d0c remove this forgor i still had that here lol 2024-09-13 13:30:10 +02:00
Alug 169ee01338 this used to be const 2024-09-13 13:22:43 +02:00
Alug d335898584 no need to save saturnjoin value + smol cleanup 2024-09-13 13:20:49 +02:00
Alug 4269ccdee4 super smol optimization R_ThingWithinDist
no need to run fixedhypot on every sprite when you dont use draw distance limit
2024-09-13 12:44:29 +02:00
Alug f12622f1e3 kek i dont have this and was too lazy to fix merge conflicts 2024-09-13 12:34:18 +02:00
Alug 866d4f6b1d smol menu visual cleanup 2024-09-13 12:32:50 +02:00
Alug a344a5efc5 add old line whatever in intermission add beta intermission visual to menu 2024-09-13 12:27:57 +02:00
Alug e272885f26 small cleanup intermission drawer 2024-09-13 12:17:21 +02:00
Alug a6c28245be Revert "delete half the game again"
This reverts commit 87bc2f1b64.
2024-09-13 01:49:50 +02:00
Alug 13e8367106 Revert "forgor to remove cv_call"
This reverts commit 87c5336cf4.
2024-09-13 01:49:46 +02:00
Alug 925180c10f only need to check all this when in splitscreen
retains vanilla behaviour
2024-09-13 00:22:57 +02:00
Alug 69844884b7 clean up sprite stuff 2024-09-13 00:16:28 +02:00
Alug e07efa1c21 fix wöter shader interpolation
accidentally reverted that when redoing palette rendering
2024-09-12 22:43:06 +02:00
Alug 87c5336cf4 forgor to remove cv_call 2024-09-12 12:36:48 +02:00
Alug 113d418144 try a funny = randomized directional lighningh 2024-09-12 02:23:39 +02:00
Alug 87bc2f1b64 delete half the game again 2024-09-12 02:17:47 +02:00
Alug d522dc4acc delete nights grade stuff
psure this is unused
2024-09-12 01:14:50 +02:00
Alug ef40f4a0ca forgor this 2024-09-12 01:04:33 +02:00
Alug 8b1d30b319 delete DEH_WriteUndoline
it literally does nothing lol
2024-09-12 01:03:03 +02:00
Alug 3bb18a1bc7 port directional + sprite lightning
doesent do all too much without soc
but was bored and could make smth cool out of it

needs a global toggle since it does some stuff by default
2024-09-11 23:17:47 +02:00
Alug 65793db889 apparently this always runs
i am in pain
2024-09-11 20:11:15 +02:00
Alug 862a4437e9 let item button toggle encore in mapselect screen
guh
2024-09-11 19:56:17 +02:00
Alug 58b3ab8185 add missing masterserver ifdef 2024-09-11 19:43:57 +02:00
Alug fa3a9c4be8 this can be int16 2024-09-10 19:51:52 +02:00
Alug 1db698961c Revert "smol optimization to HWR_AddLine"
This reverts commit 77c9badeca.
2024-09-10 10:58:37 +02:00
Alug c9bc9ce38c Revert "smol optimization R_AddLine"
This reverts commit 677cdc77e4.
2024-09-10 10:58:34 +02:00
Alug 8ab836c081 Revert "Zzz..."
This reverts commit b703428ee3.
2024-09-10 10:58:30 +02:00
Alug b703428ee3 Zzz... 2024-09-10 10:31:13 +02:00
indev 00a4c30979 Snap title demo logo to bottom right corner 2024-09-10 10:13:57 +02:00
Alug 3b080f4563 smol optimization R_AddLine 2024-09-09 22:54:18 +02:00
Alug d0f0e97254 smol cleanup 2024-09-09 22:32:51 +02:00
Alug 85f39b5310 smol optimization to HWR_AddLine 2024-09-09 22:31:38 +02:00
Alug b5f980a4ff remove redundant check 2024-09-09 22:02:49 +02:00
Alug 1d0032561e only change lightlevel/colormap behaviour in palette rendering 2024-09-09 21:50:55 +02:00
Alug dfc6ffe2ba fix off by one in sprite lightlevels 2024-09-09 21:50:24 +02:00
Alug 8c379f56cd revert this ig 2024-09-09 18:51:00 +02:00
Alug 0a54114db0 add toggle for director prompt
cause ik some ppl will complain lol
2024-09-09 16:05:01 +02:00
Alug fcb37a75da make this less complicated lol 2024-09-09 15:58:36 +02:00
Alug 95382298ce fade director hud after 4 secs after toggling it 2024-09-09 10:38:30 +02:00
Alug 51cf4b7b6f disable director on title screen and record attack demos 2024-09-09 09:21:35 +02:00
Alug 77c40d8aa1 remove unused ctf resynchpak stuff 2024-09-09 09:15:07 +02:00
Alug af7abea5e1 dont think this ever gets called but just in case 2024-09-09 09:03:33 +02:00
Alug 32a1a7ee3f huge cleanup gametypes
removed half the game lol
2024-09-09 08:46:13 +02:00
Alug 2d43624a87 make it static actually 2024-09-08 23:36:50 +02:00
Alug df6ef9752a turn off director by default when playing replays and restore the setting when done
you can  still toggle it in replays no issues
but you mostly want to watch yourself or a certain person during replays, so having to manually toggle it off always is weird
2024-09-08 23:33:54 +02:00
Alug 8b9efaa179 dont trigger rumble in offroad when under hyu effect 2024-09-08 23:09:09 +02:00
Alug 2ffb37e8ec Revert "Reapply "optimize pointon functions""
This reverts commit 47dad991b9.
2024-09-08 18:43:24 +02:00
Alug 3397bf912d readd this crap 2024-09-08 16:52:33 +02:00
Alug 448e1b3a75 lugstuff crap 2024-09-08 16:45:31 +02:00
Alug 2b32605fde slight portal cleanup 2024-09-08 16:45:09 +02:00
Alug cdf90723c3 Revert "delete ogl portal code"
This reverts commit 8cd79199e8.
2024-09-08 15:40:10 +02:00
Alug 9e9e989ec1 fix potential rendering issues on large maps 2024-09-08 14:51:16 +02:00
Alug 589c16e1fc smol cleanup 2024-09-08 14:51:01 +02:00
Alug 8cd79199e8 delete ogl portal code 2024-09-08 14:50:37 +02:00
Alug 364d2a042b oops 2024-09-07 20:09:36 +02:00
Alug b0b7bf5e14 clean up and improve ogl portals 2024-09-07 20:06:11 +02:00
Alug d9d766c098 this is literally broken and noone knows about it anyways lol 2024-09-07 17:52:13 +02:00
Alug 1f1d6df342 Show a console error if the gamestate contains too many tables 2024-09-07 17:30:00 +02:00
Alug 1a1e2f0c78 this needs to be shifted 2024-09-07 17:04:00 +02:00
Alug e01ee77a52 guh 2024-09-07 16:57:33 +02:00
Alug 2521d06233 this should use angleturn
uhhh
2024-09-07 16:46:23 +02:00
Alug 4200e263ed set camera angle to player angle in CL_ReloadReceivedSavegame
hope i did this right lol
2024-09-07 16:27:22 +02:00
Alug f3dfda530e dont rerun levelload executors when gamestate resent 2024-09-07 15:59:10 +02:00
Alug d0e04ca603 dont print "Map is now" everytime you resynch from gamestate resend 2024-09-07 15:55:44 +02:00
indev f45f733ff4 Document changes to lua P_PlayRinglossSound and K_PlayHitEmSound functions 2024-09-07 15:35:23 +02:00
Alug 951bf35db6 smol fixes for gamestate resend in P_SetupLevel
- dont reset cameras during gamestate resynch
- dont reinit director during gamesate resynch
- dont reset view interpolators aswell
- dont reset localaiming aswell

should make resynching less jarring visually hopefully
2024-09-07 15:35:17 +02:00
Alug eaea684e71 add compiler flags NOSATURNSYNCH, NOSATURNJOIN and NOSATURNPAK
not building with SATURNSYNCH also will disable SATURNJOIN since it makes not much sense to have that when synch stuff is unused
2024-09-06 21:41:46 +02:00
Alug 0261fa3077 % 2024-09-06 21:06:00 +02:00
Alug 8c6414ce5a smol cleanup + add comments 2024-09-06 21:05:21 +02:00
Alug c7262e257d set netgame save stuff to false for replays
to retain max vanilla compat for replays
dont want those breaking between clients
2024-09-06 21:02:16 +02:00
Alug c5df712c7d reserve saturn packet even if unused
to not cause any weird isssues if either one is undefined and stuff like that
2024-09-06 20:36:20 +02:00
Alug 8ed7bd0034 menu offset stuff for if not using SATURNSYNCH 2024-09-06 20:06:49 +02:00
Alug e7a0ac104a oops again 2024-09-06 19:59:39 +02:00
Alug e21b83b1ec hide gamestate resynch stuff behind SATURNSYNCH ifdef 2024-09-06 19:55:22 +02:00
Alug 31b8038aa0 oops 2024-09-06 19:52:04 +02:00
Alug dcb262f192 put saturn specific join allow stuff behind SATURNJOIN define
so it can be seperate from SATURNPAK
2024-09-06 19:23:35 +02:00
Alug 47dad991b9 Reapply "optimize pointon functions"
This reverts commit 5a4c9f4633.
2024-09-06 19:11:15 +02:00
Alug 21cf80dd58 make this completely toggable actually 2024-09-06 18:50:57 +02:00
Alug 5a4c9f4633 Revert "optimize pointon functions"
This reverts commit f95c751ff2.
2024-09-05 20:27:13 +02:00
Alug c25db4d9be Revert "smol cleanup p_maputl"
This reverts commit 1950b0956e.
2024-09-05 20:27:07 +02:00
Alug 457f73bc0f Revert "test kill SEENAMES without removing its netvar"
This reverts commit aa6a011bef.
2024-09-05 20:26:58 +02:00
Alug 1488457211 move those so backtraces still write if savedemo should crash 2024-09-05 17:56:04 +02:00
Alug 33ddb1fa4f only save demo in map command if you atleast spend 35 seconds in one map 2024-09-05 17:36:53 +02:00
Alug 57b5614124 toggle for saving replays on changing to same map 2024-09-05 10:52:15 +02:00
Alug 7e813768ed test save replay when crashing in signal handler 2024-09-05 10:09:02 +02:00
Alug eb2f64801e test also save replay on mapchange command 2024-09-05 00:11:30 +02:00
Alug 1396d6b06b this should also check for screentex cvar value 2
dont run certain postprocessor effects when you dont have screentextures enabled
2024-09-04 23:45:00 +02:00
Alug 8ce2ad0d39 add a little bit of safety to R_SetupFrame 2024-09-04 23:17:37 +02:00
Alug a699be42c7 remove IFCHANGED macro, check directly in R_Lerp funcs + inline those
basically does the same thing lol just looks better
2024-09-04 18:47:47 +02:00
Alug 05009b9c82 scale precip momz with mobjscale when cv_mobjscaleprecip enabled 2024-09-04 18:31:01 +02:00
Alug 39cf5d5f70 also scale precip sprite with mobjscale when cv_mobjscaleprecip enabled 2024-09-04 18:30:37 +02:00
Alug 836658d5d5 only call HWR_RenderPlayerView in ogl explictly 2024-09-04 18:14:53 +02:00
Alug 1b5cd02289 smol cleanup for led stuff again 2024-09-04 15:03:06 +02:00
Alug 9180f27315 smol cleanup hw_shaders 2024-09-04 15:02:31 +02:00
Alug aa6a011bef test kill SEENAMES without removing its netvar
why is this even defined
2024-09-03 12:31:13 +02:00
Alug 32ee5a8a61 smol cleanup p_map 2024-09-03 12:25:22 +02:00
Alug 1950b0956e smol cleanup p_maputl 2024-09-03 12:16:14 +02:00
Alug 542d5a4127 test use HWR_ProcessPolygon for skywalls 2024-09-03 07:31:32 +02:00
Alug b94b3c9d17 lol 2024-09-03 07:30:59 +02:00
Alug dab48b4183 precalc this 2024-09-03 07:30:51 +02:00
indev 10f0c9c0d8 Make server send serverinfo packet so client can know server name even when connecting just by ip 2024-09-02 22:44:27 +02:00
Alug 61bd811dfd more stuff i forgor 2024-09-02 17:43:57 +02:00
Alug ce4a89ed96 missed those 2024-09-02 17:40:19 +02:00
indev db4e94652d Add ctrl-w (delete word), ctrl-left (move to word beginning) and ctrl-right (move to word end) shortcuts for console 2024-09-02 17:28:17 +02:00
Alug 34196dc989 revert bunch of lugstuff specific stuff so i dont desynch and stuffs 2024-09-02 17:27:43 +02:00
Alug a8a71cc70c Revert "dont access delayremoved thinkers"
This reverts commit 7d885f7100.
2024-09-02 17:05:57 +02:00
Alug f95c751ff2 optimize pointon functions 2024-09-02 14:22:58 +02:00
Alug eed32527cd those are unused 2024-09-02 12:18:51 +02:00
Alug 1134bbf672 dont draw precip in skyboxes in opengl like software does 2024-09-02 12:12:08 +02:00
Alug 2635dab82f this can be static 2024-09-02 12:10:24 +02:00
Alug 57b6495e06 optimize polyobject spawn
should speed up level loading with maps with polyobjects
thx geezeedoom
2024-09-01 19:37:50 +02:00
Alug bc356ceac9 make downsampleshader respect the resoltion factor 2024-09-01 00:51:58 +02:00
Alug 8aeedadbcf no idea why i put those here 2024-08-31 20:19:06 +02:00
Alug 1e3459c588 update camera when paused and changing cam dist or height 2024-08-31 20:15:34 +02:00
Alug 8dda416592 throw menu bg conditions into own function since it s terrible 2024-08-31 19:52:24 +02:00
Alug 39a5b43e30 add camera options menu 2024-08-31 19:51:49 +02:00
Alug 9bdcfc34b5 add some comments 2024-08-31 18:54:21 +02:00
Alug 04b76339cb give camera lookback a toggle + extra option 2024-08-31 18:45:29 +02:00
Alug 2e80a9ffe9 super tiny cleanup m_menu again 2024-08-31 18:34:37 +02:00
Alug 900d4fe433 forgor speedo doesent draw in splitscreen + change offsets 2024-08-31 18:10:52 +02:00
Alug 76e9b8a599 add battlespeedometer to saturn hud menu + apply offset to bumper gfx when enabled 2024-08-31 18:01:12 +02:00
Alug b2fc9cc141 make timer flash at 99´59´99 again 2024-08-31 17:39:17 +02:00
Alug f280748d71 fix pal render postprocess shader by combining stuff
godawful but i dont want to draw another screen texture since itll tank performance
2024-08-30 22:15:03 +02:00
Alug 8a19bda170 use shader for downsampling with fbo
looks alot better and actually makes supersampling worth it

will be disabled when shaders also are
2024-08-30 21:21:21 +02:00
Alug 6f1fcd3e10 this can be static and inlined 2024-08-28 17:08:38 +02:00
Alug 9c5e591038 changes to saturn menu
-Add new Saturn Hud options menu to declutter normal saturn options
- If in any of the hud options the game will force display the kart hud and disable the fade background
- i hate m_menu
2024-08-27 18:22:56 +02:00
Alug 0790919125 respawn precip when toggling any of its settings 2024-08-27 16:28:45 +02:00
Alug 0840e5be3f toggle to scale weather with mobjscale
toggle since it may tank performance on certain maps for some + may make visability worse
2024-08-27 15:58:52 +02:00
Alug 4894d42e67 fix precip switching 2024-08-27 05:42:36 +02:00
Alug 664128cc18 optimize z position checking for mobjs without collision and camera
idk how much this does tbh
only for stuff without collision since it may desynch otherwise

based on
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2214

and

https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2250
2024-08-26 19:54:16 +02:00
Alug 3809f06ae8 when looking back camera momentum should inherit the mom of the player
makes using shoes or any boost stuff less jarring when looking back
2024-08-23 15:44:51 +02:00
Alug b7347fd371 fix compileur warnings
idk if this is right lol
2024-08-23 15:43:21 +02:00
Alug 189b91be57 fix potential crash in P_TryCameraMove for dedi servers 2024-08-23 15:31:35 +02:00
Alug 105d57c78d cleanup P_DoSuperTransformation
its still exposed to lua for whatever reason
so cant really remove crap kek
2024-08-23 15:31:00 +02:00
Alug eaed388d33 cleanup birdmusic crap again
music_resync_powerups_only literally didnt do shit lol
removed some other unused crap
changed some conditions to better check for stuff
etc idk
i just rather remove this whole thing at this point but oh well
2024-08-23 15:29:36 +02:00
Alug 564e8f6df4 forgor 2024-08-21 15:38:40 +02:00
Alug 6059753e73 cleanup FBO on shutdown + make some stuff static 2024-08-20 23:26:11 +02:00
Alug d82886c517 more changes to FBO stuff
now it wont ever do anything when disabled
also properly deletes the FBO when disabling it
2024-08-20 23:17:26 +02:00
Alug 23734480cc revert this in y_inter 2024-08-20 20:39:26 +02:00
Alug 50871fa9b5 make this more robust ig 2024-08-20 03:57:43 +02:00
Alug 39a11a4196 forgor return 2024-08-19 21:54:15 +02:00
Alug 80cd5ea6b4 do not constantly query ogl extensions 2024-08-19 21:48:34 +02:00
Alug a197a85930 enforce the xwayland hack even if fbo cvar is disabled
we have a bunch of guards in it so dont think there will be a problem
2024-08-19 18:57:16 +02:00
Alug aa4bf55574 change some stuff for saturn 2024-08-19 17:38:01 +02:00
NepDisk 0651a744fb Appimage compile pt2 2024-08-19 17:17:42 +02:00
NepDisk 3e4cdd4cf1 Appimage compile pt1 2024-08-19 17:17:38 +02:00
Alug 29b1409122 raise maxpng res 2024-08-19 17:16:48 +02:00
Alug e26c65bffb git pls 2024-08-19 17:16:39 +02:00
Alug 69bed9dcb6 Update LUASTUFF
idk i suck at explaining lmao
but atleast those should be mentioned
2024-08-19 14:58:32 +02:00
indev a49081a473 Don't execute exitgame command on dedicated servers 2024-08-19 13:29:50 +02:00
indev 1aa49108d0 Fix compilation when SDL_VERSION_ATLEAST(2,0,18) is false (if its false then 'else' statement would not be valid) 2024-08-19 13:29:47 +02:00
Alug 0dbc68a7df try async vsync here too 2024-08-19 13:28:48 +02:00
Alug 5fd25a76ad Fix typo 2024-08-19 11:55:49 +02:00
NepDisk f4535b6465 Fix Compile without with out of date SDL 2024-08-19 11:55:49 +02:00
Alug ac35961a15 Fix some tooltips so they don't go offscreen
grr git not crediting neppy for some reason
2024-08-19 11:55:49 +02:00
NepDisk b2c4ca99c2 Allow the control binds menu to use lower case 2024-08-19 11:51:13 +02:00
NepDisk ce8cf450b7 Fix gamepad menus for green reses via scrolling 2024-08-19 11:51:10 +02:00
Alug 112839a489 use qsort instead of qs22j for vissprite sorting
seems to be actually faster in this case
2024-08-18 20:46:07 +02:00
Alug 60041b03f7 this should not be in HWRENDER ifdef 2024-08-17 20:03:49 +02:00
Alug 67df9e0a50 fix NOHW compile 2024-08-17 20:02:09 +02:00
Alug 5113387134 throw saturnpacket and join stuff behind "SATURNPAK" ifdef, disable it for now 2024-08-17 19:57:56 +02:00
Alug 3f267034a8 smol fix to slope light 2024-08-17 16:31:04 +02:00
Alug dec8a16921 better slope light 2024-08-17 15:55:39 +02:00
Alug e3a9fdff22 smol changes 2024-08-17 15:37:24 +02:00
Alug 0bf25fad84 Use a const for the contrast 2024-08-17 15:30:04 +02:00
Alug 2e09d88999 Update light offset on polyobjects when they rotate 2024-08-17 15:28:37 +02:00
Alug 6df8f5b35c precalc fakecontrast on mapload 2024-08-17 15:25:12 +02:00
indev bce621d647 Always allow typing replay search query, similar to addon search 2024-08-16 01:03:18 +02:00
indev 01e51767e7 Add 'Hit Em Delay' option in menu 2024-08-16 01:03:14 +02:00
Alug 9a24ed2a09 add onchange func for led + fix rumble onchange 2024-08-16 00:34:08 +02:00
Alug a5f756eeb0 add toggles for gamepad led stuff 2024-08-16 00:08:40 +02:00
Alug e92c3d4d79 dont think we need that here 2024-08-15 23:54:35 +02:00
Alug ca4471ea6a reset rumble when player is exiting 2024-08-15 23:44:40 +02:00
Alug ecdbba2d28 dont change connect behaviour regardless of client + smol cleanup and fixes
should hopefully fix any remaining issues
2024-08-15 23:40:54 +02:00
Alug 057fb30b39 smol cleanup 2024-08-15 17:33:18 +02:00
Alug 678ddd781c remove duplicates in ResetNode 2024-08-15 17:32:15 +02:00
Alug 98111fe114 check for changed state before everything else 2024-08-15 15:47:10 +02:00
Alug b47f5ab235 move this in hw_main 2024-08-15 15:19:11 +02:00
Alug b909fe8ea9 shut up compiler 2024-08-15 14:42:30 +02:00
Alug 276ef2a150 move this in coindition 2024-08-15 13:41:20 +02:00
Alug 72540a8a0d smol cleanup HWR_RenderPlane 2024-08-15 13:41:00 +02:00
indev 0ce6cb4cee Fix increasing number of viewpoints in replays by more than 1 (like pressing '3' with only one viewpoint) crashing game 2024-08-14 15:56:44 +02:00
Alug 8b81f4cef2 completely disable director in splitscreen
will eventually get to splitscreen support lul
2024-08-14 14:44:22 +02:00
Alug d04d278f0e fix director lol 2024-08-14 14:10:16 +02:00
Alug 23f839dc19 also do this when player gets invul "power" 2024-08-14 12:49:05 +02:00
indev 6eca8150f1 Prioritize display players when assigning delayed 'hit em' 2024-08-12 11:18:34 +02:00
indev 521c9f686f Fix LUA_EvalMath warnings being broken sometimes 2024-08-11 12:03:54 +03:00
Alug 37da18cdcb Revert "Only load map lumps that are WADs or have no extension"
This reverts commit 1fb126b4d3.
2024-08-10 21:52:32 +02:00
indev cdc5460fd6 Oops forgot to change that
Dunno if this function ever gets called for non-player objects but just in case
2024-08-10 13:22:39 +02:00
indev 8aa6f62b2d Add delayed hit em sound (like in DRRR), togglable via 'karthitemdialog' cvar 2024-08-10 13:22:35 +02:00
Alug 5c9b9b6295 no need to check for ogl here 2024-08-10 09:55:25 +02:00
Alug 2e70119e68 smol cleanup for downsample stuff 2024-08-10 09:55:16 +02:00
Alug 1c5a312867 throw this behind ifdef 2024-08-10 09:44:20 +02:00
Alug f2e0b4dbc0 Flash gamepad LED when invul or grow 2024-08-09 20:41:29 +02:00
indev 15fd488e0d Fix smol memory leak in replay search thread oops 2024-08-09 18:51:08 +02:00
indev 04c0dad598 Load replay titles in separate thread 2024-08-09 18:44:08 +02:00
indev 0acb817e38 Visual improvements for replay search 2024-08-08 21:53:37 +02:00
indev fd00a08fa2 Add alternative button ('/') to open replay search 2024-08-08 21:53:33 +02:00
indev 0bc529ef5c Oops shouldn't z_free that 2024-08-08 21:53:29 +02:00
indev 2e8f06286d Greatly improve replay search perfomance by only reading replay name, and not entire file. Increase default search rate up to 1000 2024-08-08 21:53:26 +02:00
indev 52c1a950ba Fix M_HutCheckReplays still being called in menu (hopefully) 2024-08-08 21:53:22 +02:00
indev e946c93fe8 Search replays using title instead of filename 2024-08-08 17:54:53 +02:00
indev 220e996531 Test replay search 2024-08-08 17:54:49 +02:00
Alug 05a0085e22 fix nvidia xwayland screentex issue in dumb way
josdifgjs09ef09
2024-08-07 09:41:10 +02:00
Alug 27074cb8d2 more smol cleanup 2024-08-07 09:19:28 +02:00
Alug 1fb126b4d3 Only load map lumps that are WADs or have no extension 2024-08-05 16:21:29 +02:00
Alug b5ba82e52b smol cleanup w_wad 2024-08-05 16:12:12 +02:00
Alug a71139749f Test: remove Z_Unlock and proper free some stuff 2024-08-05 14:12:00 +02:00
Alug dd6332b715 smol cleanup 2024-08-05 12:15:18 +02:00
indev 936e461812 Fix chat not saving in console
Not sure why it was working before but broke now, maybe making va use snprintf instead of sprintf broke that
2024-08-04 16:53:32 +03:00
Alug 8c2367d0e7 check if theres even controllers in rumble ticker 2024-08-04 14:51:35 +02:00
Alug eb3c68df88 update led status in main loop
makes this whole ordeal alot less hacky tbh
player color always gets updated if it changes
still allows for directly setting led color elsewhere by using G_SetPlayerGamepadIndicatorColor directly
hoping crap doesent cost any perf but honestly shouldnt
2024-08-04 14:51:19 +02:00
Alug d9123c50d6 no need for this 2024-08-04 14:07:54 +02:00
Alug 43dfab7974 proper pass fwrapv to gcc 2024-08-04 13:01:45 +02:00
Alug 4d5b993490 forgor 2024-08-04 12:50:31 +02:00
Alug 44ab751fcb fix warning in director 2024-08-04 12:46:30 +02:00
Alug 96fcf2f668 support gcc 14.2.1 + fix some stuff 2024-08-04 12:45:23 +02:00
Alug 4db7992542 better statdisplay offsets in splitscreen
lots of trial and error.....
2024-08-03 23:49:31 +02:00
Alug 5a3893b46d smol fix to viewroll interp 2024-08-03 22:44:57 +02:00
Alug 9f4f728541 Revert "only works for displayplayer 0"
This reverts commit ba20020929.
2024-08-03 22:44:38 +02:00
Alug ba20020929 only works for displayplayer 0 2024-08-03 22:36:51 +02:00
Alug a3f224da6e expose viewroll to lua 2024-08-03 22:33:08 +02:00
Alug 9e7d4b3c22 fix crap here too even if its commented out 2024-08-03 21:47:53 +02:00
Alug 56e5242201 Fix few remaining uses of this_scale and ty
Not too sure if this is correct tho
2024-08-03 21:25:59 +02:00
Alug 38c1462fef add controller rumble to menu 2024-08-03 21:25:31 +02:00
indev 156173b3b9 Smol safeguard for R_PointToDist2 2024-08-03 20:46:52 +02:00
Alug b6a8f96e02 misplaced this 2024-08-03 18:02:50 +02:00
Alug 6bb9c88a1f make inline macros for pointtodist 2024-08-03 07:31:12 +02:00
Alug 00ea95ee2b stuff 2024-07-31 07:37:17 +02:00
Alug 859e08d628 Reapply "lol"
This reverts commit 340450a67e.
2024-07-31 06:07:49 +02:00
Alug 7c24fcfecb Reapply "optimize precip thinker"
This reverts commit dd73787c8b.
2024-07-31 06:07:43 +02:00
Alug 1c17d82836 send latency command after lua command 2024-07-31 06:06:05 +02:00
Alug 2d822ded27 add very light rumble to brakedrift 2024-07-31 06:05:49 +02:00
Alug 143c8bd436 fix up ogl sprite drawers, fix floor clip fix remove ty and reduntand hires stuff 2024-07-31 05:31:16 +02:00
Alug 2d166a35d0 check if displayplayer skincolor is availible before returning it 2024-07-31 00:28:29 +02:00
Alug eb02f15a5d fix rumble condition 2024-07-31 00:20:31 +02:00
Alug a8559c3c29 smol interp fixes 2024-07-30 23:54:49 +02:00
Alug bdb175f84b revert some lightlevel stuff in hw_main 2024-07-30 01:43:56 +02:00
Alug 7122c7cd5a make this more explicit 2024-07-30 01:04:24 +02:00
Alug b9f5fd21e7 remove redundant check 2024-07-30 01:02:05 +02:00
Alug 69f75a9191 change rumble ticker loop a bit 2024-07-30 00:59:06 +02:00
Alug b753c5ab2d set default duration to 84 2024-07-30 00:20:26 +02:00
Alug 7389537c63 do not constantly reset rumble
so it can work from lua
2024-07-30 00:20:13 +02:00
Alug 00096d340f throw rumble ticker into right place 2024-07-30 00:16:19 +02:00
Alug 1b3977436d fix cassting, make one tic duration default, but can still pass ms to it 2024-07-29 23:35:32 +02:00
Alug 0631468f0d add duration field to G_PlayerDeviceRumble
duration is in ms
2024-07-29 23:27:36 +02:00
Alug a57cb9eb6a expose rumble and led to lua 2024-07-29 22:54:23 +02:00
Alug ed4c4cb311 rename to G_SetPlayerGamepadIndicatorColor 2024-07-29 22:45:39 +02:00
Alug 094373d89f splitscreen support for rumble 2024-07-29 22:17:01 +02:00
Alug a6d08a12b5 add splitscreen support to gamepad led
also add more proper device check
2024-07-29 21:41:18 +02:00
Alug 55c6aa78e5 add basic rumble support for gamepads 2024-07-29 20:40:13 +02:00
Alug f95d0a1d34 i didnt knew k_positiondelay exists 2024-07-29 18:00:04 +02:00
Alug 73b84a0e02 another smol fix to director 2024-07-29 16:40:37 +02:00
Alug 7704bf7c90 lower breakawaydist in director 2024-07-29 04:29:05 +02:00
Alug a76ebe3600 fix K_DrawDirectorDebugger 2024-07-29 04:26:06 +02:00
Alug f8c8fedbe8 cleanup k_director 2024-07-29 04:13:51 +02:00
Alug 6a21729ff9 lower pinchdist in director
since we cant get an accurate value for distance to finish line, this should do it perhaps
2024-07-29 04:13:42 +02:00
Alug 9839d7ca3a change gamepad rgb color when switching viewpoints 2024-07-29 03:57:20 +02:00
Alug 82ad38e7f4 Revert "let invul flash rgb in rainbow lol"
This reverts commit 0a717e0081.
2024-07-29 03:17:47 +02:00
Alug 654c98f2ee Revert "smol fix"
This reverts commit b9f4eaa413.
2024-07-29 03:17:45 +02:00
Alug febadb6c08 simplify reduntand condition 2024-07-29 03:00:02 +02:00
Alug b9f4eaa413 smol fix 2024-07-29 01:53:31 +02:00
Alug ddf1db3d3d ressting to defaultcolor should also set led color 2024-07-29 01:39:33 +02:00
Alug 987253afcb Revert "dont return true for removed thing in P_CheckPosition"
This reverts commit 3f4d399afd.
2024-07-29 01:12:46 +02:00
Alug 0a717e0081 let invul flash rgb in rainbow lol 2024-07-29 01:12:35 +02:00
Alug ae0bce61f6 change color light when you cycle between colors in player setup 2024-07-29 01:12:17 +02:00
Alug a0ee75ebf4 give rgb custom color support, change rgb light color earlier in Color_OnChange
so it always unconditionally changes the color
also
2024-07-29 01:11:54 +02:00
Alug 1665d9aaa3 removed those by accident 2024-07-29 00:44:36 +02:00
indev be43f4d528 Only do lookup for mobjtype and states for drift stars and water trails at map load 2024-07-29 00:34:27 +02:00
Alug 6bcd2024a0 set controller rgb to playercolor
eh only for 1st player now no splitscreen support
idk if everything here is even correct
2024-07-28 19:54:08 +02:00
Alug f2b21c6055 Revert "fix some G_BuildMapTitle memleaks"
This reverts commit e5159e13dd.
2024-07-28 18:54:18 +02:00
Alug afb96c60cb Fix NULL lump name guard in W_CheckNumForMap 2024-07-28 18:40:58 +02:00
Alug e5159e13dd fix some G_BuildMapTitle memleaks 2024-07-28 18:37:20 +02:00
Alug fb622eda2a SDL: only react to window focus changes if state actually changes 2024-07-28 18:18:29 +02:00
Alug 5565edfcb4 dont reload palette until config was loaded 2024-07-28 18:13:28 +02:00
Alug 9b141b9f9f calloc soundchannels insteal of mallocing 2024-07-28 18:06:46 +02:00
Alug 6c885bff1e fix potential player reference issus in CL_ClearPlayer 2024-07-28 18:04:18 +02:00
Alug 9e575d89db can inline this 2024-07-28 17:46:04 +02:00
Alug 9e266c7a41 some reference fixes for shadows and overlays 2024-07-28 17:15:11 +02:00
Alug b08c175bfc Do not run ST_Ticker if dedicated 2024-07-28 16:54:24 +02:00
Alug 97c01c5951 smol fix to P_SetTarget 2024-07-28 16:37:07 +02:00
Alug 519e23ec36 P_NetUnArchiveThinkers: set thinker references to 0 before removing 2024-07-28 16:25:28 +02:00
Alug 3f4d399afd dont return true for removed thing in P_CheckPosition 2024-07-28 16:24:11 +02:00
Alug efaded5016 reset this in P_InitThinkers 2024-07-28 16:08:46 +02:00
Alug 2410bbfe4c some more smol mobj fixes 2024-07-28 15:57:03 +02:00
Alug 9637ae563c HMS_fetch_rules: Return NULL if the curl connection failed, instead of producing garbled rules 2024-07-28 15:49:01 +02:00
Alug f71631e732 try to prevent potential infinite SIGARBT hang in signal handler 2024-07-28 15:37:23 +02:00
Alug cca082b091 Cache pk3 central directory and Refactor ResFindSignature to work in chunks
https://github.com/KartKrewDev/RingRacers/commit/8ca2dc77e75b1ba8c511380257f0bbaf6d21c27b
https://github.com/KartKrewDev/RingRacers/commit/dedd0047bd8f9f73aba4defc19c429af7c987983
2024-07-28 15:35:47 +02:00
Alug cf8c38d08e fix potential crash on nix while quitting 2024-07-28 15:05:19 +02:00
Alug 4254e47bf4 dont always reset texture depth in ogl 2024-07-28 15:04:47 +02:00
Alug 2b32aee35d Ensure Z_Malloc provides same alignment as libc 2024-07-28 15:04:25 +02:00
Alug adfc22e377 Fix sound falloff calculation overflow 2024-07-28 15:04:14 +02:00
Alug 949d1a81ac smol fix to frameskipping 2024-07-28 15:04:01 +02:00
Alug 09a7999e4e e 2024-07-27 15:56:44 +02:00
Alug 351583ecf7 Revert "raise MAXVISSPRITES for 64-bit again"
This reverts commit d5258786e5.
2024-07-27 15:48:24 +02:00
Alug 3afd3aab8f lagless cam toggle 2024-07-27 15:02:47 +02:00
Alug 4bae40170f this is not a server cvar lol 2024-07-27 15:00:07 +02:00
Alug 09cb9831ef toggle for laptimes 2024-07-27 14:38:25 +02:00
indev 3864dc5833 Lets not compile lua code multiple time each frame x) 2024-07-27 03:26:37 +03:00
Alug 60d7b0272e Show last lap time on HUD
god this is kinda ass lol
doesent work when you join midgame so disabled for there
2024-07-26 22:18:49 +02:00
Alug fec72732e5 small change to director for battle 2024-07-26 20:41:26 +02:00
Alug 1571b11b0b R_LoadTexturePwad: fix faulty texture counting 2024-07-26 19:43:48 +02:00
indev 8d168076ef R_LoadTexturesPwad: don't do anything wad has no textures 2024-07-26 19:43:44 +02:00
Alug 9c6669fd5c Do not reload every texture when adding a wad
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1725?commit_id=37add34b9c729b21e624e22d64159073c9258e25
2024-07-26 19:43:30 +02:00
Alug e2dedfff00 Split R_LoadTextures 2024-07-26 19:43:24 +02:00
Alug a07c619947 rename draw dist settings 2024-07-26 19:15:59 +02:00
Alug c5ee27c1b4 raise MAXVISSPRITES for 64-bit again 2024-07-26 19:15:23 +02:00
Alug 2530667b86 add more sprite draw dist settings for 64bit clients 2024-07-26 19:14:08 +02:00
Alug 83f8591afa when no autoload config is found skip everything in D_AddAutoloadFiles
stuff doesent need to run if theres nothing to autoload so things can be skipped
2024-07-26 15:03:01 +02:00
Alug 78213a7ed5 add some extra safety to orbit and bananachain funcs 2024-07-26 13:59:37 +02:00
indev 08ff64da12 Add check for if lua state exist in UnArchiveExtVars, since server can have local luas that may add player/mobj fields into savegame 2024-07-25 22:50:53 +03:00
indev 57650dc955 Oops 2024-07-25 20:27:59 +02:00
indev 9e8c1d694a Make water trail not use hardcode freeslots too 2024-07-25 20:24:43 +02:00
indev 1dd7d63380 Make drift stars not use hardcode freeslots 2024-07-25 19:06:29 +02:00
Alug 6a8ed13a99 some cleanup 2024-07-25 19:05:44 +02:00
Alug d6c5066bfd let autoload run later to mitigate server join issues
itll now run at a similar place to postautoload
this may hopefully prevent some issuess with freeslotting lua
however sadly this makes menu replacements not work at startup anymore
2024-07-25 16:42:33 +02:00
Alug 60783d7109 fix fail condition 2024-07-23 22:02:54 +02:00
Alug db525f15da make backup of kartconfig before writing to it 2024-07-23 21:48:38 +02:00
Alug f33daf6bee toggle palrendering and fbo off if screen textures are disabled 2024-07-23 20:31:34 +02:00
Alug d13928b394 add cam check here 2024-07-23 20:06:01 +02:00
Alug 5613a0d173 reset tilt when respawning 2024-07-23 20:02:20 +02:00
Alug aa38586f82 simplify this 2024-07-23 19:01:44 +02:00
Alug d2b1ceb641 forgor this 2024-07-23 18:56:51 +02:00
Alug 9dd7e9a25f fix up bird screen tilting
removes old lerp variables that did nothing
properly interpolated viewroll
made it proper adjust to mobjscale
doesent roll view when spectating
general cleanup
2024-07-23 18:54:27 +02:00
Alug 1648273ddd allowjoin now sets saturnjoin to its value use CV_StealthSet to prevent
its only for scripts pretty much so no need to toggle it seperately
2024-07-23 17:45:00 +02:00
Alug 3f90e4f12a add "allowsaturnjoin" cvar to let toggle allowjoin for saturn clients seperately 2024-07-23 17:07:59 +02:00
Alug 2b9d565f0c e 2024-07-23 00:59:15 +02:00
Alug 70af63cc94 add to menu 2024-07-23 00:55:48 +02:00
Alug 64b92881f9 changuer how this works
counter decrements - 1 double the cooldown time
2024-07-22 23:36:13 +02:00
Alug be5ea069ad add gamestateresendattempts
so you can specify how often the game tries to resend gamestate to player in given time
so they dont get stuck in a synch loop
this is gamestateresendattempts value in the time of resynchcooldown *2
2024-07-22 23:09:04 +02:00
Alug 71e9357114 add check here too 2024-07-22 22:20:42 +02:00
Alug e28f86ac32 add "gamestatecooldown" cvar
to be able to change the cooldown between gamestate resends
2024-07-22 22:20:38 +02:00
Alug f97fe4bd65 Test: Restore save_p after P_LoadLevel
P_LoadLevel calls some functions that save gamedata and
unset save_p.

this is kinda hacky but i perhaps will port the redone save buffer sometime
2024-07-22 19:51:56 +02:00
Alug 3d0ac03f06 optimize MT_TUBEWAYPOINT
Store waypoints at map load instead of iterating through the thinker list to find them

https://git.do.srb2.org/STJr/SRB2/-/merge_requests/938
2024-07-22 19:51:44 +02:00
Alug 094132b7d3 Make polyobjects agree with sector lighting/colormap like a FOF. 2024-07-22 19:03:14 +02:00
Alug 51b9c9ae5a prevent potential level load crash 2024-07-22 18:13:06 +02:00
Alug d31941ef13 don't check flippedness in HWR_RotateSpritePolyToAim if the mobj is actually a precipmobj! 2024-07-22 18:08:26 +02:00
Alug 48db826142 2 2024-07-22 12:58:28 +02:00
Alug 32b62d19ff add missing copyright stuff to k_director 2024-07-22 12:57:29 +02:00
Alug e4f2961129 lagless cam test 2024-07-21 23:28:29 +02:00
Alug eba09dfad2 Revert "Free mipmaps before freeing tags"
This reverts commit 2437c5a19a.
2024-07-21 23:25:32 +02:00
Alug d9b72fcae6 whitespace hell 2024-07-21 22:51:36 +02:00
Alug 6f17e7f735 revert this
doesent do anything but complicate stuff lol
2024-07-21 22:46:01 +02:00
Alug 047b82acc0 remove hw_light 2024-07-21 22:38:51 +02:00
Alug 5347039d75 cleanup hw_main 2024-07-21 22:23:21 +02:00
Alug edc8095577 cleanup r_things a little 2024-07-21 22:21:01 +02:00
Alug 06f69723c2 fix this oops 2024-07-21 20:22:10 +02:00
Alug 8218fd4f57 stop yelling clang 2024-07-21 20:07:39 +02:00
Alug 6ee22edac5 smol cleanup
also check for splitscreen and if not dont run a for loop lul
2024-07-21 20:07:23 +02:00
Alug 37215ef1f4 clean director up a little
toggling director now resets cooldown so it switches players immediately
also consolidated condition to be active
and ensure DirectorFollowAttack doesent always run when it doesent need to be
2024-07-21 19:35:17 +02:00
Alug a2eb2222b9 more reference fixes 2024-07-21 17:38:06 +02:00
Alug d63b4d9463 Revert "attempt at mitigating palette bug in ogl"
This reverts commit 3bd85c20bc.
2024-07-21 16:21:56 +02:00
Alug 3bd85c20bc attempt at mitigating palette bug in ogl 2024-07-21 16:10:23 +02:00
indev f70063c7d8 Add director hud indicator 2024-07-21 17:03:27 +03:00
Alug a2f7dd7408 fix cmake 2024-07-21 15:45:53 +02:00
indev 147014d43a Add bind for director toggle 2024-07-21 16:11:33 +03:00
Alug 9460d1e9a1 oops 2024-07-21 15:11:28 +02:00
Alug b3a9a6b59a add stuff for directordebugger i forgor 2024-07-21 15:11:01 +02:00
Alug 69f7d669c8 only update director if consoleplayers specs or in demo playback
dont need to update this ever if we dont even use it lol
2024-07-21 14:42:48 +02:00
Alug 74a68b1462 fix crash if everyone spectates 2024-07-21 14:42:17 +02:00
Alug 006ea90493 port director from RR 2024-07-21 14:20:54 +02:00
Alug aede063266 Merge remote-tracking branch 'origin/absolutehell' into lugstuff 2024-07-20 19:47:37 +02:00
Alug 5aaeff4c5d improve virtual resource management 2024-07-19 22:44:12 +02:00
Alug 5f80d6c18d fix hoop midjoin crash in the dumbest way possible
cant figure out why it crashes so thisll do lol
2024-07-19 22:42:50 +02:00
Alug 7c59c9e6ec fix ScreenCoords on 2 plyr splitscreen and shearing
+ remove non 16:10 hack since that issue was fixed elsewhere
2024-07-19 19:25:05 +02:00
Alug aae83b3235 disable hudoffsets in splitscreen 2024-07-19 18:52:53 +02:00
indev 520165128a Add option to play power items sfx for growmusic and supermusic 2024-07-19 18:17:23 +02:00
Alug 556ced63cf whoopss remove test stuff 2024-07-19 14:39:23 +02:00
Alug 063bf830ff make a packet to tell if a joined client is on saturn
initial stuff
works and seems to be vanilla compatible
needs its own function and other things to be useful
2024-07-19 14:38:38 +02:00
Alug 7fd3bd412c reenable gme music position setting 2024-07-19 12:13:20 +02:00
Alug 47b9508af2 lul 2024-07-19 01:22:36 +02:00
Alug 417c44aad0 lül 2024-07-19 01:20:18 +02:00
Alug 1fefa0a99a remove spriteclipshader crap 2024-07-18 15:23:27 +02:00
Alug 06db4d2b62 add audio buffer size into sound menu 2024-07-18 14:43:05 +02:00
Alug bf7fc12a8d revert this in teleport 2024-07-17 22:19:03 +02:00
Alug 395daf57fa Revert "clean up mapload code a little more"
This reverts commit 79a5d174a5.
2024-07-17 12:26:38 +02:00
indev 97219b7a84 Attempt to fix possible use-after-free for awayviewmobj 2024-07-17 11:56:22 +02:00
Alug 0d5d677eff Skip over empty entries when populating vres, saving memory 2024-07-17 11:56:19 +02:00
Alug 3bd6c99a3b vres_GetMap: Count resources in folders up until next 0-length lump
justs in case the order of stuff may be weird
fixes keepmapmusic crash on some maps
2024-07-17 11:56:17 +02:00
Alug 1d2d8d58db clean up mapload code a little more 2024-07-17 11:56:14 +02:00
indev 9909b002fe Fix linedef 415 executing random text if script lump doesn't have null terminator 2024-07-16 15:46:37 +02:00
Alug ccda1ef104 did not mean to add this lol 2024-07-16 10:43:47 +02:00
Alug 52a882bda2 remove this check 2024-07-15 21:58:07 +02:00
Alug 177c60e857 fix more warnings 2024-07-15 21:43:48 +02:00
Alug 0566b96738 fix some warnings in clang 2024-07-15 21:43:46 +02:00
Alug f72c179f56 fix A_ action protottypes 2024-07-15 21:43:44 +02:00
Alug 0da963c794 Revert "fix some clang warnings"
This reverts commit fea89de037.
2024-07-15 21:43:40 +02:00
Alug 7d885f7100 dont access delayremoved thinkers
uhhh
2024-07-15 14:34:33 +02:00
Alug c1c2f794e3 more mobj reference fixes + cleanup 2024-07-15 13:58:08 +02:00
Alug 8bb1c7a032 Revert "run this in actual fullscreen"
This reverts commit 4a2d6b2241.
2024-07-14 18:03:21 +02:00
Alug 804123afc1 ndef 2024-07-14 17:32:33 +02:00
Alug 8e4f278ce4 this does nothing lol 2024-07-14 17:15:31 +02:00
Alug 3193241b11 shut up 32bit gcc 2024-07-14 16:59:54 +02:00
indev edb44fa6a2 Refactor music name scrolling in music test 2024-07-14 16:59:46 +02:00
Alug 66e9ac3657 Free mipmaps before freeing tags
ŝhould hopefully fix some random Z_free crashes
2024-07-14 16:44:09 +02:00
Alug 87e0796bf4 inline M_Memcpy 2024-07-13 15:55:30 +02:00
Alug 6bc6db3665 also use IFCHANGED macro for levelinterpolators
just looks a bit neater
2024-07-13 15:12:43 +02:00
Alug 2a4aa51373 Revert "smol optimization to HWR_Addline"
This reverts commit e6359663b1.
2024-07-13 14:55:28 +02:00
Alug e15b052570 Revert "shut up gcc"
This reverts commit 17a5c6ed06.
2024-07-13 14:55:26 +02:00
Alug 629e249a12 Revert "dont do this with portals"
This reverts commit f949fa54af.
2024-07-13 14:55:21 +02:00
Alug 86a260bb89 fix NOHW compile 2024-07-13 14:54:55 +02:00
Alug 6ab2de2787 shut up windoze 2024-07-11 10:36:27 +02:00
Alug 8effdc1615 Clean up graphic menus
- Renamed Experimental Options to Advanced Options
- Fixed the tooltips not displaying
- Made it look good again
2024-07-10 19:26:40 +02:00
Alug 561fc2d01a only interpolate pitch and roll when using 3d models
sprites dont need this for now
2024-07-10 18:43:20 +02:00
Alug 3fd9cf573b dont think precip mobj angle ever changes 2024-07-10 18:42:42 +02:00
Alug d7c0bed4eb remove those 2 from experimental video menu
no reason to ever toggle them off
2024-07-10 18:35:04 +02:00
Alug afd1f595e1 remove cv_grfofcut
same story
2024-07-10 18:34:45 +02:00
Alug f47a43df2f remove cv_slopepegfix
same as the other ones
2024-07-10 18:34:13 +02:00
Alug 4385327101 remove cv_fofzfightfix
more bloat
2024-07-10 18:33:25 +02:00
Alug 4e73c05ef9 remove R_Pointtoangle toggle
its bloat, the difference is negigble at best
2024-07-10 18:32:57 +02:00
Alug c01ef035a5 remove cv_mobjssector
idk why it even checks for pointinsubsector
2024-07-10 18:31:46 +02:00
Alug b59c080943 fix IFCHANGED macro 2024-07-10 18:31:39 +02:00
Alug 814c65b290 dont do this with portals 2024-07-10 09:21:58 +02:00
Alug 9f1c1c3f18 dont need to check this in precip 2024-07-10 08:49:19 +02:00
Alug e0df7dfba5 shut up gcc 2024-07-10 07:12:58 +02:00
Alug 220db7212f inline some crap 2024-07-10 07:11:38 +02:00
Alug d59f45a26a smol optimization to HWR_Addline 2024-07-10 06:55:47 +02:00
Alug f88d92ecee change when dynamic slopes run depending on if you joined midgame 2024-07-10 06:21:48 +02:00
Alug c28188b6d8 smol cleanup 2024-07-10 05:50:01 +02:00
Alug 80419748db forgor this 2024-07-10 05:45:06 +02:00
Alug 874e6cd5af fix conflict 2024-07-10 05:26:27 +02:00
Alug cd500fc344 clean up P_SetupLevel a little more 2024-07-10 05:25:31 +02:00
Alug ae7afc5749 Map data lump interface
cleans up code alot and stuff

https://git.do.srb2.org/STJr/SRB2/-/merge_requests/535
2024-07-10 05:25:22 +02:00
indev b0fa94c781 Call ServerJoin hook when consoleplayer becomes available, since it is needed for configs (which what this hook is created for) 2024-07-10 05:23:53 +02:00
indev 9bf717fae9 Add info about ServerJoin into LUASTUFF.md (so i don't forget to do it later) 2024-07-10 05:23:47 +02:00
indev 859c1020e6 Add ServerJoin lua hook, which gets called when client joins a server (listen server hosts joining their server also count) 2024-07-10 05:23:22 +02:00
Alug 9108d64820 mitigate dynamic slope desynchs
Perform dynamic slope thinking before other thinkers.
2024-07-10 05:22:38 +02:00
Alug e9d3c1a421 Fix mobj reference management of player->mo
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/d0719ef5ba86a1da32fed171d74eb76c7254f4f6
2024-07-10 05:21:45 +02:00
Alug f36e069f40 unhack this again 2024-07-09 09:06:11 +02:00
Alug 1f5c7b1d12 more changes to dither
use interger for distance scales
start z factor earlier
rename halfResolution to endResolution
2024-07-09 08:39:38 +02:00
Alug 94ecb9e634 ass 2024-07-08 20:49:05 +02:00
Alug b9db67bc08 more tweaks 2024-07-08 20:42:38 +02:00
Alug c152799295 oops that actually didnt fade out at all lol 2024-07-08 20:42:35 +02:00
Alug f91165857d scale and fade out dither pattern
makes the image a bit cleaner and easier to look at in palrender
2024-07-08 20:42:29 +02:00
Alug 29b93f02f1 crap 2024-07-08 20:42:02 +02:00
Alug f9a6452528 simplify this a little 2024-07-08 20:41:27 +02:00
Alug e7e51957e9 oops this should be min 2024-07-08 20:41:17 +02:00
Alug f8903e7ce7 clean up some net stuff 2024-07-08 20:41:10 +02:00
Alug d3548a4dfb Always use system-specific path seperator
https://git.srb2.org/KartKrew/RingRacers/-/commit/0f16c61d04f42b463db5c8987571fc986ae6ce9f
2024-07-08 20:40:51 +02:00
Alug eca72c6dc6 dont think kart even supports trivial maps
so no need to constantly check for this
2024-07-08 20:40:43 +02:00
NepDisk 6e378f4de6 Leave me alonmg kate 2024-07-03 13:04:45 +02:00
Alug 94ac52d792 Clamp lindex during vissprite light calculation
Mitigates against negative or very large xscale values causing lindex
to evaluate < 0, preventing a potential colormap indexing-related crash.
2024-07-03 13:04:11 +02:00
NepDisk 1f276a7eb6 Fix automap multiplayer crash
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2488
2024-07-03 13:03:12 +02:00
Alug a28a590078 prevent potential crash when trying to kill bananachain 2024-07-03 13:02:53 +02:00
Alug 91d052d25e shut up gcc 2024-07-03 13:02:32 +02:00
Alug 2f6ded132d Zzz... 2024-07-03 13:02:29 +02:00
Alug 51cdc1ce90 forgor 2024-07-03 13:02:26 +02:00
Alug 494fe0b1e7 revert software screen shit 2024-07-03 13:02:20 +02:00
Alug eac5310f5e some crap from asan 2024-07-03 13:02:16 +02:00
Alug 7f4a2f9943 fix some clang warnings 2024-07-03 13:02:11 +02:00
Alug 28a31301d4 forgor this crap 2024-07-03 13:01:49 +02:00
Alug 1c5e575718 remove all the ogl fix toggless 2024-07-03 13:01:44 +02:00
Alug 4a2d6b2241 run this in actual fullscreen
somehow makes xwayland happy
2024-07-03 13:01:11 +02:00
Alug 001baec444 scale dithering a little diff for a little smoother "fade" in pal render 2024-07-03 13:01:06 +02:00
Alug 1b35d4f03b stuff 2024-07-03 13:00:57 +02:00
Alug 75fc8cb766 change dither matrix to 4x4
a little grittier also smol cleanup
2024-07-03 13:00:43 +02:00
indev 28bef8c54f Use a fake 2d array in dither shader so it compiles with older glsl versions (1.20 at least) 2024-07-03 13:00:36 +02:00
indev 787973a3d5 If shader compilation failed, print info log 2024-07-03 13:00:31 +02:00
Alug f0e3ca7c1f add gr_lightdithering to shader
mhhm dithering
2024-07-03 13:00:26 +02:00
Alug 1b837a81ef improve teleport interpolation stuff 2024-07-03 13:00:07 +02:00
Alug b74dd85ef2 small optimization to batching 2024-07-03 13:00:01 +02:00
Alug fc9cc62b12 remove this crap
this doesent work on nix anyways
2024-07-03 12:59:54 +02:00
Alug e665edb652 no need for this 2024-07-03 12:59:30 +02:00
Alug e81cde8753 smoller opitmizations 2024-07-03 12:58:40 +02:00
Alug 4e995436c5 optimize ogl polyobjs slightly 2024-07-03 12:58:13 +02:00
Alug c57154a8e5 prevent crash in hw bsp 2024-07-03 12:58:07 +02:00
Alug 31fbba057a remove this again 2024-07-03 12:57:44 +02:00
Alug 46fa6e7ba4 change the shader z shit again 2024-07-03 12:57:17 +02:00
NepDisk bbb0379813 Allow Users to Connect to Servers While In-Game
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2401/
2024-07-03 12:57:09 +02:00
NepDisk 156b63440e Linux customshader compilation fix
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2418/
2024-07-03 12:56:41 +02:00
Alug 20e062b031 move HWR_LoadLevel to hw_main 2024-07-03 12:56:22 +02:00
Alug c98ebc9f35 Try fix glib preallocating too much space for sound freeslots
idk why git keeps removing credits
but thx indev <3
2024-07-03 12:55:57 +02:00
Alug c6001c7bf6 this should be called on mapload 2024-07-03 12:55:42 +02:00
Alug 2d0945264f oops 2 2024-06-20 21:16:47 +02:00
Alug 3d0981cf7b oops 2024-06-20 21:13:50 +02:00
Alug cce581fa51 these appear to be unused so comment them out
dont need 6 arrays being allocated with MAXSKINS for nothing lul
2024-06-20 16:22:13 +02:00
Alug 2446b804c7 forgor this 2024-06-20 03:00:48 +02:00
Alug 20cdb1c5ec limit localskins to 32
hope this doesent just die lol
2024-06-20 02:42:49 +02:00
Alug 212b184320 Do not access memory on misaligned addresses
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2438
2024-06-17 17:11:20 +02:00
Alug 37e98f342c Revert "fix some interpolation issues"
This reverts commit ccb1aecd01d376b0c0d73bbe4c898e89e35e25d0.
2024-06-17 12:51:42 +02:00
Alug 578f5b85dd Revert "more interp fixes"
This reverts commit 3a1a58bcfc.
2024-06-17 12:51:29 +02:00
Alug 99b1e3f969 Revert "attempt at speeding up sdl_render stuff"
This reverts commit f91d3ccf24.
2024-06-17 12:51:20 +02:00
Alug 8c9ef0e8f3 Merge branch 'lugstuff' of https://github.com/Indev450/SRB2Kart-Saturn into lugstuff 2024-06-16 22:41:45 +02:00
Alug f91d3ccf24 attempt at speeding up sdl_render stuff 2024-06-16 22:41:32 +02:00
Alug 691063983e Revert "Test: kill unused skin sounds freeslotting"
This reverts commit b9b97d0a56.
2024-06-16 21:05:40 +02:00
Alug b912047f68 35/2 != 17 = 17.5 ? 2024-06-16 16:17:24 +02:00
Alug f2ddbf1e68 a 2024-06-15 21:16:25 +02:00
Alug 5cd36e55ab Maybe hopefully fix ogl masterserver crash thing
port from durr
2024-06-14 04:01:30 +02:00
Alug 1cb590ebb8 this does not exist 2024-06-14 03:00:40 +02:00
Alug 280e937844 add missing HAVE_THREADS 2024-06-13 14:47:20 +02:00
Alug 5afb55547d opengles 2 seems to be fastest for me lul 2024-06-12 22:31:47 +02:00
Alug e3c91629db use sdl ogl render instead of software for software mode on nix
oops
2024-06-12 22:31:29 +02:00
Alug 1b0496b1e7 fix some clang warnings 2024-06-12 21:56:27 +02:00
Alug b7369b40cb fix oopsie on titled software wöter 2024-06-12 21:49:20 +02:00
Alug 6567313de6 add back le returns 2024-06-12 20:51:34 +02:00
Alug 5ecf3cc36c lower min audio buffersize to 256 2024-06-12 12:59:23 +02:00
Alug 71e3d89181 move that again 2024-06-11 19:47:51 +02:00
Alug a284ece8e4 e 2024-06-11 12:59:00 +02:00
Alug e73e75e740 dumbass hack 2024-06-11 12:58:25 +02:00
Alug 9bfd61fabc shut up compiler 2024-06-11 12:58:17 +02:00
Alug a2aeaa51e8 change this to int64 cause it fixes the intermission thing on high res
idk why that fixes it tbh but it does
2024-06-11 10:02:23 +02:00
Alug b558c3db98 more interp fixes 2024-06-11 01:35:22 +02:00
Alug 0f70bcbf28 basic frame skipping system 2024-06-11 01:16:35 +02:00
Alug f7c4600007 remove windows timing crap again
it actually made stuff a little wonky so revert that
2024-06-11 01:15:32 +02:00
Alug 8910f073e5 fix encore flipcam with ogl shearing 2024-06-09 22:02:46 +02:00
Alug ea18be1866 more lööp stuff 2024-06-09 18:49:41 +02:00
Alug 0bd687eb15 reset those here ig 2024-06-09 18:49:33 +02:00
Alug 25b74bf3dd e 2024-06-09 18:14:22 +02:00
Alug e4f9ca3f3c add mobj check here 2024-06-09 18:13:17 +02:00
Alug 38a3f403bd add check earlier in p_killmobj 2024-06-09 18:03:58 +02:00
Alug 51dd2030a0 maybe fix the sock_send crash on windoze
often happens with unstable net
2024-06-08 19:24:16 +02:00
Alug 7e31067e6a fix redifinition warning 2024-06-06 18:57:04 +02:00
Alug 9bf06ff30b disable upx on nix by default 2024-06-06 18:53:40 +02:00
Alug 85aa726bb7 fix masterserver ifdef 2024-06-06 18:47:06 +02:00
Alug 3a67ff3afa fix HAVE_CURL 2024-06-06 18:42:32 +02:00
Alug 0a022a4348 Revert "instant update after screen mode change"
This reverts commit 02bd819f7e.
2024-06-05 14:42:30 +02:00
Alug ad24beea5b more minor loop stuff 2024-06-05 14:42:23 +02:00
Alug 9026ae7a16 minor sprite opitmizations 2024-06-05 02:27:18 +02:00
Alug 2fee9b861f high dpi test 2024-06-05 01:40:57 +02:00
Alug b7e2bcf02e lol 2024-06-05 01:40:39 +02:00
Alug d548848b18 Reapply "use shader to prevent sprite floor clipping"
This reverts commit 5ec1ca46e5.
2024-06-05 01:28:09 +02:00
Alug 4c628ea74f Revert "zzz..."
This reverts commit e19db23bb5.
2024-06-05 01:28:06 +02:00
Alug d3ef97f637 test remove all the networking crap from rendering code 2024-06-04 17:11:30 +02:00
Alug 02bd819f7e instant update after screen mode change 2024-06-04 17:11:12 +02:00
Alug ea3b4ddeb0 smol optimization to skin loading 2024-06-04 17:10:24 +02:00
Alug ab3ea7475f think this should be casted to angle_t 2024-06-04 17:08:09 +02:00
Alug b9b97d0a56 Test: kill unused skin sounds freeslotting 2024-06-03 18:47:59 +02:00
Alug e19db23bb5 zzz... 2024-06-03 17:15:16 +02:00
Alug 5ec1ca46e5 Revert "use shader to prevent sprite floor clipping"
This reverts commit ee2ec01eb9.
2024-06-03 17:11:58 +02:00
Alug c2c918fdda Revert "fix le dispoffset"
This reverts commit f977af6a80.
2024-06-03 17:11:55 +02:00
Alug 4627989401 Make sfxinfo_t and state_t use field tables too 2024-06-03 17:02:27 +02:00
indev 9552e09471 Lua_optoption shouldn't change stack state at the end of call now 2024-06-03 17:02:14 +02:00
indev c8fb25066b Fix compilation for some gcc versions 2024-06-03 17:02:10 +02:00
Alug b1cb6d42f4 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-06-03 17:01:22 +02:00
Alug caf7e4a1cf stuffs 2024-06-01 17:03:27 +02:00
Alug 6a5c0223c4 forgor to remove that 2024-06-01 16:31:49 +02:00
Alug 9ff2d66079 fix papersprites in software (hopefully)
lul
2024-06-01 16:29:20 +02:00
Alug 2db2b9309d flexible array stuff for columnofs
hopefully this fixes some crashes or smth
2024-05-31 23:04:26 +02:00
Alug 7a38c15d59 cleanup some super old stuff that did nothing
lul
2024-05-31 22:43:49 +02:00
Alug cb7375f873 theres no value 3 oops
i shouldnt do stuff after waking up at 4 in the morning lol
2024-05-30 19:59:01 +02:00
Alug 41e52f9e88 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-05-30 19:10:03 +02:00
Alug ce7e30a752 smth smth encore magic numbers idk 2024-05-28 22:38:20 +02:00
Alug 3214811fcb casting stuff 2024-05-28 22:22:58 +02:00
Alug edda2a5399 that should be there lul 2024-05-28 22:22:48 +02:00
Alug 926bc8e72c split sprite draw loops
so crap doesent constantly check for papersprites on all sprites
2024-05-28 20:55:03 +02:00
Alug eadffb6be3 make r_fps if else hell a bit more bearable to look at
lol lmao
2024-05-28 20:28:27 +02:00
Alug cf04e8c23c scale precip size with mobjscale 2024-05-28 20:07:12 +02:00
Alug ec5840f840 scale sprite draw distance with mapobjscale 2024-05-28 20:02:54 +02:00
Alug 7dc4a7177d shut up gcc 2024-05-28 01:07:13 +02:00
Alug 3d91de8178 when not using screentextures draw kart bg on intermission screen 2024-05-28 00:52:40 +02:00
Alug 6ea1abfedc draw a black screen instead of "nothing" during wipes on disabled screentextures
should resolve the intense flashing that can occur
2024-05-28 00:52:09 +02:00
Alug 5251482dd7 Optimize field lookups in Lua metatables
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2024#cd5b5ee262bf5129c4d400ad60d006e1fa917c1f
2024-05-27 18:14:59 +02:00
Alug dd73787c8b Revert "optimize precip thinker"
This reverts commit bc382366a1.
2024-05-25 19:54:20 +02:00
Alug 340450a67e Revert "lol"
This reverts commit 0d40989f4c.
2024-05-25 19:54:13 +02:00
Alug 0d40989f4c lol 2024-05-25 19:00:07 +02:00
Alug c640096d9c Merge remote-tracking branch 'ghghghghghg/lua-hudinterpolate-redux' into lugstuff 2024-05-25 17:23:49 +02:00
indev 76081869e3 Store hooks in a table with integer keys instead of registry with string keys 2024-05-25 15:45:20 +02:00
Alug 9156c1b850 use ternary 2024-05-25 15:44:33 +02:00
Alug d78718d8f4 make only player dust be sparkle otherwise normal driftdust 2024-05-25 15:40:22 +02:00
Alug eef1e986a6 add proper check to sparkle lol 2024-05-25 15:28:41 +02:00
Alug 8fa99c34be Revert "ok kill this again ig"
This reverts commit 98c27fe8ef.
2024-05-25 15:07:07 +02:00
Alug a35fbdd1b5 move some cvars to be registerrerd latur in ogl 2024-05-25 14:50:24 +02:00
Alug 0efef78684 Turn of FBO downsampling when you turn off screen textures
fbo downsampling needs those and if theyre disabled youre essentially seeing nothing at all lol
2024-05-25 14:43:52 +02:00
Alug 62ce17cb4c super smol optimization to R_DrawRepeatMaskedColumn
only maths once not twice lul
2024-05-25 14:37:30 +02:00
Alug 6112be232a revert solidcol stuffs i did ages ago apparently lol 2024-05-25 12:57:41 +02:00
Alug c1a9c58eb5 Cull BSP behind a raised floor or lowered ceiling that covers the entire screen
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/7b8a564f69688515319ccd425f2b88ffe8b7b120
2024-05-25 02:02:06 +02:00
Alug 0393588fe8 Only call the Lua API for overridden actions 2024-05-25 01:35:44 +02:00
Alug b7ff0325ea optimize sight checks 2024-05-25 00:08:14 +02:00
Alug c4d39eae25 declare outside of lööp also add const in r_ 2024-05-25 00:01:58 +02:00
Alug 0e88981425 Cache water trail mobjs from qtpie dev
cant really cherry pick so uuuh
2024-05-23 22:23:39 +02:00
Alug ed7fcae33b Merge remote-tracking branch 'ghghghghghg/lua-hudinterpolate-redux' into lugstuff 2024-05-23 20:29:22 +02:00
Alug 8b967fb3b7 change wöter visual thing 2024-05-23 20:16:37 +02:00
Alug 4d68a5dc2b change names to be less basic 2024-05-23 19:25:04 +02:00
Alug ecd6ef40ef allow gamepad dpad to hold scroll shit in menu aaa
absolute arsepain cant wait to see this breaking kek
2024-05-23 19:11:11 +02:00
Alug 0c9dc33ff0 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-05-21 21:15:21 +02:00
Alug 98c27fe8ef ok kill this again ig 2024-05-20 22:46:29 +02:00
Alug 3d490f52b2 a 2024-05-20 22:18:17 +02:00
Alug c78c17d953 funny driftsparkle 2024-05-20 22:18:15 +02:00
Alug ee5d667a24 changes to woter thing 2024-05-20 19:23:46 +02:00
Alug b9653b4ff8 unhack the animated votescreen a little
also make it pause when the game is paused like it was intended originally
2024-05-20 17:18:06 +02:00
Alug 78bcfa8cfa conflict moment 2024-05-20 13:40:47 +02:00
Alug 1f1130efda Merge remote-tracking branch 'origin/Saturn' into lugstuff 2024-05-20 13:39:00 +02:00
Alug 3d7b05d633 forgor this crap 2024-05-15 16:54:41 +02:00
Alug 343bbd8a1a support gcc14 ig 2024-05-13 20:48:32 +02:00
Alug f702df48f5 kept forger to declare this 2024-05-13 20:48:21 +02:00
Alug bc382366a1 optimize precip thinker 2024-05-06 01:18:57 +02:00
Alug c158144b7b Revert "refactor weather stuff"
This reverts commit dc95b2e8d7.
2024-05-06 00:33:38 +02:00
Alug d4337fbc56 Revert "optimize-precip-thinker"
This reverts commit e822d8e7d1.
2024-05-06 00:33:36 +02:00
Alug e822d8e7d1 optimize-precip-thinker 2024-05-06 00:32:57 +02:00
Alug dc95b2e8d7 refactor weather stuff
not netsafe
2024-05-06 00:05:16 +02:00
Alug d226ad38ff Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-05-05 22:02:07 +02:00
Alug 2a160c5247 goddamn synched sound effect aaa 2024-05-05 13:00:14 +02:00
Alug 641a9dc4e2 Revert "follower crap cause i want smol spb"
This reverts commit 1b963c9439.
2024-05-04 01:58:58 +01:00
Alug 7e71af8d25 durr water stuff uhhhhhhh
hope this wont break lmao
2024-04-29 10:12:33 +02:00
Alug 8e33d2e1b2 simplify SOFTLIGHT alot
also should make sure it gets applied everywhere lul
2024-04-29 09:12:44 +02:00
Alug 61118b348c Merge remote-tracking branch 'ghg/lua-hudinterpolate-redux' into lugstuff 2024-04-25 18:41:10 +02:00
Alug 84faff82a2 fix rare precip crash 2024-04-25 17:08:02 +02:00
Alug d6cf7cc06f funny wöter from durr 2024-04-25 16:12:53 +02:00
Alug 0688b94729 update libbacktrace windows lib 2024-04-24 21:26:50 +02:00
Alug 695f53194d inline those 2024-04-24 10:59:09 +02:00
Alug 1b963c9439 follower crap cause i want smol spb
will softcode crap sometime idk
2024-04-23 12:47:18 +02:00
Alug b50d6dd389 Merge remote-tracking branch 'origin/it-cv-bigfloat' into lugstuff 2024-04-22 05:26:51 +02:00
Alug 2afad9490e Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-22 05:26:36 +02:00
Alug 812a275add fix some visual issues with fofs 2024-04-22 05:24:49 +02:00
Alug 90ccf7699b a 2024-04-20 22:52:22 +02:00
Alug 31ed12d88a some stuff from ceepeepeecheck 2024-04-20 22:36:23 +02:00
Alug 5a4e44d064 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-20 12:34:03 +02:00
Alug 515c67fa3a disable palette rendering if screentextures aint enabled 2024-04-19 06:21:58 +02:00
Alug 81d60165a3 z 2024-04-19 05:08:47 +02:00
Alug cc0fac3546 more things
-Fix a division by zero in BCZ2 Metal Sonic's routine
-Fix a bug where adding the same mod multiple times counted towards the mod limit
and other thigns
2024-04-19 04:49:12 +02:00
Alug d71ad13fcf some smol fixes 2024-04-19 04:22:29 +02:00
Alug 0d13811305 Make FixedRem less laggy by just using the modulo operator. 2024-04-19 03:52:21 +02:00
Alug b69cc4e34a Revert "port thinkerlists + cache and reuse mobjs for the 420th time"
This reverts commit bd8a392882.
2024-04-19 03:38:59 +02:00
Alug caf8f383ad Revert "change a few things"
This reverts commit c5c61f7692.
2024-04-19 03:38:55 +02:00
Alug 7db160a8e2 Revert "i dont understand this crap so ill revert it"
This reverts commit 7e895f82b2.
2024-04-19 03:38:52 +02:00
Alug 202a3d1fb1 Revert "some cleanup"
This reverts commit 332135fc6f.
2024-04-19 03:38:49 +02:00
Alug 332135fc6f some cleanup 2024-04-18 23:10:35 +02:00
Alug 7e895f82b2 i dont understand this crap so ill revert it 2024-04-18 14:14:51 +02:00
Alug c5c61f7692 change a few things 2024-04-18 13:40:27 +02:00
Alug bd8a392882 port thinkerlists + cache and reuse mobjs for the 420th time
i am in pain
2024-04-18 12:07:57 +02:00
Alug 36183e6dc8 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-17 05:34:51 +02:00
Alug 5ae4af54da smth smth paranthesis 2024-04-12 21:55:45 +02:00
Alug 620bdd1419 Merge branch 'lugstuff' of https://github.com/Indev450/SRB2Kart-Saturn into lugstuff 2024-04-12 20:41:16 +02:00
Alug c18eacbb81 fix software crash
Zzz...
2024-04-12 20:41:10 +02:00
Alug bb8acc5f51 fkldjnasofjosdfoisfj 2024-04-11 19:48:42 +02:00
Alug d41f4810d7 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-11 18:39:58 +02:00
indev 387c4edb3b Fix potential negative array index in V_ThinStringWidth 2024-04-11 18:00:01 +02:00
Alug c3fd7c1a7a grrrr 2024-04-10 18:21:11 +02:00
Alug 94f1ec18de Revert "fix ifdefs"
This reverts commit 5e8e2f4b3a.
2024-04-10 18:19:24 +02:00
Alug e00f8f6cee Revert "Zzz..."
This reverts commit 79b0a9c833.
2024-04-10 18:19:21 +02:00
Alug 79b0a9c833 Zzz... 2024-04-10 18:15:42 +02:00
Alug 5e8e2f4b3a fix ifdefs 2024-04-10 17:59:41 +02:00
Alug f0158dd915 move this to first init too 2024-04-10 17:58:06 +02:00
Alug 10cf251b46 that wasnt the onchange im sleepy 2024-04-10 17:40:35 +02:00
Alug 72231e5658 forgor to remove those Zzz... 2024-04-10 17:32:06 +02:00
Alug c510ff3b1c should throw that into onchange oops 2024-04-10 17:29:08 +02:00
Alug 936e138fee throw stuff into own function, also check on game start 2024-04-10 17:24:03 +02:00
Alug 8325696b55 put those in 1st init 2024-04-10 07:05:38 +02:00
Alug d63f517ae5 simplify this crap 2024-04-10 07:02:03 +02:00
Alug e74df8db90 raise max fpscap 2024-04-10 06:47:45 +02:00
Alug 1a0bf67452 Merge remote-tracking branch 'origin/fborender' into lugstuff 2024-04-09 17:38:44 +02:00
Alug f0df9b399b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-05 17:40:19 +02:00
Alug f9345308ff Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-05 01:45:11 +02:00
Alug 6ed7c75448 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-04 03:57:32 +02:00
Alug cb71167fb7 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-02 16:40:37 +02:00
Alug d4292987cc Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-02 16:14:35 +02:00
Alug 5da24a18dc Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-02 15:54:06 +02:00
Alug 1cf7b3e697 tf 2024-04-02 03:51:36 +02:00
Alug 3f3672497b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-02 03:49:01 +02:00
Alug 7714304c7a Merge remote-tracking branch 'origin/Saturn' into lugstuff 2024-04-01 19:15:13 +02:00
Alug ff640639b2 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-04-01 03:52:55 +02:00
Alug 0965603c8f Merge remote-tracking branch 'origin/interpjitter' into lugstuff 2024-04-01 03:52:52 +02:00
Alug b8412cec96 Fix minor off-by-one error in faketic calculation 2024-03-31 23:22:26 +02:00
Alug 86b7e192b2 fix this for splitscreen and move to own function 2024-03-30 03:34:38 +01:00
Alug 32b9e6094b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-28 15:07:00 +01:00
Alug 3ff7f3158b why tf is that here 2024-03-28 14:58:44 +01:00
Alug bd83ba8ca9 when the GLENCORE 2024-03-28 13:21:58 +01:00
Alug 785881c90e fixeur compile for qt 2024-03-28 12:23:07 +01:00
Alug 567ccf8a59 use this instead 2024-03-28 08:13:16 +01:00
Alug 11423a6d78 fix highresscale issue on startup in the worst way ever cause CV_NOINIT doesent work for whatever reason 2024-03-28 00:15:44 +01:00
Alug ab6b716e78 Read only header bytes when creating textures list 2024-03-27 21:31:45 +01:00
Alug 7b1be2e34f Ehh this thing is enough tbh 2024-03-27 20:32:14 +01:00
Alug 19d0d247b4 right v6 lul 2024-03-27 18:26:20 +01:00
Alug 1074a9e1d2 Prevent dropped ticcmds due to interp timing jutter
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2046
2024-03-27 18:17:27 +01:00
Alug 0648f384bb kill some stuff that did nothing 2024-03-27 18:13:39 +01:00
Alug 58d72204cc offline play menu pauses game so gib cool vhs effect 2024-03-27 15:51:47 +01:00
Alug 067b4c260f handle async vsync fail better
a
2024-03-27 14:44:02 +01:00
Alug 9e7e4d5fe7 testing smth
yes -1 is valid for this sometimes
2024-03-27 12:11:45 +01:00
Alug 7d9609be76 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-27 04:35:47 +01:00
Alug 7e510f8bc5 Merge remote-tracking branch 'origin/texload' into lugstuff 2024-03-26 20:42:39 +01:00
Alug a16e009370 make custom buttons bindable to joyaxis
triggers and such
2024-03-25 21:13:47 +01:00
Alug a021c497b6 forgor to remove this 2024-03-25 17:22:21 +01:00
Alug e77159cb58 remove this too 2024-03-24 20:18:31 +01:00
Alug 36ac353f1f Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-24 20:16:27 +01:00
Alug 58122bf023 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-24 18:30:21 +01:00
Alug c5da23bb02 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-24 16:56:14 +01:00
indev fd45391616 Fix drift sound keep playing when player go off ground 2024-03-24 15:12:02 +01:00
Alug 11dd80e4e7 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-24 15:11:53 +01:00
Alug 298f8ef842 Fix crash when passing a long string to v.drawString
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2403
2024-03-24 15:10:14 +01:00
Alug 4c45b9fb85 dfsafsdf 2024-03-23 19:13:14 +01:00
Alug 599cea3238 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-23 19:08:59 +01:00
Alug 0c5685e9eb dont need this anymore now 2024-03-23 18:07:58 +01:00
Alug 760b82fd63 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-23 18:07:08 +01:00
Alug 340034adf7 this can be just M_PI 2024-03-21 12:52:40 +01:00
Alug d978bfd0db Revert "Add common I_GetSysName function"
This reverts commit f3eedc03e6.
2024-03-21 12:40:44 +01:00
Alug de9f9722ac reapply hacky scaling thing 2024-03-21 12:38:50 +01:00
Alug 4dd9dc03fe ok git 2024-03-21 12:37:58 +01:00
Alug 47fc4aa39a Merge remote-tracking branch 'ghg/hud-uncap' into lugstuff 2024-03-21 12:36:29 +01:00
Alug 84ad608d70 Revert "software sdl windows scaling quality setting"
This reverts commit 7ee6de6b6a.
2024-03-21 12:35:00 +01:00
Alug d4dd0c9992 conflict fix 2024-03-21 12:33:43 +01:00
Alug ac93d027af Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-03-21 12:31:01 +01:00
Alug 190a95584c SFC32 for M_random funcs
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1780
2024-03-19 11:15:23 +01:00
Alug 9ad368e420 e 2024-03-17 23:32:09 +01:00
Alug a524215479 add the note so i dont forger if i wanna update this again 2024-03-17 22:43:05 +01:00
Alug 6104c36455 properly link libopenmpt
one dll instead of 4
2024-03-17 22:37:18 +01:00
Alug a04287c9f6 cute icon 2024-03-17 19:29:40 +01:00
indev 99876e3f73 Fix 'cast to non-matching type' warning 2024-03-17 14:57:02 +01:00
indev f16f498f27 Add include guard for qs22j.h 2024-03-17 14:56:37 +01:00
indev 4f9b5923bd Add snap to top flag for pause gfx 2024-03-15 12:54:06 +01:00
Alug 84476cd51f this didnt work 2024-03-15 11:32:33 +01:00
Alug bf9a6bde82 test this 2024-03-15 11:32:24 +01:00
Alug a6f8f57725 testing smth 2024-03-14 07:44:07 +01:00
Alug 02f4c334f0 mhhm ternaries 2024-03-13 22:06:45 +01:00
Alug 9884b294c6 i want to see more precip thx 2024-03-13 21:55:23 +01:00
Alug 49f22b5790 revert some stuff that broke some stuff 2024-03-13 19:25:14 +01:00
Alug 841270e824 fix ogl precip interpolation 2024-03-13 17:56:08 +01:00
Alug 630ce57303 this looks better lul 2024-03-13 13:18:30 +01:00
Alug 94aed4d1d1 clean up 2024-03-13 10:16:07 +01:00
Alug cdc0ec96a9 forgor menu stuff 2024-03-13 10:07:51 +01:00
Alug 751188bcd8 remove xs_CRoundToInt
while ye, less exact stuff doesent matter too much in the context of doom, it matters more in kart, due to polygon rendering and seg processing being extremely heavy and also generally more complex maps
2024-03-13 10:06:56 +01:00
Alug c0c44d46bc Ensure opaque midtextures always use PF_Masked 2024-03-13 08:48:04 +01:00
Alug 19d8749abf Revert "inline some things"
This reverts commit 0b47c310eccf55871a5bd466f44afa3215cc1322.
2024-03-13 08:35:47 +01:00
Alug c6f9fb2ac2 Revert "optimize "p_pointon" functions"
This reverts commit b9b963f999b902ab7f0f6fae4ec61264e713e15e.
2024-03-13 08:35:44 +01:00
Alug b1cfdfbc14 Revert "optimize fixedhypot"
This reverts commit ae68bd577558f45b81741396a899b7c311f753fc.
2024-03-13 08:35:41 +01:00
Alug 360df11aa6 Revert "LUT for bmapwidth imul instructions."
This reverts commit e45a7f911f0d156b7cc38675bec1a14a2080c367.
2024-03-13 08:35:30 +01:00
Alug d88cc3251f Revert "fix some oopsies"
This reverts commit 578770818ed96e366bbe9ed5ede720de07c0000a.
2024-03-13 08:35:27 +01:00
Alug cd7079da92 Revert "Zzz...."
This reverts commit e05197af882049e555c4116d1e6b4fd5ec4e879d.
2024-03-13 08:35:24 +01:00
Alug 77a0e8213b Revert "Zzz... 2"
This reverts commit bdd32702f9dc3ccbefb6444f1b76329b8ddbc9d7.
2024-03-13 08:35:20 +01:00
Alug 5efa778509 Revert "adjust the pointon funcs again"
This reverts commit b5861b2beeb04b6de1fcbd2088069374658f31ee.
2024-03-13 08:35:12 +01:00
Alug 02e6463fae Revert "P_PointOnDivlineSide stuff"
This reverts commit 1fa738d46448bd716547aa1812e38ec0de2221d1.
2024-03-13 08:35:09 +01:00
Alug b411787fe7 Revert "forgor"
This reverts commit 28950e6a15a3350da9a7441d81e3e043985a6c8d.
2024-03-13 08:34:59 +01:00
Alug 8fd91194a7 hm 2024-03-13 07:36:52 +01:00
Alug 4f85e1d603 revert that part 2024-03-13 07:34:12 +01:00
Alug fae0aeb442 Revert "Revert "forgor""
This reverts commit a1afcbc855.
2024-03-13 07:31:56 +01:00
Alug ec77824a96 Revert "Revert "dont inline those""
This reverts commit ae829375a0.
2024-03-13 07:31:53 +01:00
Alug 4127936eef optimize HWR_AddLine and HWR_ProcessSeg 2024-03-13 07:28:16 +01:00
Alug ae829375a0 Revert "dont inline those"
This reverts commit 2e34de8a125644dd7a0689af28b2076cf4c92e21.
2024-03-13 06:51:26 +01:00
Alug a1afcbc855 Revert "forgor"
This reverts commit e1e3aa899d.
2024-03-13 06:51:21 +01:00
Alug e1e3aa899d forgor 2024-03-13 06:07:59 +01:00
Alug 2644a3bf6e dont inline those 2024-03-13 06:03:19 +01:00
Alug 6b4e81e1ec P_PointOnDivlineSide stuff 2024-03-13 06:00:37 +01:00
Alug c705a0f35a adjust the pointon funcs again 2024-03-13 04:51:48 +01:00
indev b1b3102b31 If game crashes in level, add it to crash report 2024-03-12 18:51:00 +01:00
Alug 2d823d34f9 Fix buffer overrun in I_ClipboardPaste
https://git.do.srb2.org/STJr/SRB2/-/commit/9772bbeda172bc60482f137fc465e12070c76f22
2024-03-12 18:50:55 +01:00
Alug 1bb9fb2c67 cant override crap, thx msys 2024-03-12 18:27:55 +01:00
Alug b90e3ce9da i will add those in compiler flag instead 2024-03-12 18:19:12 +01:00
Alug e04a074a79 Revert "condensetics"
This reverts commit 87001f7e78.
2024-03-12 16:30:00 +01:00
Alug f98c3311af Zzz... 2 2024-03-12 16:21:42 +01:00
Alug 1a8c44af27 Zzz.... 2024-03-12 16:20:32 +01:00
Alug a57089c1a9 fix some oopsies 2024-03-12 16:16:40 +01:00
Alug 87001f7e78 condensetics 2024-03-12 16:06:12 +01:00
Alug 1fbb05c938 LUT for bmapwidth imul instructions. 2024-03-12 15:28:12 +01:00
Alug 3eef9d3b62 inline blockthing iterator aswell 2024-03-12 14:27:15 +01:00
Alug af2adf0134 remove some suff 2024-03-12 14:02:46 +01:00
Alug bbdfee8d33 optimize fixedhypot 2024-03-12 12:58:17 +01:00
Alug 2c4da83502 optimize "p_pointon" functions 2024-03-12 10:47:27 +01:00
Alug 75f2868971 inline some things 2024-03-12 02:13:35 +01:00
Alug 87d9ecc3c8 midi music bros 2024-03-11 23:52:26 +01:00
indev b637943bd9 Add snap to bottom flags for race countdown and level title too 2024-03-11 22:30:45 +01:00
Alug 0514475155 uuuuh 2024-03-11 22:30:37 +01:00
Alug 8cfb39e035 sort grid when opening skin menu instead of everytime a skin is added 2024-03-11 21:01:43 +01:00
Alug a9a7cb7be0 i 2024-03-11 12:58:22 +01:00
Alug f8649a24aa those can all be static 2024-03-11 11:54:32 +01:00
Alug ee5a860e07 more opitmizations stuff 2024-03-11 11:47:05 +01:00
Alug e6f03c1136 can do that directly 2024-03-11 11:22:08 +01:00
Alug 780162f516 optimize hwr_renderbpsnode
actually just make it behave like the software version lol
2024-03-11 11:00:14 +01:00
Alug a6d32d834b make 64 default again 2024-03-11 04:27:52 +01:00
Alug cef3c7f032 remove pseudoangle as its slower 2024-03-11 04:25:41 +01:00
Alug 07f8a532f9 attempt at unfucking renderview 2024-03-11 03:40:13 +01:00
Alug 352adf526a give this a better name lol 2024-03-11 02:22:40 +01:00
Alug df48f9caf9 actually move stuff back to hw_clip lmao 2024-03-11 02:15:34 +01:00
Alug f611053d4f replace server list sorting with qs22j 2024-03-10 20:28:27 +01:00
indev 39011cd93b Snap viewpoint text to bottom 2024-03-10 19:54:20 +01:00
Alug 562cb8cebd clean up stuff a little 2024-03-10 18:50:38 +01:00
Alug 89ae721421 i am in pain 2024-03-10 17:59:24 +01:00
Alug f65f4b32e2 Revert "remove pseudoangle"
This reverts commit c5d6ac63c5.
2024-03-10 15:19:36 +01:00
Alug 303fca6bcc smol adjustment 2024-03-10 04:39:55 +01:00
Alug 4aba159ee8 clean up this mess 2024-03-10 04:25:59 +01:00
Alug 5838e60bf6 fix overflow stuffs 2024-03-10 03:43:21 +01:00
Alug 527e436d57 Revert "stuffs"
This reverts commit 60ede73ff8.
2024-03-09 14:06:18 +01:00
Alug 60ede73ff8 stuffs 2024-03-09 13:43:06 +01:00
Alug 298d5e95fc unfuck thinker crap 2024-03-09 13:34:34 +01:00
Alug e9a68f0b7d forgor 2024-03-09 12:02:20 +01:00
Alug d613cf4d4c sUgGeSt PaReNtHeSeS ArOuNd '&&' 2024-03-09 12:01:18 +01:00
Alug 3487fae95d simplify this crap 2024-03-09 10:51:32 +01:00
Alug 9ee47a071b oops 2024-03-09 10:22:20 +01:00
Alug 3579fc3dea remove this 2024-03-09 10:11:06 +01:00
Alug 921bff19f1 add toggle for old fps counter behaviour
idk people hate the new one so brap
2024-03-09 07:58:14 +01:00
Alug d07420eaeb fix compile for everyone but me lmao 2024-03-09 07:40:38 +01:00
Alug 8028db77d8 implicit declaration of deez nuts 2024-03-09 07:12:56 +01:00
Alug e49a059783 fix dumbass compiler warnings + reformat it a bit 2024-03-09 07:12:18 +01:00
Alug 482b6e6844 use it for other stuff 2024-03-09 07:02:16 +01:00
Alug aa70635919 dont think this should write to relplays 2024-03-09 02:00:40 +01:00
Alug c331b0fa89 e 2024-03-09 01:59:27 +01:00
Alug fe55744de2 a 2024-03-09 00:57:40 +01:00
Alug 15e9d85a14 Revert "Revert "avx destruction idk""
This reverts commit f547020fc5.
2024-03-09 00:54:33 +01:00
Alug 51043b61a1 Revert "cache and reuse mobjs again"
This reverts commit 04455c9625.
2024-03-08 23:43:52 +01:00
Alug 6620d5fb26 faster qsort for rendering 2024-03-08 15:03:58 +01:00
Alug f547020fc5 Revert "avx destruction idk"
This reverts commit 4fdb2174f0.
2024-03-08 11:14:42 +01:00
Alug 89ea473c3b fix shit on party cruiser
well fixing the cullplane broke party cruiser, so im just gonna give it the same parameters as the software version i guess idk
2024-03-08 01:19:25 +01:00
Alug b60d9d0be7 readd this cause i dumb 2024-03-08 01:19:15 +01:00
Alug 4fdb2174f0 avx destruction idk 2024-03-08 00:15:43 +01:00
Alug 06a48584d6 expose this cause i want to use it in local scripts 2024-03-08 00:09:08 +01:00
Alug e9f9c1009d more mobj stuffs 2024-03-07 00:35:26 +01:00
Alug b66ceda525 Revert "attempt at exclusive fullscreen mode"
This reverts commit 19f1d8b847.
2024-03-06 09:27:09 +01:00
Alug 7c9c28f026 Revert "use desktop resolution for stuff"
This reverts commit a54384a579.
2024-03-06 09:27:06 +01:00
Alug 72f0552ef1 Revert "reset windowsize on normal fullscreen mode"
This reverts commit 85c7216eaa.
2024-03-06 09:26:59 +01:00
Alug 877a1f15a9 Revert "multidisplay stuff + only activate framebuffer for downsampling"
This reverts commit 5f58e7b343.
2024-03-06 09:26:46 +01:00
Alug efa2a68805 Revert "Zzz... moment"
This reverts commit 8cec2dab82.
2024-03-06 09:26:43 +01:00
Alug 023209bb76 Revert "only do things here when theres more than one display"
This reverts commit 9eb68bf052.
2024-03-06 09:26:38 +01:00
Alug da5dcde6ee Revert "wait uhhhh"
This reverts commit 875adb17b1.
2024-03-06 09:26:33 +01:00
Alug e92c5e1bf9 Revert "ugh this still takes the wrong display blergh"
This reverts commit 298b4d23e8.
2024-03-06 09:26:30 +01:00
Alug 2b7c4ae76c Revert "ill just uhhhhh use main display stuff for now idk"
This reverts commit a2d0ea9d11.
2024-03-06 09:26:24 +01:00
Alug ea26db2cbd Revert "change things a bit"
This reverts commit 9c42b77879.
2024-03-06 09:26:21 +01:00
Alug b9e3747f99 Revert "forgor"
This reverts commit 4d608b7f37.
2024-03-06 09:26:19 +01:00
Alug 4d608b7f37 forgor 2024-03-06 09:20:21 +01:00
Alug 9c42b77879 change things a bit 2024-03-06 09:19:17 +01:00
Alug a2d0ea9d11 ill just uhhhhh use main display stuff for now idk 2024-03-06 08:07:40 +01:00
Alug 298b4d23e8 ugh this still takes the wrong display blergh 2024-03-06 07:59:31 +01:00
Alug 875adb17b1 wait uhhhh 2024-03-06 07:42:46 +01:00
Alug 9eb68bf052 only do things here when theres more than one display 2024-03-06 07:39:36 +01:00
Alug 8cec2dab82 Zzz... moment 2024-03-06 07:36:28 +01:00
Alug 5f58e7b343 multidisplay stuff + only activate framebuffer for downsampling
idk i hope this shit works lmao
also moved some things in OglSdlSurface so it doesent intialize certain things everytime we change framebuffer shit
2024-03-06 07:26:53 +01:00
Alug 28bb88e9b4 Dynamically allocate space for a state's action field
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1478
2024-03-06 04:39:29 +01:00
Alug 04455c9625 cache and reuse mobjs again
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2200
2024-03-06 04:14:21 +01:00
Alug 9853150e57 Merge remote-tracking branch 'origin/maybemobjcrashfixes' into lugstuff 2024-03-06 00:26:24 +01:00
Alug 85c7216eaa reset windowsize on normal fullscreen mode 2024-03-05 02:15:06 +01:00
Alug a54384a579 use desktop resolution for stuff 2024-03-05 02:02:02 +01:00
Alug 19f1d8b847 attempt at exclusive fullscreen mode 2024-03-05 01:44:10 +01:00
indev 8270b64624 Make custom cvar menu bit wider 2024-03-04 23:52:45 +01:00
indev 81e3810c32 Don't add string cvars (a bit hacky solution) 2024-03-04 21:08:05 +01:00
Alug c266151071 change some numbers uuuuuh 2024-03-04 20:17:18 +01:00
Alug 27d55260e8 remove minmax sliders 2024-03-04 19:45:49 +01:00
Alug 233583657e oops 2024-03-04 19:04:51 +01:00
Alug 7bb1eed249 dont do stuff for anything thats not in normal us ascii or smth 2024-03-04 18:34:09 +01:00
Alug aa85fc3787 dont use it for control setup 2024-03-04 18:13:18 +01:00
Alug c9a88617b1 only use this for text inputs not gameplay 2024-03-04 17:46:45 +01:00
Alug 2f899fdfcc make it even simpler 2024-03-04 05:24:41 +01:00
Alug cdd2b6560e i will just use my compilers memcpy thx 2024-03-04 05:19:54 +01:00
Alug 60f29edbca turn it off completely when your gpu cant use it 2024-03-04 02:51:12 +01:00
Alug 60cffe1ed1 unhack framebuffer functions a little 2024-03-04 02:47:42 +01:00
Alug e77e7d1643 o 2024-03-04 01:13:23 +01:00
Alug 5dc22f502e dont need this 2024-03-04 00:45:14 +01:00
Alug 7a309c1175 when the ;; 2024-03-04 00:13:21 +01:00
Alug 9ce5baad9e fix ogl freelook breaking with shearing enabled
also removed uneeded stuff
2024-03-03 08:40:24 +01:00
Alug a4aa9a76f2 should only do that when rendering stuff 2024-03-03 07:57:46 +01:00
Alug befa25de5c add missing interpolators in mapload 2024-03-03 07:50:02 +01:00
Alug 83175d5c09 bruh
im going insane
2024-03-03 06:45:37 +01:00
Alug d8df8e8778 Revert "Revert "we have functions for that dont check for slopes everywhere""
This reverts commit 09957d0279.
2024-03-03 05:51:35 +01:00
Alug 09957d0279 Revert "we have functions for that dont check for slopes everywhere"
This reverts commit 46da9bf98b.
2024-03-03 05:34:01 +01:00
Alug 9e44985f56 Do not reload every texture when adding a wad
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1725?commit_id=37add34b9c729b21e624e22d64159073c9258e25
2024-03-03 05:18:37 +01:00
Alug b657a84699 Split R_LoadTextures 2024-03-03 04:53:15 +01:00
Alug 5ec7835556 Merge branch 'lugstuff' of https://github.com/Indev450/SRB2Kart-Saturn into lugstuff 2024-03-03 04:34:59 +01:00
Alug 03a864156d fix conflict 2024-03-03 04:34:53 +01:00
Alug c823bf3320 Revert "multithread exec command and some filesearch/add stuff"
This reverts commit 0d7025f714cbef34ca6e92e683561df411fa149a.
2024-03-03 04:32:13 +01:00
Alug 4f4d2f1f4c clean up r_segs 2024-03-03 03:13:46 +01:00
Alug 1bb389052d fix this 2024-03-02 23:36:48 +01:00
Alug 31fdc5bbc1 dont need to check if we dont use it 2024-03-02 22:56:26 +01:00
Alug db3833430d we have functions for that dont check for slopes everywhere
the functions already do it for us anyways
2024-03-02 22:33:34 +01:00
Alug 6d2212d259 move sprite mobj checks first 2024-03-02 21:56:39 +01:00
Alug 912c0e7fc4 check for those i guess 2024-03-02 18:36:34 +01:00
Alug 43d232819a forgor screenspace clipping 2024-03-02 18:25:13 +01:00
Alug 302eaf60b5 GetScreenCoord lua parity 2024-03-02 17:36:59 +01:00
Alug 84535faa90 remove more unused stuff 2024-03-02 15:57:25 +01:00
Alug 8c55d3c705 bruh 2024-03-02 13:23:50 +01:00
Alug ec11b9268f did not mean to commit this lul 2024-03-02 03:33:26 +01:00
Alug a45af4a80c i 2024-03-02 03:18:27 +01:00
Alug df627b6830 a 2024-03-02 03:11:06 +01:00
Alug dfbeaf30ad m 2024-03-02 03:10:47 +01:00
Alug a03f74b125 add this 2024-03-02 03:05:36 +01:00
Alug 1a01f1299c fix compiler complains
those were for coronas code which we dont even have
2024-03-02 02:43:53 +01:00
Alug 91f0cdbaca unhack palrendering screentex stuff 2024-03-02 02:15:28 +01:00
Alug e50bd4125d e 2024-03-02 02:07:54 +01:00
Alug ded2c8a7c8 a 2024-03-02 02:03:22 +01:00
Alug 88ce9fc0a6 more stuffs 2024-03-02 02:02:03 +01:00
Alug 3c713248b3 more shader stuff 2024-03-02 01:53:11 +01:00
Alug 75f3edcd92 shader stuffs 2024-03-02 01:50:35 +01:00
Alug 081a7779a6 make netvars red 2024-03-02 01:32:12 +01:00
Alug 6e995207a6 smh 2024-03-02 01:15:03 +01:00
Alug 3492b77aa0 we dont have IT_CV_FLOATSLIDER so dont even need to check for float 2024-03-02 01:14:36 +01:00
Alug e864901035 Options Menu for custom console variables
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2380#9cc73f4b99ff925448389969b0ade6ba3947fc31
2024-03-02 01:09:10 +01:00
Alug 7ee6de6b6a software sdl windows scaling quality setting 2024-03-01 23:12:23 +01:00
Alug 553b8ccf6b Revert "i am in pain"
This reverts commit e0e75eac33.
2024-03-01 15:26:57 +01:00
Alug bceef0b861 Fix nametag offsets with reverse gravity and flipcam 2024-03-01 15:24:04 +01:00
Alug 53cce6c6bb this does not exist 2024-03-01 02:31:55 +01:00
Alug b95047d09f fix vertical flip driftgauge
and make non flipcam behave like the sg lua version
2024-03-01 01:53:17 +01:00
Alug c6cb4375f5 fix shearing offset with flipcam in K_GetScreenCoords 2024-03-01 01:03:03 +01:00
Alug a07e2b8eda only check for stplayer flipcam
until i figure out a better way to check all of this crap
2024-02-29 23:08:24 +01:00
Alug 98e7002167 z 2024-02-29 16:22:07 +01:00
Alug 3428dde3c6 test 2024-02-29 05:37:21 +01:00
Alug 13d48f982b just make it like this 2024-02-29 00:27:37 +01:00
Alug b2e4dc27e4 give me a little more info on vanilla scoreboard but a bit ugly lul 2024-02-29 00:22:50 +01:00
Alug deddeab049 stimky ugly 2024-02-28 22:31:06 +01:00
Alug c3a6410822 Revert "dont need SEENAMES"
This reverts commit 01172bca77.
2024-02-28 22:06:02 +01:00
Alug c5915091aa kill have_blua 2024-02-28 21:53:59 +01:00
Alug 4401f0659e kill delfile 2024-02-28 18:58:04 +01:00
Alug a0c72d32e8 kill weighted recycling 2024-02-28 18:38:54 +01:00
Alug 1493045ec4 this doesent even exist anymore lmao 2024-02-28 18:33:12 +01:00
Alug 210efb2be7 kill eslope_typeshim 2024-02-28 18:26:54 +01:00
Alug a02fc1de63 kill GL_SHADERS 2024-02-28 18:19:11 +01:00
Alug 7755bfc861 Zzz... 2024-02-28 18:05:24 +01:00
Alug 01172bca77 dont need SEENAMES
esp when we get nametags its obsolete
2024-02-28 17:58:06 +01:00
Alug 143cbc8587 kill polyobjects ifdef 2024-02-28 17:55:47 +01:00
Alug b65f655a8a update libcurl to 7.69.0 2024-02-28 15:23:54 +01:00
Alug ed04c86369 u 2024-02-28 04:53:42 +01:00
Alug c0eaa17eb3 e 2024-02-28 04:51:13 +01:00
Alug 6383a55038 kill hw_trick 2024-02-28 04:47:55 +01:00
Alug 574df60d58 kill eslope 2024-02-28 04:40:03 +01:00
Alug 61ee575cd3 forgor this 2024-02-28 04:11:39 +01:00
Alug bdd963081e OpenGL: Fix linedef type 10 not culling FOFs 2024-02-28 03:50:43 +01:00
Alug 6b908d7a14 missed those 2024-02-27 22:16:52 +01:00
Alug 7d0d70c094 oopsie 2024-02-27 22:11:32 +01:00
Alug e75c5a9248 delete half of srb2 2024-02-27 21:49:31 +01:00
Alug b8ed5f4f1a dont need this anymore 2024-02-27 21:36:57 +01:00
GenericHeroGuy 660d7060e4 Don't return aggregates 2024-02-27 20:24:46 +01:00
Alug 79c5f57714 Merge remote-tracking branch 'origin/joinrefusemessage' into lugstuff 2024-02-27 20:03:47 +01:00
Alug 606d8fbe55 optimize gif palette creation 2024-02-27 20:01:56 +01:00
Alug edfa116a40 a 2024-02-27 18:38:28 +01:00
Alug 55ca0c712f add dynamic gif delay
fixes issues with low framerates, uncapped and stutters
2024-02-27 17:41:40 +01:00
Alug 16bef488ee no idea how that ever got there 2024-02-27 15:52:50 +01:00
Alug 82d784d9f8 Toggle for R_Pointtoangle Ex or 64
Ex may perform better on 32bit clients and some cpus so lets just make it toggable
2024-02-27 15:52:34 +01:00
indev 103fb2dfc1 Don't return NULL when creating MT_NULL mobj, since it is needed in some parts of game 2024-02-27 13:29:20 +01:00
Alug bba3e1810b add this 2024-02-27 05:14:05 +01:00
Alug af5333f63e fix P_PlayerInPain 2024-02-27 05:07:44 +01:00
Alug ea77a5fb53 Fix con_hudlines being off by one, Fix con_hudtime overflow 2024-02-27 05:07:11 +01:00
Alug a4aef0894b fix compile for qt 2024-02-26 23:48:47 +01:00
Alug bab7972518 Put HTTP downloading on a background thread
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2322
2024-02-26 23:37:54 +01:00
Alug 88853a7aee make the menus a little prettier 2024-02-26 22:01:11 +01:00
Alug d3339df853 toggle for showing nametags during spectating 2024-02-26 22:00:53 +01:00
Alug 385614b448 add toggle for showing nametags after you finished a race
off by default to match sg nametags
2024-02-26 21:19:59 +01:00
Alug c47ba80f5d death 2024-02-26 20:58:58 +01:00
Alug 6de0700f49 use V_LocalTransFlag for driftgauge 2024-02-26 20:58:50 +01:00
Alug d9fe52b1a1 use V_LocalTransFlag for nametags 2024-02-26 20:58:39 +01:00
Alug ccfc476ec0 replace SCR_FPSflags with V_LocalTransFlag
so we can actually display hud transparency stuff before the hud appears, since that doesent work with V_HUDTRANS
2024-02-26 20:58:18 +01:00
Alug f518b3c48b e 2024-02-26 20:04:12 +01:00
Alug 81d52db722 Revert "connect loadingscreen should clear menus"
This reverts commit 6b41cf676c.
2024-02-25 23:42:30 +01:00
Alug df9973da99 fix tagsdisplayed counter 2024-02-25 21:32:25 +01:00
Alug ca4c779c66 dont quit addon downloading with the mousewheel lmao 2024-02-25 19:47:52 +01:00
Alug 7897352175 connect loadingscreen should clear menus 2024-02-25 19:42:21 +01:00
Alug e0e75eac33 i am in pain 2024-02-25 19:06:32 +01:00
Alug 31d83dd26e disable driftgauge by default 2024-02-25 18:35:00 +01:00
Alug 698a0b811f disable nametag by default 2024-02-25 18:34:46 +01:00
Alug f69609b403 Merge branch 'lugstuff' of https://github.com/Indev450/SRB2Kart-Saturn into lugstuff 2024-02-25 18:21:12 +01:00
Alug 56259e3476 lua hud disable option for driftgauge 2024-02-25 18:21:03 +01:00
Alug f3dfa53f31 lua hud disable option for nametags 2024-02-25 18:21:03 +01:00
Alug e10d60c08e hud disable option for driftgauge 2024-02-25 18:20:32 +01:00
Alug ad4037351f hud disable option for nametags 2024-02-25 18:20:19 +01:00
NepDisk f9e1da8c9f Add coloring to large numbers 2024-02-25 17:34:12 +01:00
NepDisk 2f05137af7 Fix fillbar 2024-02-25 17:34:08 +01:00
Alug c305e31c2e fix first person splitscreen driftgauge stuff a 2024-02-25 12:21:57 +01:00
Alug a55fabe4f9 k... 2024-02-25 12:12:18 +01:00
Alug c58848b298 add splitscreen to screencoords and fix splitscreen for driftgauge 2024-02-25 12:10:23 +01:00
Alug ede644d3c4 use SleepEX on windows and set the min sleep duration to 16ms 2024-02-25 04:08:25 +01:00
Alug 4ff98e62a9 actually disable it for splitscreen for now
its botched and needs fixing
2024-02-24 20:32:15 +01:00
Alug e87fd2fff6 dont draw driftgauge when not using chasecam 2024-02-24 20:14:52 +01:00
indev 33e8b10579 Don't need for long there, fixed_t is big enough 2024-02-24 20:05:12 +01:00
Alug d11780f62d add -1 check for driftgauge too 2024-02-24 20:05:07 +01:00
Alug 7706aa0bf0 fix conflict 2024-02-24 16:56:28 +01:00
Alug cf96e10552 Revert "Refactor Batching code"
This reverts commit 8d737c96c9.
2024-02-24 16:49:04 +01:00
Alug 1d01e1e6cd Revert "Optimize polygon sorting on batch renderer"
This reverts commit 1687fb9120.
2024-02-24 16:48:14 +01:00
Alug a5c4759662 disable driftgauge in record attack
it actually gives you an advantage over using other clients
record attack should be fair and even
2024-02-24 15:58:47 +01:00
Alug e7ff1d693b fix K_GetScreenCoords y clipping 2024-02-24 15:38:32 +01:00
Alug 9b4354a057 rename all of those to not conflict with mods 2024-02-24 14:46:13 +01:00
Alug 51a46ba92c this aswell 2024-02-23 01:35:49 +01:00
Alug 31c4e0d59f forgor those aswell 2024-02-23 01:27:52 +01:00
Alug 6b246548c3 raise compile time significantly 2024-02-22 23:58:28 +01:00
Alug 57dda3843a use the current not old state
also add dont interp precip angle if it doesent change
2024-02-22 23:45:56 +01:00
Alug b04ac14751 remove redundant check 2024-02-22 23:45:53 +01:00
Alug 5ad8497db2 those too 2024-02-22 22:53:10 +01:00
Alug 672f07a5ee forgor those 2024-02-22 22:46:58 +01:00
Alug aceffafc4e fix ternary hell for palette rendering lightlevels 2024-02-22 21:42:28 +01:00
Alug 891b3183ed dont interpolate unchanging things + remove unused dynslope interp code 2024-02-22 19:55:45 +01:00
Alug 26dd066280 fix conflicts 2024-02-22 01:43:54 +01:00
Alug 157ebdb5fe Merge remote-tracking branch 'ghg/lua-hudstuff' into lugstuff 2024-02-22 01:39:34 +01:00
Alug 1a18839f82 remove R_PointToAngleEx
R_PointToAngle64 does its job better anyways
2024-02-20 21:10:04 +01:00
Alug e7f8e7628f I HATE MENUS I HATE MENUS 2024-02-20 18:42:37 +01:00
Alug 07190571a1 lol 2024-02-20 18:40:01 +01:00
Alug f04d922fca fix warning 2024-02-20 18:17:25 +01:00
Alug 7fa382d4e9 rename driftgauge cvar and fix nametag rendering bug 2024-02-20 18:12:17 +01:00
Alug 97766710c0 e 2024-02-20 17:37:29 +01:00
Alug 994ee060a7 a 2024-02-20 17:36:05 +01:00
NepDisk 589c27fdcf Driftgauge flipcam 2024-02-20 17:35:01 +01:00
NepDisk 37a018fda4 Give these tooltips 2024-02-20 17:34:58 +01:00
NepDisk f49381d1c5 Forgot this lol 2024-02-20 17:34:54 +01:00
Alug 573095bbad Driftgauge 2024-02-20 17:34:49 +01:00
Alug 0fdcc8e288 some fixes 2024-02-20 17:33:24 +01:00
Alug 03d7e26c3d oop 2024-02-20 13:18:23 +01:00
Alug 3a5cd835ad Fix tint equation shader 2024-02-20 13:17:46 +01:00
Alug 47a8f081e9 set currenttex to null if it gets an invalid texture id 2024-02-20 13:17:35 +01:00
Alug ad8d691c11 kill this 2024-02-20 13:16:50 +01:00
NepDisk 8186696e62 Nametag sightofline fix 2024-02-19 20:35:38 +01:00
Alug 183ec22923 Revert "Revert "Linked list for textures""
This reverts commit fe0dabb177.
2024-02-19 20:26:59 +01:00
Alug 5376995350 add max cap to nametagmaxplayers 2024-02-19 19:02:54 +01:00
Alug acb6e30fad dont apply this for players 2024-02-19 18:20:11 +01:00
Alug fe0dabb177 Revert "Linked list for textures"
This reverts commit 7eec58a834.
2024-02-19 12:15:12 +01:00
NepDisk 194ae46ce8 Remove unused functions that were originally added for nametags 2024-02-19 11:14:49 +01:00
NepDisk 2e9f1bfe90 Fix nametag weight offset for small and minimal 2024-02-19 11:14:46 +01:00
Alug a82adc4948 Fix nametag limit 2024-02-19 11:14:41 +01:00
Alug 6440c70a38 Zzz... 2024-02-19 01:57:42 +01:00
Alug 748eb07c9a forgor 2024-02-19 01:57:04 +01:00
Alug 5be2f591d2 ok so this needs to be done for the scaling stuff cool 2024-02-19 01:49:20 +01:00
Alug f2e4950e89 die 2024-02-19 01:26:01 +01:00
Alug 7444c5b826 remove hpmod stuffs since its not netsafe 2024-02-19 01:02:39 +01:00
Alug 5f6cca68cc Nametags Rewrites 2
contains netunsafe stuff but easy to remove
2024-02-19 00:44:07 +01:00
Alug 3d33e5351b bruh 2024-02-19 00:13:42 +01:00
Alug c6e245450d those are not server commands
idk why i threw them there in the first place but those are not needed at all (or even usefull for that matter) for dedicated servers
also moves some stuff to its group
2024-02-19 00:12:11 +01:00
Alug 36854a16b7 Revert "Clean up cvar stuff a little"
This reverts commit 6fe87ab05a.
2024-02-19 00:04:25 +01:00
Alug b4ee8229ee Revert "more stuff"
This reverts commit 150c695979.
2024-02-19 00:03:27 +01:00
Alug cf0a3841e8 Revert "those need to be here for some reason"
This reverts commit 2efaebcf89.
2024-02-19 00:03:16 +01:00
Alug 3ebd2257f8 ok i dont want to the new gamma system
it looks off honestly
2024-02-18 23:47:42 +01:00
Alug 844d1967cc i wanna try the new gamma stuff 2024-02-18 22:29:24 +01:00
Alug dac37f8938 revert those 2024-02-18 22:29:12 +01:00
Alug dd74bc7c2b fuckit make the scale even smoler 2024-02-18 22:29:05 +01:00
Alug 7eec58a834 Linked list for textures 2024-02-18 22:28:52 +01:00
Alug da81998c71 fix up colour cube/saturation/gamma
cleans up things, and fixes it not being applied to 3D models and colourmapped sectors when not in palette rendering mode
also adds a new way of handling gamma which can be used if wanted
2024-02-18 20:43:40 +01:00
Alug d1552e7b71 clean up patch drawers a little
esp for software
2024-02-18 19:45:17 +01:00
Alug c64e10083b Optimize R_StoreWallRange
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2336?commit_id=a04bef7d39f71cfda1fe85b2ca3a820f95612b06
2024-02-17 22:52:12 +01:00
Alug 43e2be58da Revert "add an error message here"
This reverts commit 44b8a8a0d8.
2024-02-17 17:31:14 +01:00
Alug 63b60d2546 those too 2024-02-17 16:11:32 +01:00
Alug 91ddc709eb forgor 2024-02-17 16:09:39 +01:00
Alug 1bcb67ffb9 remove bloat from windows libs + move dlls into dlls folder
+ remove msvc project files since they dont work anyways
2024-02-17 15:59:16 +01:00
Alug 976177c244 Revert "Revert "fix the dumbass compiler warning""
This reverts commit 69d47a5e53.
2024-02-17 11:13:07 +01:00
Alug a37c81a142 Revert "Revert "fix some issues with framebuffer""
This reverts commit 6457847633.
2024-02-17 11:13:04 +01:00
Alug 58de3a35a0 Revert "Revert "Implement framebuffer and renderbuffer objects""
This reverts commit b0f5f4338f.
2024-02-17 11:13:00 +01:00
Alug 44b8a8a0d8 add an error message here
dunno if we can prevent it from crashing, but atleast its a little more informative
2024-02-17 10:42:16 +01:00
Alug b0f5f4338f Revert "Implement framebuffer and renderbuffer objects"
This reverts commit d6d70e1525.
2024-02-17 09:57:38 +01:00
Alug 6457847633 Revert "fix some issues with framebuffer"
This reverts commit fcc810f703.
2024-02-17 09:57:25 +01:00
Alug 69d47a5e53 Revert "fix the dumbass compiler warning"
This reverts commit d0b7f6203c.
2024-02-17 09:57:12 +01:00
NepDisk 02177a7794 Nametags Rewrites 2024-02-17 09:11:27 +01:00
Alug 65c15126f1 larger console buffer for high res 2024-02-17 09:10:24 +01:00
Alug 76c78b8e63 remove all this crap 2024-02-16 15:30:18 +01:00
Alug f63342ff0f lol 2024-02-16 13:35:30 +01:00
Alug e3410cf34c move this 2024-02-16 13:35:25 +01:00
Alug 7a129047e7 i will play this in 8k yes 2024-02-16 09:36:51 +01:00
Alug 343716b7da make this save 2024-02-15 20:22:05 +01:00
Alug 1687fb9120 Optimize polygon sorting on batch renderer 2024-02-14 21:39:31 +01:00
Alug 3e89057c23 Fix dangling pointer in mapthing after removing mobj 2024-02-14 21:39:20 +01:00
Alug 774587efa6 fix inline warnings 2024-02-14 19:43:44 +01:00
Alug 2dc8bf321e do this again 2024-02-14 19:27:25 +01:00
Alug 992813d770 Revert "remove mobj realscales"
This reverts commit 9f45dabd9c.
2024-02-14 19:27:21 +01:00
Alug 46882dee93 Revert "move this, remove interp things, and add some comments"
This reverts commit 47c90f63a8.
2024-02-14 19:27:18 +01:00
Alug 8bbb7b540f Revert "forgor"
This reverts commit e4ec7484aa.
2024-02-14 19:27:14 +01:00
Alug f5f1ab036d Fix segfault when removing mobjs while iterating thinglist 2024-02-14 15:31:06 +01:00
Alug f15d556c05 fix segfaults when damaging mobj with no painstate and when removing source from ShouldDamage 2024-02-14 15:27:15 +01:00
Alug 570a664db8 Use po2 patches to fix mipmaps 2024-02-14 12:50:40 +01:00
Alug 52f69324d9 better savegame errors 2024-02-14 12:19:38 +01:00
Alug ea6016b1ba forgor 2024-02-14 12:00:25 +01:00
Alug 30fcffd63c move this, remove interp things, and add some comments 2024-02-14 11:44:14 +01:00
Alug 50446bbde4 remove mobj realscales
idk those just seem absolutely useless its literally just an alias for mobj scale
2024-02-14 11:42:51 +01:00
Alug b307033aab a? 2024-02-14 05:58:04 +01:00
Alug 3e5985833c Snap to software lightlevel values when using Paletter renderer
bye bye smooth fades, here i come 32 light levels
2024-02-13 16:35:10 +01:00
Alug 8421f02aab e 2024-02-13 12:44:34 +01:00
Alug b6daafec17 Realloc software lookups for current screen res instead of MAXVID define
so the thing just allocs what it needs, so it can perform as good as it can on any resolution
2024-02-13 12:44:05 +01:00
Alug fc058b669e better comment 2024-02-13 11:16:00 +01:00
Alug 99214b98b9 set this to 1440p
also made a new define for use in the png limits so that can stay at 4k. but having both maxvids allocate things for 4k is not a good thing for software renderer, not that anyone would ever want to run it at 4k anyways
2024-02-13 11:15:14 +01:00
Alug ab35a44ed9 more revert 2024-02-13 10:57:36 +01:00
Alug 125b82a5bb forgor 2024-02-13 10:53:38 +01:00
Alug f294ea157f more things 2024-02-13 10:50:11 +01:00
Alug 486ae052ef this stuff too 2024-02-13 10:42:03 +01:00
Alug 53b5442dad bruh 2024-02-13 10:40:42 +01:00
Alug 507c5f75bd revert a few things 2024-02-13 10:39:27 +01:00
Alug 0fb72c579e forgor 2024-02-13 06:16:38 +01:00
Alug c5d6ac63c5 remove pseudoangle 2024-02-13 06:12:32 +01:00
Alug a934c76263 revert this 2024-02-12 14:38:47 +01:00
Alug 0098c3bbc0 update SDL2 to v2.30.0 2024-02-12 14:29:49 +01:00
Alug f3eedc03e6 Add common I_GetSysName function
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2308
2024-02-12 14:23:09 +01:00
Alug 17c71a2528 Change from double to INT64 2024-02-12 14:19:25 +01:00
Alug d2ecbd7c6e Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-02-12 14:14:49 +01:00
Alug 2ce7dc0c37 update zlib to v1.3.1
update zlib to v1.3.1
2024-02-11 16:43:19 +01:00
Alug b648424c18 add stuff to menu 2024-02-11 15:21:20 +01:00
Alug 301754c857 forgor 2024-02-11 15:10:16 +01:00
Alug c9a3c4c9b8 only interpolate those if we use the stuff that uses them 2024-02-11 15:05:58 +01:00
Alug ce0c8b363a only interpolate pitch, roll, slopepitch and sloperoll when using sprite rotation 2024-02-11 14:51:44 +01:00
Alug 9d6c38004c toggable mobj subsector interpolation
honestly couldnt spot any difference at all
but R_PointinSubsector is quite expensive so making a toggle seems cool
2024-02-11 14:51:14 +01:00
Alug 19a58cc8c6 mobj interp optimization 2024-02-11 14:19:08 +01:00
Alug d855c39da2 a 2024-02-11 13:45:48 +01:00
Alug 03f4bfecc1 Dont need this
I_GetPrecise Precision already gets the high res windows time anyways
2024-02-11 13:42:12 +01:00
Alug c8d9e4c7b3 add thiis 2024-02-11 09:22:59 +01:00
Alug cb2b8f2e7c add it here too 2024-02-11 06:38:45 +01:00
Alug 0272dd4c24 oops 2024-02-11 06:29:28 +01:00
Alug 3b327937c2 use Windows High Precision Timer on Windows builds
lul may help with frametime and other stuff
2024-02-11 06:16:45 +01:00
Alug f8f2f17184 Merge remote-tracking branch 'origin/cvarcleanup' into lugstuff 2024-02-09 15:18:17 +01:00
Alug 2efaebcf89 those need to be here for some reason
game complains
2024-02-09 15:12:41 +01:00
Alug 150c695979 more stuff 2024-02-09 15:05:23 +01:00
Alug 6fe87ab05a Clean up cvar stuff a little 2024-02-09 14:42:55 +01:00
Alug f6613a5555 proper check for colourized speedometer patches 2024-02-09 12:35:48 +01:00
Alug 947d5c2739 add achiiro speedometer stuffs 2024-02-09 12:07:34 +01:00
Alug 1544706ff4 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-02-09 10:20:21 +01:00
Alug e121d1a8a1 proper POST request to curl 2024-02-09 10:19:35 +01:00
Alug badbdbf03f Clipping and portal stuff
idk this actually does not break ante station for some reason
2024-02-09 10:19:18 +01:00
Alug 3b5495b53a brap 2024-02-07 11:52:04 +01:00
Alug 545027ae64 use this stuff 2024-02-07 11:40:05 +01:00
Alug 91896433f8 fix menu updating + add default to switch 2024-02-07 11:01:53 +01:00
Alug a60074fc8a fix menu stuff 2024-02-07 10:49:04 +01:00
Alug eb82aa14bb option for small nametags 2024-02-07 10:35:16 +01:00
Alug cb4b640730 why add the same thing twice? 2024-02-07 09:42:16 +01:00
Alug 266d9a3c71 also turn this off 2024-02-07 09:37:01 +01:00
Alug 7a5a704a15 forgor to comment this out 2024-02-07 09:36:37 +01:00
Alug 29ed8de935 Nametags from Chaoskart
https://gitlab.com/Fafabis/kart-chaotic/-/commit/8b4a12e144fbff587ee70c30e7f461900d839650#025e5c90ea9aeb6187b4fe002e0fbb277ef4b33d_7024_7035
2024-02-07 09:35:14 +01:00
Alug 3418cab5de switchable native keyboard input
taken from chaoskart this is completely non invasive
2024-02-07 09:20:36 +01:00
Alug e2ce015d49 fix for opengl sprite shadow colour 2024-02-07 09:15:17 +01:00
indev 0d0ab3f414 If have libbacktrace, write crash reports from I_Error 2024-02-04 19:08:33 +01:00
Alug 22b5bcc7e1 split cache functions
seems to fix a few stutters
2024-02-04 09:21:45 +01:00
indev 34d5d73d7e Fix battle playing wrong ending music sometimes 2024-02-04 08:31:10 +01:00
Alug 7ae4441731 Add cvar gr_maxinterpdist, which allows to control max distance on which mobjs will be interpolated 2024-02-04 08:26:54 +01:00
Alug d0b7f6203c fix the dumbass compiler warning 2024-02-04 07:56:55 +01:00
Alug 3757f3ae57 smol cleanup 2024-02-04 07:46:25 +01:00
Alug 8f9366da5a Zzz... 2024-02-04 07:12:26 +01:00
Alug b8e55f87a9 little portal cleanup 2024-02-04 06:48:58 +01:00
Alug b469f70e02 experimental fast sprite sorting 2024-02-04 06:28:07 +01:00
Alug 6df69b24db Revert "DSDADoom shenanigans"
This reverts commit c7931ca69c.
2024-02-02 16:49:08 +01:00
Alug 0133a5eb23 Revert "do this"
This reverts commit 7f93bc305d.
2024-02-02 16:48:26 +01:00
Alug 86712c2c48 fix compiler warning 2024-02-02 02:59:08 +01:00
Alug 5195caa3c6 Remove Build2DMipmaps and GLU library stuff
gluBuild2DMipmaps is just broken anyways
and it was the only thing used from the GLU library aswell so can remove things in favor of better solutions
having a pc with opengl 1.4 should be a given by now
2024-02-01 22:26:06 +01:00
Alug 684ad38d4b add an I_Error for when opengl is started on unsupported hardware or driver 2024-02-01 19:57:23 +01:00
Alug c6d292a3d7 e 2024-02-01 04:47:55 +01:00
Alug 246414a735 move that where it belongs 2024-02-01 04:42:28 +01:00
Alug 429bcffaf8 dont need to extra check for this actually 2024-02-01 03:48:17 +01:00
Alug d92e7b138c fix sprite roll angles in software for sprites with one rotation frame
ofc only when the rotation stuff is set to rotate everything not just the player
also changes that the shadows only rotate on that setting unless someone wants it and wants really dumb checks for it
2024-02-01 03:46:15 +01:00
Alug cd51ad2a25 remove non working fisheye lens code
remnants of birdhouse, this was never finished nor does it work
2024-02-01 03:26:33 +01:00
Alug 8732825404 fix software shadow rotation in the worst way possible kek 2024-02-01 03:25:58 +01:00
Alug fc37cdcc95 use it for camang 2024-02-01 02:39:27 +01:00
Alug 2435ec9515 Revert "batch this stuff too for portals"
This reverts commit 2df4738af2.
2024-02-01 02:11:21 +01:00
Alug 623fab8ea8 Revert "clean this up a little"
This reverts commit 99c9d921e3ab3ee3fde3dcf141e20323e064902a.
2024-02-01 02:03:23 +01:00
Alug e063345c4b Revert "oops"
This reverts commit 59b6987bf2e9f00bfdf50b268f0ec61e735dfe0e.
2024-02-01 02:03:10 +01:00
Alug 27533a1dcd Revert "replace check"
This reverts commit 36eaaee202c4d1f7e86dd2b24dcfe5573ac2f280.
2024-02-01 02:03:00 +01:00
Alug d232e0e2c6 oops 2024-02-01 01:55:04 +01:00
Alug 0475489e24 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-31 16:58:09 +01:00
Alug 34b35db27f Interpolate polyobjects properly for the software renderer
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2284/
2024-01-31 03:28:00 +01:00
Alug b47bc12e48 change x scale a little 2024-01-30 21:43:44 +01:00
Alug 4d102dcf68 similar scale to old speedo 2024-01-29 23:08:19 +01:00
Alug a8c9663200 ok i can just do it like this lol
now its good finally
2024-01-29 22:23:04 +01:00
Alug 57660cc5af fix 1 pixel gap
i hate maths
2024-01-29 22:13:54 +01:00
Alug c459e918af prep some speedometer stuff 2024-01-29 22:01:16 +01:00
Alug 962abba1b2 Buffer API is OpenGL 1.5, so can be used in STATIC_OPENGL
https://git.do.srb2.org/STJr/SRB2/-/commit/623629b04ab72071e6ea4f0c4a3245e6cde72e2c
2024-01-29 18:19:01 +01:00
Alug 5297d18f92 ugh whyyyy 2024-01-29 18:08:18 +01:00
Alug 7853e48a6f update libopenmpt libs 2024-01-29 18:07:35 +01:00
Alug 303d87f69d update libgme 2024-01-29 15:59:48 +01:00
Alug 9dcdc9500d Revert "bruh wtf"
This reverts commit 493091cd66.
2024-01-29 14:43:12 +01:00
Alug 7723bafff6 replace check 2024-01-29 04:38:26 +01:00
Alug d74a89c6c1 oops 2024-01-29 04:11:21 +01:00
Alug cce443be0b clean this up a little 2024-01-29 04:08:14 +01:00
Alug 81fa3d27bf uuuuuuuhhh 2024-01-29 03:56:43 +01:00
Alug 493091cd66 bruh wtf 2024-01-28 22:07:49 +01:00
Alug c75f5ee961 use this for portal clipping too 2024-01-28 19:33:45 +01:00
Alug 083e0ca2e0 dont need this anymore 2024-01-28 19:19:16 +01:00
Alug 79bd89016c dont need it as an extra file 2024-01-28 19:16:04 +01:00
Alug eca7e38763 Zzz... 2024-01-28 19:15:14 +01:00
Alug b5cbfb970f forgor 2024-01-28 18:58:52 +01:00
Alug 74e1cafd9d this too 2024-01-28 18:57:19 +01:00
Alug ee7381b67d revert this 2024-01-28 18:56:10 +01:00
Alug 7f93bc305d do this 2024-01-26 02:44:37 +01:00
Alug c7931ca69c DSDADoom shenanigans
R_PointToPseudoAngle seems rather promising
2024-01-26 02:28:07 +01:00
Alug 90f06a3289 a little better solution still bad lmao 2024-01-26 00:04:42 +01:00
Alug 0e344a7e02 screw it ill just do this 2024-01-25 23:40:37 +01:00
Alug 3f91a4e908 i want a small hud 2024-01-25 23:04:21 +01:00
Alug fb443c58ab add "Reset All" button to hud offset menu 2024-01-25 23:02:01 +01:00
Alug b233514b58 more offset 2024-01-25 16:48:16 +01:00
Alug 11615171d1 Revert "Optimize polygon sorting on batch renderer"
This reverts commit ad86e7f34a.
2024-01-25 14:57:49 +01:00
Alug 2df4738af2 batch this stuff too for portals 2024-01-25 04:06:54 +01:00
Alug 9e62f5bd52 make the ripple thing toggable for now 2024-01-25 03:46:26 +01:00
Alug 80349ae8ee a 2024-01-25 03:24:32 +01:00
Alug 06d51f2648 only apply fog if it is water only
ugh
2024-01-25 02:59:30 +01:00
Alug fcc810f703 fix some issues with framebuffer 2024-01-25 00:35:31 +01:00
Alug d6d70e1525 Implement framebuffer and renderbuffer objects
wew https://git.do.srb2.org/Lactozilla/SRB2/-/commit/211c3720de8dda8e2a896b6887eb4bbbd991ebbf
2024-01-24 22:35:30 +01:00
Alug e5f79e061c rotating shadows
uuuuhhh
2024-01-24 18:13:50 +01:00
Alug ad3c0a1ffd attempt at fixing some issues
it fixed some things but broke the underwater ripple if the water is on a fof
2024-01-24 17:09:15 +01:00
Alug 2ef935198a more pronounced ripple
eeeh kinda close ig
2024-01-24 03:41:02 +01:00
Alug dc3b9c648a make this a little neater 2024-01-24 03:09:09 +01:00
Alug 2d610d40b6 add better check for colormap stuff
so it only gets applied where it should (i hope)
works on tiled byway tho
2024-01-24 03:00:31 +01:00
Alug d2c686f48b attempt at making ogl water ripple better
well all it does is ripple the floor below the water fof lmao no idea how i would implement this for the walls too
2024-01-24 02:43:27 +01:00
Alug 5cafec3262 uuuh oops dont do it for non transparent fofs 2024-01-24 00:26:36 +01:00
Alug 580c42d167 more offset ugh 2024-01-23 21:33:15 +01:00
Alug dcfec35e57 remove this since its not needed anymore 2024-01-23 21:24:18 +01:00
Alug 701bac6e11 alr add more offset
kinda dumb way but itll do for now until i figure out smth better
2024-01-23 21:21:03 +01:00
Alug 0c46d593d8 attempt at making colormapped translucent fofs more accurate 2024-01-23 18:55:19 +01:00
Alug b867de0667 Zzz... 2024-01-23 15:50:51 +01:00
Alug e207b75c7a Revert "add pMasterPalette"
This reverts commit dfb05b9d39.
2024-01-23 15:49:00 +01:00
Alug fc3df5bfe4 Revert "attempt at unmangling lighttables and colormaps"
This reverts commit 19702daecd.
2024-01-23 06:41:25 +01:00
Alug dfb05b9d39 add pMasterPalette 2024-01-23 05:33:04 +01:00
Alug 19702daecd attempt at unmangling lighttables and colormaps
ugh i hope this doesent break
2024-01-22 23:28:34 +01:00
Alug dde4b4df3b merge conflict moment 2024-01-22 21:32:38 +01:00
Alug c070930a8c Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-22 21:31:04 +01:00
Alug d36b5f7c59 add hw_shaders to cmakelist 2024-01-22 18:41:00 +01:00
Alug 0e517907ce change this 2024-01-22 18:32:13 +01:00
Alug 739e9716ab add toggle for custom shaders
it seems better like this, atleast thats how hannu set it up
2024-01-22 18:25:51 +01:00
Alug 0e5972d895 shaderstate should be set here 2024-01-22 18:15:53 +01:00
Alug 71975658ca split hw_shader files 2024-01-22 18:14:14 +01:00
Alug 6572e29a64 OpenGL shader code rearrangement and shader pre-preprocessor
https://git.do.srb2.org/STJr/SRB2/-/commit/de37df1be04e9d1dfb11083a9585eb6ac1761633?merge_request_iid=1516
wew
2024-01-22 16:57:47 +01:00
indev 41b21c2a0c Fix sound, music, and midi music toggles 2024-01-22 13:48:13 +01:00
Alug 2b19d2e6de Revert "revert this"
This reverts commit 5bce9d5abf.
2024-01-22 13:48:10 +01:00
Alug f99aa3459c e 2024-01-22 13:48:00 +01:00
Alug 5bce9d5abf revert this
this caused sound and music to alyways toggle themselves on after a restart + other issues
2024-01-22 02:55:40 +01:00
Alug abe102649e forgor 2024-01-22 02:52:33 +01:00
Alug 424fcdc63a change some memfree names 2024-01-22 02:46:59 +01:00
Alug a3fd451c74 3D model texture Z_tag 2024-01-22 02:43:55 +01:00
Alug 731fd113d2 more cleanup 2024-01-22 02:34:07 +01:00
Alug c9ca1bda5c Texture buffer for non RGBA to RGBA conversion 2024-01-22 02:09:55 +01:00
Alug 58ea822050 Remove 3Dfx and glide things
gr_rounddown toggle did nothing instead the game always resized textures, now it wont, seems like this makes stutters on mapload less
2024-01-22 01:03:48 +01:00
Alug 671484d6f9 fix merge conflict 2024-01-21 16:41:38 +01:00
Alug e6e74194bc Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-21 16:40:12 +01:00
Alug 04432c8368 simplify this uuh 2024-01-21 15:43:46 +01:00
Alug 6782876c0c i hate this so i just make it a boolean
confused the heck outta me so just do it like this lmao
2024-01-21 15:31:07 +01:00
Alug 4b09e92d7c grr 2024-01-20 17:24:11 +01:00
Alug 3266f64fb9 oops 2024-01-20 17:03:05 +01:00
Alug 2a9886e698 cleanup s_sound a little + fix onchanges 2024-01-20 17:01:48 +01:00
Alug 1319e3a811 make NO_MIDI=0 compile 2024-01-20 16:52:46 +01:00
Alug 6cbb40f874 make some things static + remove cdmusic leftovers 2024-01-20 15:43:42 +01:00
Alug 07fd6a3ad4 make sound precaching useful at all
so it also precaches addon sounds and all
thx indev for help <3
2024-01-20 15:39:25 +01:00
Alug 8891869013 fix issues with sound precaching
adds a check if sounds have been previously loaded already

also makes it useful at all by not freeing soundsfx data on each mapload when its enabled

also adds an onchange so toggling it either caches all sounds again or frees them
2024-01-20 13:58:11 +01:00
Alug 04fc735e12 Merge remote-tracking branch 'origin/morenewpalshader' into lugstuff 2024-01-19 19:37:07 +01:00
Alug 7b9860f1be Merge remote-tracking branch 'origin/morenewpalshader' into lugstuff 2024-01-19 19:25:24 +01:00
Alug 38f26a2bd8 simplify setpalette 2024-01-19 18:07:32 +01:00
Alug a9750f8cff Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-19 12:29:20 +01:00
Alug ad86e7f34a Optimize polygon sorting on batch renderer
again
2024-01-19 02:14:20 +01:00
Alug 496435ef3b dont check for precip in sprite sorting + smol cleanup 2024-01-19 02:14:04 +01:00
Alug 5275b31e7e smol stuffs 2024-01-19 00:39:07 +01:00
Alug e341991703 Add toggle for horizonlines 2024-01-18 20:53:59 +01:00
Alug fb65496507 use fudges from newer paletter shader 2024-01-18 16:49:10 +01:00
Alug abe52ba440 make thundershield follow player offset
this allows the to stay on the player when saltyhopping etc.
2024-01-18 15:21:20 +01:00
Alug ee5d097201 Prevent FOF alpha from wrapping around in OpenGL 2024-01-18 15:07:29 +01:00
Alug 0ea182d04f change this 2024-01-18 14:12:27 +01:00
Alug 8d737c96c9 Refactor Batching code
from Hannu Hanhi
https://git.do.srb2.org/STJr/SRB2/-/commit/707687beea50a2bfcc14638e923ac516195351b1?merge_request_iid=1774
2024-01-17 18:30:53 +01:00
Alug 5c93b90c2e Merge remote-tracking branch 'origin/batching-stuff' into lugstuff 2024-01-17 18:16:06 +01:00
Alug 41bee850da Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-17 14:59:21 +01:00
Alug 416c2a9e9d Merge remote-tracking branch 'origin/planestuff2' into lugstuff 2024-01-17 12:42:59 +01:00
Alug 8fa9fccc79 Revert "use malloc here"
This reverts commit 75d1076bbe.
2024-01-17 12:42:56 +01:00
Alug c5a4071a06 Revert "Move water ripple spanfunc out of r_plane + tilted water support"
This reverts commit 139d937c86.
2024-01-17 12:42:48 +01:00
Alug 930e48ad39 Revert "Plane optimization and cleanup"
This reverts commit db61bfb568.
2024-01-17 12:42:39 +01:00
Alug 868678f321 Revert "Revert "Revert "Fix vibing slope planes"""
This reverts commit 8530b6512c.
2024-01-17 12:42:34 +01:00
Alug 8530b6512c Revert "Revert "Fix vibing slope planes""
This reverts commit 2a5f487e5f.
2024-01-17 12:32:50 +01:00
Alug 2a5f487e5f Revert "Fix vibing slope planes"
This reverts commit 82562bc20d.
2024-01-17 12:31:28 +01:00
Alug 141f6c51dc Revert "optimize plane stuff even more"
This reverts commit 120def9676.
2024-01-17 12:31:24 +01:00
Alug 1fc9492b30 Revert "Use floating point trig in R_SetSlopePlane"
This reverts commit 3555783284.
2024-01-17 12:31:13 +01:00
Alug 65782d3d75 Revert "more changes"
This reverts commit cb6d657c03.
2024-01-17 12:31:08 +01:00
Alug b5cb6dfb9d Revert "forgoer"
This reverts commit f476befc4b.
2024-01-17 12:31:03 +01:00
Alug 6667e4b8bc Revert "forgor R_GetSlopeZAt"
This reverts commit 4a94939d4f.
2024-01-17 12:30:58 +01:00
Alug 5e2492a930 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-17 12:19:30 +01:00
Alug 4f07372e0f (hopefully) fix overflow in R_DrawRepeatMaskedColumn
well this fixes the game hanging in software renderer on Marsh´s Marble Zone
2024-01-17 12:11:32 +01:00
Alug 80a1a97083 Revert "Revert "Revert "Localskins on replays"""
This reverts commit 12059955e5.
2024-01-16 16:44:41 +01:00
Alug 204476c55d Revert "Hopefully fix the localskin replay issues 🙏"
This reverts commit 8fab258778.
2024-01-16 16:44:38 +01:00
hayaunderscore 8fab258778 Hopefully fix the localskin replay issues 🙏 2024-01-16 16:35:39 +01:00
Alug 12059955e5 Revert "Revert "Localskins on replays""
This reverts commit d3e5dfc346.
2024-01-16 16:35:33 +01:00
Alug 3ca1f957ba fix ogl shearing with flipcam 2024-01-16 16:22:30 +01:00
Alug b11362aec1 remove the extra screentex and apply palshader directly to finaltex
theres basically barely any difference, even in the fades theres very little, and it just cost so freaking much performance

however, ill keep the revamped screentex setup as this it allows us to keep the better fadescreen background for menus
2024-01-15 20:12:35 +01:00
Alug 75630df10e readd oldpal
for performance reasons its better
2024-01-15 19:36:37 +01:00
Alug 4d93abb7ac do this a little better 2024-01-15 17:44:07 +01:00
Alug 731943f980 ensure consistent shader state 2024-01-15 16:50:20 +01:00
Alug 265dc1f296 Light table support for HWR_FadeScreenMenuBack 2024-01-15 16:29:01 +01:00
Alug c449ffcc98 remove gr_oldpal for now 2024-01-15 16:23:19 +01:00
Alug 34500d32d0 paletterenderer screentex stuff again
this didnt really work like it shouldve
so ill keep it here for now
2024-01-15 16:17:17 +01:00
Alug d3e5dfc346 Revert "Localskins on replays"
This reverts commit e1f821e121.
2024-01-15 15:51:28 +01:00
Alug 8ed11107eb remove Shader_Load as Shader_SetUniforms literally did the same thing 2024-01-15 15:10:02 +01:00
Alug 2f51108783 fix lighttable batching for new batching and palshader code 2024-01-15 15:09:36 +01:00
Alug 2667a66419 Merge remote-tracking branch 'origin/batching-stuff' into lugstuff 2024-01-15 14:27:10 +01:00
Alug 0fd073f2f0 Merge remote-tracking branch 'origin/batching-stuff' into lugstuff 2024-01-15 14:18:10 +01:00
Alug 840cf4e00a Revert "Revert "Optimize HWR_RenderBatches polygon sorting""
This reverts commit a36e633555.
2024-01-15 14:15:26 +01:00
Alug d5d99f94b7 cap flashpals again
well it often resulted in flashpals that just made stuff so badly visable lmao
2024-01-15 11:38:09 +01:00
Alug dea19e4416 forgor R_GetSlopeZAt 2024-01-15 11:20:54 +01:00
Alug f7612d7398 forgoer 2024-01-15 11:17:19 +01:00
Alug e39182607e more changes 2024-01-15 11:16:16 +01:00
Alug 79f1febbce Use floating point trig in R_SetSlopePlane 2024-01-15 11:10:12 +01:00
Alug 120def9676 optimize plane stuff even more 2024-01-15 11:09:07 +01:00
Alug 82562bc20d Fix vibing slope planes 2024-01-15 10:44:43 +01:00
Alug 1c51361120 Plane optimization and cleanup
sned help

https://git.do.srb2.org/STJr/SRB2/-/commit/c07c80fd9e626f15b4d84d1766f8963e089d295a
2024-01-15 10:40:51 +01:00
Alug c07e79deb7 Move water ripple spanfunc out of r_plane + tilted water support
idk man
2024-01-15 10:18:13 +01:00
Alug 81cb1111b4 use malloc here 2024-01-15 09:36:35 +01:00
Alug 369307181e this can be static 2024-01-15 08:35:45 +01:00
Alug 7881e04e6b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-15 08:26:13 +01:00
Alug 66a72eb1be Copy Interpolation to Shields and Overlays, Splitscreen Overlays
from https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1992
2024-01-15 08:25:54 +01:00
Alug ad77f11859 Optimize polygon sorting on batch renderer
from https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2253

again lul
2024-01-15 00:31:29 +01:00
Alug 96d177876f Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-14 23:50:14 +01:00
Alug dc7392f86b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-14 22:57:24 +01:00
Alug 6f6252b6f8 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-14 22:50:11 +01:00
Alug 20b32df2c6 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-14 22:13:42 +01:00
Alug d413d02bf7 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-14 21:38:49 +01:00
Alug 426c0366cc Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-13 16:12:04 +01:00
Alug d3d3655580 Merge remote-tracking branch 'origin/crash-log-mention' into lugstuff 2024-01-13 12:05:55 +01:00
Alug d4a011ee6d Merge remote-tracking branch 'origin/addfilelocal-load-animdefs' into lugstuff 2024-01-12 13:37:17 +01:00
Alug b08118734e Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-12 13:37:14 +01:00
indev 41ee6de784 Make non-important files still load textures and animdefs 2024-01-12 15:35:24 +03:00
hayaunderscore 139d2e6be8 Localskins on replays 2024-01-12 12:26:21 +01:00
Alug a866461b0a Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-11 18:46:14 +01:00
Alug 6f61331d46 Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-11 18:46:12 +01:00
Alug 7731ca9fb2 Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-11 09:53:47 +01:00
Alug 3de0c4f5d8 Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-11 01:10:04 +01:00
Alug 2e602f8861 Revert "Revert "just show text instead of miscoloured boxes""
This reverts commit 7072a50060.
2024-01-11 00:50:36 +01:00
Alug 1a7d92a082 Revert "Revert "fix some things""
This reverts commit a65e586de5.
2024-01-11 00:50:26 +01:00
Alug 5aa2a0c821 Revert "Revert "Merge remote-tracking branch 'origin/gammastuff' into lugstuff""
This reverts commit a9d7ca3332.
2024-01-11 00:50:17 +01:00
Alug 4f2328b8dc Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-11 00:47:24 +01:00
Alug e929e524a3 Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-10 14:18:45 +01:00
Alug e6b9f18d3d Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-10 14:14:53 +01:00
Alug 7f197ef84e Merge remote-tracking branch 'origin/newpalshader' into lugstuff 2024-01-10 13:52:26 +01:00
Alug a9d7ca3332 Revert "Merge remote-tracking branch 'origin/gammastuff' into lugstuff"
This reverts commit 9aca8438a2, reversing
changes made to c2d37dfb61.
2024-01-10 13:51:51 +01:00
Alug a65e586de5 Revert "fix some things"
This reverts commit 69ffee271d.
2024-01-10 13:51:46 +01:00
Alug 7072a50060 Revert "just show text instead of miscoloured boxes"
This reverts commit fc1a367c2e.
2024-01-10 13:51:43 +01:00
Alug fc1a367c2e just show text instead of miscoloured boxes 2024-01-09 14:27:05 +01:00
Alug 3b376d85d4 fix some things 2024-01-09 14:19:36 +01:00
Alug 9aca8438a2 Merge remote-tracking branch 'origin/gammastuff' into lugstuff 2024-01-09 14:09:56 +01:00
Alug c2d37dfb61 use og values for pal 2024-01-09 13:38:24 +01:00
Alug 3c3bd0f0ea stuff 2024-01-09 13:25:59 +01:00
Alug 958db336b7 change this 2024-01-09 13:23:54 +01:00
Alug 342d570b3b Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-08 09:07:24 +01:00
Alug 67457c25df Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-08 08:54:08 +01:00
Alug a98d46f8a8 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-08 08:51:05 +01:00
Alug b2fca84b15 Zzz... 2024-01-07 08:25:49 +01:00
Alug 2e31169738 use fudge defines + remove wall and floor shader
both are now consilidated ( i have no idea how to spell that) into doom_colormap shader
2024-01-06 08:11:57 +01:00
Alug 4cda2c8093 use srb2´s sky shader
also its finally a defined shader now + move default fragment shader to the top
2024-01-06 08:07:11 +01:00
Alug 73b4e8a988 change this 2024-01-06 04:57:18 +01:00
Alug 82dbfb4379 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-06 01:15:05 +01:00
Alug 0e2ff2390a Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-05 21:56:11 +01:00
Alug 220d5db739 optimize camera mobj z stuff lol
idk wanna see if this does anything
2024-01-05 06:40:16 +01:00
Alug 212d475f50 fix menu fade screen background using wrong things in palshader 2024-01-05 01:23:05 +01:00
Alug b7fbd0433f little changes to palshader
use gl_texture 2 in postprocess like srb2s palshader does it
also disable depthtest for screentextures in palshader mode
2024-01-05 00:53:19 +01:00
Alug d28dd96aa0 revert this 2024-01-05 00:22:13 +01:00
Alug 0e46f91c51 change order of those 2024-01-05 00:21:51 +01:00
Alug d6dabacb05 wöter... 2024-01-04 23:31:55 +01:00
Alug 4363473955 hehe funky colours 2024-01-04 23:11:46 +01:00
Alug 7e5fd4e290 Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2024-01-03 20:02:35 +01:00
Alug c30a0cd4f1 Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2024-01-03 20:00:34 +01:00
Alug 98d56a38f5 Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2024-01-03 19:45:14 +01:00
Alug f26e95e7c9 Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2024-01-03 18:24:19 +01:00
Alug f39e1a9b70 wöter 2 2024-01-03 02:24:15 +01:00
Alug 1d5b531ba3 Revert "uuuh refactor batching a little + port Optimize polygon sorting"
This reverts commit d757e82e3f.
2024-01-02 22:21:25 +01:00
Alug a90bd08405 Revert " Avoid batching skybox and horizon lines"
This reverts commit b5fbaaa2b9ae91877c7c6ad3602956d677fa6e0c.
2024-01-02 22:21:21 +01:00
Alug 1cbb726cab Merge branch 'lugstuff' of https://github.com/Indev450/SRB2Kart-Saturn into lugstuff 2024-01-02 22:13:17 +01:00
Alug ce61d00dcf fix inline warnings 2024-01-02 22:13:13 +01:00
indev 2d92b798c6 Fix warnings related to boolean glib getters/setters 2024-01-03 00:10:28 +03:00
Alug cc62164a7c Revert "Revert "Merge remote-tracking branch 'origin/Saturn-Next-EnumLib' into lugstuff""
This reverts commit 142540e263.
2024-01-02 21:08:03 +01:00
Alug af510bce93 inline deez nuts 2024-01-02 21:07:02 +01:00
Alug 4ba60bedcd AAAAAaaa 2024-01-02 20:36:32 +01:00
Alug 583bf26129 wöter 2024-01-02 20:36:14 +01:00
Alug d8c3623141 Avoid batching skybox and horizon lines 2024-01-02 20:35:26 +01:00
Alug 2cd0875da6 lol 2024-01-02 06:19:31 +01:00
Alug 73d0848f7e (hopefully) fix horizonlines 2024-01-02 03:49:32 +01:00
Alug d757e82e3f uuuh refactor batching a little + port Optimize polygon sorting
uhhh https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2253
2024-01-02 01:02:42 +01:00
Alug 007238e7dd Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-02 00:09:27 +01:00
Alug 944e019020 let indev compile this branch uwu 2024-01-01 21:28:03 +01:00
Alug 634f8897b4 Revert "uuuh refactor batching a little + port Optimize polygon sorting"
This reverts commit 7651d31c50.
2024-01-01 21:19:14 +01:00
Alug 7651d31c50 uuuh refactor batching a little + port Optimize polygon sorting
uhhh https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2253
2024-01-01 20:44:19 +01:00
Alug 1702873ab1 Revert "attempt at making water shader ripple more accurate to software"
This reverts commit 8ab37040db.
2024-01-01 18:55:41 +01:00
Alug 44e7d5249c dont pack my memories 2024-01-01 18:30:06 +01:00
Alug 8ab37040db attempt at making water shader ripple more accurate to software 2024-01-01 18:29:04 +01:00
Alug ac203b0ccb Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2024-01-01 17:08:31 +01:00
Alug 557546c9c3 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2024-01-01 17:08:18 +01:00
Alug 52a94dbe78 try and make p-speedometer a little less painful to look at 2023-12-31 03:39:24 +01:00
Alug f4ffc19981 lil k_kart cleanup
uh
2023-12-31 03:12:35 +01:00
Alug ac3c117b03 uh 2023-12-31 00:12:11 +01:00
Alug 1ac008ab02 Merge remote-tracking branch 'origin/compilation-warnings-fix' into lugstuff 2023-12-31 00:07:39 +01:00
Alug 58ac86e3bf noone cares about c90 mixed declarations lmao 2023-12-30 21:51:23 +01:00
Alug 1daf06858b Revert "(maybe?) fix net issues on server join"
This reverts commit af40bdb11b.
2023-12-30 21:41:33 +01:00
Alug a4e8ce7f01 Fix most of compilation warnings 2023-12-30 15:55:07 +01:00
Alug ed6e16cdce uuh 2023-12-30 01:20:09 +01:00
Alug 57bb92a36c this didnt work out lmao 2023-12-30 00:55:24 +01:00
Alug 142540e263 Revert "Merge remote-tracking branch 'origin/Saturn-Next-EnumLib' into lugstuff"
This reverts commit 5dab606980, reversing
changes made to 661dfde6af.
2023-12-29 23:24:08 +01:00
Alug 5a17430747 Revert "Merge remote-tracking branch 'origin/moreopengl' into lugstuff"
This reverts commit a6015e4647, reversing
changes made to fcbe95447a.
2023-12-29 22:49:51 +01:00
Alug 23c84a9e96 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-29 22:49:27 +01:00
Alug 6bb9dcc216 revert that part it stuttered race conditions or somethjing lmao 2023-12-29 15:36:12 +01:00
Alug 1901e4dbdc fuckit idk lmoa 2023-12-29 14:23:29 +01:00
Alug 1657f769da Revert "dont need that"
This reverts commit f274ed3fd8.
2023-12-29 13:11:43 +01:00
Alug c82eb489fe give me all that shit yes 2023-12-29 01:47:27 +01:00
Alug 9f05befd70 i have no idea what im doing lmao 2023-12-29 01:36:33 +01:00
Alug f274ed3fd8 dont need that 2023-12-29 01:35:50 +01:00
Alug f6e027abcb Merge remote-tracking branch 'origin/gl-noencore-effect-fix' into lugstuff 2023-12-27 15:30:13 +01:00
Alug a92114a854 Merge remote-tracking branch 'origin/gl-noencore-effect-fix' into lugstuff 2023-12-27 15:04:36 +01:00
Alug ffb84705d3 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-27 14:40:50 +01:00
Alug 2f8366b6f9 -flto breaks crashlogs it seems lol 2023-12-24 20:28:57 +01:00
Alug a6f062c126 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-24 19:41:15 +01:00
Alug 41c24f3bc9 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-24 19:13:15 +01:00
Alug af40bdb11b (maybe?) fix net issues on server join
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2238?commit_id=d79d22de63c5b84e3e0f4d737af81f74321dd80d

needs alot of testing
2023-12-24 00:15:47 +01:00
Alug 00a69e6aed Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-23 17:24:07 +01:00
Alug 04b2d784ce Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-22 20:28:28 +01:00
Alug a5de51b039 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-21 13:54:33 +01:00
Alug 4a80e9f20f Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-20 23:06:24 +01:00
Alug 8676769a8f Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-20 17:53:09 +01:00
Alug 2f8c7a81ca Revert "Merge remote-tracking branch 'origin/thinkercache' into lugstuff"
This reverts commit 760fe392a8, reversing
changes made to 5dab606980.
2023-12-20 08:35:16 +01:00
Alug ac11af6048 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-20 06:09:25 +01:00
Alug 7c558802a4 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-20 05:16:05 +01:00
Alug 5a516aa1ad dont need that 2023-12-19 21:52:21 +01:00
Alug 4d1b6ed974 Merge remote-tracking branch 'origin/Saturn-Next' into lugstuff 2023-12-19 20:20:57 +01:00
Alug e8e6bb0499 Revert "test stuff"
This reverts commit 085efaa605.
2023-12-19 19:41:55 +01:00
Alug 58f94666d1 timeout sticker uses wrong patch 2023-12-19 18:58:10 +01:00
Alug 085efaa605 test stuff
very crude, console scream at me if those are botched
most likely not the issue but whatever
2023-12-19 18:57:47 +01:00
Alug 6028e392f0 dont prep shaders if theyre uneeded 2023-12-19 17:34:15 +01:00
Alug fa67dd74a0 huehue 2023-12-19 16:28:51 +01:00
Alug cb734b50c3 bru 2023-12-19 16:24:33 +01:00
Alug 087e58b88b bugger off discord rpc 2023-12-19 16:21:35 +01:00
Alug 78b9d67aaa im not on pentium 4 2023-12-19 16:17:15 +01:00
Alug a6015e4647 Merge remote-tracking branch 'origin/moreopengl' into lugstuff 2023-12-19 16:14:18 +01:00
Alug fcbe95447a Merge remote-tracking branch 'origin/multithreadshit' into lugstuff 2023-12-19 16:13:44 +01:00
Alug 760fe392a8 Merge remote-tracking branch 'origin/thinkercache' into lugstuff 2023-12-19 16:11:54 +01:00
Alug 5dab606980 Merge remote-tracking branch 'origin/Saturn-Next-EnumLib' into lugstuff 2023-12-19 16:11:36 +01:00
indev c265575dfd Fix config 2023-11-16 22:14:18 +03:00
alufolie91 4a1f526ac6 multithread exec command and some filesearch/add stuff
hey it actually improves some things alot
esp the loading addons stage when joining a server
2023-11-16 19:14:48 +01:00
Alug 497b633661 Revert "why did i remove this back then??"
This reverts commit 91ed5c4871.
2023-11-15 09:59:24 +01:00
alufolie91 c7f54a98e0 Merge remote-tracking branch 'origin/Saturn-Next' into moreopengl 2023-11-14 21:16:47 +01:00
alufolie91 7da8c20409 remove that stuff 2023-11-14 21:16:04 +01:00
Alug 116328c7bf attempt at linked list for textures
also changes to caching handling a bit
seems to have helped with stuck colors a bit
2023-11-08 02:50:17 +01:00
Alug bd68fef4a2 Zzzzz... 2023-11-08 00:38:48 +01:00
alufolie91 7759d56ad3 Fix uninitialized reads in PreparePolygon
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1392
2023-11-08 00:17:42 +01:00
Alug 9c7020a369 GRRRRRR not GLLLLLLLL 2023-11-07 18:23:31 +01:00
alufolie91 f8c1903316 change how mipmap caching works
also a bit of texture conversion
idk
2023-11-07 18:19:40 +01:00
alufolie91 652423ad14 Cache and reuse removed mobjs when spawning mobjs
from https://git.do.srb2.org/STJr/SRB2/-/merge_requests/2200
2023-11-06 12:27:23 +01:00
421 changed files with 160639 additions and 31726 deletions

No files matched your search

+1
View File
@@ -4,6 +4,7 @@
*.plg
*.suo
*.vcproj.*.*.user
*.kate-swp
Win32_LIB_ASM_Debug
Win32_LIB_ASM_Release
*.bsc
-1
View File
@@ -42,4 +42,3 @@ compversion() {
[ -f "$path/comptime.c" ] && compversion "$@"
exit 2
+5 -1
View File
@@ -31,4 +31,8 @@ and don't forget to build r_opengl.dll for srb2dd.
Updated 2/17/2024 (v1.6 Saturn)
No i threw everthing into dll-binaries
theres no reason at all to have stuff spread across multiple directories
theres no reason at all to have stuff spread across multiple directories
Updated 3/19/2025 (v1.6; Neptune)
We're using some C++ code now, so we need to have a few more DLLs.
Otherwise, it's about the same as prior.
File diff suppressed because it is too large. Load diff
-191
View File
@@ -1,191 +0,0 @@
/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */
#ifndef __CURL_CURLBUILD_H
#define __CURL_CURLBUILD_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* ================================================================ */
/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* Nothing in this file is intended to be modified or adjusted by the
* curl library user nor by the curl library builder.
*
* If you think that something actually needs to be changed, adjusted
* or fixed in this file, then, report it on the libcurl development
* mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/
*
* This header file shall only export symbols which are 'curl' or 'CURL'
* prefixed, otherwise public name space would be polluted.
*
* NOTE 2:
* -------
*
* Right now you might be staring at file include/curl/curlbuild.h.in or
* at file include/curl/curlbuild.h, this is due to the following reason:
*
* On systems capable of running the configure script, the configure process
* will overwrite the distributed include/curl/curlbuild.h file with one that
* is suitable and specific to the library being configured and built, which
* is generated from the include/curl/curlbuild.h.in template file.
*
*/
/* ================================================================ */
/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
/* ================================================================ */
#ifdef CURL_SIZEOF_LONG
# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_SOCKLEN_T
# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined
#endif
#ifdef CURL_TYPEOF_CURL_OFF_T
# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_T
# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined
#endif
#ifdef CURL_FORMAT_CURL_OFF_TU
# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined
#endif
#ifdef CURL_FORMAT_OFF_T
# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined
#endif
#ifdef CURL_SIZEOF_CURL_OFF_T
# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_T
# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined
#endif
#ifdef CURL_SUFFIX_CURL_OFF_TU
# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined
#endif
/* ================================================================ */
/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
/* ================================================================ */
/* Configure process defines this to 1 when it finds out that system */
/* header file ws2tcpip.h must be included by the external interface. */
#define CURL_PULL_WS2TCPIP_H 1
#ifdef CURL_PULL_WS2TCPIP_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# endif
# include <windows.h>
# include <winsock2.h>
# include <ws2tcpip.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/types.h must be included by the external interface. */
#define CURL_PULL_SYS_TYPES_H 1
#ifdef CURL_PULL_SYS_TYPES_H
# include <sys/types.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file stdint.h must be included by the external interface. */
#define CURL_PULL_STDINT_H 1
#ifdef CURL_PULL_STDINT_H
# include <stdint.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file inttypes.h must be included by the external interface. */
#define CURL_PULL_INTTYPES_H 1
#ifdef CURL_PULL_INTTYPES_H
# include <inttypes.h>
#endif
/* Configure process defines this to 1 when it finds out that system */
/* header file sys/socket.h must be included by the external interface. */
/* #undef CURL_PULL_SYS_SOCKET_H */
#ifdef CURL_PULL_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* The size of `long', as computed by sizeof. */
#define CURL_SIZEOF_LONG 4
/* Integral data type used for curl_socklen_t. */
#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
/* The size of `curl_socklen_t', as computed by sizeof. */
#define CURL_SIZEOF_CURL_SOCKLEN_T 4
/* Data type definition of curl_socklen_t. */
typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
/* Signed integral data type used for curl_off_t. */
#define CURL_TYPEOF_CURL_OFF_T int64_t
/* Data type definition of curl_off_t. */
typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
/* curl_off_t formatting string directive without "%" conversion specifier. */
#define CURL_FORMAT_CURL_OFF_T "I64d"
/* unsigned curl_off_t formatting string without "%" conversion specifier. */
#define CURL_FORMAT_CURL_OFF_TU "I64u"
/* curl_off_t formatting string directive with "%" conversion specifier. */
#define CURL_FORMAT_OFF_T "%I64d"
/* The size of `curl_off_t', as computed by sizeof. */
#define CURL_SIZEOF_CURL_OFF_T 8
/* curl_off_t constant suffix. */
#define CURL_SUFFIX_CURL_OFF_T LL
/* unsigned curl_off_t constant suffix. */
#define CURL_SUFFIX_CURL_OFF_TU ULL
#endif /* __CURL_CURLBUILD_H */
-261
View File
@@ -1,261 +0,0 @@
#ifndef __CURL_CURLRULES_H
#define __CURL_CURLRULES_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* ================================================================ */
/* COMPILE TIME SANITY CHECKS */
/* ================================================================ */
/*
* NOTE 1:
* -------
*
* All checks done in this file are intentionally placed in a public
* header file which is pulled by curl/curl.h when an application is
* being built using an already built libcurl library. Additionally
* this file is also included and used when building the library.
*
* If compilation fails on this file it is certainly sure that the
* problem is elsewhere. It could be a problem in the curlbuild.h
* header file, or simply that you are using different compilation
* settings than those used to build the library.
*
* Nothing in this file is intended to be modified or adjusted by the
* curl library user nor by the curl library builder.
*
* Do not deactivate any check, these are done to make sure that the
* library is properly built and used.
*
* You can find further help on the libcurl development mailing list:
* http://cool.haxx.se/mailman/listinfo/curl-library/
*
* NOTE 2
* ------
*
* Some of the following compile time checks are based on the fact
* that the dimension of a constant array can not be a negative one.
* In this way if the compile time verification fails, the compilation
* will fail issuing an error. The error description wording is compiler
* dependent but it will be quite similar to one of the following:
*
* "negative subscript or subscript is too large"
* "array must have at least one element"
* "-1 is an illegal array size"
* "size of array is negative"
*
* If you are building an application which tries to use an already
* built libcurl library and you are getting this kind of errors on
* this file, it is a clear indication that there is a mismatch between
* how the library was built and how you are trying to use it for your
* application. Your already compiled or binary library provider is the
* only one who can give you the details you need to properly use it.
*/
/*
* Verify that some macros are actually defined.
*/
#ifndef CURL_SIZEOF_LONG
# error "CURL_SIZEOF_LONG definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing
#endif
#ifndef CURL_TYPEOF_CURL_SOCKLEN_T
# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!"
Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing
#endif
#ifndef CURL_SIZEOF_CURL_SOCKLEN_T
# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing
#endif
#ifndef CURL_TYPEOF_CURL_OFF_T
# error "CURL_TYPEOF_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing
#endif
#ifndef CURL_FORMAT_CURL_OFF_T
# error "CURL_FORMAT_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing
#endif
#ifndef CURL_FORMAT_CURL_OFF_TU
# error "CURL_FORMAT_CURL_OFF_TU definition is missing!"
Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing
#endif
#ifndef CURL_FORMAT_OFF_T
# error "CURL_FORMAT_OFF_T definition is missing!"
Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing
#endif
#ifndef CURL_SIZEOF_CURL_OFF_T
# error "CURL_SIZEOF_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing
#endif
#ifndef CURL_SUFFIX_CURL_OFF_T
# error "CURL_SUFFIX_CURL_OFF_T definition is missing!"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing
#endif
#ifndef CURL_SUFFIX_CURL_OFF_TU
# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!"
Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing
#endif
/*
* Macros private to this header file.
*/
#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1
#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1
/*
* Verify that the size previously defined and expected for long
* is the same as the one reported by sizeof() at compile time.
*/
typedef char
__curl_rule_01__
[CurlchkszEQ(long, CURL_SIZEOF_LONG)];
/*
* Verify that the size previously defined and expected for
* curl_off_t is actually the the same as the one reported
* by sizeof() at compile time.
*/
typedef char
__curl_rule_02__
[CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)];
/*
* Verify at compile time that the size of curl_off_t as reported
* by sizeof() is greater or equal than the one reported for long
* for the current compilation.
*/
typedef char
__curl_rule_03__
[CurlchkszGE(curl_off_t, long)];
/*
* Verify that the size previously defined and expected for
* curl_socklen_t is actually the the same as the one reported
* by sizeof() at compile time.
*/
typedef char
__curl_rule_04__
[CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)];
/*
* Verify at compile time that the size of curl_socklen_t as reported
* by sizeof() is greater or equal than the one reported for int for
* the current compilation.
*/
typedef char
__curl_rule_05__
[CurlchkszGE(curl_socklen_t, int)];
/* ================================================================ */
/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */
/* ================================================================ */
/*
* CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
* these to be visible and exported by the external libcurl interface API,
* while also making them visible to the library internals, simply including
* setup.h, without actually needing to include curl.h internally.
* If some day this section would grow big enough, all this should be moved
* to its own header file.
*/
/*
* Figure out if we can use the ## preprocessor operator, which is supported
* by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
* or __cplusplus so we need to carefully check for them too.
*/
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
defined(__ILEC400__)
/* This compiler is believed to have an ISO compatible preprocessor */
#define CURL_ISOCPP
#else
/* This compiler is believed NOT to have an ISO compatible preprocessor */
#undef CURL_ISOCPP
#endif
/*
* Macros for minimum-width signed and unsigned curl_off_t integer constants.
*/
#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
# define __CURL_OFF_T_C_HLPR2(x) x
# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
__CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
#else
# ifdef CURL_ISOCPP
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
# else
# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
# endif
# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
#endif
/*
* Get rid of macros private to this header file.
*/
#undef CurlchkszEQ
#undef CurlchkszGE
/*
* Get rid of macros not intended to exist beyond this point.
*/
#undef CURL_PULL_WS2TCPIP_H
#undef CURL_PULL_SYS_TYPES_H
#undef CURL_PULL_SYS_SOCKET_H
#undef CURL_PULL_STDINT_H
#undef CURL_PULL_INTTYPES_H
#undef CURL_TYPEOF_CURL_SOCKLEN_T
#undef CURL_TYPEOF_CURL_OFF_T
#ifdef CURL_NO_OLDIES
#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */
#endif
#endif /* __CURL_CURLRULES_H */
-1
View File
@@ -1 +0,0 @@
/* not used */
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+94 -94
View File
@@ -1,94 +1,94 @@
# CMake project definition file.
project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop
# down the requirement, but I can't test that.
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
# Default emulators to build (all of them! ;)
if (NOT DEFINED USE_GME_AY)
SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
endif()
if (NOT DEFINED USE_GME_GBS)
SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
endif()
if (NOT DEFINED USE_GME_GYM)
SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
endif()
if (NOT DEFINED USE_GME_HES)
SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
endif()
if (NOT DEFINED USE_GME_KSS)
SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
endif()
if (NOT DEFINED USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
endif()
if (NOT DEFINED USE_GME_NSFE)
SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
endif()
if (NOT DEFINED USE_GME_SAP)
SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
endif()
if (NOT DEFINED USE_GME_SPC)
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
endif()
if (NOT DEFINED USE_GME_VGM)
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
endif()
if (USE_GME_NSFE AND NOT USE_GME_NSF)
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif()
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
set (ENABLE_VISIBILITY OFF)
if (__LIBGME_TEST_VISIBILITY)
# get the gcc version
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
# gcc <4.1 had poor support for symbol visibility
if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set (ENABLE_VISIBILITY ON)
add_definitions (-DLIBGME_VISIBILITY)
# GCC >= 4.2 also correctly supports making inline members have hidden
# visibility by default.
if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
endif()
endif()
endif() # test visibility
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here
add_subdirectory(gme)
# EXCLUDE_FROM_ALL adds build rules but keeps it out of default build
add_subdirectory(player EXCLUDE_FROM_ALL)
add_subdirectory(demo EXCLUDE_FROM_ALL)
# CMake project definition file.
project(libgme)
include (CheckCXXCompilerFlag)
# When version is changed, also change the one in gme/gme.h to match
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
# Of course, 2.4 might work, in which case you're welcome to drop
# down the requirement, but I can't test that.
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
# Default emulators to build (all of them! ;)
if (NOT DEFINED USE_GME_AY)
SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
endif()
if (NOT DEFINED USE_GME_GBS)
SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
endif()
if (NOT DEFINED USE_GME_GYM)
SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
endif()
if (NOT DEFINED USE_GME_HES)
SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
endif()
if (NOT DEFINED USE_GME_KSS)
SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
endif()
if (NOT DEFINED USE_GME_NSF)
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
endif()
if (NOT DEFINED USE_GME_NSFE)
SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
endif()
if (NOT DEFINED USE_GME_SAP)
SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
endif()
if (NOT DEFINED USE_GME_SPC)
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
endif()
if (NOT DEFINED USE_GME_VGM)
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
endif()
if (USE_GME_NSFE AND NOT USE_GME_NSF)
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
endif()
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
# Check for GCC "visibility" support.
if (CMAKE_COMPILER_IS_GNUCXX)
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
set (ENABLE_VISIBILITY OFF)
if (__LIBGME_TEST_VISIBILITY)
# get the gcc version
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
# gcc <4.1 had poor support for symbol visibility
if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set (ENABLE_VISIBILITY ON)
add_definitions (-DLIBGME_VISIBILITY)
# GCC >= 4.2 also correctly supports making inline members have hidden
# visibility by default.
if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2"))
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
endif()
endif()
endif() # test visibility
# Cache this result
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
endif (CMAKE_COMPILER_IS_GNUCXX)
# Shared library defined here
add_subdirectory(gme)
# EXCLUDE_FROM_ALL adds build rules but keeps it out of default build
add_subdirectory(player EXCLUDE_FROM_ALL)
add_subdirectory(demo EXCLUDE_FROM_ALL)
+5 -5
View File
@@ -1,5 +1,5 @@
Game_Music_Emu Change Log
-------------------------
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
for the accurate change log.
Game_Music_Emu Change Log
-------------------------
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
for the accurate change log.
+194 -194
View File
@@ -1,194 +1,194 @@
Game_Music_Emu 0.6.0 Design
---------------------------
This might be slightly out-of-date at times, but will be a big help in
understanding the library implementation.
Architecture
------------
The library is essentially a bunch of independent game music file
emulators unified with a common interface.
Gme_File and Music_Emu provide a common interface to the emulators. The
virtual functions are protected rather than public to allow pre- and
post-processing of arguments and data in one place. This allows the
emulator classes to assume that everything is set up properly when
starting a track and playing samples.
All file input is done with the Data_Reader interface. Many derived
classes are present, for the usual disk-based file and block of memory,
to specialized adaptors for things like reading a subset of data or
combining a block of memory with a Data_Reader to the remaining data.
This makes the library much more flexible with regard to the source of
game music file data. I still added a specialized load_mem() function to
have the emulator keep a pointer to data already read in memory, for
those formats whose files can be absolutely huge (GYM, some VGMs). This
is important if for some reason the caller must load the data ahead of
time, but doesn't want the emulator needlessly making a copy.
Since silence checking and fading are relatively complex, they are kept
separate from basic file loading and track information, which are
handled in the base class Gme_File. My original intent was to use
Gme_File as the common base class for full emulators and track
information-only readers, but implementing the C interface was much
simpler if both derived from Music_Emu. User C++ code can still benefit
from static checking by using Gme_File where only track information will
be accessed.
Each emulator generally has three components: main emulator, CPU
emulator, and sound chip emulator(s). Each component has minimal
coupling, so use in a full emulator or stand alone is fairly easy. This
modularity really helps reduce complexity. Blip_Buffer helps a lot with
simplifying the APU interfaces and implementation.
The "classic" emulators derive from Classic_Emu, which handles
Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
output, allowing you to derive a custom buffer that could output each
voice to a separate sound channel and do different processing on each.
At some point I'm going to implement a better Effects_Buffer that allows
individual control of every channel.
In implementing the C interface, I wanted a way to specify an emulator
type that didn't require linking in all the emulators. For each emulator
type there is a global object with pointers to functions to create the
emulator or a track information reader. The emulator type is thus a
pointer to this, which conveniently allows for a NULL value. The user
referencing this emulator type object is what ultimately links the
emulator in (unless new Foo_Emu is used in C++, of course). This type
also serves as a useful substitute for RTTI on older C++ compilers.
Addendum: I have since added gme_type_list(), which causes all listed
emulators to be linked in. To avoid this, I make the list itself
editable in blargg_config.h. Having a built-in list allows
gme_load_file() to take a path and give back an emulator with the file
loaded, which is extremely useful for new users.
Interface conventions
----------------------
If a function retains a pointer to or replaces the value of an object
passed, it takes a pointer so that it will be clear in the caller's
source code that care is required.
Multi-word names have an underscore '_' separator between individual
words.
Functions are named with lowercase words. Functions which perform an
action with side-effects are named with a verb phrase (i.e. load, move,
run). Functions which return the value of a piece of state are named
using a noun phrase (i.e. loaded, moved, running).
Classes are named with capitalized words. Only the first letter of an
acronym is capitalized. Class names are nouns, sometimes suggestive of
what they do (i.e. File_Scanner).
Structure, enumeration, and typedefs to these and built-in types are
named using lowercase words with a _t suffix.
Macros are named with all-uppercase words.
Internal names which can't be hidden due to technical reasons have an
underscore '_' suffix.
Managing Complexity
-------------------
Complexity has been a factor in most library decisions. Many features
have been passed by due to the complexity they would add. Once
complexity goes past a certain level, it mentally grasping the library
in its entirety, at which point more defects will occur and be hard to
find.
I chose 16-bit signed samples because it seems to be the most common
format. Supporting multiple formats would add too much complexity to be
worth it. Other formats can be obtained via conversion.
I've kept interfaces fairly lean, leaving many possible features
untapped but easy to add if necessary. For example the classic emulators
could have volume and frequency equalization adjusted separately for
each channel, since they each have an associated Blip_Synth.
Source files of 400 lines or less seem to be the best size to limit
complexity. In a few cases there is no reasonable way to split longer
files, or there is benefit from having the source together in one file.
Preventing Bugs
---------------
I've done many things to reduce the opportunity for defects. A general
principle is to write code so that defects will be as visible as
possible. I've used several techniques to achieve this.
I put assertions at key points where defects seem likely or where
corruption due to a defect is likely to be visible. I've also put
assertions where violations of the interface are likely. In emulators
where I am unsure of exact hardware operation in a particular case, I
output a debug-only message noting that this has occurred; many times I
haven't implemented a hardware feature because nothing uses it. I've
made code brittle where there is no clear reason flexibility; code
written to handle every possibility sacrifices quality and reliability
to handle vaguely defined situations.
Flexibility through indirection
-------------------------------
I've tried to allow the most flexibility of modules by using indirection
to allow extension by the user. This keeps each module simpler and more
focused on its unique task.
The classic emulators use Multi_Buffer, which potentially allows a
separate Blip_Buffer for each channel. This keeps emulators free of
typical code to allow output in mono, stereo, panning, etc.
All emulators use a reader object to access file data, allowing it to be
stored in a regular file, compressed archive, memory, or generated
on-the-fly. Again, the library can be kept free of the particulars of
file access and changes required to support new formats.
Emulators in general
--------------------
When I wrote the first NES sound emulator, I stored most of the state in
an emulator-specific format, with significant redundancy. In the
register write function I decoded everything into named variables. I
became tired of the verbosity and wanted to more closely model the
hardware, so I moved to a style of storing the last written value to
each register, along with as little other state as possible, mostly the
internal hardware registers. While this involves slightly more
recalculation, in most cases the emulation code is of comparable size.
It also makes state save/restore (for use in a full emulator) much
simpler. Finally, it makes debugging easier since the hardware registers
used in emulation are obvious.
CPU Cores
---------
I've spent lots of time coming up with techniques to optimize the CPU
cores. Some of the most important: execute multiple instructions during
an emulation call, keep state in local variables to allow register
assignment, optimize state representation for most common instructions,
defer status flag calculation until actually needed, read program code
directly without a call to the memory read function, always pre-fetch
the operand byte before decoding instruction, and emulate instructions
using common blocks of code.
I've successfully used Nes_Cpu in a fairly complete NES emulator, and
I'd like to make all the CPU emulators suitable for use in emulators. It
seems a waste for them to be used only for the small amount of emulation
necessary for game music files.
I debugged the CPU cores by writing a test shell that ran them in
parallel with other CPU cores and compared all memory accesses and
processor states at each step. This provided good value at little cost.
The CPU mapping page size is adjustable to allow the best tradeoff
between memory/cache usage and handler granularity. The interface allows
code to be somewhat independent of the page size.
I optimize program memory accesses to direct reads rather than calls to
the memory read function. My assumption is that it would be difficult to
get useful code out of hardware I/O addresses, so no software will
intentionally execute out of I/O space. Since the page size can be
changed easily, most program memory mapping schemes can be accommodated.
This greatly reduces memory access function calls.
Game_Music_Emu 0.6.0 Design
---------------------------
This might be slightly out-of-date at times, but will be a big help in
understanding the library implementation.
Architecture
------------
The library is essentially a bunch of independent game music file
emulators unified with a common interface.
Gme_File and Music_Emu provide a common interface to the emulators. The
virtual functions are protected rather than public to allow pre- and
post-processing of arguments and data in one place. This allows the
emulator classes to assume that everything is set up properly when
starting a track and playing samples.
All file input is done with the Data_Reader interface. Many derived
classes are present, for the usual disk-based file and block of memory,
to specialized adaptors for things like reading a subset of data or
combining a block of memory with a Data_Reader to the remaining data.
This makes the library much more flexible with regard to the source of
game music file data. I still added a specialized load_mem() function to
have the emulator keep a pointer to data already read in memory, for
those formats whose files can be absolutely huge (GYM, some VGMs). This
is important if for some reason the caller must load the data ahead of
time, but doesn't want the emulator needlessly making a copy.
Since silence checking and fading are relatively complex, they are kept
separate from basic file loading and track information, which are
handled in the base class Gme_File. My original intent was to use
Gme_File as the common base class for full emulators and track
information-only readers, but implementing the C interface was much
simpler if both derived from Music_Emu. User C++ code can still benefit
from static checking by using Gme_File where only track information will
be accessed.
Each emulator generally has three components: main emulator, CPU
emulator, and sound chip emulator(s). Each component has minimal
coupling, so use in a full emulator or stand alone is fairly easy. This
modularity really helps reduce complexity. Blip_Buffer helps a lot with
simplifying the APU interfaces and implementation.
The "classic" emulators derive from Classic_Emu, which handles
Blip_Buffer filling and multiple channels. It uses Multi_Buffer for
output, allowing you to derive a custom buffer that could output each
voice to a separate sound channel and do different processing on each.
At some point I'm going to implement a better Effects_Buffer that allows
individual control of every channel.
In implementing the C interface, I wanted a way to specify an emulator
type that didn't require linking in all the emulators. For each emulator
type there is a global object with pointers to functions to create the
emulator or a track information reader. The emulator type is thus a
pointer to this, which conveniently allows for a NULL value. The user
referencing this emulator type object is what ultimately links the
emulator in (unless new Foo_Emu is used in C++, of course). This type
also serves as a useful substitute for RTTI on older C++ compilers.
Addendum: I have since added gme_type_list(), which causes all listed
emulators to be linked in. To avoid this, I make the list itself
editable in blargg_config.h. Having a built-in list allows
gme_load_file() to take a path and give back an emulator with the file
loaded, which is extremely useful for new users.
Interface conventions
----------------------
If a function retains a pointer to or replaces the value of an object
passed, it takes a pointer so that it will be clear in the caller's
source code that care is required.
Multi-word names have an underscore '_' separator between individual
words.
Functions are named with lowercase words. Functions which perform an
action with side-effects are named with a verb phrase (i.e. load, move,
run). Functions which return the value of a piece of state are named
using a noun phrase (i.e. loaded, moved, running).
Classes are named with capitalized words. Only the first letter of an
acronym is capitalized. Class names are nouns, sometimes suggestive of
what they do (i.e. File_Scanner).
Structure, enumeration, and typedefs to these and built-in types are
named using lowercase words with a _t suffix.
Macros are named with all-uppercase words.
Internal names which can't be hidden due to technical reasons have an
underscore '_' suffix.
Managing Complexity
-------------------
Complexity has been a factor in most library decisions. Many features
have been passed by due to the complexity they would add. Once
complexity goes past a certain level, it mentally grasping the library
in its entirety, at which point more defects will occur and be hard to
find.
I chose 16-bit signed samples because it seems to be the most common
format. Supporting multiple formats would add too much complexity to be
worth it. Other formats can be obtained via conversion.
I've kept interfaces fairly lean, leaving many possible features
untapped but easy to add if necessary. For example the classic emulators
could have volume and frequency equalization adjusted separately for
each channel, since they each have an associated Blip_Synth.
Source files of 400 lines or less seem to be the best size to limit
complexity. In a few cases there is no reasonable way to split longer
files, or there is benefit from having the source together in one file.
Preventing Bugs
---------------
I've done many things to reduce the opportunity for defects. A general
principle is to write code so that defects will be as visible as
possible. I've used several techniques to achieve this.
I put assertions at key points where defects seem likely or where
corruption due to a defect is likely to be visible. I've also put
assertions where violations of the interface are likely. In emulators
where I am unsure of exact hardware operation in a particular case, I
output a debug-only message noting that this has occurred; many times I
haven't implemented a hardware feature because nothing uses it. I've
made code brittle where there is no clear reason flexibility; code
written to handle every possibility sacrifices quality and reliability
to handle vaguely defined situations.
Flexibility through indirection
-------------------------------
I've tried to allow the most flexibility of modules by using indirection
to allow extension by the user. This keeps each module simpler and more
focused on its unique task.
The classic emulators use Multi_Buffer, which potentially allows a
separate Blip_Buffer for each channel. This keeps emulators free of
typical code to allow output in mono, stereo, panning, etc.
All emulators use a reader object to access file data, allowing it to be
stored in a regular file, compressed archive, memory, or generated
on-the-fly. Again, the library can be kept free of the particulars of
file access and changes required to support new formats.
Emulators in general
--------------------
When I wrote the first NES sound emulator, I stored most of the state in
an emulator-specific format, with significant redundancy. In the
register write function I decoded everything into named variables. I
became tired of the verbosity and wanted to more closely model the
hardware, so I moved to a style of storing the last written value to
each register, along with as little other state as possible, mostly the
internal hardware registers. While this involves slightly more
recalculation, in most cases the emulation code is of comparable size.
It also makes state save/restore (for use in a full emulator) much
simpler. Finally, it makes debugging easier since the hardware registers
used in emulation are obvious.
CPU Cores
---------
I've spent lots of time coming up with techniques to optimize the CPU
cores. Some of the most important: execute multiple instructions during
an emulation call, keep state in local variables to allow register
assignment, optimize state representation for most common instructions,
defer status flag calculation until actually needed, read program code
directly without a call to the memory read function, always pre-fetch
the operand byte before decoding instruction, and emulate instructions
using common blocks of code.
I've successfully used Nes_Cpu in a fairly complete NES emulator, and
I'd like to make all the CPU emulators suitable for use in emulators. It
seems a waste for them to be used only for the small amount of emulation
necessary for game music files.
I debugged the CPU cores by writing a test shell that ran them in
parallel with other CPU cores and compared all memory accesses and
processor states at each step. This provided good value at little cost.
The CPU mapping page size is adjustable to allow the best tradeoff
between memory/cache usage and handler granularity. The interface allows
code to be somewhat independent of the page size.
I optimize program memory accesses to direct reads rather than calls to
the memory read function. My assumption is that it would be difficult to
get useful code out of hardware I/O addresses, so no software will
intentionally execute out of I/O space. Since the page size can be
changed easily, most program memory mapping schemes can be accommodated.
This greatly reduces memory access function calls.
+376 -376
View File
@@ -1,376 +1,376 @@
Game_Music_Emu 0.6.2
--------------------
Author : Shay Green <gblargg@gmail.com>
Maintainer : Michael Pyne <mpyne@purinchu.net>
Website : https://bitbucket.org/mpyne/game-music-emu/
Source : https://bitbucket.org/mpyne/game-music-emu/
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents
--------
* Overview
* Error handling
* Emulator types
* M3U playlist support
* Information fields
* Track length
* Loading file data
* Sound parameters
* VGM/GYM YM2413 & YM2612 FM sound
* Modular construction
* Obscure features
* Solving problems
* Thanks
Overview
--------
This library can open game music files, play tracks, and read game and
track information tags. To play a game music file, do the following:
* Open the file with gme_open_file()
* Start a track with gme_start_track();
* Generate samples as needed with gme_play()
* Play samples through speaker using your operating system
* Delete emulator when done with gme_delete()
Your code must arrange for the generated samples to be played through
the computer's speaker using whatever method your operating system
requires.
There are many additional features available; you can:
* Determine of the type of a music file without opening it with
gme_identify_*()
* Load just the file's information tags with gme_info_only
* Load from a block of memory rather than a file with gme_load_data()
* Arrange for a fade-out at a particular time with gme_set_fade
* Find when a track has ended with gme_track_ended()
* Seek to a new time in the track with gme_seek()
* Load an extended m3u playlist with gme_load_m3u()
* Get a list of the voices (channels) and mute them individually with
gme_voice_names() and gme_mute_voice()
* Change the playback tempo without affecting pitch with gme_set_tempo()
* Adjust treble/bass equalization with gme_set_equalizer()
* Associate your own data with an emulator and later get it back with
gme_set_user_data()
* Register a function of yours to be called back when the emulator is
deleted with gme_set_user_cleanup()
Refer to gme.h for a comprehensive summary of features.
Error handling
--------------
Functions which can fail have a return type of gme_err_t, which is a
pointer to an error string (const char*). If a function is successful it
returns NULL. Errors that you can easily avoid are checked with debug
assertions; gme_err_t return values are only used for genuine run-time
errors that can't be easily predicted in advance (out of memory, I/O
errors, incompatible file data). Your code should check all error
values.
When loading a music file in the wrong emulator or trying to load a
non-music file, gme_wrong_file_type is returned. You can check for this
error in C++ like this:
gme_err_t err = gme_open_file( path, &emu );
if ( err == gme_wrong_file_type )
...
To check for minor problems, call gme_warning() to get a string
describing the last warning. Your player should allow the user some way
of knowing when this is the case, since these minor errors could affect
playback. Without this information the user can't solve problems as
well. When playing a track, gme_warning() returns minor playback-related
problems (major playback problems end the track immediately and set the
warning string).
Emulator types
--------------
The library includes several game music emulators that each support a
different file type. Each is identified by a gme_type_t constant defined
in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
gme_open_file() or gme_open_data(), the library does the work of
determining the file type and creating an appropriate emulator. If you
want more control over this process, read on.
There are two basic ways to identify a game music file's type: look at
its file extension, or read the header data. The library includes
functions to help with both methods. The first is preferable because it
is fast and the most common way to identify files. Sometimes the
extension is lost or wrong, so the header must be read.
Use gme_identify_extension() to find the correct game music type based
on a filename. To identify a file based on its extension and header
contents, use gme_identify_file(). If you read the header data yourself,
use gme_identify_header().
If you want to remove support for some music types to reduce your
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
support just NSF and GBS, use this:
#define GME_TYPE_LIST \
gme_nsf_type,\
gme_gbs_type
M3U playlist support
--------------------
The library supports playlists in an extended m3u format with
gme_load_m3u() to give track names and times to multi-song formats: AY,
GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
itself is not well-defined so some m3u files won't work properly
(particularly those provided with KSS files). Only m3u files referencing
a single file are supported; your code must handle m3u files covering
more than one game music file, though it can use the built-in m3u
parsing provided by the library.
Information fields
------------------
Support is provided for the various text fields and length information
in a file with gme_track_info(). If you just need track information for
a file (for example, building a playlist), use gme_new_info() in place
of gme_new_emu(), load the file normally, then you can access the track
count and info, but nothing else.
M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
-------------------------------------------------------
Track Count | * * * * * * * * *
|
System | * * * * * * * * * *
|
Game | * * * * * * *
|
Song | * * * * * * *
|
Author | * * * * * * * *
|
Copyright | * * * * * * * *
|
Comment | * * * *
|
Dumper | * * * *
|
Length | * * * * * *
|
Intro Length| * * *
|
Loop Length | * * *
As listed above, the HES and KSS file formats don't include a track
count, and tracks are often scattered over the 0-255 range, so an m3u
playlist for these is a must.
Unavailable text fields are set to an empty string and times to -1. Your
code should be prepared for any combination of available and unavailable
fields, as a particular music file might not use all of the supported
fields listed above.
Currently text fields are truncated to 255 characters. Obscure fields of
some formats are not currently decoded; contact me if you want one
added.
Track length
------------
The library leaves it up to you as to when to stop playing a track. You
can ask for available length information and then tell the library what
time it should start fading the track with gme_set_fade(). By default it
also continually checks for 6 or more seconds of silence to mark the end
of a track. Here is a reasonable algorithm you can use to decide how
long to play a track:
* If the track length is > 0, use it
* If the loop length > 0, play for intro + loop * 2
* Otherwise, default to 2.5 minutes (150000 msec)
If you want to play a track longer than normal, be sure the loop length
isn't zero. See Music_Player.cpp around line 145 for example code.
By default, the library skips silence at the beginning of a track. It
also continually checks for the end of a non-looping track by watching
for 6 seconds of unbroken silence. When doing this is scans *ahead* by
several seconds so it can report the end of the track after only one
second of silence has actually played. This feature can be disabled with
gme_ignore_silence().
Loading file data
-----------------
The library allows file data to be loaded in many different ways. All
load functions return an error which you should check. The following
examples assume these variables:
Music_Emu* emu;
gme_err_t error;
If you're letting the library determine a file's type, you can use
either gme_open_file() or gme_open_data():
error = gme_open_file( pathname, &emu );
error = gme_open_data( pointer, size, &emu );
If you're manually determining file type and using used gme_new_emu() to
create an emulator, you can use the following methods of loading:
* From a block of memory:
error = gme_load_data( emu, pointer, size );
* Have library call your function to read data:
gme_err_t my_read( void* my_data, void* out, long count )
{
// code that reads 'count' bytes into 'out' buffer
// and return 0 if no error
}
error = gme_load_custom( emu, my_read, file_size, my_data );
Sound parameters
----------------
All emulators support an arbitrary output sampling rate. A rate of 44100
Hz should work well on most systems. Since band-limited synthesis is
used, a sampling rate above 48000 Hz is not necessary and will actually
reduce sound quality and performance.
All emulators also support adjustable gain, mainly for the purpose of
getting consistent volume between different music formats and avoiding
excessive modulation. The gain can only be set *before* setting the
emulator's sampling rate, so it's not useful as a general volume
control. The default gains of emulators are set so that they give
generally similar volumes, though some soundtracks are significantly
louder or quieter than normal.
Some emulators support adjustable treble and bass frequency equalization
(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
Parameters are specified using gme_equalizer_t eq = { treble_dB,
bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
for an extra crisp sound. Bass_freq sets the frequency where bass
response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
and 15000 Hz removes all bass. For example, the following makes the
sound extra-crisp but lacking bass:
gme_equalizer_t eq = { 5.0, 1000 };
gme_set_equalizer( music_emu, &eq );
Each emulator's equalization defaults to approximate the particular
console's sound quality; this default can be determined by calling
equalizer() just after creating the emulator. The Music_Emu::tv_eq
profile gives sound as if coming from a TV speaker, and some emulators
include other profiles for different versions of the system. For
example, to use Famicom sound equalization with the NSF emulator, do the
following:
music_emu->set_equalizer( Nsf_Emu::famicom_eq );
VGM/GYM YM2413 & YM2612 FM sound
--------------------------------
The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
chip emulator based on the Gens project. Because this has some
inaccuracies, other YM2612 emulators can be used in its place by
re-implementing the interface in YM2612_Emu.h. Available on my website
is a modified version of MAME's YM2612 emulator, which sounds better in
some ways and whose author is still making improvements.
VGM music files using the YM2413 FM sound chip are also supported, but a
YM2413 emulator isn't included with the library due to technical
reasons. I have put one of the available YM2413 emulators on my website
that can be used directly.
Modular construction
--------------------
The library is made of many fairly independent modules. If you're using
only one music file emulator, you can eliminate many of the library
sources from your program. Refer to the files list in readme.txt to get
a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
(see "Emulator types" above). Post to the forum if you'd like me to put
together a smaller version for a particular use, as this only takes me a
few minutes to do.
If you want to use one of the individual sound chip emulators (or CPU
cores) in your own console emulator, first check the libraries page on
my website since I have released several of them as stand alone
libraries with included documentation and examples on their use. If you
don't find it as a standalone library, contact me and I'll consider
separating it.
The "classic" sound chips use my Blip_Buffer library, which greatly
simplifies their implementation and efficiently handles band-limited
synthesis. It is also available as a stand alone library with
documentation and many examples.
Obscure features
----------------
The library's flexibility allows many possibilities. Contact me if you
want help implementing ideas or removing limitations.
* Uses no global/static variables, allowing multiple instances of any
emulator. This is useful in a music player if you want to allow
simultaneous recording or scanning of other tracks while one is already
playing. This will also be useful if your platform disallows global
data.
* Emulators that support a custom sound buffer can have *every* voice
routed to a different Blip_Buffer, allowing custom processing on each
voice. For example you could record a Game Boy track as a 4-channel
sound file.
* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
synthesis on "classic" emulators, which might help on some really old
processors. This significantly lowers sound quality and prevents treble
equalization. Try this if your platform's processor isn't fast enough
for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
the quality loss.
Solving problems
----------------
If you're having problems, try the following:
* If you're getting garbled sound, try this simple siren generator in
place of your call to play(). This will quickly tell whether the problem
is in the library or in your code.
static void play_siren( long count, short* out )
{
static double a, a2;
while ( count-- )
*out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
}
* Enable debugging support in your environment. This enables assertions
and other run-time checks.
* Turn the compiler's optimizer is off. Sometimes an optimizer generates
bad code.
* If multiple threads are being used, ensure that only one at a time is
accessing a given set of objects from the library. This library is not
in general thread-safe, though independent objects can be used in
separate threads.
* If all else fails, see if the demos work.
Thanks
------
Big thanks to Chris Moeller (kode54) for help with library testing and
feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
for original work on openspc++ that was used when developing Spc_Emu.
Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
and giving feedback for the library in their respective game music
players. More recently, Lucas Paul and Michael Pyne have helped nudge the
library into a public repository and get its interface more stable for use
in shared libraries.
Game_Music_Emu 0.6.2
--------------------
Author : Shay Green <gblargg@gmail.com>
Maintainer : Michael Pyne <mpyne@purinchu.net>
Website : https://bitbucket.org/mpyne/game-music-emu/
Source : https://bitbucket.org/mpyne/game-music-emu/
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
Contents
--------
* Overview
* Error handling
* Emulator types
* M3U playlist support
* Information fields
* Track length
* Loading file data
* Sound parameters
* VGM/GYM YM2413 & YM2612 FM sound
* Modular construction
* Obscure features
* Solving problems
* Thanks
Overview
--------
This library can open game music files, play tracks, and read game and
track information tags. To play a game music file, do the following:
* Open the file with gme_open_file()
* Start a track with gme_start_track();
* Generate samples as needed with gme_play()
* Play samples through speaker using your operating system
* Delete emulator when done with gme_delete()
Your code must arrange for the generated samples to be played through
the computer's speaker using whatever method your operating system
requires.
There are many additional features available; you can:
* Determine of the type of a music file without opening it with
gme_identify_*()
* Load just the file's information tags with gme_info_only
* Load from a block of memory rather than a file with gme_load_data()
* Arrange for a fade-out at a particular time with gme_set_fade
* Find when a track has ended with gme_track_ended()
* Seek to a new time in the track with gme_seek()
* Load an extended m3u playlist with gme_load_m3u()
* Get a list of the voices (channels) and mute them individually with
gme_voice_names() and gme_mute_voice()
* Change the playback tempo without affecting pitch with gme_set_tempo()
* Adjust treble/bass equalization with gme_set_equalizer()
* Associate your own data with an emulator and later get it back with
gme_set_user_data()
* Register a function of yours to be called back when the emulator is
deleted with gme_set_user_cleanup()
Refer to gme.h for a comprehensive summary of features.
Error handling
--------------
Functions which can fail have a return type of gme_err_t, which is a
pointer to an error string (const char*). If a function is successful it
returns NULL. Errors that you can easily avoid are checked with debug
assertions; gme_err_t return values are only used for genuine run-time
errors that can't be easily predicted in advance (out of memory, I/O
errors, incompatible file data). Your code should check all error
values.
When loading a music file in the wrong emulator or trying to load a
non-music file, gme_wrong_file_type is returned. You can check for this
error in C++ like this:
gme_err_t err = gme_open_file( path, &emu );
if ( err == gme_wrong_file_type )
...
To check for minor problems, call gme_warning() to get a string
describing the last warning. Your player should allow the user some way
of knowing when this is the case, since these minor errors could affect
playback. Without this information the user can't solve problems as
well. When playing a track, gme_warning() returns minor playback-related
problems (major playback problems end the track immediately and set the
warning string).
Emulator types
--------------
The library includes several game music emulators that each support a
different file type. Each is identified by a gme_type_t constant defined
in gme.h, for example gme_nsf_emu is for the NSF emulator. If you use
gme_open_file() or gme_open_data(), the library does the work of
determining the file type and creating an appropriate emulator. If you
want more control over this process, read on.
There are two basic ways to identify a game music file's type: look at
its file extension, or read the header data. The library includes
functions to help with both methods. The first is preferable because it
is fast and the most common way to identify files. Sometimes the
extension is lost or wrong, so the header must be read.
Use gme_identify_extension() to find the correct game music type based
on a filename. To identify a file based on its extension and header
contents, use gme_identify_file(). If you read the header data yourself,
use gme_identify_header().
If you want to remove support for some music types to reduce your
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
support just NSF and GBS, use this:
#define GME_TYPE_LIST \
gme_nsf_type,\
gme_gbs_type
M3U playlist support
--------------------
The library supports playlists in an extended m3u format with
gme_load_m3u() to give track names and times to multi-song formats: AY,
GBS, HES, KSS, NSF, NSFE, and SAP. Some aspects of the file format
itself is not well-defined so some m3u files won't work properly
(particularly those provided with KSS files). Only m3u files referencing
a single file are supported; your code must handle m3u files covering
more than one game music file, though it can use the built-in m3u
parsing provided by the library.
Information fields
------------------
Support is provided for the various text fields and length information
in a file with gme_track_info(). If you just need track information for
a file (for example, building a playlist), use gme_new_info() in place
of gme_new_emu(), load the file normally, then you can access the track
count and info, but nothing else.
M3U VGM GYM SPC SAP NSFE NSF AY GBS HES KSS
-------------------------------------------------------
Track Count | * * * * * * * * *
|
System | * * * * * * * * * *
|
Game | * * * * * * *
|
Song | * * * * * * *
|
Author | * * * * * * * *
|
Copyright | * * * * * * * *
|
Comment | * * * *
|
Dumper | * * * *
|
Length | * * * * * *
|
Intro Length| * * *
|
Loop Length | * * *
As listed above, the HES and KSS file formats don't include a track
count, and tracks are often scattered over the 0-255 range, so an m3u
playlist for these is a must.
Unavailable text fields are set to an empty string and times to -1. Your
code should be prepared for any combination of available and unavailable
fields, as a particular music file might not use all of the supported
fields listed above.
Currently text fields are truncated to 255 characters. Obscure fields of
some formats are not currently decoded; contact me if you want one
added.
Track length
------------
The library leaves it up to you as to when to stop playing a track. You
can ask for available length information and then tell the library what
time it should start fading the track with gme_set_fade(). By default it
also continually checks for 6 or more seconds of silence to mark the end
of a track. Here is a reasonable algorithm you can use to decide how
long to play a track:
* If the track length is > 0, use it
* If the loop length > 0, play for intro + loop * 2
* Otherwise, default to 2.5 minutes (150000 msec)
If you want to play a track longer than normal, be sure the loop length
isn't zero. See Music_Player.cpp around line 145 for example code.
By default, the library skips silence at the beginning of a track. It
also continually checks for the end of a non-looping track by watching
for 6 seconds of unbroken silence. When doing this is scans *ahead* by
several seconds so it can report the end of the track after only one
second of silence has actually played. This feature can be disabled with
gme_ignore_silence().
Loading file data
-----------------
The library allows file data to be loaded in many different ways. All
load functions return an error which you should check. The following
examples assume these variables:
Music_Emu* emu;
gme_err_t error;
If you're letting the library determine a file's type, you can use
either gme_open_file() or gme_open_data():
error = gme_open_file( pathname, &emu );
error = gme_open_data( pointer, size, &emu );
If you're manually determining file type and using used gme_new_emu() to
create an emulator, you can use the following methods of loading:
* From a block of memory:
error = gme_load_data( emu, pointer, size );
* Have library call your function to read data:
gme_err_t my_read( void* my_data, void* out, long count )
{
// code that reads 'count' bytes into 'out' buffer
// and return 0 if no error
}
error = gme_load_custom( emu, my_read, file_size, my_data );
Sound parameters
----------------
All emulators support an arbitrary output sampling rate. A rate of 44100
Hz should work well on most systems. Since band-limited synthesis is
used, a sampling rate above 48000 Hz is not necessary and will actually
reduce sound quality and performance.
All emulators also support adjustable gain, mainly for the purpose of
getting consistent volume between different music formats and avoiding
excessive modulation. The gain can only be set *before* setting the
emulator's sampling rate, so it's not useful as a general volume
control. The default gains of emulators are set so that they give
generally similar volumes, though some soundtracks are significantly
louder or quieter than normal.
Some emulators support adjustable treble and bass frequency equalization
(AY, GBS, HES, KSS, NSF, NSFE, SAP, VGM) using set_equalizer().
Parameters are specified using gme_equalizer_t eq = { treble_dB,
bass_freq }. Treble_dB sets the treble level (in dB), where 0.0 dB gives
normal treble; -200.0 dB is quite muffled, and 5.0 dB emphasizes treble
for an extra crisp sound. Bass_freq sets the frequency where bass
response starts to diminish; 15 Hz is normal, 0 Hz gives maximum bass,
and 15000 Hz removes all bass. For example, the following makes the
sound extra-crisp but lacking bass:
gme_equalizer_t eq = { 5.0, 1000 };
gme_set_equalizer( music_emu, &eq );
Each emulator's equalization defaults to approximate the particular
console's sound quality; this default can be determined by calling
equalizer() just after creating the emulator. The Music_Emu::tv_eq
profile gives sound as if coming from a TV speaker, and some emulators
include other profiles for different versions of the system. For
example, to use Famicom sound equalization with the NSF emulator, do the
following:
music_emu->set_equalizer( Nsf_Emu::famicom_eq );
VGM/GYM YM2413 & YM2612 FM sound
--------------------------------
The library plays Sega Genesis/Mega Drive music using a YM2612 FM sound
chip emulator based on the Gens project. Because this has some
inaccuracies, other YM2612 emulators can be used in its place by
re-implementing the interface in YM2612_Emu.h. Available on my website
is a modified version of MAME's YM2612 emulator, which sounds better in
some ways and whose author is still making improvements.
VGM music files using the YM2413 FM sound chip are also supported, but a
YM2413 emulator isn't included with the library due to technical
reasons. I have put one of the available YM2413 emulators on my website
that can be used directly.
Modular construction
--------------------
The library is made of many fairly independent modules. If you're using
only one music file emulator, you can eliminate many of the library
sources from your program. Refer to the files list in readme.txt to get
a general idea of what can be removed, and be sure to edit GME_TYPE_LIST
(see "Emulator types" above). Post to the forum if you'd like me to put
together a smaller version for a particular use, as this only takes me a
few minutes to do.
If you want to use one of the individual sound chip emulators (or CPU
cores) in your own console emulator, first check the libraries page on
my website since I have released several of them as stand alone
libraries with included documentation and examples on their use. If you
don't find it as a standalone library, contact me and I'll consider
separating it.
The "classic" sound chips use my Blip_Buffer library, which greatly
simplifies their implementation and efficiently handles band-limited
synthesis. It is also available as a stand alone library with
documentation and many examples.
Obscure features
----------------
The library's flexibility allows many possibilities. Contact me if you
want help implementing ideas or removing limitations.
* Uses no global/static variables, allowing multiple instances of any
emulator. This is useful in a music player if you want to allow
simultaneous recording or scanning of other tracks while one is already
playing. This will also be useful if your platform disallows global
data.
* Emulators that support a custom sound buffer can have *every* voice
routed to a different Blip_Buffer, allowing custom processing on each
voice. For example you could record a Game Boy track as a 4-channel
sound file.
* Defining BLIP_BUFFER_FAST uses lower quality, less-multiply-intensive
synthesis on "classic" emulators, which might help on some really old
processors. This significantly lowers sound quality and prevents treble
equalization. Try this if your platform's processor isn't fast enough
for normal quality. Even on my ten-year-old 400 MHz Mac, this reduces
processor usage at most by about 0.6% (from 4% to 3.4%), hardly worth
the quality loss.
Solving problems
----------------
If you're having problems, try the following:
* If you're getting garbled sound, try this simple siren generator in
place of your call to play(). This will quickly tell whether the problem
is in the library or in your code.
static void play_siren( long count, short* out )
{
static double a, a2;
while ( count-- )
*out++ = 0x2000 * sin( a += .1 + .05*sin( a2+=.00005 ) );
}
* Enable debugging support in your environment. This enables assertions
and other run-time checks.
* Turn the compiler's optimizer is off. Sometimes an optimizer generates
bad code.
* If multiple threads are being used, ensure that only one at a time is
accessing a given set of objects from the library. This library is not
in general thread-safe, though independent objects can be used in
separate threads.
* If all else fails, see if the demos work.
Thanks
------
Big thanks to Chris Moeller (kode54) for help with library testing and
feedback, for maintaining the Foobar2000 plugin foo_gep based on it, and
for original work on openspc++ that was used when developing Spc_Emu.
Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
and giving feedback for the library in their respective game music
players. More recently, Lucas Paul and Michael Pyne have helped nudge the
library into a public repository and get its interface more stable for use
in shared libraries.
+89
View File
@@ -0,0 +1,89 @@
/* Included at the beginning of library source files, after all other #include lines.
* Sets up helpful macros and services used in my source code. They don't need
* module an annoying module prefix on their names since they are defined after
* all other #include lines. */
#ifndef BLARGG_SOURCE_H
#define BLARGG_SOURCE_H
/* If debugging is enabled, abort program if expr is false. Meant for checking
* internal state and consistency. A failed assertion indicates a bug in the module.
* void assert( bool expr ); */
#include <assert.h>
/* If debugging is enabled and expr is false, abort program. Meant for checking
* caller-supplied parameters and operations that are outside the control of the
* module. A failed requirement indicates a bug outside the module.
* void require( bool expr ); */
#undef require
#define require( expr ) assert( expr )
/* Use to provide hints to compiler for optimized code layout in situations where we
* can almost always expect a conditional to go one way or the other. Should only be
* used in situations where an unexpected branch is truly exceptional though! */
#undef likely
#undef unlikely
#ifdef __GNUC__
#define likely( x ) __builtin_expect(x, 1)
#define unlikely( x ) __builtin_expect(x, 0)
#else
#define likely( x ) (x)
#define unlikely( x ) (x)
#endif
/* Like printf() except output goes to debug log file. Might be defined to do
* nothing (not even evaluate its arguments).
* void debug_printf( const char* format, ... ); */
#if defined(__cplusplus)
static inline void blargg_dprintf_( const char* fmt_str, ... ) { (void) fmt_str; }
#undef debug_printf
#define debug_printf (1) ? (void) 0 : blargg_dprintf_
#endif
/* If enabled, evaluate expr and if false, make debug log entry with source file
* and line. Meant for finding situations that should be examined further, but that
* don't indicate a problem. In all cases, execution continues normally. */
#undef check
#define check( expr ) ((void) 0)
/* If expr yields error string, return it from current function, otherwise continue. */
#undef RETURN_ERR
#define RETURN_ERR( expr ) do { \
blargg_err_t blargg_return_err_ = (expr); \
if ( blargg_return_err_ ) return blargg_return_err_; \
} while ( 0 )
/* If ptr is 0, return out of memory error string. */
#undef CHECK_ALLOC
#define CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
/* TODO: good idea? bad idea? */
#undef byte
#define byte byte_
typedef unsigned char byte;
/* Setup compiler defines useful for exporting required public API symbols in gme.cpp */
#ifndef BLARGG_EXPORT
#if defined (_WIN32)
#if defined(BLARGG_BUILD_DLL)
#define BLARGG_EXPORT __declspec(dllexport)
#else
#define BLARGG_EXPORT /* Leave blank: friendly with both static and shared linking */
#endif
#elif defined (LIBGME_VISIBILITY) && defined(__cplusplus)
#define BLARGG_EXPORT __attribute__((visibility ("default")))
#else
#define BLARGG_EXPORT
#endif
#endif
/* deprecated */
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
#define BLARGG_RETURN_ERR RETURN_ERR
/* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check */
#ifdef BLARGG_SOURCE_BEGIN
#include BLARGG_SOURCE_BEGIN
#endif
#endif
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
+504 -504
View File
File diff suppressed because it is too large. Load diff
+231 -231
View File
@@ -1,231 +1,231 @@
Game_Music_Emu 0.6.2: Game Music Emulators
------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems:
AY ZX Spectrum/Amstrad CPC
GBS Nintendo Game Boy
GYM Sega Genesis/Mega Drive
HES NEC TurboGrafx-16/PC Engine
KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
SAP Atari systems using POKEY sound chip
SPC Super Nintendo/Super Famicom
VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
Features:
* C interface for use in C, C++, and other compatible languages
* High emphasis has been placed on making the library very easy to use
* One set of common functions work with all emulators the same way
* Several code examples, including music player using SDL
* Portable code for use on any system with modern or older C++ compilers
* Adjustable output sample rate using quality band-limited resampling
* Uniform access to text information fields and track timing information
* End-of-track fading and automatic look ahead silence detection
* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
* Tempo can be adjusted and individual voices can be muted while playing
* Can read music data from file, memory, or custom reader function/class
* Can access track information without having to load into full emulator
* M3U track listing support for multi-track formats
* Modular design allows elimination of unneeded emulators/features
This library has been used in game music players for Windows, Linux on
several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
GP2X, and Nintendo DS.
Author : Shay Green <gblargg@gmail.com>
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
License: GNU Lesser General Public License (LGPL)
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
Getting Started
---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
all source files in gme/.
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
extracted source directory):
mkdir build
cd build
cmake ../ # <-- Pass any needed CMake flags here
make # To build the library
cd demo
make # To build the demo itself
Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav".
You can use "make install" to install the library. To choose where to install
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
(and replace /usr/local with the base path you wish to use). Alternately, you
can specify the base path to install to when you run "make install" by passing
'DESTDIR=/usr/local' on the make install command line (again, replace
/usr/local as appropriate).
To build a static library instead of shared (the default), pass
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
A slightly more extensive demo application is available in the player/
directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for
assistance.
Files
-----
gme.txt General notes about the library
changes.txt Changes made since previous releases
design.txt Library design notes
license.txt GNU Lesser General Public License
CMakeLists.txt CMake build rules
test.nsf Test file for NSF emulator
test.m3u Test m3u playlist for features.c demo
demo/
basics.c Records NSF file to wave sound file
features.c Demonstrates many additional features
Wave_Writer.h WAVE sound file writer used for demo output
Wave_Writer.cpp
CMakeLists.txt CMake build rules
player/ Player using the SDL multimedia library
player.cpp Simple music player with waveform display
Music_Player.cpp Stand alone player for background music
Music_Player.h
Audio_Scope.cpp Audio waveform scope
Audio_Scope.h
CMakeLists.txt CMake build rules
gme/
blargg_config.h Library configuration (modify this file as needed)
gme.h Library interface header file
gme.cpp
Ay_Emu.h ZX Spectrum AY emulator
Ay_Emu.cpp
Ay_Apu.cpp
Ay_Apu.h
Ay_Cpu.cpp
Ay_Cpu.h
Gbs_Emu.h Nintendo Game Boy GBS emulator
Gbs_Emu.cpp
Gb_Apu.cpp
Gb_Apu.h
Gb_Cpu.cpp
Gb_Cpu.h
gb_cpu_io.h
Gb_Oscs.cpp
Gb_Oscs.h
Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
Hes_Apu.cpp
Hes_Apu.h
Hes_Cpu.cpp
Hes_Cpu.h
hes_cpu_io.h
Hes_Emu.cpp
Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
Kss_Emu.cpp
Kss_Cpu.cpp
Kss_Cpu.h
Kss_Scc_Apu.cpp
Kss_Scc_Apu.h
Ay_Apu.h
Ay_Apu.cpp
Sms_Apu.h
Sms_Apu.cpp
Sms_Oscs.h
Nsf_Emu.h Nintendo NES NSF/NSFE emulator
Nsf_Emu.cpp
Nes_Apu.cpp
Nes_Apu.h
Nes_Cpu.cpp
Nes_Cpu.h
nes_cpu_io.h
Nes_Oscs.cpp
Nes_Oscs.h
Nes_Fme7_Apu.cpp
Nes_Fme7_Apu.h
Nes_Namco_Apu.cpp
Nes_Namco_Apu.h
Nes_Vrc6_Apu.cpp
Nes_Vrc6_Apu.h
Nsfe_Emu.h NSFE support
Nsfe_Emu.cpp
Spc_Emu.h Super Nintendo SPC emulator
Spc_Emu.cpp
Snes_Spc.cpp
Snes_Spc.h
Spc_Cpu.cpp
Spc_Cpu.h
Spc_Dsp.cpp
Spc_Dsp.h
Fir_Resampler.cpp
Fir_Resampler.h
Sap_Emu.h Atari SAP emulator
Sap_Emu.cpp
Sap_Apu.cpp
Sap_Apu.h
Sap_Cpu.cpp
Sap_Cpu.h
sap_cpu_io.h
Vgm_Emu.h Sega VGM emulator
Vgm_Emu_Impl.cpp
Vgm_Emu_Impl.h
Vgm_Emu.cpp
Ym2413_Emu.cpp
Ym2413_Emu.h
Gym_Emu.h Sega Genesis GYM emulator
Gym_Emu.cpp
Sms_Apu.cpp Common Sega emulator files
Sms_Apu.h
Sms_Oscs.h
Ym2612_Emu.cpp
Ym2612_Emu.h
Dual_Resampler.cpp
Dual_Resampler.h
Fir_Resampler.cpp
Fir_Resampler.h
M3u_Playlist.h M3U playlist support
M3u_Playlist.cpp
Effects_Buffer.h Sound buffer with stereo echo and panning
Effects_Buffer.cpp
blargg_common.h Common files needed by all emulators
blargg_endian.h
blargg_source.h
Blip_Buffer.cpp
Blip_Buffer.h
Gme_File.h
Gme_File.cpp
Music_Emu.h
Music_Emu.cpp
Classic_Emu.h
Classic_Emu.cpp
Multi_Buffer.h
Multi_Buffer.cpp
Data_Reader.h
Data_Reader.cpp
CMakeLists.txt CMake build rules
Legal
-----
Game_Music_Emu library copyright (C) 2003-2009 Shay Green.
Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
--
Shay Green <gblargg@gmail.com>
Game_Music_Emu 0.6.2: Game Music Emulators
------------------------------------------
Game_Music_Emu is a collection of video game music file emulators that
support the following formats and systems:
AY ZX Spectrum/Amstrad CPC
GBS Nintendo Game Boy
GYM Sega Genesis/Mega Drive
HES NEC TurboGrafx-16/PC Engine
KSS MSX Home Computer/other Z80 systems (doesn't support FM sound)
NSF/NSFE Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
SAP Atari systems using POKEY sound chip
SPC Super Nintendo/Super Famicom
VGM/VGZ Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
Features:
* C interface for use in C, C++, and other compatible languages
* High emphasis has been placed on making the library very easy to use
* One set of common functions work with all emulators the same way
* Several code examples, including music player using SDL
* Portable code for use on any system with modern or older C++ compilers
* Adjustable output sample rate using quality band-limited resampling
* Uniform access to text information fields and track timing information
* End-of-track fading and automatic look ahead silence detection
* Treble/bass and stereo echo for AY/GBS/HES/KSS/NSF/NSFE/SAP/VGM
* Tempo can be adjusted and individual voices can be muted while playing
* Can read music data from file, memory, or custom reader function/class
* Can access track information without having to load into full emulator
* M3U track listing support for multi-track formats
* Modular design allows elimination of unneeded emulators/features
This library has been used in game music players for Windows, Linux on
several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
GP2X, and Nintendo DS.
Author : Shay Green <gblargg@gmail.com>
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
License: GNU Lesser General Public License (LGPL)
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
Getting Started
---------------
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
all source files in gme/.
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
extracted source directory):
mkdir build
cd build
cmake ../ # <-- Pass any needed CMake flags here
make # To build the library
cd demo
make # To build the demo itself
Be sure "test.nsf" is in the same directory as the demo program. Running it
should generate the recording "out.wav".
You can use "make install" to install the library. To choose where to install
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
(and replace /usr/local with the base path you wish to use). Alternately, you
can specify the base path to install to when you run "make install" by passing
'DESTDIR=/usr/local' on the make install command line (again, replace
/usr/local as appropriate).
To build a static library instead of shared (the default), pass
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
A slightly more extensive demo application is available in the player/
directory. It requires SDL to build.
Read gme.txt for more information. Post to the discussion forum for
assistance.
Files
-----
gme.txt General notes about the library
changes.txt Changes made since previous releases
design.txt Library design notes
license.txt GNU Lesser General Public License
CMakeLists.txt CMake build rules
test.nsf Test file for NSF emulator
test.m3u Test m3u playlist for features.c demo
demo/
basics.c Records NSF file to wave sound file
features.c Demonstrates many additional features
Wave_Writer.h WAVE sound file writer used for demo output
Wave_Writer.cpp
CMakeLists.txt CMake build rules
player/ Player using the SDL multimedia library
player.cpp Simple music player with waveform display
Music_Player.cpp Stand alone player for background music
Music_Player.h
Audio_Scope.cpp Audio waveform scope
Audio_Scope.h
CMakeLists.txt CMake build rules
gme/
blargg_config.h Library configuration (modify this file as needed)
gme.h Library interface header file
gme.cpp
Ay_Emu.h ZX Spectrum AY emulator
Ay_Emu.cpp
Ay_Apu.cpp
Ay_Apu.h
Ay_Cpu.cpp
Ay_Cpu.h
Gbs_Emu.h Nintendo Game Boy GBS emulator
Gbs_Emu.cpp
Gb_Apu.cpp
Gb_Apu.h
Gb_Cpu.cpp
Gb_Cpu.h
gb_cpu_io.h
Gb_Oscs.cpp
Gb_Oscs.h
Hes_Emu.h TurboGrafx-16/PC Engine HES emulator
Hes_Apu.cpp
Hes_Apu.h
Hes_Cpu.cpp
Hes_Cpu.h
hes_cpu_io.h
Hes_Emu.cpp
Kss_Emu.h MSX Home Computer/other Z80 systems KSS emulator
Kss_Emu.cpp
Kss_Cpu.cpp
Kss_Cpu.h
Kss_Scc_Apu.cpp
Kss_Scc_Apu.h
Ay_Apu.h
Ay_Apu.cpp
Sms_Apu.h
Sms_Apu.cpp
Sms_Oscs.h
Nsf_Emu.h Nintendo NES NSF/NSFE emulator
Nsf_Emu.cpp
Nes_Apu.cpp
Nes_Apu.h
Nes_Cpu.cpp
Nes_Cpu.h
nes_cpu_io.h
Nes_Oscs.cpp
Nes_Oscs.h
Nes_Fme7_Apu.cpp
Nes_Fme7_Apu.h
Nes_Namco_Apu.cpp
Nes_Namco_Apu.h
Nes_Vrc6_Apu.cpp
Nes_Vrc6_Apu.h
Nsfe_Emu.h NSFE support
Nsfe_Emu.cpp
Spc_Emu.h Super Nintendo SPC emulator
Spc_Emu.cpp
Snes_Spc.cpp
Snes_Spc.h
Spc_Cpu.cpp
Spc_Cpu.h
Spc_Dsp.cpp
Spc_Dsp.h
Fir_Resampler.cpp
Fir_Resampler.h
Sap_Emu.h Atari SAP emulator
Sap_Emu.cpp
Sap_Apu.cpp
Sap_Apu.h
Sap_Cpu.cpp
Sap_Cpu.h
sap_cpu_io.h
Vgm_Emu.h Sega VGM emulator
Vgm_Emu_Impl.cpp
Vgm_Emu_Impl.h
Vgm_Emu.cpp
Ym2413_Emu.cpp
Ym2413_Emu.h
Gym_Emu.h Sega Genesis GYM emulator
Gym_Emu.cpp
Sms_Apu.cpp Common Sega emulator files
Sms_Apu.h
Sms_Oscs.h
Ym2612_Emu.cpp
Ym2612_Emu.h
Dual_Resampler.cpp
Dual_Resampler.h
Fir_Resampler.cpp
Fir_Resampler.h
M3u_Playlist.h M3U playlist support
M3u_Playlist.cpp
Effects_Buffer.h Sound buffer with stereo echo and panning
Effects_Buffer.cpp
blargg_common.h Common files needed by all emulators
blargg_endian.h
blargg_source.h
Blip_Buffer.cpp
Blip_Buffer.h
Gme_File.h
Gme_File.cpp
Music_Emu.h
Music_Emu.cpp
Classic_Emu.h
Classic_Emu.cpp
Multi_Buffer.h
Multi_Buffer.cpp
Data_Reader.h
Data_Reader.cpp
CMakeLists.txt CMake build rules
Legal
-----
Game_Music_Emu library copyright (C) 2003-2009 Shay Green.
Sega Genesis YM2612 emulator copyright (C) 2002 Stephane Dallongeville.
--
Shay Green <gblargg@gmail.com>
+9 -8
View File
@@ -1,5 +1,5 @@
/* backtrace.h -- Public header file for stack backtrace library.
Copyright (C) 2012-2020 Free Software Foundation, Inc.
Copyright (C) 2012-2021 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
@@ -54,13 +54,14 @@ struct backtrace_state;
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, but the function
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The
MSG in this case will be something along the lines of "no debug
info". Similarly, ERRNUM will be passed as -1 if there is no
symbol table, but the function requires a symbol table (e.g.,
backtrace_syminfo). This may be used as a signal that some other
approach should be tried. */
debug info can be found for the executable, or if the debug info
exists but has an unsupported version, but the function requires
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
this case will be something along the lines of "no debug info".
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
but the function requires a symbol table (e.g., backtrace_syminfo).
This may be used as a signal that some other approach should be
tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);
Binary file not shown.
+3
View File
@@ -3,6 +3,9 @@ SRB2.res
depend.dep
depend.ped
*.o
buildvm*
minilua*
lj_vm.S
#VC9 folder only
/VC9/Win32
/VC9/x64
-1
View File
@@ -1,4 +1,3 @@
/cscope.out
/srb2wii
*.json
*.idx
+39 -25
View File
@@ -68,7 +68,6 @@ ALL_SYSTEMS=\
LINUX64\
MINGW64\
HAIKU\
DUMMY\
MINGW\
UNIX\
LINUX\
@@ -158,17 +157,6 @@ endif
include Makefile.cfg
ifdef DUMMY
NOPNG=1
NOZLIB=1
NONET=1
NOHW=1
NOIPX=1
EXENAME?=srb2dummy
OBJS=$(OBJDIR)/i_video.o
LIBS=-lm
endif
ifdef HAIKU
NOIPX=1
ifndef NONET
@@ -245,6 +233,10 @@ endif
MSGFMT?=msgfmt
ifndef NOBLUAJIT
include bluajit/Makefile.cfg
endif
ifndef ECHO
REMOVE:=@$(REMOVE)
CC:=@$(CC)
@@ -292,15 +284,10 @@ else
endif
else
ifdef X86_64
ARCHOPTS?=-march=nocona
ARCHOPTS?=-march=native
endif
endif
# apparently MingW just completely ignores everything so just always force this shit
# FIXME: we should port our code to c24
CFLAGS+=-std=gnu17
CPPFLAGS+=-std=gnu17
ifndef NOPNG
OPTS+=-DHAVE_PNG
@@ -414,7 +401,10 @@ CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN
OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o
endif
ifdef NOBLUAJIT
OPTS+=-DNOBLUAJIT
include blua/Makefile.cfg
endif
ifdef NOMD5
OPTS+=-DNOMD5
@@ -610,10 +600,6 @@ ifdef SDL
all: pre-build $(BIN)/$(EXENAME)
endif
ifdef DUMMY
all: $(BIN)/$(EXENAME)
endif
cleandep:
$(REMOVE) $(OBJDIR)/depend.dep
$(REMOVE) comptime.h
@@ -628,6 +614,13 @@ endif
clean:
$(REMOVE) *~ *.flc
$(REMOVE) $(OBJDIR)/*.o
ifndef NOBLUAJIT
$(REMOVE) $(OBJDIR)/buildvm* $(OBJDIR)/minilua* $(OBJDIR)/lj_vm* $(ALL_HDRGEN)
cleanjit:
$(REMOVE) $(LJVMCORE_O) $(ALL_GEN)
$(REMOVE) $(OBJDIR)/buildvm* $(OBJDIR)/minilua* $(OBJDIR)/lj_vm* $(ALL_HDRGEN)
endif
ifdef MINGW
$(REMOVE) $(OBJDIR)/*.res
@@ -643,7 +636,7 @@ endif
$(BIN)/$(EXENAME): $(POS) $(OBJS)
-$(MKDIR) $(BIN)
@echo Linking $(EXENAME)...
$(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS)
$(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) -lstdc++
ifndef VALGRIND
ifndef NOOBJDUMP
@echo Dumping debugging info
@@ -734,21 +727,34 @@ endif
#dependecy made by gcc itself !
$(OBJS):
ifndef DUMMY
-include $(OBJDIR)/depend.dep
endif
$(OBJDIR)/depend.dep:
@echo "Creating dependency file, depend.dep"
@echo > comptime.h
-$(MKDIR) $(OBJDIR)
$(CC) $(CFLAGS) -MM *.c > $(OBJDIR)/depend.ped
$(CXX) $(CXXFLAGS) -MM *.cpp >> $(OBJDIR)/depend.ped
$(CC) $(CFLAGS) -MM $(INTERFACE)/*.c >> $(OBJDIR)/depend.ped
ifndef NOHW
$(CC) $(CFLAGS) -MM hardware/*.c >> $(OBJDIR)/depend.ped
endif
ifdef NOBLUAJIT
$(CC) $(CFLAGS) -MM blua/*.c >> $(OBJDIR)/depend.ped
else
@for file in $(ALL_HDRGEN); do \
test -f $$file || touch $$file; \
done
@$(HOST_CC) $(HOST_ACFLAGS) -MM bluajit/*.c bluajit/host/*.c | \
sed -e "s| [^ ]*/dasm_\S*\.h||g" \
-e "s| lj_target_\S*\.h| lj_target_*.h|g" \
-e "s| lj_emit_\S*\.h| lj_emit_*.h|g" \
-e "s| lj_asm_\S*\.h| lj_asm_*.h|g" >>$(OBJDIR)/depend.ped
@for file in $(ALL_HDRGEN); do \
test -s $$file || $(HOST_RM) $$file; \
done
endif
@sed -e 's,\(.*\)\.o: ,$(subst /,\/,$(OBJDIR))\/&,g' < $(OBJDIR)/depend.ped > $(OBJDIR)/depend.dep
$(REMOVE) $(OBJDIR)/depend.ped
@@ -780,8 +786,16 @@ endif
$(OBJDIR)/%.o: hardware/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
ifdef NOBLUAJIT
$(OBJDIR)/%.o: blua/%.c
$(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@
else
include bluajit/Makefile.cfg2
endif
# C++
$(OBJDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(WFLAGS) -c $< -o $@
$(OBJDIR)/%.o: %.s
$(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@
-10
View File
@@ -489,7 +489,6 @@ ifndef CYGWIN32
ifndef MINGW
ifndef MINGW64
ifndef SDL
ifndef DUMMY
$(error No interface or platform flag defined)
endif
endif
@@ -497,7 +496,6 @@ endif
endif
endif
endif
endif
#determine the interface directory (where you put all i_*.c)
i_net_o=$(OBJDIR)/i_net.o
@@ -522,11 +520,6 @@ UPX_OPTS+=-q
endif
#Interface Setup
ifdef DUMMY
INTERFACE=dummy
OBJDIR:=$(OBJDIR)/dummy
BIN:=$(BIN)/dummy
else
ifdef LINUX
SDL=1
ifdef LINUX64
@@ -573,7 +566,6 @@ endif
endif
endif
endif
endif
ifdef ARCHNAME
OBJDIR:=$(OBJDIR)/$(ARCHNAME)
@@ -588,7 +580,6 @@ ifdef SDL
OBJDIR:=$(OBJDIR)/SDL
endif
ifndef DUMMY
ifdef DEBUGMODE
OBJDIR:=$(OBJDIR)/Debug
BIN:=$(BIN)/Debug
@@ -596,4 +587,3 @@ else
OBJDIR:=$(OBJDIR)/Release
BIN:=$(BIN)/Release
endif
endif
+4 -3
View File
@@ -312,12 +312,13 @@ static void AM_initVariables(void)
m_h = FTOM(f_h);
// find player to center on initially
if (!playeringame[pnum = consoleplayer])
if (!players[pnum = consoleplayer].ingame)
for (pnum = 0; pnum < MAXPLAYERS; pnum++)
if (playeringame[pnum])
if (players[pnum].ingame)
break;
plr = &players[pnum];
if (plr != NULL && plr->mo != NULL)
{
m_x = (plr->mo->x >> FRACTOMAPBITS) - m_w/2;
@@ -1227,7 +1228,7 @@ static inline void AM_drawPlayers(void)
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
if (!players[i].ingame || players[i].spectator)
continue;
if (!players[i].mo)
+2
View File
@@ -49,7 +49,9 @@ OBJS:=$(OBJS) \
$(OBJDIR)/lua_skinlib.o \
$(OBJDIR)/lua_thinkerlib.o \
$(OBJDIR)/lua_maplib.o \
$(OBJDIR)/hashtable.o \
$(OBJDIR)/lua_hudlib.o \
$(OBJDIR)/lua_hudlib_drawlist.o \
$(OBJDIR)/lua_udatalib.o \
$(OBJDIR)/lua_glib.o
+5 -70
View File
@@ -17,27 +17,14 @@
#include "lauxlib.h"
#include "lualib.h"
#include "../i_system.h"
#include "../doomdef.h"
#include "../d_main.h"
#include "../m_misc.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
#define FILELIMIT 1024*1024 // Size limit for reading/writing files
static const char *const fnames[] = {"input", "output"};
static const char *whitelist[] = { // Allow scripters to write files of these types to SRB2's folder
".txt",
".sav2",
".cfg",
".png",
".bmp"
};
static int pushresult (lua_State *L, int i, const char *filename) {
@@ -159,59 +146,12 @@ static int io_tostring (lua_State *L) {
return 1;
}
static int StartsWith(const char *a, const char *b) // this is wolfs being lazy yet again
{
if(strncmp(a, b, strlen(b)) == 0) return 1;
return 0;
}
static int io_open (lua_State *L) {
FILE **pf;
const char *filename = luaL_checkstring(L, 1);
int pass = 0;
size_t i;
int length = strlen(filename);
char *splitter, *forward, *backward;
char *destFilename;
const char *mode = luaL_optstring(L, 2, "r");
for (i = 0; i < (sizeof (whitelist) / sizeof(const char *)); i++)
{
if (!stricmp(&filename[length - strlen(whitelist[i])], whitelist[i]))
{
pass = 1;
break;
}
}
if (strstr(filename, "..") || strchr(filename, ':') || StartsWith(filename, "\\")
|| StartsWith(filename, "/") || !pass)
{
luaL_error(L,"access denied to %s", filename);
return pushresult(L,0,filename);
}
destFilename = va("%s"PATHSEP"luafiles"PATHSEP"%s", srb2home, filename);
// Make directories as needed
splitter = destFilename;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
while ((splitter = (forward && backward) ? min(forward, backward) : (forward ?: backward)))
{
*splitter = 0;
I_mkdir(destFilename, 0755);
*splitter = '/';
splitter++;
forward = strchr(splitter, '/');
backward = strchr(splitter, '\\');
}
pf = newfile(L);
*pf = fopen(destFilename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
@@ -454,11 +394,6 @@ static int g_write (lua_State *L, FILE *f, int arg) {
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
if (ftell(f) + l > FILELIMIT)
{
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
}
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
+9
View File
@@ -0,0 +1,9 @@
luajit
luajit.h
luajit_relver.txt
lj_bcdef.h
lj_ffdef.h
lj_libdef.h
lj_recdef.h
lj_folddef.h
lj_vm.[sS]
+408
View File
@@ -0,0 +1,408 @@
##############################################################################
# LuaJIT Makefile. Requires GNU Make.
#
# Please read doc/install.html before changing any variables!
#
# Suitable for POSIX platforms (Linux, *BSD, OSX etc.).
# Also works with MinGW and Cygwin on Windows.
# Please check msvcbuild.bat for building with MSVC on Windows.
#
# Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
##############################################################################
# this is a very dumbed down version of the LuaJIT makefile.
# to get the original makefile, visit
# https://github.com/GenericHeroGuy/bluajit
XCFLAGS=
XCFLAGS+= -DLUAJIT_DISABLE_FFI
#XCFLAGS+= -DLUAJIT_ENABLE_LUA52COMPAT
#XCFLAGS+= -DLUAJIT_DISABLE_JIT
#XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
#XCFLAGS+= -DLUAJIT_USE_VALGRIND
#XCFLAGS+= -DLUAJIT_USE_GDBJIT
#XCFLAGS+= -DLUA_USE_APICHECK
#XCFLAGS+= -DLUA_USE_ASSERT
XCFLAGS+= -DLUAJIT_DISABLE_BYTECODE
# load standard libraries in debug mode, so jit.dump etc works
ifndef DEBUGMODE
XCFLAGS+= -DLUAJIT_SRB2LIB -DLUAJIT_DISABLE_BUFFER
endif
# additional functions
#XCFLAGS+= -DLUAJIT_SRB2LIB_OS
XCFLAGS+= -DLUAJIT_SRB2LIB_DEBUG
XCFLAGS+= -DLUAJIT_SRB2LIB_IO
# don't touch these unless you wanna have a bad time
XCFLAGS+= -DLUAJIT_NUMMODE=2
XCFLAGS+= -DLUAJIT_INTONLY
# needed for the headers
OPTS+=-DLUAJIT_INTONLY
ifdef MINGW
TARGET_SYS= Windows
HOST_MSYS= mingw
endif
ifeq (Windows,$(findstring Windows,$(OS))$(MSYSTEM)$(TERM))
HOST_SYS= Windows
else
HOST_SYS:= $(shell uname -s)
ifneq (,$(findstring MINGW,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= mingw
endif
ifneq (,$(findstring MSYS,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= mingw
endif
ifneq (,$(findstring CYGWIN,$(HOST_SYS)))
HOST_SYS= Windows
HOST_MSYS= cygwin
endif
endif
ASOPTIONS= $(CCOPT) $(XCFLAGS) $(CFLAGS)
CCOPTIONS= $(ASOPTIONS)
HOST_CC= $(CC)
HOST_RM?= rm -f
HOST_XCFLAGS= -Ibluajit
HOST_XLIBS=
HOST_ACFLAGS= $(XCFLAGS) $(HOST_XCFLAGS) $(TARGET_ARCH)
TARGET_CC= $(CROSS)$(CC)
TARGET_LFSFLAGS= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
TARGET_XCFLAGS= $(TARGET_LFSFLAGS) -U_FORTIFY_SOURCE
TARGET_XLIBS= -lm
TARGET_ACFLAGS= $(CCOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS)
TARGET_ASFLAGS= $(ASOPTIONS) $(TARGET_XCFLAGS) $(TARGET_FLAGS)
TARGET_ACFLAGS+= $(LUA_CFLAGS)
TARGET_TESTARCH:=$(shell $(TARGET_CC) $(TARGET_ACFLAGS) -E bluajit/lj_arch.h -dM)
ifneq (,$(findstring LJ_TARGET_X64 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x64
else
ifneq (,$(findstring LJ_TARGET_X86 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= x86
else
ifneq (,$(findstring LJ_TARGET_ARM ,$(TARGET_TESTARCH)))
TARGET_LJARCH= arm
else
ifneq (,$(findstring LJ_TARGET_ARM64 ,$(TARGET_TESTARCH)))
ifneq (,$(findstring __AARCH64EB__ ,$(TARGET_TESTARCH)))
TARGET_ARCH= -D__AARCH64EB__=1
endif
TARGET_LJARCH= arm64
else
ifneq (,$(findstring LJ_TARGET_PPC ,$(TARGET_TESTARCH)))
ifneq (,$(findstring LJ_LE 1,$(TARGET_TESTARCH)))
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_LE
else
TARGET_ARCH= -DLJ_ARCH_ENDIAN=LUAJIT_BE
endif
TARGET_LJARCH= ppc
else
ifneq (,$(findstring LJ_TARGET_MIPS ,$(TARGET_TESTARCH)))
ifneq (,$(findstring MIPSEL ,$(TARGET_TESTARCH)))
TARGET_ARCH= -D__MIPSEL__=1
endif
ifneq (,$(findstring LJ_TARGET_MIPS64 ,$(TARGET_TESTARCH)))
TARGET_LJARCH= mips64
else
TARGET_LJARCH= mips
endif
else
$(error Unsupported target architecture)
endif
endif
endif
endif
endif
endif
ifneq (,$(findstring LJ_TARGET_PS3 1,$(TARGET_TESTARCH)))
TARGET_SYS= PS3
TARGET_ARCH+= -D__CELLOS_LV2__
TARGET_XCFLAGS+= -DLUAJIT_USE_SYSMALLOC
TARGET_XLIBS+= -lpthread
endif
TARGET_ARCH+= $(patsubst %,-DLUAJIT_TARGET=LUAJIT_ARCH_%,$(TARGET_LJARCH))
ifneq (,$(PREFIX))
ifneq (/usr/local,$(PREFIX))
TARGET_XCFLAGS+= -DLUA_ROOT=\"$(PREFIX)\"
endif
endif
ifneq (,$(MULTILIB))
TARGET_XCFLAGS+= -DLUA_MULTILIB=\"$(MULTILIB)\"
endif
ifneq (,$(LMULTILIB))
TARGET_XCFLAGS+= -DLUA_LMULTILIB=\"$(LMULTILIB)\"
endif
ifneq (,$(INSTALL_LJLIBD))
TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\"
endif
##############################################################################
# Target system detection.
##############################################################################
TARGET_SYS?= $(HOST_SYS)
ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-stack-protector 2>/dev/null || echo 1))
TARGET_XCFLAGS+= -fno-stack-protector
endif
ifeq (Darwin,$(TARGET_SYS))
ifeq (,$(MACOSX_DEPLOYMENT_TARGET))
$(error missing: export MACOSX_DEPLOYMENT_TARGET=XX.YY)
endif
TARGET_XCFLAGS+= -DLUAJIT_UNWIND_EXTERNAL
else
ifeq (iOS,$(TARGET_SYS))
ifeq (arm64,$(TARGET_LJARCH))
TARGET_XCFLAGS+= -fno-omit-frame-pointer
endif
else
ifeq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
# Find out whether the target toolchain always generates unwind tables.
TARGET_TESTUNWIND=$(shell exec 2>/dev/null; echo 'extern void b(void);int a(void){b();return 0;}' | $(TARGET_CC) -c -x c - -o tmpunwind.o && { grep -qa -e eh_frame -e __unwind_info tmpunwind.o || grep -qU -e eh_frame -e __unwind_info tmpunwind.o; } && echo E; rm -f tmpunwind.o)
ifneq (,$(findstring E,$(TARGET_TESTUNWIND)))
TARGET_XCFLAGS+= -DLUAJIT_UNWIND_EXTERNAL
endif
endif
ifeq (Linux,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
ifeq (GNU/kFreeBSD,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
endif
endif
ifneq ($(HOST_SYS),$(TARGET_SYS))
ifeq (Windows,$(TARGET_SYS))
HOST_XCFLAGS+= -malign-double -DLUAJIT_OS=LUAJIT_OS_WINDOWS
else
ifeq (Linux,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_LINUX
else
ifeq (Darwin,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX
else
ifeq (iOS,$(TARGET_SYS))
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OSX -DTARGET_OS_IPHONE=1
else
HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_OTHER
endif
endif
endif
endif
endif
##############################################################################
# Files and pathnames.
##############################################################################
MINILUA_O= $(OBJDIR)/minilua.o
MINILUA_LIBS= -lm
MINILUA_T= $(OBJDIR)/minilua
MINILUA_X= $(MINILUA_T)
MINILUA_DEP=
HOST_LUA= $(MINILUA_X)
MINILUA_DEP= $(MINILUA_T)
DASM_DIR= bluajit/dynasm
DASM= $(HOST_LUA) $(DASM_DIR)/dynasm.lua
DASM_XFLAGS=
DASM_AFLAGS=
DASM_ARCH= $(TARGET_LJARCH)
ifneq (,$(findstring LJ_LE 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D ENDIAN_LE
else
DASM_AFLAGS+= -D ENDIAN_BE
endif
ifneq (,$(findstring LJ_ARCH_BITS 64,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D P64
endif
ifneq (,$(findstring LJ_HASJIT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D JIT
endif
ifneq (,$(findstring LJ_HASFFI 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FFI
endif
ifneq (,$(findstring LJ_DUALNUM 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D DUALNUM
endif
ifneq (,$(findstring LJ_INTONLY 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D INTONLY
endif
ifneq (,$(findstring LJ_ARCH_HASFPU 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D FPU
TARGET_ARCH+= -DLJ_ARCH_HASFPU=1
else
TARGET_ARCH+= -DLJ_ARCH_HASFPU=0
endif
ifeq (,$(findstring LJ_ABI_SOFTFP 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D HFABI
TARGET_ARCH+= -DLJ_ABI_SOFTFP=0
else
TARGET_ARCH+= -DLJ_ABI_SOFTFP=1
endif
ifneq (,$(findstring LJ_NO_UNWIND 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D NO_UNWIND
TARGET_ARCH+= -DLUAJIT_NO_UNWIND
endif
ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D PAUTH
TARGET_ARCH+= -DLJ_ABI_PAUTH=1
endif
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
ifeq (Windows,$(TARGET_SYS))
DASM_AFLAGS+= -D WIN
endif
ifeq (x64,$(TARGET_LJARCH))
ifeq (,$(findstring LJ_FR2 1,$(TARGET_TESTARCH)))
DASM_ARCH= x86
endif
else
ifeq (arm,$(TARGET_LJARCH))
ifeq (iOS,$(TARGET_SYS))
DASM_AFLAGS+= -D IOS
endif
else
ifneq (,$(findstring LJ_TARGET_MIPSR6 ,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D MIPSR6
endif
ifeq (ppc,$(TARGET_LJARCH))
ifneq (,$(findstring LJ_ARCH_SQRT 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D SQRT
endif
ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D ROUND
endif
ifneq (,$(findstring LJ_ARCH_PPC32ON64 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D GPR64
endif
ifeq (PS3,$(TARGET_SYS))
DASM_AFLAGS+= -D PPE -D TOC
endif
endif
endif
endif
DASM_FLAGS= $(DASM_XFLAGS) $(DASM_AFLAGS)
DASM_DASC= bluajit/vm_$(DASM_ARCH).dasc
GIT= git
ifeq (Windows,$(HOST_SYS)$(HOST_MSYS))
GIT_RELVER= if exist ..\.git ( $(GIT) show -s --format=%%ct >bluajit/luajit_relver.txt ) else ( type ..\.relver >bluajit/luajit_relver.txt )
else
GIT_RELVER= [ -e ../.git ] && $(GIT) show -s --format=%ct >bluajit/luajit_relver.txt 2>/dev/null || cat ../.relver >bluajit/luajit_relver.txt 2>/dev/null || :
endif
GIT_DEP= $(wildcard ../.git/HEAD ../.git/refs/heads/*)
BUILDVM_O= $(OBJDIR)/buildvm.o $(OBJDIR)/buildvm_asm.o $(OBJDIR)/buildvm_peobj.o \
$(OBJDIR)/buildvm_lib.o $(OBJDIR)/buildvm_fold.o
BUILDVM_T= $(OBJDIR)/buildvm
BUILDVM_X= $(BUILDVM_T)
HOST_O= $(MINILUA_O) $(BUILDVM_O)
HOST_T= $(MINILUA_T) $(BUILDVM_T)
LJVM_S= $(OBJDIR)/lj_vm.S
LJVM_O= $(OBJDIR)/lj_vm.o
LJVM_BOUT= $(LJVM_S)
LJVM_MODE= elfasm
LJLIB_O= lib_base.o lib_string.o lib_table.o lib_io.o lib_jit.o
ifeq (,$(filter -DLUAJIT_SRB2LIB,$(XCFLAGS)))
LJLIB_O+= lib_math.o lib_bit.o lib_os.o lib_package.o lib_debug.o lib_ffi.o lib_buffer.o
else
ifneq (,$(filter -DLUAJIT_SRB2LIB_OS,$(XCFLAGS)))
LJLIB_O+= lib_os.o
endif
ifneq (,$(filter -DLUAJIT_SRB2LIB_DEBUG,$(XCFLAGS)))
LJLIB_O+= lib_debug.o
endif
endif
LJLIB_C= $(addprefix bluajit/,$(LJLIB_O:.o=.c))
LJCORE_O= lj_assert.o lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o \
lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \
lj_prng.o lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o \
lj_strscan.o lj_strfmt.o lj_strfmt_num.o lj_serialize.o \
lj_api.o lj_profile.o \
lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \
lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \
lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \
lj_mcode.o lj_snap.o lj_record.o lj_crecord.o lj_ffrecord.o \
lj_asm.o lj_trace.o lj_gdbjit.o \
lj_ctype.o lj_cdata.o lj_cconv.o lj_ccall.o lj_ccallback.o \
lj_carith.o lj_clib.o lj_cparse.o \
lj_lib.o lj_alloc.o lib_aux.o \
$(LJLIB_O) lib_init.o
LJCORE_O:= $(addprefix $(OBJDIR)/,$(LJCORE_O))
LJVMCORE_O= $(LJVM_O) $(LJCORE_O)
LIB_VMDEF= bluajit/jit/vmdef.lua
LIB_VMDEFP= $(LIB_VMDEF)
ALL_T= $(HOST_T)
ALL_HDRGEN:= lj_bcdef.h lj_ffdef.h lj_libdef.h lj_recdef.h lj_folddef.h \
host/buildvm_arch.h luajit.h
ALL_HDRGEN:= $(addprefix bluajit/,$(ALL_HDRGEN))
ALL_GEN= $(LJVM_S) $(ALL_HDRGEN) bluajit/luajit_relver.txt $(LIB_VMDEFP)
##############################################################################
# Build mode handling.
##############################################################################
ifeq (Windows,$(TARGET_SYS))
LJVM_MODE= peobj
LJVM_BOUT= $(LJVM_O)
endif
ifeq (Darwin,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (iOS,$(TARGET_SYS))
LJVM_MODE= machasm
endif
ifeq (Windows,$(TARGET_SYS))
MINILUA_T= $(OBJDIR)/minilua.exe
BUILDVM_T= $(OBJDIR)/buildvm.exe
ifeq (,$(HOST_MSYS))
MINILUA_X= $(OBJDIR)\minilua
BUILDVM_X= $(OBJDIR)\buildvm
HOST_RM= del
endif
endif
OBJS:=$(OBJS) \
$(LJVMCORE_O) \
$(OBJDIR)/lua_script.o \
$(OBJDIR)/lua_baselib.o \
$(OBJDIR)/lua_blockmaplib.o \
$(OBJDIR)/lua_mathlib.o \
$(OBJDIR)/lua_hooklib.o \
$(OBJDIR)/lua_consolelib.o \
$(OBJDIR)/lua_infolib.o \
$(OBJDIR)/lua_mobjlib.o \
$(OBJDIR)/lua_playerlib.o \
$(OBJDIR)/lua_skinlib.o \
$(OBJDIR)/lua_thinkerlib.o \
$(OBJDIR)/lua_maplib.o \
$(OBJDIR)/hashtable.o \
$(OBJDIR)/lua_hudlib.o \
$(OBJDIR)/lua_hudlib_drawlist.o \
$(OBJDIR)/lua_udatalib.o \
$(OBJDIR)/lua_glib.o
+63
View File
@@ -0,0 +1,63 @@
Q= @
E= @true
#Q=
#E= @:
$(MINILUA_T): $(MINILUA_O)
$(E) "HOSTLINK $@"
$(HOST_CC) -o $@ $(MINILUA_O) $(MINILUA_LIBS)
bluajit/luajit.h: $(MINILUA_DEP) $(GIT_DEP) bluajit/luajit_rolling.h
$(E) "VERSION $@"
$(Q)$(GIT_RELVER)
$(Q)cd bluajit && ../$(HOST_LUA) host/genversion.lua
bluajit/host/buildvm_arch.h: $(DASM_DASC) $(MINILUA_DEP) bluajit/lj_arch.h bluajit/lua.h bluajit/luaconf.h
$(E) "DYNASM $@"
$(Q)$(DASM) $(DASM_FLAGS) -o $@ $(DASM_DASC)
$(OBJDIR)/buildvm.o: $(DASM_DIR)/dasm_*.h
$(BUILDVM_T): $(BUILDVM_O)
$(E) "HOSTLINK $@"
$(HOST_CC) -o $@ $(BUILDVM_O)
$(LJVM_BOUT): $(BUILDVM_T)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m $(LJVM_MODE) -o $@
bluajit/lj_bcdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m bcdef -o $@ $(LJLIB_C)
bluajit/lj_ffdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m ffdef -o $@ $(LJLIB_C)
bluajit/lj_libdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m libdef -o $@ $(LJLIB_C)
bluajit/lj_recdef.h: $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m recdef -o $@ $(LJLIB_C)
$(LIB_VMDEF): $(BUILDVM_T) $(LJLIB_C)
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m vmdef -o $(LIB_VMDEFP) $(LJLIB_C)
bluajit/lj_folddef.h: $(BUILDVM_T) bluajit/lj_opt_fold.c
$(E) "BUILDVM $@"
$(Q)$(BUILDVM_X) -m folddef -o $@ bluajit/lj_opt_fold.c
$(OBJDIR)/%.o: bluajit/%.c
$(E) "CC $@"
$(TARGET_CC) $(TARGET_ACFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: $(OBJDIR)/lj_vm.S
$(E) "ASM $@"
$(TARGET_CC) $(TARGET_ASFLAGS) -c -o $@ $<
$(HOST_O): $(OBJDIR)/%.o: bluajit/host/%.c
$(E) "HOSTCC $@"
$(HOST_CC) $(HOST_ACFLAGS) -c -o $@ $<
+456
View File
@@ -0,0 +1,456 @@
/*
** DynASM ARM encoding engine.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "arm"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. */
enum {
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC,
DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12, DASM_IMMV8,
DASM__MAX
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned int *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals. */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl;
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
static int dasm_imm12(unsigned int n)
{
int i;
for (i = 0; i < 16; i++, n = (n << 2) | (n >> 30))
if (n <= 255) return (int)(n + (i << 8));
return -1;
}
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
if (action >= DASM__MAX) {
ofs += 4;
} else {
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
switch (action) {
case DASM_STOP: goto stop;
case DASM_SECTION:
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
D->section = &D->sections[n]; goto stop;
case DASM_ESC: p++; ofs += 4; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
break;
case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
}
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_IMM:
case DASM_IMM16:
#ifdef DASM_CHECKS
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
if ((ins & 0x8000))
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
else
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
#endif
b[pos++] = n;
break;
case DASM_IMMV8:
CK((n & 3) == 0, RANGE_I);
n >>= 2;
/* fallthrough */
case DASM_IMML8:
case DASM_IMML12:
CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :
(((-n)>>((ins>>5)&31)) == 0), RANGE_I);
b[pos++] = n;
break;
case DASM_IMM12:
CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
b[pos++] = n;
break;
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: p++; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: case DASM_IMM12: case DASM_IMM16:
case DASM_IMML8: case DASM_IMML12: case DASM_IMMV8: pos++; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
#else
#define CK(x, st) ((void)0)
#endif
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
char *base = (char *)buffer;
unsigned int *cp = (unsigned int *)buffer;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: *cp++ = *p++; break;
case DASM_REL_EXT:
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
goto patchrel;
case DASM_ALIGN:
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
break;
case DASM_REL_LG:
if (n < 0) {
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp - 4);
goto patchrel;
}
/* fallthrough */
case DASM_REL_PC:
CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
patchrel:
if ((ins & 0x800) == 0) {
CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);
cp[-1] |= ((n >> 2) & 0x00ffffff);
} else if ((ins & 0x1000)) {
CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
goto patchimml8;
} else if ((ins & 0x2000) == 0) {
CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
goto patchimml;
} else {
CK((n & 3) == 0 && -1020 <= n && n <= 1020, RANGE_REL);
n >>= 2;
goto patchimml;
}
break;
case DASM_LABEL_LG:
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
break;
case DASM_LABEL_PC: break;
case DASM_IMM:
cp[-1] |= ((n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
case DASM_IMM12:
cp[-1] |= dasm_imm12((unsigned int)n);
break;
case DASM_IMM16:
cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
break;
case DASM_IMML8: patchimml8:
cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
((-n & 0x0f) | ((-n & 0xf0) << 4));
break;
case DASM_IMML12: case DASM_IMMV8: patchimml:
cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
break;
default: *cp++ = ins; break;
}
}
stop: (void)0;
}
}
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
#undef CK
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large. Load diff
+558
View File
@@ -0,0 +1,558 @@
/*
** DynASM ARM64 encoding engine.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "arm64"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. */
enum {
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC, DASM_REL_A,
DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,
DASM_IMMV, DASM_VREG,
DASM__MAX
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_RANGE_VREG 0x16000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned int *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals. */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl;
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
static int dasm_imm12(unsigned int n)
{
if ((n >> 12) == 0)
return n;
else if ((n & 0xff000fff) == 0)
return (n >> 12) | 0x1000;
else
return -1;
}
static int dasm_ffs(unsigned long long x)
{
int n = -1;
while (x) { x >>= 1; n++; }
return n;
}
static int dasm_imm13(int lo, int hi)
{
int inv = 0, w = 64, s = 0xfff, xa, xb;
unsigned long long n = (((unsigned long long)hi) << 32) | (unsigned int)lo;
unsigned long long m = 1ULL, a, b, c;
if (n & 1) { n = ~n; inv = 1; }
a = n & (unsigned long long)-(long long)n;
b = (n+a)&(unsigned long long)-(long long)(n+a);
c = (n+a-b)&(unsigned long long)-(long long)(n+a-b);
xa = dasm_ffs(a); xb = dasm_ffs(b);
if (c) {
w = dasm_ffs(c) - xa;
if (w == 32) m = 0x0000000100000001UL;
else if (w == 16) m = 0x0001000100010001UL;
else if (w == 8) m = 0x0101010101010101UL;
else if (w == 4) m = 0x1111111111111111UL;
else if (w == 2) m = 0x5555555555555555UL;
else return -1;
s = (-2*w & 0x3f) - 1;
} else if (!a) {
return -1;
} else if (xb == -1) {
xb = 64;
}
if ((b-a) * m != n) return -1;
if (inv) {
return ((w - xb) << 6) | (s+w+xa-xb);
} else {
return ((w - xa) << 6) | (s+xb-xa);
}
return -1;
}
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
if (action >= DASM__MAX) {
ofs += 4;
} else {
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
switch (action) {
case DASM_STOP: goto stop;
case DASM_SECTION:
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
D->section = &D->sections[n]; goto stop;
case DASM_ESC: p++; ofs += 4; break;
case DASM_REL_EXT: if ((ins & 0x8000)) ofs += 8; break;
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
if ((ins & 0x8000)) ofs += 8;
break;
case DASM_REL_A:
b[pos++] = n;
b[pos++] = va_arg(ap, int);
break;
case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
}
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_IMM:
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
n >>= ((ins>>10)&31);
#ifdef DASM_CHECKS
if ((ins & 0x8000))
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
else
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
#endif
b[pos++] = n;
break;
case DASM_IMM6:
CK((n >> 6) == 0, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM12:
CK(dasm_imm12((unsigned int)n) != -1, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM13W:
CK(dasm_imm13(n, n) != -1, RANGE_I);
b[pos++] = n;
break;
case DASM_IMM13X: {
int m = va_arg(ap, int);
CK(dasm_imm13(n, m) != -1, RANGE_I);
b[pos++] = n;
b[pos++] = m;
break;
}
case DASM_IMML: {
#ifdef DASM_CHECKS
int scale = (ins & 3);
CK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||
(unsigned int)(n+256) < 512, RANGE_I);
#endif
b[pos++] = n;
break;
}
case DASM_IMMV:
ofs += 4;
b[pos++] = n;
break;
case DASM_VREG:
CK(n < 32, RANGE_VREG);
b[pos++] = n;
break;
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: p++; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:
case DASM_IMML: case DASM_IMMV: case DASM_VREG: pos++; break;
case DASM_IMM13X: case DASM_REL_A: pos += 2; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
#else
#define CK(x, st) ((void)0)
#endif
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
char *base = (char *)buffer;
unsigned int *cp = (unsigned int *)buffer;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: *cp++ = *p++; break;
case DASM_REL_EXT:
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
goto patchrel;
case DASM_ALIGN:
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xd503201f;
break;
case DASM_REL_LG:
if (n < 0) {
ptrdiff_t na = (ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp + 4;
n = (int)na;
CK((ptrdiff_t)n == na, RANGE_REL);
goto patchrel;
}
/* fallthrough */
case DASM_REL_PC:
CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) + 4;
patchrel:
if (!(ins & 0xf800)) { /* B, BL */
CK((n & 3) == 0 && ((n+0x08000000) >> 28) == 0, RANGE_REL);
cp[-1] |= ((n >> 2) & 0x03ffffff);
} else if ((ins & 0x800)) { /* B.cond, CBZ, CBNZ, LDR* literal */
CK((n & 3) == 0 && ((n+0x00100000) >> 21) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x00ffffe0);
} else if ((ins & 0x3000) == 0x2000) { /* ADR */
CK(((n+0x00100000) >> 21) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x00ffffe0) | ((n & 3) << 29);
} else if ((ins & 0x3000) == 0x3000) { /* ADRP */
cp[-1] |= ((n >> 9) & 0x00ffffe0) | (((n >> 12) & 3) << 29);
} else if ((ins & 0x1000)) { /* TBZ, TBNZ */
CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);
cp[-1] |= ((n << 3) & 0x0007ffe0);
} else if ((ins & 0x8000)) { /* absolute */
cp[0] = (unsigned int)((ptrdiff_t)cp - 4 + n);
cp[1] = (unsigned int)(((ptrdiff_t)cp - 4 + n) >> 32);
cp += 2;
}
break;
case DASM_REL_A: {
ptrdiff_t na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n);
if ((ins & 0x3000) == 0x3000) { /* ADRP */
ins &= ~0x1000;
na = (na >> 12) - (((ptrdiff_t)cp - 4) >> 12);
} else {
na = na - (ptrdiff_t)cp + 4;
}
n = (int)na;
CK((ptrdiff_t)n == na, RANGE_REL);
goto patchrel;
}
case DASM_LABEL_LG:
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
break;
case DASM_LABEL_PC: break;
case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
case DASM_IMM6:
cp[-1] |= ((n&31) << 19) | ((n&32) << 26);
break;
case DASM_IMM12:
cp[-1] |= (dasm_imm12((unsigned int)n) << 10);
break;
case DASM_IMM13W:
cp[-1] |= (dasm_imm13(n, n) << 10);
break;
case DASM_IMM13X:
cp[-1] |= (dasm_imm13(n, *b++) << 10);
break;
case DASM_IMML: {
int scale = (ins & 3);
cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?
((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);
break;
}
case DASM_IMMV:
*cp++ = n;
break;
case DASM_VREG:
cp[-1] |= (n & 0x1f) << (ins & 0x1f);
break;
default: *cp++ = ins; break;
}
}
stop: (void)0;
}
}
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
#undef CK
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large. Load diff
+419
View File
@@ -0,0 +1,419 @@
/*
** DynASM MIPS encoding engine.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "mips"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. */
enum {
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMS,
DASM__MAX
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned int *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals. */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl;
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16) - 0xff00;
if (action >= DASM__MAX) {
ofs += 4;
} else {
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
switch (action) {
case DASM_STOP: goto stop;
case DASM_SECTION:
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
D->section = &D->sections[n]; goto stop;
case DASM_ESC: p++; ofs += 4; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
break;
case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
}
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_IMM: case DASM_IMMS:
#ifdef DASM_CHECKS
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
#endif
n >>= ((ins>>10)&31);
#ifdef DASM_CHECKS
if (ins & 0x8000)
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
else
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
#endif
b[pos++] = n;
break;
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16) - 0xff00;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: p++; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: case DASM_IMMS: pos++; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
#else
#define CK(x, st) ((void)0)
#endif
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
char *base = (char *)buffer;
unsigned int *cp = (unsigned int *)buffer;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16) - 0xff00;
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: *cp++ = *p++; break;
case DASM_REL_EXT:
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1);
goto patchrel;
case DASM_ALIGN:
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
break;
case DASM_REL_LG:
if (n < 0) {
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
goto patchrel;
}
/* fallthrough */
case DASM_REL_PC:
CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n);
if (ins & 2048)
n = (n + (int)(size_t)base) & 0x0fffffff;
else
n = n - (int)((char *)cp - base);
patchrel: {
unsigned int e = 16 + ((ins >> 12) & 15);
CK((n & 3) == 0 &&
((n + ((ins & 2048) ? 0 : (1<<(e+1)))) >> (e+2)) == 0, RANGE_REL);
cp[-1] |= ((n>>2) & ((1<<e)-1));
}
break;
case DASM_LABEL_LG:
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
break;
case DASM_LABEL_PC: break;
case DASM_IMMS:
cp[-1] |= ((n>>3) & 4); n &= 0x1f;
/* fallthrough */
case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
default: *cp++ = ins; break;
}
}
stop: (void)0;
}
}
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
#undef CK
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large. Load diff
+12
View File
@@ -0,0 +1,12 @@
------------------------------------------------------------------------------
-- DynASM MIPS64 module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.
-- All the interesting stuff is there.
------------------------------------------------------------------------------
mips64 = true -- Using a global is an ugly, but effective solution.
return require("dasm_mips")
+418
View File
@@ -0,0 +1,418 @@
/*
** DynASM PPC/PPC64 encoding engine.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "ppc"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. */
enum {
DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,
/* The following actions need a buffer position. */
DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
/* The following actions also have an argument. */
DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH,
DASM__MAX
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_REL 0x15000000
#define DASM_S_UNDEF_LG 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned int *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals. */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl;
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
if (action >= DASM__MAX) {
ofs += 4;
} else {
int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;
switch (action) {
case DASM_STOP: goto stop;
case DASM_SECTION:
n = (ins & 255); CK(n < D->maxsection, RANGE_SEC);
D->section = &D->sections[n]; goto stop;
case DASM_ESC: p++; ofs += 4; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;
case DASM_REL_LG:
n = (ins & 2047) - 10; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl += 10; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
break;
case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC:
pl = D->pclabels + n; CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;
}
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_IMM:
#ifdef DASM_CHECKS
CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
#endif
n >>= ((ins>>10)&31);
#ifdef DASM_CHECKS
if (ins & 0x8000)
CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);
else
CK((n>>((ins>>5)&31)) == 0, RANGE_I);
#endif
b[pos++] = n;
break;
case DASM_IMMSH:
CK((n >> 6) == 0, RANGE_I);
b[pos++] = n;
break;
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: p++; break;
case DASM_REL_EXT: break;
case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
case DASM_REL_LG: case DASM_REL_PC: pos++; break;
case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
case DASM_IMM: case DASM_IMMSH: pos++; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)
#else
#define CK(x, st) ((void)0)
#endif
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
char *base = (char *)buffer;
unsigned int *cp = (unsigned int *)buffer;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
while (1) {
unsigned int ins = *p++;
unsigned int action = (ins >> 16);
int n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;
switch (action) {
case DASM_STOP: case DASM_SECTION: goto stop;
case DASM_ESC: *cp++ = *p++; break;
case DASM_REL_EXT:
n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1) - 4;
goto patchrel;
case DASM_ALIGN:
ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
break;
case DASM_REL_LG:
if (n < 0) {
n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
goto patchrel;
}
/* fallthrough */
case DASM_REL_PC:
CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
patchrel:
CK((n & 3) == 0 &&
(((n+4) + ((ins & 2048) ? 0x00008000 : 0x02000000)) >>
((ins & 2048) ? 16 : 26)) == 0, RANGE_REL);
cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
break;
case DASM_LABEL_LG:
ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
break;
case DASM_LABEL_PC: break;
case DASM_IMM:
cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
break;
case DASM_IMMSH:
cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32);
break;
default: *cp++ = ins; break;
}
}
stop: (void)0;
}
}
if (base + D->codesize != (char *)cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
#undef CK
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large. Load diff
+83
View File
@@ -0,0 +1,83 @@
/*
** DynASM encoding engine prototypes.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#ifndef _DASM_PROTO_H
#define _DASM_PROTO_H
#include <stddef.h>
#include <stdarg.h>
#define DASM_IDENT "DynASM 1.5.0"
#define DASM_VERSION 10500 /* 1.5.0 */
#ifndef Dst_DECL
#define Dst_DECL dasm_State **Dst
#endif
#ifndef Dst_REF
#define Dst_REF (*Dst)
#endif
#ifndef DASM_FDEF
#define DASM_FDEF extern
#endif
#ifndef DASM_M_GROW
#define DASM_M_GROW(ctx, t, p, sz, need) \
do { \
size_t _sz = (sz), _need = (need); \
if (_sz < _need) { \
if (_sz < 16) _sz = 16; \
while (_sz < _need) _sz += _sz; \
(p) = (t *)realloc((p), _sz); \
if ((p) == NULL) exit(1); \
(sz) = _sz; \
} \
} while(0)
#endif
#ifndef DASM_M_FREE
#define DASM_M_FREE(ctx, p, sz) free(p)
#endif
/* Internal DynASM encoder state. */
typedef struct dasm_State dasm_State;
/* Initialize and free DynASM state. */
DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
DASM_FDEF void dasm_free(Dst_DECL);
/* Setup global array. Must be called before dasm_setup(). */
DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
/* Grow PC label array. Can be called after dasm_setup(), too. */
DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
/* Setup encoder. */
DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);
/* Feed encoder with actions. Calls are generated by pre-processor. */
DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
/* Link sections and return the resulting size. */
DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
/* Encode sections into buffer. */
DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
/* Get PC label offset. */
DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
#else
#define dasm_checkstep(a, b) 0
#endif
#endif /* _DASM_PROTO_H */
+12
View File
@@ -0,0 +1,12 @@
------------------------------------------------------------------------------
-- DynASM x64 module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- See dynasm.lua for full copyright notice.
------------------------------------------------------------------------------
-- This module just sets 64 bit mode for the combined x86/x64 module.
-- All the interesting stuff is there.
------------------------------------------------------------------------------
x64 = true -- Using a global is an ugly, but effective solution.
return require("dasm_x86")
+523
View File
@@ -0,0 +1,523 @@
/*
** DynASM x86 encoding engine.
** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
** Released under the MIT license. See dynasm.lua for full copyright notice.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define DASM_ARCH "x86"
#ifndef DASM_EXTERN
#define DASM_EXTERN(a,b,c,d) 0
#endif
/* Action definitions. DASM_STOP must be 255. */
enum {
DASM_DISP = 233,
DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
};
/* Maximum number of section buffer positions for a single dasm_put() call. */
#define DASM_MAXSECPOS 25
/* DynASM encoder status codes. Action list offset or number are or'ed in. */
#define DASM_S_OK 0x00000000
#define DASM_S_NOMEM 0x01000000
#define DASM_S_PHASE 0x02000000
#define DASM_S_MATCH_SEC 0x03000000
#define DASM_S_RANGE_I 0x11000000
#define DASM_S_RANGE_SEC 0x12000000
#define DASM_S_RANGE_LG 0x13000000
#define DASM_S_RANGE_PC 0x14000000
#define DASM_S_RANGE_VREG 0x15000000
#define DASM_S_UNDEF_L 0x21000000
#define DASM_S_UNDEF_PC 0x22000000
/* Macros to convert positions (8 bit section + 24 bit index). */
#define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
#define DASM_POS2BIAS(pos) ((pos)&0xff000000)
#define DASM_SEC2POS(sec) ((sec)<<24)
#define DASM_POS2SEC(pos) ((pos)>>24)
#define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
/* Action list type. */
typedef const unsigned char *dasm_ActList;
/* Per-section structure. */
typedef struct dasm_Section {
int *rbuf; /* Biased buffer pointer (negative section bias). */
int *buf; /* True buffer pointer. */
size_t bsize; /* Buffer size in bytes. */
int pos; /* Biased buffer position. */
int epos; /* End of biased buffer position - max single put. */
int ofs; /* Byte offset into section. */
} dasm_Section;
/* Core structure holding the DynASM encoding state. */
struct dasm_State {
size_t psize; /* Allocated size of this structure. */
dasm_ActList actionlist; /* Current actionlist pointer. */
int *lglabels; /* Local/global chain/pos ptrs. */
size_t lgsize;
int *pclabels; /* PC label chains/pos ptrs. */
size_t pcsize;
void **globals; /* Array of globals. */
dasm_Section *section; /* Pointer to active section. */
size_t codesize; /* Total size of all code sections. */
int maxsection; /* 0 <= sectionidx < maxsection. */
int status; /* Status code. */
dasm_Section sections[1]; /* All sections. Alloc-extended. */
};
/* The size of the core structure depends on the max. number of sections. */
#define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
/* Initialize DynASM state. */
void dasm_init(Dst_DECL, int maxsection)
{
dasm_State *D;
size_t psz = 0;
Dst_REF = NULL;
DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
D = Dst_REF;
D->psize = psz;
D->lglabels = NULL;
D->lgsize = 0;
D->pclabels = NULL;
D->pcsize = 0;
D->globals = NULL;
D->maxsection = maxsection;
memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
}
/* Free DynASM state. */
void dasm_free(Dst_DECL)
{
dasm_State *D = Dst_REF;
int i;
for (i = 0; i < D->maxsection; i++)
if (D->sections[i].buf)
DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
DASM_M_FREE(Dst, D, D->psize);
}
/* Setup global label array. Must be called before dasm_setup(). */
void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
{
dasm_State *D = Dst_REF;
D->globals = gl;
DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
}
/* Grow PC label array. Can be called after dasm_setup(), too. */
void dasm_growpc(Dst_DECL, unsigned int maxpc)
{
dasm_State *D = Dst_REF;
size_t osz = D->pcsize;
DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
}
/* Setup encoder. */
void dasm_setup(Dst_DECL, const void *actionlist)
{
dasm_State *D = Dst_REF;
int i;
D->actionlist = (dasm_ActList)actionlist;
D->status = DASM_S_OK;
D->section = &D->sections[0];
memset((void *)D->lglabels, 0, D->lgsize);
if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
for (i = 0; i < D->maxsection; i++) {
D->sections[i].pos = DASM_SEC2POS(i);
D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
D->sections[i].ofs = 0;
}
}
#ifdef DASM_CHECKS
#define CK(x, st) \
do { if (!(x)) { \
D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
#define CKPL(kind, st) \
do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
#else
#define CK(x, st) ((void)0)
#define CKPL(kind, st) ((void)0)
#endif
/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
void dasm_put(Dst_DECL, int start, ...)
{
va_list ap;
dasm_State *D = Dst_REF;
dasm_ActList p = D->actionlist + start;
dasm_Section *sec = D->section;
int pos = sec->pos, ofs = sec->ofs, mrm = -1;
int *b;
if (pos >= sec->epos) {
DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
}
b = sec->rbuf;
b[pos++] = start;
va_start(ap, start);
while (1) {
int action = *p++;
if (action < DASM_DISP) {
ofs++;
} else if (action <= DASM_REL_A) {
int n = va_arg(ap, int);
b[pos++] = n;
switch (action) {
case DASM_DISP:
if (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }
/* fallthrough */
case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
case DASM_IMM_D: ofs += 4; break;
case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */
case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;
case DASM_SPACE: p++; ofs += n; break;
case DASM_SETLABEL: b[pos-2] = -0x40000000; break; /* Neg. label ofs. */
case DASM_VREG: CK((n&-16) == 0 && (n != 4 || (*p>>5) != 2), RANGE_VREG);
if (*p < 0x40 && p[1] == DASM_DISP) mrm = n;
if (*p < 0x20 && (n&7) == 4) ofs++;
switch ((*p++ >> 3) & 3) {
case 3: n |= b[pos-3]; /* fallthrough */
case 2: n |= b[pos-2]; /* fallthrough */
case 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }
}
continue;
}
mrm = -1;
} else {
int *pl, n;
switch (action) {
case DASM_REL_LG:
case DASM_IMM_LG:
n = *p++; pl = D->lglabels + n;
/* Bkwd rel or global. */
if (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
pl -= 246; n = *pl;
if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
goto linkrel;
case DASM_REL_PC:
case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
putrel:
n = *pl;
if (n < 0) { /* Label exists. Get label pos and store it. */
b[pos] = -n;
} else {
linkrel:
b[pos] = n; /* Else link to rel chain, anchored at label. */
*pl = pos;
}
pos++;
ofs += 4; /* Maximum offset needed. */
if (action == DASM_REL_LG || action == DASM_REL_PC) {
b[pos++] = ofs; /* Store pass1 offset estimate. */
} else if (sizeof(ptrdiff_t) == 8) {
ofs += 4;
}
break;
case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
putlabel:
n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
*pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_ALIGN:
ofs += *p++; /* Maximum alignment needed (arg is 2**n-1). */
b[pos++] = ofs; /* Store pass1 offset estimate. */
break;
case DASM_EXTERN: p += 2; ofs += 4; break;
case DASM_ESC: p++; ofs++; break;
case DASM_MARK: mrm = p[-2]; break;
case DASM_SECTION:
n = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];
case DASM_STOP: goto stop;
}
}
}
stop:
va_end(ap);
sec->pos = pos;
sec->ofs = ofs;
}
#undef CK
/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
int dasm_link(Dst_DECL, size_t *szp)
{
dasm_State *D = Dst_REF;
int secnum;
int ofs = 0;
#ifdef DASM_CHECKS
*szp = 0;
if (D->status != DASM_S_OK) return D->status;
{
int pc;
for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
}
#endif
{ /* Handle globals not defined in this translation unit. */
int idx;
for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
int n = D->lglabels[idx];
/* Undefined label: Collapse rel chain and replace with marker (< 0). */
while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
}
}
/* Combine all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->rbuf;
int pos = DASM_SEC2POS(secnum);
int lastpos = sec->pos;
while (pos != lastpos) {
dasm_ActList p = D->actionlist + b[pos++];
int op = 0;
while (1) {
int action = *p++;
switch (action) {
case DASM_REL_LG: p++;
/* fallthrough */
case DASM_REL_PC: {
int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
if (shrink) { /* Shrinkable branch opcode? */
int lofs, lpos = b[pos];
if (lpos < 0) goto noshrink; /* Ext global? */
lofs = *DASM_POS2PTR(D, lpos);
if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
int i;
for (i = secnum; i < DASM_POS2SEC(lpos); i++)
lofs += D->sections[i].ofs;
} else {
lofs -= ofs; /* Bkwd label: unfix offset. */
}
lofs -= b[pos+1]; /* Short branch ok? */
if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
else { noshrink: shrink = 0; } /* No, cannot shrink op. */
}
b[pos+1] = shrink;
pos += 2;
break;
}
/* fallthrough */
case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
/* fallthrough */
case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
case DASM_LABEL_LG: p++;
/* fallthrough */
case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
case DASM_EXTERN: p += 2; break;
case DASM_ESC: op = *p++; break;
case DASM_MARK: break;
case DASM_SECTION: case DASM_STOP: goto stop;
default: op = action; break;
}
}
stop: (void)0;
}
ofs += sec->ofs; /* Next section starts right after current section. */
}
D->codesize = ofs; /* Total size of all code sections */
*szp = ofs;
return DASM_S_OK;
}
#define dasmb(x) *cp++ = (unsigned char)(x)
#ifndef DASM_ALIGNED_WRITES
#define dasmw(x) \
do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
#define dasmd(x) \
do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
#define dasmq(x) \
do { *((unsigned long long *)cp) = (unsigned long long)(x); cp+=8; } while (0)
#else
#define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
#define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
#define dasmq(x) do { dasmd(x); dasmd((x)>>32); } while (0)
#endif
static unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)
{
if (sizeof(ptrdiff_t) == 8)
dasmq((unsigned long long)x);
else
dasmd((unsigned int)x);
return cp;
}
#define dasma(x) (cp = dasma_(cp, (x)))
/* Pass 3: Encode sections. */
int dasm_encode(Dst_DECL, void *buffer)
{
dasm_State *D = Dst_REF;
unsigned char *base = (unsigned char *)buffer;
unsigned char *cp = base;
int secnum;
/* Encode all code sections. No support for data sections (yet). */
for (secnum = 0; secnum < D->maxsection; secnum++) {
dasm_Section *sec = D->sections + secnum;
int *b = sec->buf;
int *endb = sec->rbuf + sec->pos;
while (b != endb) {
dasm_ActList p = D->actionlist + *b++;
unsigned char *mark = NULL;
while (1) {
int action = *p++;
int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
switch (action) {
case DASM_DISP: if (!mark) mark = cp; {
unsigned char *mm = mark;
if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;
if (mrm != 5) { mm[-1] -= 0x80; break; } }
if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;
}
/* fallthrough */
case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
case DASM_IMM_DB: if (((n+128)&-256) == 0) {
db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
} else mark = NULL;
/* fallthrough */
case DASM_IMM_D: wd: dasmd(n); break;
case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;
/* fallthrough */
case DASM_IMM_W: dasmw(n); break;
case DASM_VREG: {
int t = *p++;
unsigned char *ex = cp - (t&7);
if ((n & 8) && t < 0xa0) {
if (*ex & 0x80) ex[1] ^= 0x20 << (t>>6); else *ex ^= 1 << (t>>6);
n &= 7;
} else if (n & 0x10) {
if (*ex & 0x80) {
*ex = 0xc5; ex[1] = (ex[1] & 0x80) | ex[2]; ex += 2;
}
while (++ex < cp) ex[-1] = *ex;
if (mark) mark--;
cp--;
n &= 7;
}
if (t >= 0xc0) n <<= 4;
else if (t >= 0x40) n <<= 3;
else if (n == 4 && t < 0x20) { cp[-1] ^= n; *cp++ = 0x20; }
cp[-1] ^= n;
break;
}
case DASM_REL_LG: p++; if (n >= 0) goto rel_pc;
b++; n = (int)(ptrdiff_t)D->globals[-n-10];
/* fallthrough */
case DASM_REL_A: rel_a:
n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
case DASM_REL_PC: rel_pc: {
int shrink = *b++;
int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }
n = *pb - ((int)(cp-base) + 4-shrink);
if (shrink == 0) goto wd;
if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
goto wb;
}
case DASM_IMM_LG:
p++;
if (n < 0) { dasma((ptrdiff_t)D->globals[-n-10]); break; }
/* fallthrough */
case DASM_IMM_PC: {
int *pb = DASM_POS2PTR(D, n);
dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));
break;
}
case DASM_LABEL_LG: {
int idx = *p++;
if (idx >= 10)
D->globals[idx-10] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
break;
}
case DASM_LABEL_PC: case DASM_SETLABEL: break;
case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
case DASM_ALIGN:
n = *p++;
while (((cp-base) & n)) *cp++ = 0x90; /* nop */
break;
case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
case DASM_MARK: mark = cp; break;
case DASM_ESC: action = *p++;
/* fallthrough */
default: *cp++ = action; break;
case DASM_SECTION: case DASM_STOP: goto stop;
}
}
stop: (void)0;
}
}
if (base + D->codesize != cp) /* Check for phase errors. */
return DASM_S_PHASE;
return DASM_S_OK;
}
/* Get PC label offset. */
int dasm_getpclabel(Dst_DECL, unsigned int pc)
{
dasm_State *D = Dst_REF;
if (pc*sizeof(int) < D->pcsize) {
int pos = D->pclabels[pc];
if (pos < 0) return *DASM_POS2PTR(D, -pos);
if (pos > 0) return -1; /* Undefined. */
}
return -2; /* Unused or out of range. */
}
#ifdef DASM_CHECKS
/* Optional sanity checker to call between isolated encoding steps. */
int dasm_checkstep(Dst_DECL, int secmatch)
{
dasm_State *D = Dst_REF;
if (D->status == DASM_S_OK) {
int i;
for (i = 1; i <= 9; i++) {
if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
D->lglabels[i] = 0;
}
}
if (D->status == DASM_S_OK && secmatch >= 0 &&
D->section != &D->sections[secmatch])
D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
return D->status;
}
#endif
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+3
View File
@@ -0,0 +1,3 @@
minilua
buildvm
buildvm_arch.h
+4
View File
@@ -0,0 +1,4 @@
The files in this directory are only used during the build process of LuaJIT.
For cross-compilation, they must be executed on the host, not on the target.
These files should NOT be installed!
+529
View File
@@ -0,0 +1,529 @@
/*
** LuaJIT VM builder.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** This is a tool to build the hand-tuned assembler code required for
** LuaJIT's bytecode interpreter. It supports a variety of output formats
** to feed different toolchains (see usage() below).
**
** This tool is not particularly optimized because it's only used while
** _building_ LuaJIT. There's no point in distributing or installing it.
** Only the object code generated by this tool is linked into LuaJIT.
**
** Caveat: some memory is not free'd, error handling is lazy.
** It's a one-shot tool -- any effort fixing this would be wasted.
*/
#include "buildvm.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_bc.h"
#if LJ_HASJIT
#include "lj_ir.h"
#include "lj_ircall.h"
#endif
#include "lj_frame.h"
#include "lj_dispatch.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#include "lj_ccall.h"
#endif
#include "luajit.h"
#if defined(_WIN32)
#include <fcntl.h>
#include <io.h>
#endif
/* ------------------------------------------------------------------------ */
/* DynASM glue definitions. */
#define Dst ctx
#define Dst_DECL BuildCtx *ctx
#define Dst_REF (ctx->D)
#define DASM_CHECKS 1
#include "../dynasm/dasm_proto.h"
/* Glue macros for DynASM. */
static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type);
#define DASM_EXTERN(ctx, addr, idx, type) \
collect_reloc(ctx, addr, idx, type)
/* ------------------------------------------------------------------------ */
/* Avoid trouble if cross-compiling for an x86 target. Speed doesn't matter. */
#define DASM_ALIGNED_WRITES 1
/* Embed architecture-specific DynASM encoder. */
#if LJ_TARGET_X86ORX64
#include "../dynasm/dasm_x86.h"
#elif LJ_TARGET_ARM
#include "../dynasm/dasm_arm.h"
#elif LJ_TARGET_ARM64
#include "../dynasm/dasm_arm64.h"
#elif LJ_TARGET_PPC
#include "../dynasm/dasm_ppc.h"
#elif LJ_TARGET_MIPS
#include "../dynasm/dasm_mips.h"
#else
#error "No support for this architecture (yet)"
#endif
/* Embed generated architecture-specific backend. */
#include "buildvm_arch.h"
/* ------------------------------------------------------------------------ */
void owrite(BuildCtx *ctx, const void *ptr, size_t sz)
{
if (fwrite(ptr, 1, sz, ctx->fp) != sz) {
fprintf(stderr, "Error: cannot write to output file: %s\n",
strerror(errno));
exit(1);
}
}
/* ------------------------------------------------------------------------ */
/* Emit code as raw bytes. Only used for DynASM debugging. */
static void emit_raw(BuildCtx *ctx)
{
owrite(ctx, ctx->code, ctx->codesz);
}
/* -- Build machine code -------------------------------------------------- */
static const char *sym_decorate(BuildCtx *ctx,
const char *prefix, const char *suffix)
{
char name[256];
char *p;
#if LJ_64
const char *symprefix = ctx->mode == BUILD_machasm ? "_" : "";
#elif LJ_TARGET_XBOX360
const char *symprefix = "";
#else
const char *symprefix = ctx->mode != BUILD_elfasm ? "_" : "";
#endif
sprintf(name, "%s%s%s", symprefix, prefix, suffix);
p = strchr(name, '@');
if (p) {
#if LJ_TARGET_X86ORX64
if (!LJ_64 && (ctx->mode == BUILD_coffasm || ctx->mode == BUILD_peobj))
name[0] = name[1] == 'R' ? '_' : '@'; /* Just for _RtlUnwind@16. */
else
*p = '\0';
#elif LJ_TARGET_PPC && !LJ_TARGET_CONSOLE
/* Keep @plt etc. */
#else
*p = '\0';
#endif
}
p = (char *)malloc(strlen(name)+1); /* MSVC doesn't like strdup. */
strcpy(p, name);
return p;
}
#define NRELOCSYM (sizeof(extnames)/sizeof(extnames[0])-1)
static int relocmap[NRELOCSYM];
/* Collect external relocations. */
static int collect_reloc(BuildCtx *ctx, uint8_t *addr, int idx, int type)
{
if (ctx->nreloc >= BUILD_MAX_RELOC) {
fprintf(stderr, "Error: too many relocations, increase BUILD_MAX_RELOC.\n");
exit(1);
}
if (relocmap[idx] < 0) {
relocmap[idx] = ctx->nrelocsym;
ctx->relocsym[ctx->nrelocsym] = sym_decorate(ctx, "", extnames[idx]);
ctx->nrelocsym++;
}
ctx->reloc[ctx->nreloc].ofs = (int32_t)(addr - ctx->code);
ctx->reloc[ctx->nreloc].sym = relocmap[idx];
ctx->reloc[ctx->nreloc].type = type;
ctx->nreloc++;
#if LJ_TARGET_XBOX360
return (int)(ctx->code - addr) + 4; /* Encode symbol offset of .text. */
#else
return 0; /* Encode symbol offset of 0. */
#endif
}
/* Naive insertion sort. Performance doesn't matter here. */
static void sym_insert(BuildCtx *ctx, int32_t ofs,
const char *prefix, const char *suffix)
{
ptrdiff_t i = ctx->nsym++;
while (i > 0) {
if (ctx->sym[i-1].ofs <= ofs)
break;
ctx->sym[i] = ctx->sym[i-1];
i--;
}
ctx->sym[i].ofs = ofs;
ctx->sym[i].name = sym_decorate(ctx, prefix, suffix);
}
/* Build the machine code. */
static int build_code(BuildCtx *ctx)
{
int status;
int i;
/* Initialize DynASM structures. */
ctx->nglob = GLOB__MAX;
ctx->glob = (void **)malloc(ctx->nglob*sizeof(void *));
memset(ctx->glob, 0, ctx->nglob*sizeof(void *));
ctx->nreloc = 0;
ctx->globnames = globnames;
ctx->extnames = extnames;
ctx->relocsym = (const char **)malloc(NRELOCSYM*sizeof(const char *));
ctx->nrelocsym = 0;
for (i = 0; i < (int)NRELOCSYM; i++) relocmap[i] = -1;
ctx->dasm_ident = DASM_IDENT;
ctx->dasm_arch = DASM_ARCH;
dasm_init(Dst, DASM_MAXSECTION);
dasm_setupglobal(Dst, ctx->glob, ctx->nglob);
dasm_setup(Dst, build_actionlist);
/* Call arch-specific backend to emit the code. */
ctx->npc = build_backend(ctx);
/* Finalize the code. */
(void)dasm_checkstep(Dst, -1);
if ((status = dasm_link(Dst, &ctx->codesz))) return status;
ctx->code = (uint8_t *)malloc(ctx->codesz);
if ((status = dasm_encode(Dst, (void *)ctx->code))) return status;
/* Allocate symbol table and bytecode offsets. */
ctx->beginsym = sym_decorate(ctx, "", LABEL_PREFIX "vm_asm_begin");
ctx->sym = (BuildSym *)malloc((ctx->npc+ctx->nglob+1)*sizeof(BuildSym));
ctx->nsym = 0;
ctx->bc_ofs = (int32_t *)malloc(ctx->npc*sizeof(int32_t));
/* Collect the opcodes (PC labels). */
for (i = 0; i < ctx->npc; i++) {
int32_t ofs = dasm_getpclabel(Dst, i);
if (ofs < 0) return 0x22000000|i;
ctx->bc_ofs[i] = ofs;
if ((LJ_HASJIT ||
!(i == BC_JFORI || i == BC_JFORL || i == BC_JITERL || i == BC_JLOOP ||
i == BC_IFORL || i == BC_IITERL || i == BC_ILOOP)) &&
(LJ_HASFFI || i != BC_KCDATA))
sym_insert(ctx, ofs, LABEL_PREFIX_BC, bc_names[i]);
}
/* Collect the globals (named labels). */
for (i = 0; i < ctx->nglob; i++) {
const char *gl = globnames[i];
int len = (int)strlen(gl);
if (!ctx->glob[i]) {
fprintf(stderr, "Error: undefined global %s\n", gl);
exit(2);
}
/* Skip the _Z symbols. */
if (!(len >= 2 && gl[len-2] == '_' && gl[len-1] == 'Z'))
sym_insert(ctx, (int32_t)((uint8_t *)(ctx->glob[i]) - ctx->code),
LABEL_PREFIX, globnames[i]);
}
/* Close the address range. */
sym_insert(ctx, (int32_t)ctx->codesz, "", "");
ctx->nsym--;
dasm_free(Dst);
return 0;
}
/* -- Generate VM enums --------------------------------------------------- */
const char *const bc_names[] = {
#define BCNAME(name, ma, mb, mc, mt) #name,
BCDEF(BCNAME)
#undef BCNAME
NULL
};
#if LJ_HASJIT
const char *const ir_names[] = {
#define IRNAME(name, m, m1, m2) #name,
IRDEF(IRNAME)
#undef IRNAME
NULL
};
const char *const irt_names[] = {
#define IRTNAME(name, size) #name,
IRTDEF(IRTNAME)
#undef IRTNAME
NULL
};
const char *const irfpm_names[] = {
#define FPMNAME(name) #name,
IRFPMDEF(FPMNAME)
#undef FPMNAME
NULL
};
const char *const irfield_names[] = {
#define FLNAME(name, ofs) #name,
IRFLDEF(FLNAME)
#undef FLNAME
NULL
};
const char *const ircall_names[] = {
#define IRCALLNAME(cond, name, nargs, kind, type, flags) #name,
IRCALLDEF(IRCALLNAME)
#undef IRCALLNAME
NULL
};
static const char *const trace_errors[] = {
#define TREDEF(name, msg) msg,
#include "lj_traceerr.h"
NULL
};
#endif
#if LJ_HASJIT
static const char *lower(char *buf, const char *s)
{
char *p = buf;
while (*s) {
*p++ = (*s >= 'A' && *s <= 'Z') ? *s+0x20 : *s;
s++;
}
*p = '\0';
return buf;
}
#endif
/* Emit C source code for bytecode-related definitions. */
static void emit_bcdef(BuildCtx *ctx)
{
int i;
fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_ofs[] = {\n");
for (i = 0; i < ctx->npc; i++) {
if (i != 0)
fprintf(ctx->fp, ",\n");
fprintf(ctx->fp, "%d", ctx->bc_ofs[i]);
}
}
/* Emit VM definitions as Lua code for debug modules. */
static void emit_vmdef(BuildCtx *ctx)
{
#if LJ_HASJIT
char buf[80];
#endif
int i;
fprintf(ctx->fp, "-- This is a generated file. DO NOT EDIT!\n\n");
fprintf(ctx->fp, "assert(require(\"jit\").version == \"%s\", \"LuaJIT core/library version mismatch\")\n\n", LUAJIT_VERSION);
fprintf(ctx->fp, "return {\n\n");
fprintf(ctx->fp, "bcnames = \"");
for (i = 0; bc_names[i]; i++) fprintf(ctx->fp, "%-6s", bc_names[i]);
fprintf(ctx->fp, "\",\n\n");
#if LJ_HASJIT
fprintf(ctx->fp, "irnames = \"");
for (i = 0; ir_names[i]; i++) fprintf(ctx->fp, "%-6s", ir_names[i]);
fprintf(ctx->fp, "\",\n\n");
fprintf(ctx->fp, "irfpm = { [0]=");
for (i = 0; irfpm_names[i]; i++)
fprintf(ctx->fp, "\"%s\", ", lower(buf, irfpm_names[i]));
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "irfield = { [0]=");
for (i = 0; irfield_names[i]; i++) {
char *p;
lower(buf, irfield_names[i]);
p = strchr(buf, '_');
if (p) *p = '.';
fprintf(ctx->fp, "\"%s\", ", buf);
}
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "ircall = {\n[0]=");
for (i = 0; ircall_names[i]; i++)
fprintf(ctx->fp, "\"%s\",\n", ircall_names[i]);
fprintf(ctx->fp, "},\n\n");
fprintf(ctx->fp, "traceerr = {\n[0]=");
for (i = 0; trace_errors[i]; i++)
fprintf(ctx->fp, "\"%s\",\n", trace_errors[i]);
fprintf(ctx->fp, "},\n\n");
#endif
}
/* -- Argument parsing ---------------------------------------------------- */
/* Build mode names. */
static const char *const modenames[] = {
#define BUILDNAME(name) #name,
BUILDDEF(BUILDNAME)
#undef BUILDNAME
NULL
};
/* Print usage information and exit. */
static void usage(void)
{
int i;
fprintf(stderr, LUAJIT_VERSION " VM builder.\n");
fprintf(stderr, LUAJIT_COPYRIGHT ", " LUAJIT_URL "\n");
fprintf(stderr, "Target architecture: " LJ_ARCH_NAME "\n\n");
fprintf(stderr, "Usage: buildvm -m mode [-o outfile] [infiles...]\n\n");
fprintf(stderr, "Available modes:\n");
for (i = 0; i < BUILD__MAX; i++)
fprintf(stderr, " %s\n", modenames[i]);
exit(1);
}
/* Parse the output mode name. */
static BuildMode parsemode(const char *mode)
{
int i;
for (i = 0; modenames[i]; i++)
if (!strcmp(mode, modenames[i]))
return (BuildMode)i;
usage();
return (BuildMode)-1;
}
/* Parse arguments. */
static void parseargs(BuildCtx *ctx, char **argv)
{
const char *a;
int i;
ctx->mode = (BuildMode)-1;
ctx->outname = "-";
for (i = 1; (a = argv[i]) != NULL; i++) {
if (a[0] != '-')
break;
switch (a[1]) {
case '-':
if (a[2]) goto err;
i++;
goto ok;
case '\0':
goto ok;
case 'm':
i++;
if (a[2] || argv[i] == NULL) goto err;
ctx->mode = parsemode(argv[i]);
break;
case 'o':
i++;
if (a[2] || argv[i] == NULL) goto err;
ctx->outname = argv[i];
break;
default: err:
usage();
break;
}
}
ok:
ctx->args = argv+i;
if (ctx->mode == (BuildMode)-1) goto err;
}
int main(int argc, char **argv)
{
BuildCtx ctx_;
BuildCtx *ctx = &ctx_;
int status, binmode;
if (sizeof(void *) != 4*LJ_32+8*LJ_64) {
fprintf(stderr,"Error: pointer size mismatch in cross-build.\n");
fprintf(stderr,"Try: make HOST_CC=\"gcc -m32\" CROSS=...\n\n");
return 1;
}
UNUSED(argc);
parseargs(ctx, argv);
if ((status = build_code(ctx))) {
fprintf(stderr,"Error: DASM error %08x\n", status);
return 1;
}
switch (ctx->mode) {
case BUILD_peobj:
case BUILD_raw:
binmode = 1;
break;
default:
binmode = 0;
break;
}
if (ctx->outname[0] == '-' && ctx->outname[1] == '\0') {
ctx->fp = stdout;
#if defined(_WIN32)
if (binmode)
_setmode(_fileno(stdout), _O_BINARY); /* Yuck. */
#endif
} else if (!(ctx->fp = fopen(ctx->outname, binmode ? "wb" : "w"))) {
fprintf(stderr, "Error: cannot open output file '%s': %s\n",
ctx->outname, strerror(errno));
exit(1);
}
switch (ctx->mode) {
case BUILD_elfasm:
case BUILD_coffasm:
case BUILD_machasm:
emit_asm(ctx);
emit_asm_debug(ctx);
break;
case BUILD_peobj:
emit_peobj(ctx);
break;
case BUILD_raw:
emit_raw(ctx);
break;
case BUILD_bcdef:
emit_bcdef(ctx);
emit_lib(ctx);
break;
case BUILD_vmdef:
emit_vmdef(ctx);
emit_lib(ctx);
fprintf(ctx->fp, "}\n\n");
break;
case BUILD_ffdef:
case BUILD_libdef:
case BUILD_recdef:
emit_lib(ctx);
break;
case BUILD_folddef:
emit_fold(ctx);
break;
default:
break;
}
fflush(ctx->fp);
if (ferror(ctx->fp)) {
fprintf(stderr, "Error: cannot write to output file: %s\n",
strerror(errno));
exit(1);
}
fclose(ctx->fp);
return 0;
}
+105
View File
@@ -0,0 +1,105 @@
/*
** LuaJIT VM builder.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#ifndef _BUILDVM_H
#define _BUILDVM_H
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "lj_def.h"
#include "lj_arch.h"
/* Hardcoded limits. Increase as needed. */
#define BUILD_MAX_RELOC 200 /* Max. number of relocations. */
#define BUILD_MAX_FOLD 4096 /* Max. number of fold rules. */
/* Prefix for scanned library definitions. */
#define LIBDEF_PREFIX "LJLIB_"
/* Prefix for scanned fold definitions. */
#define FOLDDEF_PREFIX "LJFOLD"
/* Prefixes for generated labels. */
#define LABEL_PREFIX "lj_"
#define LABEL_PREFIX_BC LABEL_PREFIX "BC_"
#define LABEL_PREFIX_FF LABEL_PREFIX "ff_"
#define LABEL_PREFIX_CF LABEL_PREFIX "cf_"
#define LABEL_PREFIX_FFH LABEL_PREFIX "ffh_"
#define LABEL_PREFIX_LIBCF LABEL_PREFIX "lib_cf_"
#define LABEL_PREFIX_LIBINIT LABEL_PREFIX "lib_init_"
/* Forward declaration. */
struct dasm_State;
/* Build modes. */
#define BUILDDEF(_) \
_(elfasm) _(coffasm) _(machasm) _(peobj) _(raw) \
_(bcdef) _(ffdef) _(libdef) _(recdef) _(vmdef) \
_(folddef)
typedef enum {
#define BUILDENUM(name) BUILD_##name,
BUILDDEF(BUILDENUM)
#undef BUILDENUM
BUILD__MAX
} BuildMode;
/* Code relocation. */
typedef struct BuildReloc {
int32_t ofs;
int sym;
int type;
} BuildReloc;
typedef struct BuildSym {
const char *name;
int32_t ofs;
} BuildSym;
/* Build context structure. */
typedef struct BuildCtx {
/* DynASM state pointer. Should be first member. */
struct dasm_State *D;
/* Parsed command line. */
BuildMode mode;
FILE *fp;
const char *outname;
char **args;
/* Code and symbols generated by DynASM. */
uint8_t *code;
size_t codesz;
int npc, nglob, nsym, nreloc, nrelocsym;
void **glob;
BuildSym *sym;
const char **relocsym;
int32_t *bc_ofs;
const char *beginsym;
/* Strings generated by DynASM. */
const char *const *globnames;
const char *const *extnames;
const char *dasm_ident;
const char *dasm_arch;
/* Relocations. */
BuildReloc reloc[BUILD_MAX_RELOC];
} BuildCtx;
extern void owrite(BuildCtx *ctx, const void *ptr, size_t sz);
extern void emit_asm(BuildCtx *ctx);
extern void emit_peobj(BuildCtx *ctx);
extern void emit_lib(BuildCtx *ctx);
extern void emit_fold(BuildCtx *ctx);
extern const char *const bc_names[];
extern const char *const ir_names[];
extern const char *const irt_names[];
extern const char *const irfpm_names[];
extern const char *const irfield_names[];
extern const char *const ircall_names[];
#endif
+355
View File
@@ -0,0 +1,355 @@
/*
** LuaJIT VM builder: Assembler source code emitter.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
#include "lj_bc.h"
/* ------------------------------------------------------------------------ */
#if LJ_TARGET_X86ORX64
/* Emit bytes piecewise as assembler text. */
static void emit_asm_bytes(BuildCtx *ctx, uint8_t *p, int n)
{
int i;
for (i = 0; i < n; i++) {
if ((i & 15) == 0)
fprintf(ctx->fp, "\t.byte %d", p[i]);
else
fprintf(ctx->fp, ",%d", p[i]);
if ((i & 15) == 15) putc('\n', ctx->fp);
}
if ((n & 15) != 0) putc('\n', ctx->fp);
}
/* Emit relocation */
static void emit_asm_reloc(BuildCtx *ctx, int type, const char *sym)
{
switch (ctx->mode) {
case BUILD_elfasm:
if (type)
fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
else
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
case BUILD_coffasm:
fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", sym);
if (type)
fprintf(ctx->fp, "\t.long %s-.-4\n", sym);
else
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
default: /* BUILD_machasm for relative relocations handled below. */
fprintf(ctx->fp, "\t.long %s\n", sym);
break;
}
}
static const char *const jccnames[] = {
"jo", "jno", "jb", "jnb", "jz", "jnz", "jbe", "ja",
"js", "jns", "jpe", "jpo", "jl", "jge", "jle", "jg"
};
/* Emit x86/x64 text relocations. */
static void emit_asm_reloc_text(BuildCtx *ctx, uint8_t *cp, int n,
const char *sym)
{
const char *opname = NULL;
if (--n < 0) goto err;
if (cp[n] == 0xe8) {
opname = "call";
} else if (cp[n] == 0xe9) {
opname = "jmp";
} else if (cp[n] >= 0x80 && cp[n] <= 0x8f && n > 0 && cp[n-1] == 0x0f) {
opname = jccnames[cp[n]-0x80];
n--;
} else {
err:
fprintf(stderr, "Error: unsupported opcode for %s symbol relocation.\n",
sym);
exit(1);
}
emit_asm_bytes(ctx, cp, n);
if (strncmp(sym+(*sym == '_'), LABEL_PREFIX, sizeof(LABEL_PREFIX)-1)) {
/* Various fixups for external symbols outside of our binary. */
if (ctx->mode == BUILD_elfasm) {
if (LJ_32)
fprintf(ctx->fp, "#if __PIC__\n\t%s lj_wrap_%s\n#else\n", opname, sym);
fprintf(ctx->fp, "\t%s %s@PLT\n", opname, sym);
if (LJ_32)
fprintf(ctx->fp, "#endif\n");
return;
} else if (LJ_32 && ctx->mode == BUILD_machasm) {
fprintf(ctx->fp, "\t%s L%s$stub\n", opname, sym);
return;
}
}
fprintf(ctx->fp, "\t%s %s\n", opname, sym);
}
#else
/* Emit words piecewise as assembler text. */
static void emit_asm_words(BuildCtx *ctx, uint8_t *p, int n)
{
int i;
for (i = 0; i < n; i += 4) {
uint32_t ins = *(uint32_t *)(p+i);
#if LJ_TARGET_ARM64 && LJ_BE
ins = lj_bswap(ins); /* ARM64 instructions are always little-endian. */
#endif
if ((i & 15) == 0)
fprintf(ctx->fp, "\t.long 0x%08x", ins);
else
fprintf(ctx->fp, ",0x%08x", ins);
if ((i & 15) == 12) putc('\n', ctx->fp);
}
if ((n & 15) != 0) putc('\n', ctx->fp);
}
/* Emit relocation as part of an instruction. */
static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
const char *sym)
{
uint32_t ins;
emit_asm_words(ctx, p, n-4);
ins = *(uint32_t *)(p+n-4);
#if LJ_TARGET_ARM
if ((ins & 0xff000000u) == 0xfa000000u) {
fprintf(ctx->fp, "\tblx %s\n", sym);
} else if ((ins & 0x0e000000u) == 0x0a000000u) {
fprintf(ctx->fp, "\t%s%.2s %s\n", (ins & 0x01000000u) ? "bl" : "b",
&"eqnecsccmiplvsvchilsgeltgtle"[2*(ins >> 28)], sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_ARM64
if ((ins >> 26) == 0x25u) {
fprintf(ctx->fp, "\tbl %s\n", sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_PPC
#if LJ_TARGET_PS3
#define TOCPREFIX "."
#else
#define TOCPREFIX ""
#endif
if ((ins >> 26) == 16) {
fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
(ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
} else if ((ins >> 26) == 18) {
fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
} else {
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
}
#elif LJ_TARGET_MIPS
fprintf(stderr,
"Error: unsupported opcode %08x for %s symbol relocation.\n",
ins, sym);
exit(1);
#else
#error "missing relocation support for this architecture"
#endif
}
#endif
#if LJ_TARGET_ARM
#define ELFASM_PX "%%"
#else
#define ELFASM_PX "@"
#endif
/* Emit an assembler label. */
static void emit_asm_label(BuildCtx *ctx, const char *name, int size, int isfunc)
{
switch (ctx->mode) {
case BUILD_elfasm:
#if LJ_TARGET_PS3
if (!strncmp(name, "lj_vm_", 6) &&
strcmp(name, ctx->beginsym) &&
!strstr(name, "hook")) {
fprintf(ctx->fp,
"\n\t.globl %s\n"
"\t.section \".opd\",\"aw\"\n"
"%s:\n"
"\t.long .%s,.TOC.@tocbase32\n"
"\t.size %s,8\n"
"\t.previous\n"
"\t.globl .%s\n"
"\t.hidden .%s\n"
"\t.type .%s, " ELFASM_PX "function\n"
"\t.size .%s, %d\n"
".%s:\n",
name, name, name, name, name, name, name, name, size, name);
break;
}
#endif
fprintf(ctx->fp,
"\n\t.globl %s\n"
"\t.hidden %s\n"
"\t.type %s, " ELFASM_PX "%s\n"
"\t.size %s, %d\n"
"%s:\n",
name, name, name, isfunc ? "function" : "object", name, size, name);
break;
case BUILD_coffasm:
fprintf(ctx->fp, "\n\t.globl %s\n", name);
if (isfunc)
fprintf(ctx->fp, "\t.def %s; .scl 3; .type 32; .endef\n", name);
fprintf(ctx->fp, "%s:\n", name);
break;
case BUILD_machasm:
fprintf(ctx->fp,
"\n\t.private_extern %s\n"
"\t.no_dead_strip %s\n"
"%s:\n", name, name, name);
break;
default:
break;
}
}
/* Emit alignment. */
static void emit_asm_align(BuildCtx *ctx, int bits)
{
switch (ctx->mode) {
case BUILD_elfasm:
case BUILD_coffasm:
fprintf(ctx->fp, "\t.p2align %d\n", bits);
break;
case BUILD_machasm:
fprintf(ctx->fp, "\t.align %d\n", bits);
break;
default:
break;
}
}
/* ------------------------------------------------------------------------ */
/* Emit assembler source code. */
void emit_asm(BuildCtx *ctx)
{
int i, rel;
fprintf(ctx->fp, "\t.file \"buildvm_%s.dasc\"\n", ctx->dasm_arch);
fprintf(ctx->fp, "\t.text\n");
#if LJ_TARGET_MIPS32 && !LJ_ABI_SOFTFP
fprintf(ctx->fp, "\t.module fp=32\n");
#endif
#if LJ_TARGET_MIPS
fprintf(ctx->fp, "\t.set nomips16\n\t.abicalls\n\t.set noreorder\n\t.set nomacro\n");
#endif
emit_asm_align(ctx, 4);
#if LJ_TARGET_PS3
emit_asm_label(ctx, ctx->beginsym, ctx->codesz, 0);
#else
emit_asm_label(ctx, ctx->beginsym, 0, 0);
#endif
if (ctx->mode != BUILD_machasm)
fprintf(ctx->fp, ".Lbegin:\n");
#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
/* This should really be moved into buildvm_arm.dasc. */
#if LJ_ARCH_HASFPU
fprintf(ctx->fp,
".fnstart\n"
".save {r5, r6, r7, r8, r9, r10, r11, lr}\n"
".vsave {d8-d15}\n"
".save {r4}\n"
".pad #28\n");
#else
fprintf(ctx->fp,
".fnstart\n"
".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
".pad #28\n");
#endif
#endif
for (i = rel = 0; i < ctx->nsym; i++) {
int32_t ofs = ctx->sym[i].ofs;
int32_t next = ctx->sym[i+1].ofs;
#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND && LJ_HASFFI
if (!strcmp(ctx->sym[i].name, "lj_vm_ffi_call"))
fprintf(ctx->fp,
".globl lj_err_unwind_arm\n"
".personality lj_err_unwind_arm\n"
".fnend\n"
".fnstart\n"
".save {r4, r5, r11, lr}\n"
".setfp r11, sp\n");
#endif
emit_asm_label(ctx, ctx->sym[i].name, next - ofs, 1);
while (rel < ctx->nreloc && ctx->reloc[rel].ofs <= next) {
BuildReloc *r = &ctx->reloc[rel];
int n = r->ofs - ofs;
#if LJ_TARGET_X86ORX64
if (r->type != 0 &&
(ctx->mode == BUILD_elfasm || ctx->mode == BUILD_machasm)) {
emit_asm_reloc_text(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
} else {
emit_asm_bytes(ctx, ctx->code+ofs, n);
emit_asm_reloc(ctx, r->type, ctx->relocsym[r->sym]);
}
ofs += n+4;
#else
emit_asm_wordreloc(ctx, ctx->code+ofs, n, ctx->relocsym[r->sym]);
ofs += n;
#endif
rel++;
}
#if LJ_TARGET_X86ORX64
emit_asm_bytes(ctx, ctx->code+ofs, next-ofs);
#else
emit_asm_words(ctx, ctx->code+ofs, next-ofs);
#endif
}
#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
fprintf(ctx->fp,
#if !LJ_HASFFI
".globl lj_err_unwind_arm\n"
".personality lj_err_unwind_arm\n"
#endif
".fnend\n");
#endif
fprintf(ctx->fp, "\n");
switch (ctx->mode) {
case BUILD_elfasm:
#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA)
fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n");
#endif
#if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP
/* Hard-float ABI. */
fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n");
#endif
/* fallthrough */
case BUILD_coffasm:
fprintf(ctx->fp, "\t.ident \"%s\"\n", ctx->dasm_ident);
break;
case BUILD_machasm:
#if defined(__apple_build_version__) && __apple_build_version__ >= 15000000 && __apple_build_version__ < 15000300
/* Workaround for XCode 15.0 - 15.2. */
fprintf(ctx->fp, "\t.subsections_via_symbols\n");
#endif
fprintf(ctx->fp,
"\t.cstring\n"
"\t.ascii \"%s\\0\"\n", ctx->dasm_ident);
break;
default:
break;
}
fprintf(ctx->fp, "\n");
}
+236
View File
@@ -0,0 +1,236 @@
/*
** LuaJIT VM builder: IR folding hash table generator.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
#include "lj_obj.h"
#if LJ_HASJIT
#include "lj_ir.h"
/* Context for the folding hash table generator. */
static int lineno;
static uint32_t funcidx;
static uint32_t foldkeys[BUILD_MAX_FOLD];
static uint32_t nkeys;
/* Try to fill the hash table with keys using the hash parameters. */
static int tryhash(uint32_t *htab, uint32_t sz, uint32_t r, int dorol)
{
uint32_t i;
if (dorol && ((r & 31) == 0 || (r>>5) == 0))
return 0; /* Avoid zero rotates. */
memset(htab, 0xff, (sz+1)*sizeof(uint32_t));
for (i = 0; i < nkeys; i++) {
uint32_t key = foldkeys[i];
uint32_t k = key & 0xffffff;
uint32_t h = (dorol ? lj_rol(lj_rol(k, r>>5) - k, r&31) :
(((k << (r>>5)) - k) << (r&31))) % sz;
if (htab[h] != 0xffffffff) { /* Collision on primary slot. */
if (htab[h+1] != 0xffffffff) { /* Collision on secondary slot. */
/* Try to move the colliding key, if possible. */
if (h < sz-1 && htab[h+2] == 0xffffffff) {
uint32_t k2 = htab[h+1] & 0xffffff;
uint32_t h2 = (dorol ? lj_rol(lj_rol(k2, r>>5) - k2, r&31) :
(((k2 << (r>>5)) - k2) << (r&31))) % sz;
if (h2 != h+1) return 0; /* Cannot resolve collision. */
htab[h+2] = htab[h+1]; /* Move colliding key to secondary slot. */
} else {
return 0; /* Collision. */
}
}
htab[h+1] = key;
} else {
htab[h] = key;
}
}
return 1; /* Success, all keys could be stored. */
}
/* Print the generated hash table. */
static void printhash(BuildCtx *ctx, uint32_t *htab, uint32_t sz)
{
uint32_t i;
fprintf(ctx->fp, "static const uint32_t fold_hash[%d] = {\n0x%08x",
sz+1, htab[0]);
for (i = 1; i < sz+1; i++)
fprintf(ctx->fp, ",\n0x%08x", htab[i]);
fprintf(ctx->fp, "\n};\n\n");
}
/* Exhaustive search for the shortest semi-perfect hash table. */
static void makehash(BuildCtx *ctx)
{
uint32_t htab[BUILD_MAX_FOLD*2+1];
uint32_t sz, r;
/* Search for the smallest hash table with an odd size. */
for (sz = (nkeys|1); sz < BUILD_MAX_FOLD*2; sz += 2) {
/* First try all shift hash combinations. */
for (r = 0; r < 32*32; r++) {
if (tryhash(htab, sz, r, 0)) {
printhash(ctx, htab, sz);
fprintf(ctx->fp,
"#define fold_hashkey(k)\t(((((k)<<%u)-(k))<<%u)%%%u)\n\n",
r>>5, r&31, sz);
return;
}
}
/* Then try all rotate hash combinations. */
for (r = 0; r < 32*32; r++) {
if (tryhash(htab, sz, r, 1)) {
printhash(ctx, htab, sz);
fprintf(ctx->fp,
"#define fold_hashkey(k)\t(lj_rol(lj_rol((k),%u)-(k),%u)%%%u)\n\n",
r>>5, r&31, sz);
return;
}
}
}
fprintf(stderr, "Error: search for perfect hash failed\n");
exit(1);
}
/* Parse one token of a fold rule. */
static uint32_t nexttoken(char **pp, int allowlit, int allowany)
{
char *p = *pp;
if (p) {
uint32_t i;
char *q = strchr(p, ' ');
if (q) *q++ = '\0';
*pp = q;
if (allowlit && !strncmp(p, "IRFPM_", 6)) {
for (i = 0; irfpm_names[i]; i++)
if (!strcmp(irfpm_names[i], p+6))
return i;
} else if (allowlit && !strncmp(p, "IRFL_", 5)) {
for (i = 0; irfield_names[i]; i++)
if (!strcmp(irfield_names[i], p+5))
return i;
} else if (allowlit && !strncmp(p, "IRCALL_", 7)) {
for (i = 0; ircall_names[i]; i++)
if (!strcmp(ircall_names[i], p+7))
return i;
} else if (allowlit && !strncmp(p, "IRCONV_", 7)) {
for (i = 0; irt_names[i]; i++) {
const char *r = strchr(p+7, '_');
if (r && !strncmp(irt_names[i], p+7, r-(p+7))) {
uint32_t j;
for (j = 0; irt_names[j]; j++)
if (!strcmp(irt_names[j], r+1))
return (i << 5) + j;
}
}
} else if (allowlit && *p >= '0' && *p <= '9') {
for (i = 0; *p >= '0' && *p <= '9'; p++)
i = i*10 + (*p - '0');
if (*p == '\0')
return i;
} else if (allowany && !strcmp("any", p)) {
return allowany;
} else {
for (i = 0; ir_names[i]; i++)
if (!strcmp(ir_names[i], p))
return i;
}
fprintf(stderr, "Error: bad fold definition token \"%s\" at line %d\n", p, lineno);
exit(1);
}
return 0;
}
/* Parse a fold rule. */
static void foldrule(char *p)
{
uint32_t op = nexttoken(&p, 0, 0);
uint32_t left = nexttoken(&p, 0, 0x7f);
uint32_t right = nexttoken(&p, 1, 0x3ff);
uint32_t key = (funcidx << 24) | (op << 17) | (left << 10) | right;
uint32_t i;
if (nkeys >= BUILD_MAX_FOLD) {
fprintf(stderr, "Error: too many fold rules, increase BUILD_MAX_FOLD.\n");
exit(1);
}
/* Simple insertion sort to detect duplicates. */
for (i = nkeys; i > 0; i--) {
if ((foldkeys[i-1]&0xffffff) < (key & 0xffffff))
break;
if ((foldkeys[i-1]&0xffffff) == (key & 0xffffff)) {
fprintf(stderr, "Error: duplicate fold definition at line %d\n", lineno);
exit(1);
}
foldkeys[i] = foldkeys[i-1];
}
foldkeys[i] = key;
nkeys++;
}
/* Emit C source code for IR folding hash table. */
void emit_fold(BuildCtx *ctx)
{
char buf[256]; /* We don't care about analyzing lines longer than that. */
const char *fname = ctx->args[0];
FILE *fp;
if (fname == NULL) {
fprintf(stderr, "Error: missing input filename\n");
exit(1);
}
if (fname[0] == '-' && fname[1] == '\0') {
fp = stdin;
} else {
fp = fopen(fname, "r");
if (!fp) {
fprintf(stderr, "Error: cannot open input file '%s': %s\n",
fname, strerror(errno));
exit(1);
}
}
fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
fprintf(ctx->fp, "static const FoldFunc fold_func[] = {\n");
lineno = 0;
funcidx = 0;
nkeys = 0;
while (fgets(buf, sizeof(buf), fp) != NULL) {
lineno++;
/* The prefix must be at the start of a line, otherwise it's ignored. */
if (!strncmp(buf, FOLDDEF_PREFIX, sizeof(FOLDDEF_PREFIX)-1)) {
char *p = buf+sizeof(FOLDDEF_PREFIX)-1;
char *q = strchr(p, ')');
if (p[0] == '(' && q) {
p++;
*q = '\0';
foldrule(p);
} else if ((p[0] == 'F' || p[0] == 'X') && p[1] == '(' && q) {
p += 2;
*q = '\0';
if (funcidx)
fprintf(ctx->fp, ",\n");
if (p[-2] == 'X')
fprintf(ctx->fp, " %s", p);
else
fprintf(ctx->fp, " fold_%s", p);
funcidx++;
} else {
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Error: unknown fold definition tag %s%s at line %d\n",
FOLDDEF_PREFIX, p, lineno);
exit(1);
}
}
}
fclose(fp);
fprintf(ctx->fp, "\n};\n\n");
makehash(ctx);
}
#else
void emit_fold(BuildCtx *ctx)
{
UNUSED(ctx);
}
#endif
+470
View File
@@ -0,0 +1,470 @@
/*
** LuaJIT VM builder: library definition compiler.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#include "buildvm.h"
#include "lj_obj.h"
#include "lj_bc.h"
#include "lj_lib.h"
#include "buildvm_libbc.h"
/* Context for library definitions. */
static uint8_t obuf[8192];
static uint8_t *optr;
static char modname[80];
static size_t modnamelen;
static char funcname[80];
static int modstate, regfunc;
static int ffid, recffid, ffasmfunc;
enum {
REGFUNC_OK,
REGFUNC_NOREG,
REGFUNC_NOREGUV
};
static void libdef_name(const char *p, int kind)
{
size_t n = strlen(p);
if (kind != LIBINIT_STRING) {
if (n > modnamelen && p[modnamelen] == '_' &&
!strncmp(p, modname, modnamelen)) {
p += modnamelen+1;
n -= modnamelen+1;
}
}
if (n > LIBINIT_MAXSTR) {
fprintf(stderr, "Error: string too long: '%s'\n", p);
exit(1);
}
if (optr+1+n+2 > obuf+sizeof(obuf)) { /* +2 for caller. */
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = (uint8_t)(n | kind);
memcpy(optr, p, n);
optr += n;
}
static void libdef_endmodule(BuildCtx *ctx)
{
if (modstate != 0) {
char line[80];
const uint8_t *p;
int n;
if (modstate == 1)
fprintf(ctx->fp, " (lua_CFunction)0");
fprintf(ctx->fp, "\n};\n");
fprintf(ctx->fp, "static const uint8_t %s%s[] = {\n",
LABEL_PREFIX_LIBINIT, modname);
line[0] = '\0';
for (n = 0, p = obuf; p < optr; p++) {
n += sprintf(line+n, "%d,", *p);
if (n >= 75) {
fprintf(ctx->fp, "%s\n", line);
n = 0;
line[0] = '\0';
}
}
fprintf(ctx->fp, "%s%d\n};\n#endif\n\n", line, LIBINIT_END);
}
}
static void libdef_module(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
libdef_endmodule(ctx);
optr = obuf;
*optr++ = (uint8_t)ffid;
*optr++ = (uint8_t)ffasmfunc;
*optr++ = 0; /* Hash table size. */
modstate = 1;
fprintf(ctx->fp, "#ifdef %sMODULE_%s\n", LIBDEF_PREFIX, p);
fprintf(ctx->fp, "#undef %sMODULE_%s\n", LIBDEF_PREFIX, p);
fprintf(ctx->fp, "static const lua_CFunction %s%s[] = {\n",
LABEL_PREFIX_LIBCF, p);
}
modnamelen = strlen(p);
if (modnamelen > sizeof(modname)-1) {
fprintf(stderr, "Error: module name too long: '%s'\n", p);
exit(1);
}
strcpy(modname, p);
}
static int find_ffofs(BuildCtx *ctx, const char *name)
{
int i;
for (i = 0; i < ctx->nglob; i++) {
const char *gl = ctx->globnames[i];
if (gl[0] == 'f' && gl[1] == 'f' && gl[2] == '_' && !strcmp(gl+3, name)) {
return (int)((uint8_t *)ctx->glob[i] - ctx->code);
}
}
fprintf(stderr, "Error: undefined fast function %s%s\n",
LABEL_PREFIX_FF, name);
exit(1);
}
static void libdef_func(BuildCtx *ctx, char *p, int arg)
{
if (arg != LIBINIT_CF)
ffasmfunc++;
if (ctx->mode == BUILD_libdef) {
if (modstate == 0) {
fprintf(stderr, "Error: no module for function definition %s\n", p);
exit(1);
}
if (regfunc == REGFUNC_NOREG) {
if (optr+1 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_FFID;
} else {
if (arg != LIBINIT_ASM_) {
if (modstate != 1) fprintf(ctx->fp, ",\n");
modstate = 2;
fprintf(ctx->fp, " %s%s", arg ? LABEL_PREFIX_FFH : LABEL_PREFIX_CF, p);
}
if (regfunc != REGFUNC_NOREGUV) obuf[2]++; /* Bump hash table size. */
libdef_name(regfunc == REGFUNC_NOREGUV ? "" : p, arg);
}
} else if (ctx->mode == BUILD_ffdef) {
fprintf(ctx->fp, "FFDEF(%s)\n", p);
} else if (ctx->mode == BUILD_recdef) {
if (strlen(p) > sizeof(funcname)-1) {
fprintf(stderr, "Error: function name too long: '%s'\n", p);
exit(1);
}
strcpy(funcname, p);
} else if (ctx->mode == BUILD_vmdef) {
int i;
for (i = 1; p[i] && modname[i-1]; i++)
if (p[i] == '_') p[i] = '.';
fprintf(ctx->fp, "\"%s\",\n", p);
} else if (ctx->mode == BUILD_bcdef) {
if (arg != LIBINIT_CF)
fprintf(ctx->fp, ",\n%d", find_ffofs(ctx, p));
}
ffid++;
regfunc = REGFUNC_OK;
}
static uint8_t *libdef_uleb128(uint8_t *p, uint32_t *vv)
{
uint32_t v = *p++;
if (v >= 0x80) {
int sh = 0; v &= 0x7f;
do { v |= ((*p & 0x7f) << (sh += 7)); } while (*p++ >= 0x80);
}
*vv = v;
return p;
}
static void libdef_fixupbc(uint8_t *p)
{
uint32_t i, sizebc;
p += 4;
p = libdef_uleb128(p, &sizebc);
p = libdef_uleb128(p, &sizebc);
p = libdef_uleb128(p, &sizebc);
for (i = 0; i < sizebc; i++, p += 4) {
uint8_t op = p[libbc_endian ? 3 : 0];
uint8_t ra = p[libbc_endian ? 2 : 1];
uint8_t rc = p[libbc_endian ? 1 : 2];
uint8_t rb = p[libbc_endian ? 0 : 3];
if (!LJ_DUALNUM && op == BC_ISTYPE && rc == ~LJ_TNUMX+1) {
op = BC_ISNUM; rc++;
}
p[LJ_ENDIAN_SELECT(0, 3)] = op;
p[LJ_ENDIAN_SELECT(1, 2)] = ra;
p[LJ_ENDIAN_SELECT(2, 1)] = rc;
p[LJ_ENDIAN_SELECT(3, 0)] = rb;
}
}
static void libdef_lua(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
int i;
for (i = 0; libbc_map[i].name != NULL; i++) {
if (!strcmp(libbc_map[i].name, p)) {
int ofs = libbc_map[i].ofs;
int len = libbc_map[i+1].ofs - ofs;
obuf[2]++; /* Bump hash table size. */
*optr++ = LIBINIT_LUA;
libdef_name(p, 0);
memcpy(optr, libbc_code + ofs, len);
libdef_fixupbc(optr);
optr += len;
return;
}
}
fprintf(stderr, "Error: missing libbc definition for %s\n", p);
exit(1);
}
}
static uint32_t find_rec(char *name)
{
char *p = (char *)obuf;
uint32_t n;
for (n = 2; *p; n++) {
if (strcmp(p, name) == 0)
return n;
p += strlen(p)+1;
}
if (p+strlen(name)+1 >= (char *)obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
strcpy(p, name);
return n;
}
static void libdef_rec(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_recdef) {
char *q;
uint32_t n;
for (; recffid+1 < ffid; recffid++)
fprintf(ctx->fp, ",\n0");
recffid = ffid;
if (*p == '.') p = funcname;
q = strchr(p, ' ');
if (q) *q++ = '\0';
n = find_rec(p);
if (q)
fprintf(ctx->fp, ",\n0x%02x00+(%s)", n, q);
else
fprintf(ctx->fp, ",\n0x%02x00", n);
}
}
static void memcpy_endian(void *dst, void *src, size_t n)
{
union { uint8_t b; uint32_t u; } host_endian;
host_endian.u = 1;
if (host_endian.b == LJ_ENDIAN_SELECT(1, 0)) {
memcpy(dst, src, n);
} else {
size_t i;
for (i = 0; i < n; i++)
((uint8_t *)dst)[i] = ((uint8_t *)src)[n-i-1];
}
}
static void libdef_push(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
int len = (int)strlen(p);
if (*p == '"') {
if (len > 1 && p[len-1] == '"') {
p[len-1] = '\0';
libdef_name(p+1, LIBINIT_STRING);
return;
}
} else if (*p >= '0' && *p <= '9') {
char *ep;
double d = strtod(p, &ep);
if (*ep == '\0') {
if (optr+1+sizeof(double) > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_NUMBER;
memcpy_endian(optr, &d, sizeof(double));
optr += sizeof(double);
return;
}
} else if (!strcmp(p, "lastcl")) {
if (optr+1 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_LASTCL;
return;
} else if (len > 4 && !strncmp(p, "top-", 4)) {
if (optr+2 > obuf+sizeof(obuf)) {
fprintf(stderr, "Error: output buffer overflow\n");
exit(1);
}
*optr++ = LIBINIT_COPY;
*optr++ = (uint8_t)atoi(p+4);
return;
}
fprintf(stderr, "Error: bad value for %sPUSH(%s)\n", LIBDEF_PREFIX, p);
exit(1);
}
}
static void libdef_set(BuildCtx *ctx, char *p, int arg)
{
UNUSED(arg);
if (ctx->mode == BUILD_libdef) {
if (p[0] == '!' && p[1] == '\0') p[0] = '\0'; /* Set env. */
libdef_name(p, LIBINIT_STRING);
*optr++ = LIBINIT_SET;
obuf[2]++; /* Bump hash table size. */
}
}
static void libdef_regfunc(BuildCtx *ctx, char *p, int arg)
{
UNUSED(ctx); UNUSED(p);
regfunc = arg;
}
typedef void (*LibDefFunc)(BuildCtx *ctx, char *p, int arg);
typedef struct LibDefHandler {
const char *suffix;
const char *stop;
const LibDefFunc func;
const int arg;
} LibDefHandler;
static const LibDefHandler libdef_handlers[] = {
{ "MODULE_", " \t\r\n", libdef_module, 0 },
{ "CF(", ")", libdef_func, LIBINIT_CF },
{ "ASM(", ")", libdef_func, LIBINIT_ASM },
{ "ASM_(", ")", libdef_func, LIBINIT_ASM_ },
{ "LUA(", ")", libdef_lua, 0 },
{ "REC(", ")", libdef_rec, 0 },
{ "PUSH(", ")", libdef_push, 0 },
{ "SET(", ")", libdef_set, 0 },
{ "NOREGUV", NULL, libdef_regfunc, REGFUNC_NOREGUV },
{ "NOREG", NULL, libdef_regfunc, REGFUNC_NOREG },
{ NULL, NULL, (LibDefFunc)0, 0 }
};
/* Emit C source code for library function definitions. */
void emit_lib(BuildCtx *ctx)
{
const char *fname;
if (ctx->mode == BUILD_ffdef || ctx->mode == BUILD_libdef ||
ctx->mode == BUILD_recdef)
fprintf(ctx->fp, "/* This is a generated file. DO NOT EDIT! */\n\n");
else if (ctx->mode == BUILD_vmdef)
fprintf(ctx->fp, "ffnames = {\n[0]=\"Lua\",\n\"C\",\n");
if (ctx->mode == BUILD_recdef)
fprintf(ctx->fp, "static const uint16_t recff_idmap[] = {\n0,\n0x0100");
recffid = ffid = FF_C+1;
ffasmfunc = 0;
while ((fname = *ctx->args++)) {
char buf[256]; /* We don't care about analyzing lines longer than that. */
FILE *fp;
if (fname[0] == '-' && fname[1] == '\0') {
fp = stdin;
} else {
fp = fopen(fname, "r");
if (!fp) {
fprintf(stderr, "Error: cannot open input file '%s': %s\n",
fname, strerror(errno));
exit(1);
}
}
modstate = 0;
regfunc = REGFUNC_OK;
while (fgets(buf, sizeof(buf), fp) != NULL) {
char *p;
/* Simplistic pre-processor. Only handles top-level #if/#endif. */
if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
int ok = 1;
size_t len = strlen(buf);
if (buf[len-1] == '\n') {
buf[len-1] = 0;
if (buf[len-2] == '\r') {
buf[len-2] = 0;
}
}
if (!strcmp(buf, "#if LJ_52"))
ok = LJ_52;
else if (!strcmp(buf, "#if LJ_HASJIT"))
ok = LJ_HASJIT;
else if (!strcmp(buf, "#if LJ_HASFFI"))
ok = LJ_HASFFI;
else if (!strcmp(buf, "#if LJ_HASBUFFER"))
ok = LJ_HASBUFFER;
else if (!strcmp(buf, "#if !LJ_SRB2LIB"))
ok = !LJ_SRB2LIB;
else if (!strcmp(buf, "#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2IO)"))
ok = !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2IO); /* whacky! */
if (!ok) {
int lvl = 1;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (buf[0] == '#' && buf[1] == 'e' && buf[2] == 'n') {
if (--lvl == 0) break;
} else if (buf[0] == '#' && buf[1] == 'i' && buf[2] == 'f') {
lvl++;
}
}
continue;
}
}
for (p = buf; (p = strstr(p, LIBDEF_PREFIX)) != NULL; ) {
const LibDefHandler *ldh;
p += sizeof(LIBDEF_PREFIX)-1;
for (ldh = libdef_handlers; ldh->suffix != NULL; ldh++) {
size_t n, len = strlen(ldh->suffix);
if (!strncmp(p, ldh->suffix, len)) {
p += len;
n = ldh->stop ? strcspn(p, ldh->stop) : 0;
if (!p[n]) break;
p[n] = '\0';
ldh->func(ctx, p, ldh->arg);
p += n+1;
break;
}
}
if (ldh->suffix == NULL) {
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Error: unknown library definition tag %s%s\n",
LIBDEF_PREFIX, p);
exit(1);
}
}
}
fclose(fp);
if (ctx->mode == BUILD_libdef) {
libdef_endmodule(ctx);
}
}
if (ctx->mode == BUILD_ffdef) {
fprintf(ctx->fp, "\n#undef FFDEF\n\n");
fprintf(ctx->fp,
"#ifndef FF_NUM_ASMFUNC\n#define FF_NUM_ASMFUNC %d\n#endif\n\n",
ffasmfunc);
} else if (ctx->mode == BUILD_vmdef) {
fprintf(ctx->fp, "},\n\n");
} else if (ctx->mode == BUILD_bcdef) {
int i;
fprintf(ctx->fp, "\n};\n\n");
fprintf(ctx->fp, "LJ_DATADEF const uint16_t lj_bc_mode[] = {\n");
fprintf(ctx->fp, "BCDEF(BCMODE)\n");
for (i = ffasmfunc-1; i > 0; i--)
fprintf(ctx->fp, "BCMODE_FF,\n");
fprintf(ctx->fp, "BCMODE_FF\n};\n\n");
} else if (ctx->mode == BUILD_recdef) {
char *p = (char *)obuf;
fprintf(ctx->fp, "\n};\n\n");
fprintf(ctx->fp, "static const RecordFunc recff_func[] = {\n"
"recff_nyi,\n"
"recff_c");
while (*p) {
fprintf(ctx->fp, ",\nrecff_%s", p);
p += strlen(p)+1;
}
fprintf(ctx->fp, "\n};\n\n");
}
}
+81
View File
@@ -0,0 +1,81 @@
/* This is a generated file. DO NOT EDIT! */
static const int libbc_endian = 0;
static const uint8_t libbc_code[] = {
#if LJ_FR2
/* math.deg */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,241,135,158,166,3,
220,203,178,130,4,
/* math.rad */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,243,244,148,165,20,
198,190,199,252,3,
/* string.len */ 0,1,2,0,0,0,3,BC_ISTYPE,0,5,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
/* table.foreachi */ 0,2,10,0,0,0,15,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,
BC_KSHORT,2,1,0,BC_LEN,3,0,0,BC_KSHORT,4,1,0,BC_FORI,2,8,128,BC_MOV,6,1,0,
BC_MOV,8,5,0,BC_TGETR,9,5,0,BC_CALL,6,3,2,BC_ISEQP,6,0,0,BC_JMP,7,1,128,
BC_RET1,6,2,0,BC_FORL,2,248,127,BC_RET0,0,1,0,
/* table.foreach */ 0,2,11,0,0,1,16,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,BC_KPRI,
2,0,0,BC_MOV,3,0,0,BC_KNUM,4,0,0,BC_JMP,5,7,128,BC_MOV,7,1,0,BC_MOV,9,5,0,
BC_MOV,10,6,0,BC_CALL,7,3,2,BC_ISEQP,7,0,0,BC_JMP,8,1,128,BC_RET1,7,2,0,
BC_ITERN,5,3,3,BC_ITERL,5,247,127,BC_RET0,0,1,0,1,255,255,249,255,15,
/* table.getn */ 0,1,2,0,0,0,3,BC_ISTYPE,0,12,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
/* table.remove */ 0,2,10,0,0,2,30,BC_ISTYPE,0,12,0,BC_LEN,2,0,0,BC_ISNEP,1,0,
0,BC_JMP,3,7,128,BC_ISEQN,2,0,0,BC_JMP,3,23,128,BC_TGETR,3,2,0,BC_KPRI,4,0,0,
BC_TSETR,4,2,0,BC_RET1,3,2,0,BC_JMP,3,18,128,BC_ISTYPE,1,14,0,BC_KSHORT,3,1,0,
BC_ISGT,3,1,0,BC_JMP,3,14,128,BC_ISGT,1,2,0,BC_JMP,3,12,128,BC_TGETR,3,1,0,
BC_ADDVN,4,1,1,BC_MOV,5,2,0,BC_KSHORT,6,1,0,BC_FORI,4,4,128,BC_SUBVN,8,1,7,
BC_TGETR,9,7,0,BC_TSETR,9,8,0,BC_FORL,4,252,127,BC_KPRI,4,0,0,BC_TSETR,4,2,0,
BC_RET1,3,2,0,BC_RET0,0,1,0,0,2,
/* table.move */ 0,5,12,0,0,0,35,BC_ISTYPE,0,12,0,BC_ISTYPE,1,14,0,BC_ISTYPE,
2,14,0,BC_ISTYPE,3,14,0,BC_ISNEP,4,0,0,BC_JMP,5,1,128,BC_MOV,4,0,0,BC_ISTYPE,
4,12,0,BC_ISGT,1,2,0,BC_JMP,5,24,128,BC_SUBVV,5,1,3,BC_ISLT,2,3,0,BC_JMP,6,4,
128,BC_ISLE,3,1,0,BC_JMP,6,2,128,BC_ISEQV,4,0,0,BC_JMP,6,9,128,BC_MOV,6,1,0,
BC_MOV,7,2,0,BC_KSHORT,8,1,0,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,
BC_TSETR,11,10,4,BC_FORL,6,252,127,BC_JMP,6,8,128,BC_MOV,6,2,0,BC_MOV,7,1,0,
BC_KSHORT,8,255,255,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,BC_TSETR,
11,10,4,BC_FORL,6,252,127,BC_RET1,4,2,0,
#else
/* math.deg */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,241,135,158,166,3,
220,203,178,130,4,
/* math.rad */ 0,1,2,0,0,1,2,BC_MULVN,1,0,0,BC_RET1,1,2,0,243,244,148,165,20,
198,190,199,252,3,
/* string.len */ 0,1,2,0,0,0,3,BC_ISTYPE,0,5,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
/* table.foreachi */ 0,2,9,0,0,0,15,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,
BC_KSHORT,2,1,0,BC_LEN,3,0,0,BC_KSHORT,4,1,0,BC_FORI,2,8,128,BC_MOV,6,1,0,
BC_MOV,7,5,0,BC_TGETR,8,5,0,BC_CALL,6,3,2,BC_ISEQP,6,0,0,BC_JMP,7,1,128,
BC_RET1,6,2,0,BC_FORL,2,248,127,BC_RET0,0,1,0,
/* table.foreach */ 0,2,10,0,0,1,16,BC_ISTYPE,0,12,0,BC_ISTYPE,1,9,0,BC_KPRI,
2,0,0,BC_MOV,3,0,0,BC_KNUM,4,0,0,BC_JMP,5,7,128,BC_MOV,7,1,0,BC_MOV,8,5,0,
BC_MOV,9,6,0,BC_CALL,7,3,2,BC_ISEQP,7,0,0,BC_JMP,8,1,128,BC_RET1,7,2,0,
BC_ITERN,5,3,3,BC_ITERL,5,247,127,BC_RET0,0,1,0,1,255,255,249,255,15,
/* table.getn */ 0,1,2,0,0,0,3,BC_ISTYPE,0,12,0,BC_LEN,1,0,0,BC_RET1,1,2,0,
/* table.remove */ 0,2,10,0,0,2,30,BC_ISTYPE,0,12,0,BC_LEN,2,0,0,BC_ISNEP,1,0,
0,BC_JMP,3,7,128,BC_ISEQN,2,0,0,BC_JMP,3,23,128,BC_TGETR,3,2,0,BC_KPRI,4,0,0,
BC_TSETR,4,2,0,BC_RET1,3,2,0,BC_JMP,3,18,128,BC_ISTYPE,1,14,0,BC_KSHORT,3,1,0,
BC_ISGT,3,1,0,BC_JMP,3,14,128,BC_ISGT,1,2,0,BC_JMP,3,12,128,BC_TGETR,3,1,0,
BC_ADDVN,4,1,1,BC_MOV,5,2,0,BC_KSHORT,6,1,0,BC_FORI,4,4,128,BC_SUBVN,8,1,7,
BC_TGETR,9,7,0,BC_TSETR,9,8,0,BC_FORL,4,252,127,BC_KPRI,4,0,0,BC_TSETR,4,2,0,
BC_RET1,3,2,0,BC_RET0,0,1,0,0,2,
/* table.move */ 0,5,12,0,0,0,35,BC_ISTYPE,0,12,0,BC_ISTYPE,1,14,0,BC_ISTYPE,
2,14,0,BC_ISTYPE,3,14,0,BC_ISNEP,4,0,0,BC_JMP,5,1,128,BC_MOV,4,0,0,BC_ISTYPE,
4,12,0,BC_ISGT,1,2,0,BC_JMP,5,24,128,BC_SUBVV,5,1,3,BC_ISLT,2,3,0,BC_JMP,6,4,
128,BC_ISLE,3,1,0,BC_JMP,6,2,128,BC_ISEQV,4,0,0,BC_JMP,6,9,128,BC_MOV,6,1,0,
BC_MOV,7,2,0,BC_KSHORT,8,1,0,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,
BC_TSETR,11,10,4,BC_FORL,6,252,127,BC_JMP,6,8,128,BC_MOV,6,2,0,BC_MOV,7,1,0,
BC_KSHORT,8,255,255,BC_FORI,6,4,128,BC_ADDVV,10,5,9,BC_TGETR,11,9,0,BC_TSETR,
11,10,4,BC_FORL,6,252,127,BC_RET1,4,2,0,
#endif
0
};
static const struct { const char *name; int ofs; } libbc_map[] = {
{"math_deg",0},
{"math_rad",25},
{"string_len",50},
{"table_foreachi",69},
{"table_foreach",136},
{"table_getn",213},
{"table_remove",232},
{"table_move",361},
{NULL,508}
};
+473
View File
@@ -0,0 +1,473 @@
/*
** LuaJIT VM builder: PE object emitter.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Only used for building on Windows, since we cannot assume the presence
** of a suitable assembler. The host and target byte order must match.
*/
#include "buildvm.h"
#include "lj_bc.h"
#if LJ_TARGET_WINDOWS || LJ_TARGET_CYGWIN
/* Context for PE object emitter. */
static char *strtab;
static size_t strtabofs;
/* -- PE object definitions ----------------------------------------------- */
/* PE header. */
typedef struct PEheader {
uint16_t arch;
uint16_t nsects;
uint32_t time;
uint32_t symtabofs;
uint32_t nsyms;
uint16_t opthdrsz;
uint16_t flags;
} PEheader;
/* PE section. */
typedef struct PEsection {
char name[8];
uint32_t vsize;
uint32_t vaddr;
uint32_t size;
uint32_t ofs;
uint32_t relocofs;
uint32_t lineofs;
uint16_t nreloc;
uint16_t nline;
uint32_t flags;
} PEsection;
/* PE relocation. */
typedef struct PEreloc {
uint32_t vaddr;
uint32_t symidx;
uint16_t type;
} PEreloc;
/* Cannot use sizeof, because it pads up to the max. alignment. */
#define PEOBJ_RELOC_SIZE (4+4+2)
/* PE symbol table entry. */
typedef struct PEsym {
union {
char name[8];
uint32_t nameref[2];
} n;
uint32_t value;
int16_t sect;
uint16_t type;
uint8_t scl;
uint8_t naux;
} PEsym;
/* PE symbol table auxiliary entry for a section. */
typedef struct PEsymaux {
uint32_t size;
uint16_t nreloc;
uint16_t nline;
uint32_t cksum;
uint16_t assoc;
uint8_t comdatsel;
uint8_t unused[3];
} PEsymaux;
/* Cannot use sizeof, because it pads up to the max. alignment. */
#define PEOBJ_SYM_SIZE (8+4+2+2+1+1)
/* PE object CPU specific defines. */
#if LJ_TARGET_X86
#define PEOBJ_ARCH_TARGET 0x014c
#define PEOBJ_RELOC_REL32 0x14 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x06
#define PEOBJ_RELOC_OFS 0
#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
#elif LJ_TARGET_X64
#define PEOBJ_ARCH_TARGET 0x8664
#define PEOBJ_RELOC_REL32 0x04 /* MS: REL32, GNU: DISP32. */
#define PEOBJ_RELOC_DIR32 0x02
#define PEOBJ_RELOC_ADDR32NB 0x03
#define PEOBJ_RELOC_OFS 0
#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
#define PEOBJ_PDATA_NRELOC 6
#define PEOBJ_XDATA_SIZE (8*2+4+6*2)
#elif LJ_TARGET_ARM64
#define PEOBJ_ARCH_TARGET 0xaa64
#define PEOBJ_RELOC_REL32 0x03 /* MS: BRANCH26. */
#define PEOBJ_RELOC_DIR32 0x01
#define PEOBJ_RELOC_ADDR32NB 0x02
#define PEOBJ_RELOC_OFS (-4)
#define PEOBJ_TEXT_FLAGS 0x60500020 /* 60=r+x, 50=align16, 20=code. */
#define PEOBJ_PDATA_NRELOC 4
#define PEOBJ_XDATA_SIZE (4+24+4 +4+8)
#endif
/* Section numbers (0-based). */
enum {
PEOBJ_SECT_ABS = -2,
PEOBJ_SECT_UNDEF = -1,
PEOBJ_SECT_TEXT,
#ifdef PEOBJ_PDATA_NRELOC
PEOBJ_SECT_PDATA,
PEOBJ_SECT_XDATA,
#elif LJ_TARGET_X86
PEOBJ_SECT_SXDATA,
#endif
PEOBJ_SECT_RDATA_Z,
PEOBJ_NSECTIONS
};
/* Symbol types. */
#define PEOBJ_TYPE_NULL 0
#define PEOBJ_TYPE_FUNC 0x20
/* Symbol storage class. */
#define PEOBJ_SCL_EXTERN 2
#define PEOBJ_SCL_STATIC 3
/* -- PE object emitter --------------------------------------------------- */
/* Emit PE object symbol. */
static void emit_peobj_sym(BuildCtx *ctx, const char *name, uint32_t value,
int sect, int type, int scl)
{
PEsym sym;
size_t len = strlen(name);
if (!strtab) { /* Pass 1: only calculate string table length. */
if (len > 8) strtabofs += len+1;
return;
}
if (len <= 8) {
memcpy(sym.n.name, name, len);
memset(sym.n.name+len, 0, 8-len);
} else {
sym.n.nameref[0] = 0;
sym.n.nameref[1] = (uint32_t)strtabofs;
memcpy(strtab + strtabofs, name, len);
strtab[strtabofs+len] = 0;
strtabofs += len+1;
}
sym.value = value;
sym.sect = (int16_t)(sect+1); /* 1-based section number. */
sym.type = (uint16_t)type;
sym.scl = (uint8_t)scl;
sym.naux = 0;
owrite(ctx, &sym, PEOBJ_SYM_SIZE);
}
/* Emit PE object section symbol. */
static void emit_peobj_sym_sect(BuildCtx *ctx, PEsection *pesect, int sect)
{
PEsym sym;
PEsymaux aux;
if (!strtab) return; /* Pass 1: no output. */
memcpy(sym.n.name, pesect[sect].name, 8);
sym.value = 0;
sym.sect = (int16_t)(sect+1); /* 1-based section number. */
sym.type = PEOBJ_TYPE_NULL;
sym.scl = PEOBJ_SCL_STATIC;
sym.naux = 1;
owrite(ctx, &sym, PEOBJ_SYM_SIZE);
memset(&aux, 0, sizeof(PEsymaux));
aux.size = pesect[sect].size;
aux.nreloc = pesect[sect].nreloc;
owrite(ctx, &aux, PEOBJ_SYM_SIZE);
}
/* Emit Windows PE object file. */
void emit_peobj(BuildCtx *ctx)
{
PEheader pehdr;
PEsection pesect[PEOBJ_NSECTIONS];
uint32_t sofs;
int i, nrsym;
union { uint8_t b; uint32_t u; } host_endian;
#ifdef PEOBJ_PDATA_NRELOC
uint32_t fcofs = (uint32_t)ctx->sym[ctx->nsym-1].ofs;
#endif
sofs = sizeof(PEheader) + PEOBJ_NSECTIONS*sizeof(PEsection);
/* Fill in PE sections. */
memset(&pesect, 0, PEOBJ_NSECTIONS*sizeof(PEsection));
memcpy(pesect[PEOBJ_SECT_TEXT].name, ".text", sizeof(".text")-1);
pesect[PEOBJ_SECT_TEXT].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_TEXT].size = (uint32_t)ctx->codesz);
pesect[PEOBJ_SECT_TEXT].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_TEXT].nreloc = (uint16_t)ctx->nreloc) * PEOBJ_RELOC_SIZE;
/* Flags: 60 = read+execute, 50 = align16, 20 = code. */
pesect[PEOBJ_SECT_TEXT].flags = PEOBJ_TEXT_FLAGS;
#ifdef PEOBJ_PDATA_NRELOC
memcpy(pesect[PEOBJ_SECT_PDATA].name, ".pdata", sizeof(".pdata")-1);
pesect[PEOBJ_SECT_PDATA].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_PDATA].size = PEOBJ_PDATA_NRELOC*4);
pesect[PEOBJ_SECT_PDATA].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_PDATA].nreloc = PEOBJ_PDATA_NRELOC) * PEOBJ_RELOC_SIZE;
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_PDATA].flags = 0x40300040;
memcpy(pesect[PEOBJ_SECT_XDATA].name, ".xdata", sizeof(".xdata")-1);
pesect[PEOBJ_SECT_XDATA].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_XDATA].size = PEOBJ_XDATA_SIZE); /* See below. */
pesect[PEOBJ_SECT_XDATA].relocofs = sofs;
sofs += (pesect[PEOBJ_SECT_XDATA].nreloc = 1) * PEOBJ_RELOC_SIZE;
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_XDATA].flags = 0x40300040;
#elif LJ_TARGET_X86
memcpy(pesect[PEOBJ_SECT_SXDATA].name, ".sxdata", sizeof(".sxdata")-1);
pesect[PEOBJ_SECT_SXDATA].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_SXDATA].size = 4);
pesect[PEOBJ_SECT_SXDATA].relocofs = sofs;
/* Flags: 40 = read, 30 = align4, 02 = lnk_info, 40 = initialized data. */
pesect[PEOBJ_SECT_SXDATA].flags = 0x40300240;
#endif
memcpy(pesect[PEOBJ_SECT_RDATA_Z].name, ".rdata$Z", sizeof(".rdata$Z")-1);
pesect[PEOBJ_SECT_RDATA_Z].ofs = sofs;
sofs += (pesect[PEOBJ_SECT_RDATA_Z].size = (uint32_t)strlen(ctx->dasm_ident)+1);
/* Flags: 40 = read, 30 = align4, 40 = initialized data. */
pesect[PEOBJ_SECT_RDATA_Z].flags = 0x40300040;
/* Fill in PE header. */
pehdr.arch = PEOBJ_ARCH_TARGET;
pehdr.nsects = PEOBJ_NSECTIONS;
pehdr.time = 0; /* Timestamp is optional. */
pehdr.symtabofs = sofs;
pehdr.opthdrsz = 0;
pehdr.flags = 0;
/* Compute the size of the symbol table:
** @feat.00 + nsections*2
** + asm_start + nsym
** + nrsym
*/
nrsym = ctx->nrelocsym;
pehdr.nsyms = 1+PEOBJ_NSECTIONS*2 + 1+ctx->nsym + nrsym;
#ifdef PEOBJ_PDATA_NRELOC
pehdr.nsyms += 1; /* Symbol for lj_err_unwind_win. */
#endif
/* Write PE object header and all sections. */
owrite(ctx, &pehdr, sizeof(PEheader));
owrite(ctx, &pesect, sizeof(PEsection)*PEOBJ_NSECTIONS);
/* Write .text section. */
host_endian.u = 1;
if (host_endian.b != LJ_ENDIAN_SELECT(1, 0)) {
fprintf(stderr, "Error: different byte order for host and target\n");
exit(1);
}
owrite(ctx, ctx->code, ctx->codesz);
for (i = 0; i < ctx->nreloc; i++) {
PEreloc reloc;
reloc.vaddr = (uint32_t)ctx->reloc[i].ofs + PEOBJ_RELOC_OFS;
reloc.symidx = 1+2+ctx->reloc[i].sym; /* Reloc syms are after .text sym. */
reloc.type = ctx->reloc[i].type ? PEOBJ_RELOC_REL32 : PEOBJ_RELOC_DIR32;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
#if LJ_TARGET_X64
{ /* Write .pdata section. */
uint32_t pdata[3]; /* Start of .text, end of .text and .xdata. */
PEreloc reloc;
pdata[0] = 0; pdata[1] = fcofs; pdata[2] = 0;
owrite(ctx, &pdata, sizeof(pdata));
pdata[0] = fcofs; pdata[1] = (uint32_t)ctx->codesz; pdata[2] = 20;
owrite(ctx, &pdata, sizeof(pdata));
reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 12; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 16; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 20; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
{ /* Write .xdata section. */
uint16_t xdata[8+2+6];
PEreloc reloc;
xdata[0] = 0x01|0x08|0x10; /* Ver. 1, uhandler/ehandler, prolog size 0. */
xdata[1] = 0x0005; /* Number of unwind codes, no frame pointer. */
xdata[2] = 0x4200; /* Stack offset 4*8+8 = aword*5. */
xdata[3] = 0x3000; /* Push rbx. */
xdata[4] = 0x6000; /* Push rsi. */
xdata[5] = 0x7000; /* Push rdi. */
xdata[6] = 0x5000; /* Push rbp. */
xdata[7] = 0; /* Alignment. */
xdata[8] = xdata[9] = 0; /* Relocated address of exception handler. */
xdata[10] = 0x01; /* Ver. 1, no handler, prolog size 0. */
xdata[11] = 0x1504; /* Number of unwind codes, fp = rbp, fpofs = 16. */
xdata[12] = 0x0300; /* set_fpreg. */
xdata[13] = 0x0200; /* stack offset 0*8+8 = aword*1. */
xdata[14] = 0x3000; /* Push rbx. */
xdata[15] = 0x5000; /* Push rbp. */
owrite(ctx, &xdata, sizeof(xdata));
reloc.vaddr = 2*8; reloc.symidx = 1+2+nrsym+2+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
#elif LJ_TARGET_ARM64
/* https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling */
{ /* Write .pdata section. */
uint32_t pdata[4];
PEreloc reloc;
pdata[0] = 0;
pdata[1] = 0;
pdata[2] = fcofs;
pdata[3] = 4+24+4;
owrite(ctx, &pdata, sizeof(pdata));
/* Start of .text and start of .xdata. */
reloc.vaddr = 0; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 4; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
/* Start of vm_ffi_call and start of second part of .xdata. */
reloc.vaddr = 8; reloc.symidx = 1+2+nrsym+2+2+1;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
reloc.vaddr = 12; reloc.symidx = 1+2+nrsym+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
{ /* Write .xdata section. */
uint32_t u32;
uint8_t *p, uwc[24];
PEreloc reloc;
#define CBE16(x) (*p = ((x) >> 8) & 0xff, p[1] = (x) & 0xff, p += 2)
#define CALLOC_S(s) (*p++ = ((s) >> 4)) /* s < 512 */
#define CSAVE_FPLR(o) (*p++ = 0x40 | ((o) >> 3)) /* o <= 504 */
#define CSAVE_REGP(r,o) CBE16(0xc800 | (((r) - 19) << 6) | ((o) >> 3))
#define CSAVE_REGS(r1,r2,o1) do { \
int r, o; for (r = r1, o = o1; r <= r2; r += 2, o -= 16) CSAVE_REGP(r, o); \
} while (0)
#define CSAVE_REGPX(r,o) CBE16(0xcc00 | (((r) - 19) << 6) | (~(o) >> 3))
#define CSAVE_FREGP(r,o) CBE16(0xd800 | (((r) - 8) << 6) | ((o) >> 3))
#define CSAVE_FREGS(r1,r2,o1) do { \
int r, o; for (r = r1, o = o1; r <= r2; r += 2, o -= 16) CSAVE_FREGP(r, o); \
} while (0)
#define CADD_FP(s) CBE16(0xe200 | ((s) >> 3)) /* s < 8*256 */
#define CODE_NOP 0xe3
#define CODE_END 0xe4
#define CEND_ALIGN do { \
*p++ = CODE_END; \
while ((p - uwc) & 3) *p++ = CODE_NOP; \
} while (0)
/* Unwind codes for .text section with handler. */
p = uwc;
CADD_FP(192); /* +2 */
CSAVE_REGS(19, 28, 176); /* +5*2 */
CSAVE_FREGS(8, 15, 96); /* +4*2 */
CSAVE_FPLR(192); /* +1 */
CALLOC_S(208); /* +1 */
CEND_ALIGN; /* +1 +1 -> 24 */
u32 = ((24u >> 2) << 27) | (1u << 20) | (fcofs >> 2);
owrite(ctx, &u32, 4);
owrite(ctx, &uwc, 24);
u32 = 0; /* Handler RVA to be relocated at 4 + 24. */
owrite(ctx, &u32, 4);
/* Unwind codes for vm_ffi_call without handler. */
p = uwc;
CADD_FP(16); /* +2 */
CSAVE_FPLR(16); /* +1 */
CSAVE_REGPX(19, -32); /* +2 */
CEND_ALIGN; /* +1 +2 -> 8 */
u32 = ((8u >> 2) << 27) | (((uint32_t)ctx->codesz - fcofs) >> 2);
owrite(ctx, &u32, 4);
owrite(ctx, &uwc, 8);
reloc.vaddr = 4 + 24; reloc.symidx = 1+2+nrsym+2+2;
reloc.type = PEOBJ_RELOC_ADDR32NB;
owrite(ctx, &reloc, PEOBJ_RELOC_SIZE);
}
#elif LJ_TARGET_X86
/* Write .sxdata section. */
for (i = 0; i < nrsym; i++) {
if (!strcmp(ctx->relocsym[i], "_lj_err_unwind_win")) {
uint32_t symidx = 1+2+i;
owrite(ctx, &symidx, 4);
break;
}
}
if (i == nrsym) {
fprintf(stderr, "Error: extern lj_err_unwind_win not used\n");
exit(1);
}
#endif
/* Write .rdata$Z section. */
owrite(ctx, ctx->dasm_ident, strlen(ctx->dasm_ident)+1);
/* Write symbol table. */
strtab = NULL; /* 1st pass: collect string sizes. */
for (;;) {
strtabofs = 4;
/* Mark as SafeSEH compliant. */
emit_peobj_sym(ctx, "@feat.00", 1,
PEOBJ_SECT_ABS, PEOBJ_TYPE_NULL, PEOBJ_SCL_STATIC);
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_TEXT);
for (i = 0; i < nrsym; i++)
emit_peobj_sym(ctx, ctx->relocsym[i], 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
#ifdef PEOBJ_PDATA_NRELOC
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_PDATA);
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_XDATA);
emit_peobj_sym(ctx, "lj_err_unwind_win", 0,
PEOBJ_SECT_UNDEF, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
#elif LJ_TARGET_X86
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_SXDATA);
#endif
emit_peobj_sym(ctx, ctx->beginsym, 0,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_NULL, PEOBJ_SCL_EXTERN);
for (i = 0; i < ctx->nsym; i++)
emit_peobj_sym(ctx, ctx->sym[i].name, (uint32_t)ctx->sym[i].ofs,
PEOBJ_SECT_TEXT, PEOBJ_TYPE_FUNC, PEOBJ_SCL_EXTERN);
emit_peobj_sym_sect(ctx, pesect, PEOBJ_SECT_RDATA_Z);
if (strtab)
break;
/* 2nd pass: alloc strtab, write syms and copy strings. */
strtab = (char *)malloc(strtabofs);
*(uint32_t *)strtab = (uint32_t)strtabofs;
}
/* Write string table. */
owrite(ctx, strtab, strtabofs);
}
#else
void emit_peobj(BuildCtx *ctx)
{
UNUSED(ctx);
fprintf(stderr, "Error: no PE object support for this target\n");
exit(1);
}
#endif
+234
View File
@@ -0,0 +1,234 @@
----------------------------------------------------------------------------
-- Lua script to dump the bytecode of the library functions written in Lua.
-- The resulting 'buildvm_libbc.h' is used for the build process of LuaJIT.
----------------------------------------------------------------------------
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
local ffi = require("ffi")
local bit = require("bit")
local vmdef = require("jit.vmdef")
local bcnames = vmdef.bcnames
local format = string.format
local isbe = (string.byte(string.dump(function() end), 5) % 2 == 1)
local function usage(arg)
io.stderr:write("Usage: ", arg and arg[0] or "genlibbc",
" [-o buildvm_libbc.h] lib_*.c\n")
os.exit(1)
end
local function parse_arg(arg)
local outfile = "-"
if not (arg and arg[1]) then
usage(arg)
end
if arg[1] == "-o" then
outfile = arg[2]
if not outfile then usage(arg) end
table.remove(arg, 1)
table.remove(arg, 1)
end
return outfile
end
local function read_files(names)
local src = ""
for _,name in ipairs(names) do
local fp = assert(io.open(name))
src = src .. fp:read("*a")
fp:close()
end
return src
end
local function transform_lua(code)
local fixup = {}
local n = -30000
code = string.gsub(code, "CHECK_(%w*)%((.-)%)", function(tp, var)
n = n + 1
fixup[n] = { "CHECK", tp }
return format("%s=%d", var, n)
end)
code = string.gsub(code, "PAIRS%((.-)%)", function(var)
fixup.PAIRS = true
return format("nil, %s, 0x4dp80", var)
end)
return "return "..code, fixup
end
local function read_uleb128(p)
local v = p[0]; p = p + 1
if v >= 128 then
local sh = 7; v = v - 128
repeat
local r = p[0]
v = v + bit.lshift(bit.band(r, 127), sh)
sh = sh + 7
p = p + 1
until r < 128
end
return p, v
end
-- ORDER LJ_T
local name2itype = {
str = 5, func = 9, tab = 12, int = 14, num = 15
}
local BC, BCN = {}, {}
for i=0,#bcnames/6-1 do
local name = bcnames:sub(i*6+1, i*6+6):gsub(" ", "")
BC[name] = i
BCN[i] = name
end
local xop, xra = isbe and 3 or 0, isbe and 2 or 1
local xrc, xrb = isbe and 1 or 2, isbe and 0 or 3
local function fixup_dump(dump, fixup)
local buf = ffi.new("uint8_t[?]", #dump+1, dump)
local p = buf+5
local n, sizebc
p, n = read_uleb128(p)
local start = p
p = p + 4
p = read_uleb128(p)
p = read_uleb128(p)
p, sizebc = read_uleb128(p)
local startbc = tonumber(p - start)
local rawtab = {}
for i=0,sizebc-1 do
local op = p[xop]
if op == BC.KSHORT then
local rd = p[xrc] + 256*p[xrb]
rd = bit.arshift(bit.lshift(rd, 16), 16)
local f = fixup[rd]
if f then
if f[1] == "CHECK" then
local tp = f[2]
if tp == "tab" then rawtab[p[xra]] = true end
p[xop] = tp == "num" and BC.ISNUM or BC.ISTYPE
p[xrb] = 0
p[xrc] = name2itype[tp]
else
error("unhandled fixup type: "..f[1])
end
end
elseif op == BC.TGETV then
if rawtab[p[xrb]] then
p[xop] = BC.TGETR
end
elseif op == BC.TSETV then
if rawtab[p[xrb]] then
p[xop] = BC.TSETR
end
elseif op == BC.ITERC then
if fixup.PAIRS then
p[xop] = BC.ITERN
end
end
p = p + 4
end
local ndump = ffi.string(start, n)
-- Fixup hi-part of 0x4dp80 to LJ_KEYINDEX.
ndump = ndump:gsub("\x80\x80\xcd\xaa\x04", "\xff\xff\xf9\xff\x0f")
return { dump = ndump, startbc = startbc, sizebc = sizebc }
end
local function find_defs(src, mode)
local defs = {}
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
local tcode, fixup = transform_lua(code)
local func = assert(load(tcode, "", mode))
defs[name] = fixup_dump(string.dump(func, mode), fixup)
defs[#defs+1] = name
end
return defs
end
local function gen_header(defs32, defs64)
local t = {}
local function w(x) t[#t+1] = x end
w("/* This is a generated file. DO NOT EDIT! */\n\n")
w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
for j,defs in ipairs{defs64, defs32} do
local s, sb = "", ""
for i,name in ipairs(defs) do
local d = defs[name]
s = s .. d.dump
sb = sb .. string.char(i) .. ("\0"):rep(d.startbc - 1)
.. (isbe and "\0\0\0\255" or "\255\0\0\0"):rep(d.sizebc)
.. ("\0"):rep(#d.dump - d.startbc - d.sizebc*4)
end
if j == 1 then
w("static const uint8_t libbc_code[] = {\n#if LJ_FR2\n")
else
w("\n#else\n")
end
local n = 0
for i=1,#s do
local x = string.byte(s, i)
local xb = string.byte(sb, i)
if xb == 255 then
local name = BCN[x]
local m = #name + 4
if n + m > 78 then n = 0; w("\n") end
n = n + m
w("BC_"); w(name)
else
local m = x < 10 and 2 or (x < 100 and 3 or 4)
if xb == 0 then
if n + m > 78 then n = 0; w("\n") end
else
local name = defs[xb]:gsub("_", ".")
if n ~= 0 then w("\n") end
w("/* "); w(name); w(" */ ")
n = #name + 7
end
n = n + m
w(x)
end
w(",")
end
end
w("\n#endif\n0\n};\n\n")
w("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
local m32, m64 = 0, 0
for i,name in ipairs(defs32) do
assert(name == defs64[i])
w('{"'); w(name); w('",'); w(m32) w('},\n')
m32 = m32 + #defs32[name].dump
m64 = m64 + #defs64[name].dump
assert(m32 == m64)
end
w("{NULL,"); w(m32); w("}\n};\n\n")
return table.concat(t)
end
local function write_file(name, data)
if name == "-" then
assert(io.write(data))
assert(io.flush())
else
local fp = io.open(name)
if fp then
local old = fp:read("*a")
fp:close()
if data == old then return end
end
fp = assert(io.open(name, "w"))
assert(fp:write(data))
assert(fp:close())
end
end
local outfile = parse_arg(arg)
local src = read_files(arg)
local defs32 = find_defs(src, "Wdts")
local defs64 = find_defs(src, "Xdts")
local hdr = gen_header(defs32, defs64)
write_file(outfile, hdr)
+436
View File
@@ -0,0 +1,436 @@
----------------------------------------------------------------------------
-- Lua script to generate a customized, minified version of Lua.
-- The resulting 'minilua' is used for the build process of LuaJIT.
----------------------------------------------------------------------------
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
local sub, match, gsub = string.sub, string.match, string.gsub
local LUA_VERSION = "5.1.5"
local LUA_SOURCE
local function usage()
io.stderr:write("Usage: ", arg and arg[0] or "genminilua",
" lua-", LUA_VERSION, "-source-dir\n")
os.exit(1)
end
local function find_sources()
LUA_SOURCE = arg and arg[1]
if not LUA_SOURCE then usage() end
if sub(LUA_SOURCE, -1) ~= "/" then LUA_SOURCE = LUA_SOURCE.."/" end
local fp = io.open(LUA_SOURCE .. "lua.h")
if not fp then
LUA_SOURCE = LUA_SOURCE.."src/"
fp = io.open(LUA_SOURCE .. "lua.h")
if not fp then usage() end
end
local all = fp:read("*a")
fp:close()
if not match(all, 'LUA_RELEASE%s*"Lua '..LUA_VERSION..'"') then
io.stderr:write("Error: version mismatch\n")
usage()
end
end
local LUA_FILES = {
"lmem.c", "lobject.c", "ltm.c", "lfunc.c", "ldo.c", "lstring.c", "ltable.c",
"lgc.c", "lstate.c", "ldebug.c", "lzio.c", "lopcodes.c",
"llex.c", "lcode.c", "lparser.c", "lvm.c", "lapi.c", "lauxlib.c",
"lbaselib.c", "ltablib.c", "liolib.c", "loslib.c", "lstrlib.c", "linit.c",
}
local REMOVE_LIB = {}
gsub([[
collectgarbage dofile gcinfo getfenv getmetatable load print rawequal rawset
select tostring xpcall
foreach foreachi getn maxn setn
popen tmpfile seek setvbuf __tostring
clock date difftime execute getenv rename setlocale time tmpname
dump gfind len reverse
LUA_LOADLIBNAME LUA_MATHLIBNAME LUA_DBLIBNAME
]], "%S+", function(name)
REMOVE_LIB[name] = true
end)
local REMOVE_EXTINC = { ["<assert.h>"] = true, ["<locale.h>"] = true, }
local CUSTOM_MAIN = [[
typedef unsigned int UB;
static UB barg(lua_State *L,int idx){
union{lua_Number n;U64 b;}bn;
bn.n=lua_tonumber(L,idx)+6755399441055744.0;
if (bn.n==0.0&&!lua_isnumber(L,idx))luaL_typerror(L,idx,"number");
return(UB)bn.b;
}
#define BRET(b) lua_pushnumber(L,(lua_Number)(int)(b));return 1;
static int tobit(lua_State *L){
BRET(barg(L,1))}
static int bnot(lua_State *L){
BRET(~barg(L,1))}
static int band(lua_State *L){
int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b&=barg(L,i);BRET(b)}
static int bor(lua_State *L){
int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b|=barg(L,i);BRET(b)}
static int bxor(lua_State *L){
int i;UB b=barg(L,1);for(i=lua_gettop(L);i>1;i--)b^=barg(L,i);BRET(b)}
static int lshift(lua_State *L){
UB b=barg(L,1),n=barg(L,2)&31;BRET(b<<n)}
static int rshift(lua_State *L){
UB b=barg(L,1),n=barg(L,2)&31;BRET(b>>n)}
static int arshift(lua_State *L){
UB b=barg(L,1),n=barg(L,2)&31;BRET((int)b>>n)}
static int rol(lua_State *L){
UB b=barg(L,1),n=barg(L,2)&31;BRET((b<<n)|(b>>(32-n)))}
static int ror(lua_State *L){
UB b=barg(L,1),n=barg(L,2)&31;BRET((b>>n)|(b<<(32-n)))}
static int bswap(lua_State *L){
UB b=barg(L,1);b=(b>>24)|((b>>8)&0xff00)|((b&0xff00)<<8)|(b<<24);BRET(b)}
static int tohex(lua_State *L){
UB b=barg(L,1);
int n=lua_isnone(L,2)?8:(int)barg(L,2);
const char *hexdigits="0123456789abcdef";
char buf[8];
int i;
if(n<0){n=-n;hexdigits="0123456789ABCDEF";}
if(n>8)n=8;
for(i=(int)n;--i>=0;){buf[i]=hexdigits[b&15];b>>=4;}
lua_pushlstring(L,buf,(size_t)n);
return 1;
}
static const struct luaL_Reg bitlib[] = {
{"tobit",tobit},
{"bnot",bnot},
{"band",band},
{"bor",bor},
{"bxor",bxor},
{"lshift",lshift},
{"rshift",rshift},
{"arshift",arshift},
{"rol",rol},
{"ror",ror},
{"bswap",bswap},
{"tohex",tohex},
{NULL,NULL}
};
int main(int argc, char **argv){
lua_State *L = luaL_newstate();
int i;
luaL_openlibs(L);
luaL_register(L, "bit", bitlib);
if (argc < 2) return sizeof(void *);
lua_createtable(L, 0, 1);
lua_pushstring(L, argv[1]);
lua_rawseti(L, -2, 0);
lua_setglobal(L, "arg");
if (luaL_loadfile(L, argv[1]))
goto err;
for (i = 2; i < argc; i++)
lua_pushstring(L, argv[i]);
if (lua_pcall(L, argc - 2, 0, 0)) {
err:
fprintf(stderr, "Error: %s\n", lua_tostring(L, -1));
return 1;
}
lua_close(L);
return 0;
}
]]
local function read_sources()
local t = {}
for i, name in ipairs(LUA_FILES) do
local fp = assert(io.open(LUA_SOURCE..name, "r"))
t[i] = fp:read("*a")
assert(fp:close())
end
t[#t+1] = CUSTOM_MAIN
return table.concat(t)
end
local includes = {}
local function merge_includes(src)
return gsub(src, '#include%s*"([^"]*)"%s*\n', function(name)
if includes[name] then return "" end
includes[name] = true
local fp = assert(io.open(LUA_SOURCE..name, "r"))
local inc = fp:read("*a")
assert(fp:close())
inc = gsub(inc, "#ifndef%s+%w+_h\n#define%s+%w+_h\n", "")
inc = gsub(inc, "#endif%s*$", "")
return merge_includes(inc)
end)
end
local function get_license(src)
return match(src, "/%*+\n%* Copyright %(.-%*/\n")
end
local function fold_lines(src)
return gsub(src, "\\\n", " ")
end
local strings = {}
local function save_str(str)
local n = #strings+1
strings[n] = str
return "\1"..n.."\2"
end
local function save_strings(src)
src = gsub(src, '"[^"\n]*"', save_str)
return gsub(src, "'[^'\n]*'", save_str)
end
local function restore_strings(src)
return gsub(src, "\1(%d+)\2", function(numstr)
return strings[tonumber(numstr)]
end)
end
local function def_istrue(def)
return def == "INT_MAX > 2147483640L" or
def == "LUAI_BITSINT >= 32" or
def == "SIZE_Bx < LUAI_BITSINT-1" or
def == "cast" or
def == "defined(LUA_CORE)" or
def == "MINSTRTABSIZE" or
def == "LUA_MINBUFFER" or
def == "HARDSTACKTESTS" or
def == "UNUSED"
end
local head, defs = {[[
#ifdef _MSC_VER
typedef unsigned __int64 U64;
#else
typedef unsigned long long U64;
#endif
int _CRT_glob = 0;
]]}, {}
local function preprocess(src)
local t = { match(src, "^(.-)#") }
local lvl, on, oldon = 0, true, {}
for pp, def, txt in string.gmatch(src, "#(%w+) *([^\n]*)\n([^#]*)") do
if pp == "if" or pp == "ifdef" or pp == "ifndef" then
lvl = lvl + 1
oldon[lvl] = on
on = def_istrue(def)
elseif pp == "else" then
if oldon[lvl] then
if on == false then on = true else on = false end
end
elseif pp == "elif" then
if oldon[lvl] then
on = def_istrue(def)
end
elseif pp == "endif" then
on = oldon[lvl]
lvl = lvl - 1
elseif on then
if pp == "include" then
if not head[def] and not REMOVE_EXTINC[def] then
head[def] = true
head[#head+1] = "#include "..def.."\n"
end
elseif pp == "define" then
local k, sp, v = match(def, "([%w_]+)(%s*)(.*)")
if k and not (sp == "" and sub(v, 1, 1) == "(") then
defs[k] = gsub(v, "%a[%w_]*", function(tok)
return defs[tok] or tok
end)
else
t[#t+1] = "#define "..def.."\n"
end
elseif pp ~= "undef" then
error("unexpected directive: "..pp.." "..def)
end
end
if on then t[#t+1] = txt end
end
return gsub(table.concat(t), "%a[%w_]*", function(tok)
return defs[tok] or tok
end)
end
local function merge_header(src, license)
local hdr = string.format([[
/* This is a heavily customized and minimized copy of Lua %s. */
/* It's only used to build LuaJIT. It does NOT have all standard functions! */
]], LUA_VERSION)
return hdr..license..table.concat(head)..src
end
local function strip_unused1(src)
return gsub(src, '( {"?([%w_]+)"?,%s+%a[%w_]*},\n)', function(line, func)
return REMOVE_LIB[func] and "" or line
end)
end
local function strip_unused2(src)
return gsub(src, "Symbolic Execution.-}=", "")
end
local function strip_unused3(src)
src = gsub(src, "extern", "static")
src = gsub(src, "\nstatic([^\n]-)%(([^)]*)%)%(", "\nstatic%1 %2(")
src = gsub(src, "#define lua_assert[^\n]*\n", "")
src = gsub(src, "lua_assert%b();?", "")
src = gsub(src, "default:\n}", "default:;\n}")
src = gsub(src, "lua_lock%b();", "")
src = gsub(src, "lua_unlock%b();", "")
src = gsub(src, "luai_threadyield%b();", "")
src = gsub(src, "luai_userstateopen%b();", "{}")
src = gsub(src, "luai_userstate%w+%b();", "")
src = gsub(src, "%(%(c==.*luaY_parser%)", "luaY_parser")
src = gsub(src, "trydecpoint%(ls,seminfo%)",
"luaX_lexerror(ls,\"malformed number\",TK_NUMBER)")
src = gsub(src, "int c=luaZ_lookahead%b();", "")
src = gsub(src, "luaL_register%(L,[^,]*,co_funcs%);\nreturn 2;",
"return 1;")
src = gsub(src, "getfuncname%b():", "NULL:")
src = gsub(src, "getobjname%b():", "NULL:")
src = gsub(src, "if%([^\n]*hookmask[^\n]*%)\n[^\n]*\n", "")
src = gsub(src, "if%([^\n]*hookmask[^\n]*%)%b{}\n", "")
src = gsub(src, "if%([^\n]*hookmask[^\n]*&&\n[^\n]*%b{}\n", "")
src = gsub(src, "(twoto%b()%()", "%1(size_t)")
src = gsub(src, "i<sizenode", "i<(int)sizenode")
src = gsub(src, "cast%(unsigned int,key%-1%)", "cast(unsigned int,key)-1")
return gsub(src, "\n\n+", "\n")
end
local function strip_comments(src)
return gsub(src, "/%*.-%*/", " ")
end
local function strip_whitespace(src)
src = gsub(src, "^%s+", "")
src = gsub(src, "%s*\n%s*", "\n")
src = gsub(src, "[ \t]+", " ")
src = gsub(src, "(%W) ", "%1")
return gsub(src, " (%W)", "%1")
end
local function rename_tokens1(src)
src = gsub(src, "getline", "getline_")
src = gsub(src, "struct ([%w_]+)", "ZX%1")
return gsub(src, "union ([%w_]+)", "ZY%1")
end
local function rename_tokens2(src)
src = gsub(src, "ZX([%w_]+)", "struct %1")
return gsub(src, "ZY([%w_]+)", "union %1")
end
local function fix_bugs_and_warnings(src)
src = gsub(src, "(luaD_checkstack%(L,p%->maxstacksize)%)", "%1+p->numparams)")
src = gsub(src, "if%(sep==%-1%)(return'%[';)\nelse (luaX_lexerror%b();)", "if (sep!=-1)%2\n%1")
return gsub(src, "(default:{\nNode%*n=mainposition)", "/*fallthrough*/\n%1")
end
local function func_gather(src)
local nodes, list = {}, {}
local pos, len = 1, #src
while pos < len do
local d, w = match(src, "^(#define ([%w_]+)[^\n]*\n)", pos)
if d then
local n = #list+1
list[n] = d
nodes[w] = n
else
local s
d, w, s = match(src, "^(([%w_]+)[^\n]*([{;])\n)", pos)
if not d then
d, w, s = match(src, "^(([%w_]+)[^(]*%b()([{;])\n)", pos)
if not d then d = match(src, "^[^\n]*\n", pos) end
end
if s == "{" then
d = d..sub(match(src, "^%b{}[^;\n]*;?\n", pos+#d-2), 3)
if sub(d, -2) == "{\n" then
d = d..sub(match(src, "^%b{}[^;\n]*;?\n", pos+#d-2), 3)
end
end
local k, v = nil, d
if w == "typedef" then
if match(d, "^typedef enum") then
head[#head+1] = d
else
k = match(d, "([%w_]+);\n$")
if not k then k = match(d, "^.-%(.-([%w_]+)%)%(") end
end
elseif w == "enum" then
head[#head+1] = v
elseif w ~= nil then
k = match(d, "^[^\n]-([%w_]+)[(%[=]")
if k then
if w ~= "static" and k ~= "main" then v = "static "..d end
else
k = w
end
end
if w and k then
local o = nodes[k]
if o then nodes["*"..k] = o end
local n = #list+1
list[n] = v
nodes[k] = n
end
end
pos = pos + #d
end
return nodes, list
end
local function func_visit(nodes, list, used, n)
local i = nodes[n]
for m in string.gmatch(list[i], "[%w_]+") do
if nodes[m] then
local j = used[m]
if not j then
used[m] = i
func_visit(nodes, list, used, m)
elseif i < j then
used[m] = i
end
end
end
end
local function func_collect(src)
local nodes, list = func_gather(src)
local used = {}
func_visit(nodes, list, used, "main")
for n,i in pairs(nodes) do
local j = used[n]
if j and j < i then used["*"..n] = j end
end
for n,i in pairs(nodes) do
if not used[n] then list[i] = "" end
end
return table.concat(list)
end
find_sources()
local src = read_sources()
src = merge_includes(src)
local license = get_license(src)
src = fold_lines(src)
src = strip_unused1(src)
src = save_strings(src)
src = strip_unused2(src)
src = strip_comments(src)
src = preprocess(src)
src = strip_whitespace(src)
src = strip_unused3(src)
src = rename_tokens1(src)
src = func_collect(src)
src = rename_tokens2(src)
src = restore_strings(src)
src = fix_bugs_and_warnings(src)
src = merge_header(src, license)
io.write(src)
+45
View File
@@ -0,0 +1,45 @@
----------------------------------------------------------------------------
-- Lua script to embed the rolling release version in luajit.h.
----------------------------------------------------------------------------
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
local arg = {...}
local FILE_ROLLING_H = arg[1] or "luajit_rolling.h"
local FILE_RELVER_TXT = arg[2] or "luajit_relver.txt"
local FILE_LUAJIT_H = arg[3] or "luajit.h"
local function file_read(file)
local fp = assert(io.open(file, "rb"), "run from the wrong directory")
local data = assert(fp:read("*a"))
fp:close()
return data
end
local function file_write_mod(file, data)
local fp = io.open(file, "rb")
if fp then
local odata = assert(fp:read("*a"))
fp:close()
if odata == data then return end
end
fp = assert(io.open(file, "wb"))
assert(fp:write(data))
assert(fp:close())
end
local text = file_read(FILE_ROLLING_H):gsub("#error.-\n", "")
local relver = file_read(FILE_RELVER_TXT):match("(%d+)")
if relver then
text = text:gsub("ROLLING", relver)
else
io.stderr:write([[
**** WARNING Cannot determine rolling release version from git log.
**** WARNING The 'git' command must be available during the build.
]])
file_write_mod(FILE_RELVER_TXT, "ROLLING\n") -- Fallback for install target.
end
file_write_mod(FILE_LUAJIT_H, text)
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
vmdef.lua
+189
View File
@@ -0,0 +1,189 @@
----------------------------------------------------------------------------
-- LuaJIT bytecode listing module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module lists the bytecode of a Lua function. If it's loaded by -jbc
-- it hooks into the parser and lists all functions of a chunk as they
-- are parsed.
--
-- Example usage:
--
-- luajit -jbc -e 'local x=0; for i=1,1e6 do x=x+i end; print(x)'
-- luajit -jbc=- foo.lua
-- luajit -jbc=foo.list foo.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_LISTFILE. The file is overwritten every time the module
-- is started.
--
-- This module can also be used programmatically:
--
-- local bc = require("jit.bc")
--
-- local function foo() print("hello") end
--
-- bc.dump(foo) --> -- BYTECODE -- [...]
-- print(bc.line(foo, 2)) --> 0002 KSTR 1 1 ; "hello"
--
-- local out = {
-- -- Do something with each line:
-- write = function(t, ...) io.write(...) end,
-- close = function(t) end,
-- flush = function(t) end,
-- }
-- bc.dump(foo, out)
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local bit = require("bit")
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, band, shr = string.byte, bit.band, bit.rshift
local funcinfo, funcbc, funck = jutil.funcinfo, jutil.funcbc, jutil.funck
local funcuvname = jutil.funcuvname
local bcnames = vmdef.bcnames
local stdout, stderr = io.stdout, io.stderr
------------------------------------------------------------------------------
local function ctlsub(c)
if c == "\n" then return "\\n"
elseif c == "\r" then return "\\r"
elseif c == "\t" then return "\\t"
else return format("\\%03d", byte(c))
end
end
-- Return one bytecode line.
local function bcline(func, pc, prefix)
local ins, m = funcbc(func, pc)
if not ins then return end
local ma, mb, mc = band(m, 7), band(m, 15*8), band(m, 15*128)
local a = band(shr(ins, 8), 0xff)
local oidx = 6*band(ins, 0xff)
local op = sub(bcnames, oidx+1, oidx+6)
local s = format("%04d %s %-6s %3s ",
pc, prefix or " ", op, ma == 0 and "" or a)
local d = shr(ins, 16)
if mc == 13*128 then -- BCMjump
return format("%s=> %04d\n", s, pc+d-0x7fff)
end
if mb ~= 0 then
d = band(d, 0xff)
elseif mc == 0 then
return s.."\n"
end
local kc
if mc == 10*128 then -- BCMstr
kc = funck(func, -d-1)
kc = format(#kc > 40 and '"%.40s"~' or '"%s"', gsub(kc, "%c", ctlsub))
elseif mc == 9*128 then -- BCMnum
kc = funck(func, d)
if op == "TSETM " then kc = kc - 2^52 end
elseif mc == 12*128 then -- BCMfunc
local fi = funcinfo(funck(func, -d-1))
if fi.ffid then
kc = vmdef.ffnames[fi.ffid]
else
kc = fi.loc
end
elseif mc == 5*128 then -- BCMuv
kc = funcuvname(func, d)
end
if ma == 5 then -- BCMuv
local ka = funcuvname(func, a)
if kc then kc = ka.." ; "..kc else kc = ka end
end
if mb ~= 0 then
local b = shr(ins, 24)
if kc then return format("%s%3d %3d ; %s\n", s, b, d, kc) end
return format("%s%3d %3d\n", s, b, d)
end
if kc then return format("%s%3d ; %s\n", s, d, kc) end
if mc == 7*128 and d > 32767 then d = d - 65536 end -- BCMlits
return format("%s%3d\n", s, d)
end
-- Collect branch targets of a function.
local function bctargets(func)
local target = {}
for pc=1,1000000000 do
local ins, m = funcbc(func, pc)
if not ins then break end
if band(m, 15*128) == 13*128 then target[pc+shr(ins, 16)-0x7fff] = true end
end
return target
end
-- Dump bytecode instructions of a function.
local function bcdump(func, out, all)
if not out then out = stdout end
local fi = funcinfo(func)
if all and fi.children then
for n=-1,-1000000000,-1 do
local k = funck(func, n)
if not k then break end
if type(k) == "proto" then bcdump(k, out, true) end
end
end
out:write(format("-- BYTECODE -- %s-%d\n", fi.loc, fi.lastlinedefined))
local target = bctargets(func)
for pc=1,1000000000 do
local s = bcline(func, pc, target[pc] and "=>")
if not s then break end
out:write(s)
end
out:write("\n")
out:flush()
end
------------------------------------------------------------------------------
-- Active flag and output file handle.
local active, out
-- List handler.
local function h_list(func)
return bcdump(func, out)
end
-- Detach list handler.
local function bclistoff()
if active then
active = false
jit.attach(h_list)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach list handler.
local function bcliston(outfile)
if active then bclistoff() end
if not outfile then outfile = os.getenv("LUAJIT_LISTFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(h_list, "bc")
active = true
end
-- Public module functions.
return {
line = bcline,
dump = bcdump,
targets = bctargets,
on = bcliston,
off = bclistoff,
start = bcliston -- For -j command line option.
}
+629
View File
@@ -0,0 +1,629 @@
----------------------------------------------------------------------------
-- LuaJIT module to save/list bytecode.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module saves or lists the bytecode for an input file.
-- It's run by the -b command line option.
--
------------------------------------------------------------------------------
local jit = require("jit")
assert(jit.version_num == 20199, "LuaJIT core/library version mismatch")
local bit = require("bit")
-- Symbol name prefix for LuaJIT bytecode.
local LJBC_PREFIX = "luaJIT_BC_"
local type, assert = type, assert
local format = string.format
local tremove, tconcat = table.remove, table.concat
------------------------------------------------------------------------------
local function usage()
io.stderr:write[[
Save LuaJIT bytecode: luajit -b[options] input output
-l Only list bytecode.
-s Strip debug info (default).
-g Keep debug info.
-W Generate 32 bit (non-GC64) bytecode.
-X Generate 64 bit (GC64) bytecode.
-d Generate bytecode in deterministic manner.
-n name Set module name (default: auto-detect from input name).
-t type Set output file type (default: auto-detect from output name).
-a arch Override architecture for object files (default: native).
-o os Override OS for object files (default: native).
-F name Override filename (default: input filename).
-e chunk Use chunk string as input.
-- Stop handling options.
- Use stdin as input and/or stdout as output.
File types: c cc h obj o raw (default)
]]
os.exit(1)
end
local function check(ok, ...)
if ok then return ok, ... end
io.stderr:write("luajit: ", ...)
io.stderr:write("\n")
os.exit(1)
end
local function readfile(ctx, input)
if ctx.string then
return check(loadstring(input, nil, ctx.mode))
elseif ctx.filename then
local data
if input == "-" then
data = io.stdin:read("*a")
else
local fp = assert(io.open(input, "rb"))
data = assert(fp:read("*a"))
assert(fp:close())
end
return check(load(data, ctx.filename, ctx.mode))
else
if input == "-" then input = nil end
return check(loadfile(input, ctx.mode))
end
end
local function savefile(name, mode)
if name == "-" then return io.stdout end
return check(io.open(name, mode))
end
local function set_stdout_binary(ffi)
ffi.cdef[[int _setmode(int fd, int mode);]]
ffi.C._setmode(1, 0x8000)
end
------------------------------------------------------------------------------
local map_type = {
raw = "raw", c = "c", cc = "c", h = "h", o = "obj", obj = "obj",
}
local map_arch = {
x86 = { e = "le", b = 32, m = 3, p = 0x14c, },
x64 = { e = "le", b = 64, m = 62, p = 0x8664, },
arm = { e = "le", b = 32, m = 40, p = 0x1c0, },
arm64 = { e = "le", b = 64, m = 183, p = 0xaa64, },
arm64be = { e = "be", b = 64, m = 183, },
ppc = { e = "be", b = 32, m = 20, },
mips = { e = "be", b = 32, m = 8, f = 0x50001006, },
mipsel = { e = "le", b = 32, m = 8, f = 0x50001006, },
mips64 = { e = "be", b = 64, m = 8, f = 0x80000007, },
mips64el = { e = "le", b = 64, m = 8, f = 0x80000007, },
mips64r6 = { e = "be", b = 64, m = 8, f = 0xa0000407, },
mips64r6el = { e = "le", b = 64, m = 8, f = 0xa0000407, },
}
local map_os = {
linux = true, windows = true, osx = true, freebsd = true, netbsd = true,
openbsd = true, dragonfly = true, solaris = true,
}
local function checkarg(str, map, err)
str = str:lower()
local s = check(map[str], "unknown ", err)
return type(s) == "string" and s or str
end
local function detecttype(str)
local ext = str:lower():match("%.(%a+)$")
return map_type[ext] or "raw"
end
local function checkmodname(str)
check(str:match("^[%w_.%-]+$"), "bad module name")
return str:gsub("[%.%-]", "_")
end
local function detectmodname(str)
if type(str) == "string" then
local tail = str:match("[^/\\]+$")
if tail then str = tail end
local head = str:match("^(.*)%.[^.]*$")
if head then str = head end
str = str:match("^[%w_.%-]+")
else
str = nil
end
check(str, "cannot derive module name, use -n name")
return str:gsub("[%.%-]", "_")
end
------------------------------------------------------------------------------
local function bcsave_tail(fp, output, s)
local ok, err = fp:write(s)
if ok and output ~= "-" then ok, err = fp:close() end
check(ok, "cannot write ", output, ": ", err)
end
local function bcsave_raw(output, s)
if output == "-" and jit.os == "Windows" then
local ok, ffi = pcall(require, "ffi")
check(ok, "FFI library required to write binary file to stdout")
set_stdout_binary(ffi)
end
local fp = savefile(output, "wb")
bcsave_tail(fp, output, s)
end
local function bcsave_c(ctx, output, s)
local fp = savefile(output, "w")
if ctx.type == "c" then
fp:write(format([[
#ifdef __cplusplus
extern "C"
#endif
#ifdef _WIN32
__declspec(dllexport)
#endif
const unsigned char %s%s[] = {
]], LJBC_PREFIX, ctx.modname))
else
fp:write(format([[
#define %s%s_SIZE %d
static const unsigned char %s%s[] = {
]], LJBC_PREFIX, ctx.modname, #s, LJBC_PREFIX, ctx.modname))
end
local t, n, m = {}, 0, 0
for i=1,#s do
local b = tostring(string.byte(s, i))
m = m + #b + 1
if m > 78 then
fp:write(tconcat(t, ",", 1, n), ",\n")
n, m = 0, #b + 1
end
n = n + 1
t[n] = b
end
bcsave_tail(fp, output, tconcat(t, ",", 1, n).."\n};\n")
end
local function bcsave_elfobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct {
uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
uint16_t type, machine;
uint32_t version;
uint32_t entry, phofs, shofs;
uint32_t flags;
uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
} ELF32header;
typedef struct {
uint8_t emagic[4], eclass, eendian, eversion, eosabi, eabiversion, epad[7];
uint16_t type, machine;
uint32_t version;
uint64_t entry, phofs, shofs;
uint32_t flags;
uint16_t ehsize, phentsize, phnum, shentsize, shnum, shstridx;
} ELF64header;
typedef struct {
uint32_t name, type, flags, addr, ofs, size, link, info, align, entsize;
} ELF32sectheader;
typedef struct {
uint32_t name, type;
uint64_t flags, addr, ofs, size;
uint32_t link, info;
uint64_t align, entsize;
} ELF64sectheader;
typedef struct {
uint32_t name, value, size;
uint8_t info, other;
uint16_t sectidx;
} ELF32symbol;
typedef struct {
uint32_t name;
uint8_t info, other;
uint16_t sectidx;
uint64_t value, size;
} ELF64symbol;
typedef struct {
ELF32header hdr;
ELF32sectheader sect[6];
ELF32symbol sym[2];
uint8_t space[4096];
} ELF32obj;
typedef struct {
ELF64header hdr;
ELF64sectheader sect[6];
ELF64symbol sym[2];
uint8_t space[4096];
} ELF64obj;
]]
local symname = LJBC_PREFIX..ctx.modname
local ai = assert(map_arch[ctx.arch])
local is64, isbe = ai.b == 64, ai.e == "be"
-- Handle different host/target endianess.
local function f32(x) return x end
local f16, fofs = f32, f32
if ffi.abi("be") ~= isbe then
f32 = bit.bswap
function f16(x) return bit.rshift(bit.bswap(x), 16) end
if is64 then
local two32 = ffi.cast("int64_t", 2^32)
function fofs(x) return bit.bswap(x)*two32 end
else
fofs = f32
end
end
-- Create ELF object and fill in header.
local o = ffi.new(is64 and "ELF64obj" or "ELF32obj")
local hdr = o.hdr
if ctx.os == "bsd" or ctx.os == "other" then -- Determine native hdr.eosabi.
local bf = assert(io.open("/bin/ls", "rb"))
local bs = bf:read(9)
bf:close()
ffi.copy(o, bs, 9)
check(hdr.emagic[0] == 127, "no support for writing native object files")
else
hdr.emagic = "\127ELF"
hdr.eosabi = ({ freebsd=9, netbsd=2, openbsd=12, solaris=6 })[ctx.os] or 0
end
hdr.eclass = is64 and 2 or 1
hdr.eendian = isbe and 2 or 1
hdr.eversion = 1
hdr.type = f16(1)
hdr.machine = f16(ai.m)
hdr.flags = f32(ai.f or 0)
hdr.version = f32(1)
hdr.shofs = fofs(ffi.offsetof(o, "sect"))
hdr.ehsize = f16(ffi.sizeof(hdr))
hdr.shentsize = f16(ffi.sizeof(o.sect[0]))
hdr.shnum = f16(6)
hdr.shstridx = f16(2)
-- Fill in sections and symbols.
local sofs, ofs = ffi.offsetof(o, "space"), 1
for i,name in ipairs{
".symtab", ".shstrtab", ".strtab", ".rodata", ".note.GNU-stack",
} do
local sect = o.sect[i]
sect.align = fofs(1)
sect.name = f32(ofs)
ffi.copy(o.space+ofs, name)
ofs = ofs + #name+1
end
o.sect[1].type = f32(2) -- .symtab
o.sect[1].link = f32(3)
o.sect[1].info = f32(1)
o.sect[1].align = fofs(8)
o.sect[1].ofs = fofs(ffi.offsetof(o, "sym"))
o.sect[1].entsize = fofs(ffi.sizeof(o.sym[0]))
o.sect[1].size = fofs(ffi.sizeof(o.sym))
o.sym[1].name = f32(1)
o.sym[1].sectidx = f16(4)
o.sym[1].size = fofs(#s)
o.sym[1].info = 17
o.sect[2].type = f32(3) -- .shstrtab
o.sect[2].ofs = fofs(sofs)
o.sect[2].size = fofs(ofs)
o.sect[3].type = f32(3) -- .strtab
o.sect[3].ofs = fofs(sofs + ofs)
o.sect[3].size = fofs(#symname+2)
ffi.copy(o.space+ofs+1, symname)
ofs = ofs + #symname + 2
o.sect[4].type = f32(1) -- .rodata
o.sect[4].flags = fofs(2)
o.sect[4].ofs = fofs(sofs + ofs)
o.sect[4].size = fofs(#s)
o.sect[5].type = f32(1) -- .note.GNU-stack
o.sect[5].ofs = fofs(sofs + ofs + #s)
-- Write ELF object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
bcsave_tail(fp, output, s)
end
local function bcsave_peobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct {
uint16_t arch, nsects;
uint32_t time, symtabofs, nsyms;
uint16_t opthdrsz, flags;
} PEheader;
typedef struct {
char name[8];
uint32_t vsize, vaddr, size, ofs, relocofs, lineofs;
uint16_t nreloc, nline;
uint32_t flags;
} PEsection;
typedef struct __attribute((packed)) {
union {
char name[8];
uint32_t nameref[2];
};
uint32_t value;
int16_t sect;
uint16_t type;
uint8_t scl, naux;
} PEsym;
typedef struct __attribute((packed)) {
uint32_t size;
uint16_t nreloc, nline;
uint32_t cksum;
uint16_t assoc;
uint8_t comdatsel, unused[3];
} PEsymaux;
typedef struct {
PEheader hdr;
PEsection sect[2];
// Must be an even number of symbol structs.
PEsym sym0;
PEsymaux sym0aux;
PEsym sym1;
PEsymaux sym1aux;
PEsym sym2;
PEsym sym3;
uint32_t strtabsize;
uint8_t space[4096];
} PEobj;
]]
local symname = LJBC_PREFIX..ctx.modname
local ai = assert(map_arch[ctx.arch])
local is64 = ai.b == 64
local symexport = " /EXPORT:"..symname..",DATA "
-- The file format is always little-endian. Swap if the host is big-endian.
local function f32(x) return x end
local f16 = f32
if ffi.abi("be") then
f32 = bit.bswap
function f16(x) return bit.rshift(bit.bswap(x), 16) end
end
-- Create PE object and fill in header.
local o = ffi.new("PEobj")
local hdr = o.hdr
hdr.arch = f16(assert(ai.p))
hdr.nsects = f16(2)
hdr.symtabofs = f32(ffi.offsetof(o, "sym0"))
hdr.nsyms = f32(6)
-- Fill in sections and symbols.
o.sect[0].name = ".drectve"
o.sect[0].size = f32(#symexport)
o.sect[0].flags = f32(0x00100a00)
o.sym0.sect = f16(1)
o.sym0.scl = 3
o.sym0.name = ".drectve"
o.sym0.naux = 1
o.sym0aux.size = f32(#symexport)
o.sect[1].name = ".rdata"
o.sect[1].size = f32(#s)
o.sect[1].flags = f32(0x40300040)
o.sym1.sect = f16(2)
o.sym1.scl = 3
o.sym1.name = ".rdata"
o.sym1.naux = 1
o.sym1aux.size = f32(#s)
o.sym2.sect = f16(2)
o.sym2.scl = 2
o.sym2.nameref[1] = f32(4)
o.sym3.sect = f16(-1)
o.sym3.scl = 2
o.sym3.value = f32(1)
o.sym3.name = "@feat.00" -- Mark as SafeSEH compliant.
ffi.copy(o.space, symname)
local ofs = #symname + 1
o.strtabsize = f32(ofs + 4)
o.sect[0].ofs = f32(ffi.offsetof(o, "space") + ofs)
ffi.copy(o.space + ofs, symexport)
ofs = ofs + #symexport
o.sect[1].ofs = f32(ffi.offsetof(o, "space") + ofs)
-- Write PE object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, ffi.sizeof(o)-4096+ofs))
bcsave_tail(fp, output, s)
end
local function bcsave_machobj(ctx, output, s, ffi)
ffi.cdef[[
typedef struct
{
uint32_t magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
} mach_header;
typedef struct
{
mach_header; uint32_t reserved;
} mach_header_64;
typedef struct {
uint32_t cmd, cmdsize;
char segname[16];
uint64_t vmaddr, vmsize, fileoff, filesize;
uint32_t maxprot, initprot, nsects, flags;
} mach_segment_command_64;
typedef struct {
char sectname[16], segname[16];
uint64_t addr, size;
uint32_t offset, align, reloff, nreloc, flags;
uint32_t reserved1, reserved2, reserved3;
} mach_section_64;
typedef struct {
uint32_t cmd, cmdsize, symoff, nsyms, stroff, strsize;
} mach_symtab_command;
typedef struct {
int32_t strx;
uint8_t type, sect;
uint16_t desc;
uint64_t value;
} mach_nlist_64;
typedef struct {
mach_header_64 hdr;
mach_segment_command_64 seg;
mach_section_64 sec;
mach_symtab_command sym;
mach_nlist_64 sym_entry;
uint8_t space[4096];
} mach_obj_64;
]]
local symname = '_'..LJBC_PREFIX..ctx.modname
local cputype, cpusubtype = 0x01000007, 3
if ctx.arch ~= "x64" then
check(ctx.arch == "arm64", "unsupported architecture for OSX")
cputype, cpusubtype = 0x0100000c, 0
end
local function aligned(v, a) return bit.band(v+a-1, -a) end
-- Create Mach-O object and fill in header.
local o = ffi.new("mach_obj_64")
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
-- Fill in sections and symbols.
o.hdr.magic = 0xfeedfacf
o.hdr.cputype = cputype
o.hdr.cpusubtype = cpusubtype
o.hdr.filetype = 1
o.hdr.ncmds = 2
o.hdr.sizeofcmds = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)+ffi.sizeof(o.sym)
o.seg.cmd = 0x19
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
o.seg.vmsize = #s
o.seg.fileoff = mach_size
o.seg.filesize = #s
o.seg.maxprot = 1
o.seg.initprot = 1
o.seg.nsects = 1
ffi.copy(o.sec.sectname, "__data")
ffi.copy(o.sec.segname, "__DATA")
o.sec.size = #s
o.sec.offset = mach_size
o.sym.cmd = 2
o.sym.cmdsize = ffi.sizeof(o.sym)
o.sym.symoff = ffi.offsetof(o, "sym_entry")
o.sym.nsyms = 1
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
o.sym.strsize = aligned(#symname+2, 8)
o.sym_entry.type = 0xf
o.sym_entry.sect = 1
o.sym_entry.strx = 1
ffi.copy(o.space+1, symname)
-- Write Mach-O object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, mach_size))
bcsave_tail(fp, output, s)
end
local function bcsave_obj(ctx, output, s)
local ok, ffi = pcall(require, "ffi")
check(ok, "FFI library required to write this file type")
if output == "-" and jit.os == "Windows" then
set_stdout_binary(ffi)
end
if ctx.os == "windows" then
return bcsave_peobj(ctx, output, s, ffi)
elseif ctx.os == "osx" then
return bcsave_machobj(ctx, output, s, ffi)
else
return bcsave_elfobj(ctx, output, s, ffi)
end
end
------------------------------------------------------------------------------
local function bclist(ctx, input, output)
local f = readfile(ctx, input)
require("jit.bc").dump(f, savefile(output, "w"), true)
end
local function bcsave(ctx, input, output)
local f = readfile(ctx, input)
local s = string.dump(f, ctx.mode)
local t = ctx.type
if not t then
t = detecttype(output)
ctx.type = t
end
if t == "raw" then
bcsave_raw(output, s)
else
if not ctx.modname then ctx.modname = detectmodname(input) end
if t == "obj" then
bcsave_obj(ctx, output, s)
else
bcsave_c(ctx, output, s)
end
end
end
local function docmd(...)
local arg = {...}
local n = 1
local list = false
local ctx = {
mode = "bt", arch = jit.arch, os = jit.os:lower(),
type = false, modname = false, string = false,
}
local strip = "s"
local gc64 = ""
while n <= #arg do
local a = arg[n]
if type(a) == "string" and a:sub(1, 1) == "-" and a ~= "-" then
tremove(arg, n)
if a == "--" then break end
for m=2,#a do
local opt = a:sub(m, m)
if opt == "l" then
list = true
elseif opt == "s" then
strip = "s"
elseif opt == "g" then
strip = ""
elseif opt == "W" or opt == "X" then
gc64 = opt
elseif opt == "d" then
ctx.mode = ctx.mode .. opt
else
if arg[n] == nil or m ~= #a then usage() end
if opt == "e" then
if n ~= 1 then usage() end
ctx.string = true
elseif opt == "n" then
ctx.modname = checkmodname(tremove(arg, n))
elseif opt == "t" then
ctx.type = checkarg(tremove(arg, n), map_type, "file type")
elseif opt == "a" then
ctx.arch = checkarg(tremove(arg, n), map_arch, "architecture")
elseif opt == "o" then
ctx.os = checkarg(tremove(arg, n), map_os, "OS name")
elseif opt == "F" then
ctx.filename = "@"..tremove(arg, n)
else
usage()
end
end
end
else
n = n + 1
end
end
ctx.mode = ctx.mode .. strip .. gc64
if list then
if #arg == 0 or #arg > 2 then usage() end
bclist(ctx, arg[1], arg[2] or "-")
else
if #arg ~= 2 then usage() end
bcsave(ctx, arg[1], arg[2])
end
end
------------------------------------------------------------------------------
-- Public module functions.
return {
start = docmd -- Process -b command line option.
}
+689
View File
@@ -0,0 +1,689 @@
----------------------------------------------------------------------------
-- LuaJIT ARM disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles most user-mode ARMv7 instructions
-- NYI: Advanced SIMD and VFP instructions.
------------------------------------------------------------------------------
local type = type
local sub, byte, format = string.sub, string.byte, string.format
local match, gmatch = string.match, string.gmatch
local concat = table.concat
local bit = require("bit")
local band, bor, ror, tohex = bit.band, bit.bor, bit.ror, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Opcode maps
------------------------------------------------------------------------------
local map_loadc = {
shift = 8, mask = 15,
[10] = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "vmovFmDN", "vstmFNdr",
_ = {
shift = 21, mask = 1,
[0] = "vstrFdl",
{ shift = 16, mask = 15, [13] = "vpushFdr", _ = "vstmdbFNdr", }
},
},
{
shift = 23, mask = 3,
[0] = "vmovFDNm",
{ shift = 16, mask = 15, [13] = "vpopFdr", _ = "vldmFNdr", },
_ = {
shift = 21, mask = 1,
[0] = "vldrFdl", "vldmdbFNdr",
},
},
},
[11] = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "vmovGmDN", "vstmGNdr",
_ = {
shift = 21, mask = 1,
[0] = "vstrGdl",
{ shift = 16, mask = 15, [13] = "vpushGdr", _ = "vstmdbGNdr", }
},
},
{
shift = 23, mask = 3,
[0] = "vmovGDNm",
{ shift = 16, mask = 15, [13] = "vpopGdr", _ = "vldmGNdr", },
_ = {
shift = 21, mask = 1,
[0] = "vldrGdl", "vldmdbGNdr",
},
},
},
_ = {
shift = 0, mask = 0 -- NYI ldc, mcrr, mrrc.
},
}
local map_vfps = {
shift = 6, mask = 0x2c001,
[0] = "vmlaF.dnm", "vmlsF.dnm",
[0x04000] = "vnmlsF.dnm", [0x04001] = "vnmlaF.dnm",
[0x08000] = "vmulF.dnm", [0x08001] = "vnmulF.dnm",
[0x0c000] = "vaddF.dnm", [0x0c001] = "vsubF.dnm",
[0x20000] = "vdivF.dnm",
[0x24000] = "vfnmsF.dnm", [0x24001] = "vfnmaF.dnm",
[0x28000] = "vfmaF.dnm", [0x28001] = "vfmsF.dnm",
[0x2c000] = "vmovF.dY",
[0x2c001] = {
shift = 7, mask = 0x1e01,
[0] = "vmovF.dm", "vabsF.dm",
[0x0200] = "vnegF.dm", [0x0201] = "vsqrtF.dm",
[0x0800] = "vcmpF.dm", [0x0801] = "vcmpeF.dm",
[0x0a00] = "vcmpzF.d", [0x0a01] = "vcmpzeF.d",
[0x0e01] = "vcvtG.dF.m",
[0x1000] = "vcvt.f32.u32Fdm", [0x1001] = "vcvt.f32.s32Fdm",
[0x1800] = "vcvtr.u32F.dm", [0x1801] = "vcvt.u32F.dm",
[0x1a00] = "vcvtr.s32F.dm", [0x1a01] = "vcvt.s32F.dm",
},
}
local map_vfpd = {
shift = 6, mask = 0x2c001,
[0] = "vmlaG.dnm", "vmlsG.dnm",
[0x04000] = "vnmlsG.dnm", [0x04001] = "vnmlaG.dnm",
[0x08000] = "vmulG.dnm", [0x08001] = "vnmulG.dnm",
[0x0c000] = "vaddG.dnm", [0x0c001] = "vsubG.dnm",
[0x20000] = "vdivG.dnm",
[0x24000] = "vfnmsG.dnm", [0x24001] = "vfnmaG.dnm",
[0x28000] = "vfmaG.dnm", [0x28001] = "vfmsG.dnm",
[0x2c000] = "vmovG.dY",
[0x2c001] = {
shift = 7, mask = 0x1e01,
[0] = "vmovG.dm", "vabsG.dm",
[0x0200] = "vnegG.dm", [0x0201] = "vsqrtG.dm",
[0x0800] = "vcmpG.dm", [0x0801] = "vcmpeG.dm",
[0x0a00] = "vcmpzG.d", [0x0a01] = "vcmpzeG.d",
[0x0e01] = "vcvtF.dG.m",
[0x1000] = "vcvt.f64.u32GdFm", [0x1001] = "vcvt.f64.s32GdFm",
[0x1800] = "vcvtr.u32FdG.m", [0x1801] = "vcvt.u32FdG.m",
[0x1a00] = "vcvtr.s32FdG.m", [0x1a01] = "vcvt.s32FdG.m",
},
}
local map_datac = {
shift = 24, mask = 1,
[0] = {
shift = 4, mask = 1,
[0] = {
shift = 8, mask = 15,
[10] = map_vfps,
[11] = map_vfpd,
-- NYI cdp, mcr, mrc.
},
{
shift = 8, mask = 15,
[10] = {
shift = 20, mask = 15,
[0] = "vmovFnD", "vmovFDn",
[14] = "vmsrD",
[15] = { shift = 12, mask = 15, [15] = "vmrs", _ = "vmrsD", },
},
},
},
"svcT",
}
local map_loadcu = {
shift = 0, mask = 0, -- NYI unconditional CP load/store.
}
local map_datacu = {
shift = 0, mask = 0, -- NYI unconditional CP data.
}
local map_simddata = {
shift = 0, mask = 0, -- NYI SIMD data.
}
local map_simdload = {
shift = 0, mask = 0, -- NYI SIMD load/store, preload.
}
local map_preload = {
shift = 0, mask = 0, -- NYI preload.
}
local map_media = {
shift = 20, mask = 31,
[0] = false,
{ --01
shift = 5, mask = 7,
[0] = "sadd16DNM", "sasxDNM", "ssaxDNM", "ssub16DNM",
"sadd8DNM", false, false, "ssub8DNM",
},
{ --02
shift = 5, mask = 7,
[0] = "qadd16DNM", "qasxDNM", "qsaxDNM", "qsub16DNM",
"qadd8DNM", false, false, "qsub8DNM",
},
{ --03
shift = 5, mask = 7,
[0] = "shadd16DNM", "shasxDNM", "shsaxDNM", "shsub16DNM",
"shadd8DNM", false, false, "shsub8DNM",
},
false,
{ --05
shift = 5, mask = 7,
[0] = "uadd16DNM", "uasxDNM", "usaxDNM", "usub16DNM",
"uadd8DNM", false, false, "usub8DNM",
},
{ --06
shift = 5, mask = 7,
[0] = "uqadd16DNM", "uqasxDNM", "uqsaxDNM", "uqsub16DNM",
"uqadd8DNM", false, false, "uqsub8DNM",
},
{ --07
shift = 5, mask = 7,
[0] = "uhadd16DNM", "uhasxDNM", "uhsaxDNM", "uhsub16DNM",
"uhadd8DNM", false, false, "uhsub8DNM",
},
{ --08
shift = 5, mask = 7,
[0] = "pkhbtDNMU", false, "pkhtbDNMU",
{ shift = 16, mask = 15, [15] = "sxtb16DMU", _ = "sxtab16DNMU", },
"pkhbtDNMU", "selDNM", "pkhtbDNMU",
},
false,
{ --0a
shift = 5, mask = 7,
[0] = "ssatDxMu", "ssat16DxM", "ssatDxMu",
{ shift = 16, mask = 15, [15] = "sxtbDMU", _ = "sxtabDNMU", },
"ssatDxMu", false, "ssatDxMu",
},
{ --0b
shift = 5, mask = 7,
[0] = "ssatDxMu", "revDM", "ssatDxMu",
{ shift = 16, mask = 15, [15] = "sxthDMU", _ = "sxtahDNMU", },
"ssatDxMu", "rev16DM", "ssatDxMu",
},
{ --0c
shift = 5, mask = 7,
[3] = { shift = 16, mask = 15, [15] = "uxtb16DMU", _ = "uxtab16DNMU", },
},
false,
{ --0e
shift = 5, mask = 7,
[0] = "usatDwMu", "usat16DwM", "usatDwMu",
{ shift = 16, mask = 15, [15] = "uxtbDMU", _ = "uxtabDNMU", },
"usatDwMu", false, "usatDwMu",
},
{ --0f
shift = 5, mask = 7,
[0] = "usatDwMu", "rbitDM", "usatDwMu",
{ shift = 16, mask = 15, [15] = "uxthDMU", _ = "uxtahDNMU", },
"usatDwMu", "revshDM", "usatDwMu",
},
{ --10
shift = 12, mask = 15,
[15] = {
shift = 5, mask = 7,
"smuadNMS", "smuadxNMS", "smusdNMS", "smusdxNMS",
},
_ = {
shift = 5, mask = 7,
[0] = "smladNMSD", "smladxNMSD", "smlsdNMSD", "smlsdxNMSD",
},
},
false, false, false,
{ --14
shift = 5, mask = 7,
[0] = "smlaldDNMS", "smlaldxDNMS", "smlsldDNMS", "smlsldxDNMS",
},
{ --15
shift = 5, mask = 7,
[0] = { shift = 12, mask = 15, [15] = "smmulNMS", _ = "smmlaNMSD", },
{ shift = 12, mask = 15, [15] = "smmulrNMS", _ = "smmlarNMSD", },
false, false, false, false,
"smmlsNMSD", "smmlsrNMSD",
},
false, false,
{ --18
shift = 5, mask = 7,
[0] = { shift = 12, mask = 15, [15] = "usad8NMS", _ = "usada8NMSD", },
},
false,
{ --1a
shift = 5, mask = 3, [2] = "sbfxDMvw",
},
{ --1b
shift = 5, mask = 3, [2] = "sbfxDMvw",
},
{ --1c
shift = 5, mask = 3,
[0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
},
{ --1d
shift = 5, mask = 3,
[0] = { shift = 0, mask = 15, [15] = "bfcDvX", _ = "bfiDMvX", },
},
{ --1e
shift = 5, mask = 3, [2] = "ubfxDMvw",
},
{ --1f
shift = 5, mask = 3, [2] = "ubfxDMvw",
},
}
local map_load = {
shift = 21, mask = 9,
{
shift = 20, mask = 5,
[0] = "strtDL", "ldrtDL", [4] = "strbtDL", [5] = "ldrbtDL",
},
_ = {
shift = 20, mask = 5,
[0] = "strDL", "ldrDL", [4] = "strbDL", [5] = "ldrbDL",
}
}
local map_load1 = {
shift = 4, mask = 1,
[0] = map_load, map_media,
}
local map_loadm = {
shift = 20, mask = 1,
[0] = {
shift = 23, mask = 3,
[0] = "stmdaNR", "stmNR",
{ shift = 16, mask = 63, [45] = "pushR", _ = "stmdbNR", }, "stmibNR",
},
{
shift = 23, mask = 3,
[0] = "ldmdaNR", { shift = 16, mask = 63, [61] = "popR", _ = "ldmNR", },
"ldmdbNR", "ldmibNR",
},
}
local map_data = {
shift = 21, mask = 15,
[0] = "andDNPs", "eorDNPs", "subDNPs", "rsbDNPs",
"addDNPs", "adcDNPs", "sbcDNPs", "rscDNPs",
"tstNP", "teqNP", "cmpNP", "cmnNP",
"orrDNPs", "movDPs", "bicDNPs", "mvnDPs",
}
local map_mul = {
shift = 21, mask = 7,
[0] = "mulNMSs", "mlaNMSDs", "umaalDNMS", "mlsDNMS",
"umullDNMSs", "umlalDNMSs", "smullDNMSs", "smlalDNMSs",
}
local map_sync = {
shift = 20, mask = 15, -- NYI: brackets around N. R(D+1) for ldrexd/strexd.
[0] = "swpDMN", false, false, false,
"swpbDMN", false, false, false,
"strexDMN", "ldrexDN", "strexdDN", "ldrexdDN",
"strexbDMN", "ldrexbDN", "strexhDN", "ldrexhDN",
}
local map_mulh = {
shift = 21, mask = 3,
[0] = { shift = 5, mask = 3,
[0] = "smlabbNMSD", "smlatbNMSD", "smlabtNMSD", "smlattNMSD", },
{ shift = 5, mask = 3,
[0] = "smlawbNMSD", "smulwbNMS", "smlawtNMSD", "smulwtNMS", },
{ shift = 5, mask = 3,
[0] = "smlalbbDNMS", "smlaltbDNMS", "smlalbtDNMS", "smlalttDNMS", },
{ shift = 5, mask = 3,
[0] = "smulbbNMS", "smultbNMS", "smulbtNMS", "smulttNMS", },
}
local map_misc = {
shift = 4, mask = 7,
-- NYI: decode PSR bits of msr.
[0] = { shift = 21, mask = 1, [0] = "mrsD", "msrM", },
{ shift = 21, mask = 3, "bxM", false, "clzDM", },
{ shift = 21, mask = 3, "bxjM", },
{ shift = 21, mask = 3, "blxM", },
false,
{ shift = 21, mask = 3, [0] = "qaddDMN", "qsubDMN", "qdaddDMN", "qdsubDMN", },
false,
{ shift = 21, mask = 3, "bkptK", },
}
local map_datar = {
shift = 4, mask = 9,
[9] = {
shift = 5, mask = 3,
[0] = { shift = 24, mask = 1, [0] = map_mul, map_sync, },
{ shift = 20, mask = 1, [0] = "strhDL", "ldrhDL", },
{ shift = 20, mask = 1, [0] = "ldrdDL", "ldrsbDL", },
{ shift = 20, mask = 1, [0] = "strdDL", "ldrshDL", },
},
_ = {
shift = 20, mask = 25,
[16] = { shift = 7, mask = 1, [0] = map_misc, map_mulh, },
_ = {
shift = 0, mask = 0xffffffff,
[bor(0xe1a00000)] = "nop",
_ = map_data,
}
},
}
local map_datai = {
shift = 20, mask = 31, -- NYI: decode PSR bits of msr. Decode imm12.
[16] = "movwDW", [20] = "movtDW",
[18] = { shift = 0, mask = 0xf00ff, [0] = "nopv6", _ = "msrNW", },
[22] = "msrNW",
_ = map_data,
}
local map_branch = {
shift = 24, mask = 1,
[0] = "bB", "blB"
}
local map_condins = {
[0] = map_datar, map_datai, map_load, map_load1,
map_loadm, map_branch, map_loadc, map_datac
}
-- NYI: setend.
local map_uncondins = {
[0] = false, map_simddata, map_simdload, map_preload,
false, "blxB", map_loadcu, map_datacu,
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc",
}
local map_cond = {
[0] = "eq", "ne", "hs", "lo", "mi", "pl", "vs", "vc",
"hi", "ls", "ge", "lt", "gt", "le", "al",
}
local map_shift = { [0] = "lsl", "lsr", "asr", "ror", }
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then
extra = "\t->"..sym
elseif band(ctx.op, 0x0e000000) ~= 0x0a000000 then
extra = "\t; 0x"..tohex(ctx.rel)
end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-5s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-5s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
-- Format operand 2 of load/store opcodes.
local function fmtload(ctx, op, pos)
local base = map_gpr[band(rshift(op, 16), 15)]
local x, ofs
local ext = (band(op, 0x04000000) == 0)
if not ext and band(op, 0x02000000) == 0 then
ofs = band(op, 4095)
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
ofs = "#"..ofs
elseif ext and band(op, 0x00400000) ~= 0 then
ofs = band(op, 15) + band(rshift(op, 4), 0xf0)
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
ofs = "#"..ofs
else
ofs = map_gpr[band(op, 15)]
if ext or band(op, 0xfe0) == 0 then
elseif band(op, 0xfe0) == 0x60 then
ofs = format("%s, rrx", ofs)
else
local sh = band(rshift(op, 7), 31)
if sh == 0 then sh = 32 end
ofs = format("%s, %s #%d", ofs, map_shift[band(rshift(op, 5), 3)], sh)
end
if band(op, 0x00800000) == 0 then ofs = "-"..ofs end
end
if ofs == "#0" then
x = format("[%s]", base)
elseif band(op, 0x01000000) == 0 then
x = format("[%s], %s", base, ofs)
else
x = format("[%s, %s]", base, ofs)
end
if band(op, 0x01200000) == 0x01200000 then x = x.."!" end
return x
end
-- Format operand 2 of vector load/store opcodes.
local function fmtvload(ctx, op, pos)
local base = map_gpr[band(rshift(op, 16), 15)]
local ofs = band(op, 255)*4
if band(op, 0x00800000) == 0 then ofs = -ofs end
if base == "pc" then ctx.rel = ctx.addr + pos + 8 + ofs end
if ofs == 0 then
return format("[%s]", base)
else
return format("[%s, #%d]", base, ofs)
end
end
local function fmtvr(op, vr, sh0, sh1)
if vr == "s" then
return format("s%d", 2*band(rshift(op, sh0), 15)+band(rshift(op, sh1), 1))
else
return format("d%d", band(rshift(op, sh0), 15)+band(rshift(op, sh1-4), 16))
end
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
local op = bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
local operands = {}
local suffix = ""
local last, name, pat
local vr
ctx.op = op
ctx.rel = nil
local cond = rshift(op, 28)
local opat
if cond == 15 then
opat = map_uncondins[band(rshift(op, 25), 7)]
else
if cond ~= 14 then suffix = map_cond[cond] end
opat = map_condins[band(rshift(op, 25), 7)]
end
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
end
name, pat = match(opat, "^([a-z0-9]*)(.*)")
if sub(pat, 1, 1) == "." then
local s2, p2 = match(pat, "^([a-z0-9.]*)(.*)")
suffix = suffix..s2
pat = p2
end
for p in gmatch(pat, ".") do
local x = nil
if p == "D" then
x = map_gpr[band(rshift(op, 12), 15)]
elseif p == "N" then
x = map_gpr[band(rshift(op, 16), 15)]
elseif p == "S" then
x = map_gpr[band(rshift(op, 8), 15)]
elseif p == "M" then
x = map_gpr[band(op, 15)]
elseif p == "d" then
x = fmtvr(op, vr, 12, 22)
elseif p == "n" then
x = fmtvr(op, vr, 16, 7)
elseif p == "m" then
x = fmtvr(op, vr, 0, 5)
elseif p == "P" then
if band(op, 0x02000000) ~= 0 then
x = ror(band(op, 255), 2*band(rshift(op, 8), 15))
else
x = map_gpr[band(op, 15)]
if band(op, 0xff0) ~= 0 then
operands[#operands+1] = x
local s = map_shift[band(rshift(op, 5), 3)]
local r = nil
if band(op, 0xf90) == 0 then
if s == "ror" then s = "rrx" else r = "#32" end
elseif band(op, 0x10) == 0 then
r = "#"..band(rshift(op, 7), 31)
else
r = map_gpr[band(rshift(op, 8), 15)]
end
if name == "mov" then name = s; x = r
elseif r then x = format("%s %s", s, r)
else x = s end
end
end
elseif p == "L" then
x = fmtload(ctx, op, pos)
elseif p == "l" then
x = fmtvload(ctx, op, pos)
elseif p == "B" then
local addr = ctx.addr + pos + 8 + arshift(lshift(op, 8), 6)
if cond == 15 then addr = addr + band(rshift(op, 23), 2) end
ctx.rel = addr
x = "0x"..tohex(addr)
elseif p == "F" then
vr = "s"
elseif p == "G" then
vr = "d"
elseif p == "." then
suffix = suffix..(vr == "s" and ".f32" or ".f64")
elseif p == "R" then
if band(op, 0x00200000) ~= 0 and #operands == 1 then
operands[1] = operands[1].."!"
end
local t = {}
for i=0,15 do
if band(rshift(op, i), 1) == 1 then t[#t+1] = map_gpr[i] end
end
x = "{"..concat(t, ", ").."}"
elseif p == "r" then
if band(op, 0x00200000) ~= 0 and #operands == 2 then
operands[1] = operands[1].."!"
end
local s = tonumber(sub(last, 2))
local n = band(op, 255)
if vr == "d" then n = rshift(n, 1) end
operands[#operands] = format("{%s-%s%d}", last, vr, s+n-1)
elseif p == "W" then
x = band(op, 0x0fff) + band(rshift(op, 4), 0xf000)
elseif p == "T" then
x = "#0x"..tohex(band(op, 0x00ffffff), 6)
elseif p == "U" then
x = band(rshift(op, 7), 31)
if x == 0 then x = nil end
elseif p == "u" then
x = band(rshift(op, 7), 31)
if band(op, 0x40) == 0 then
if x == 0 then x = nil else x = "lsl #"..x end
else
if x == 0 then x = "asr #32" else x = "asr #"..x end
end
elseif p == "v" then
x = band(rshift(op, 7), 31)
elseif p == "w" then
x = band(rshift(op, 16), 31)
elseif p == "x" then
x = band(rshift(op, 16), 31) + 1
elseif p == "X" then
x = band(rshift(op, 16), 31) - last + 1
elseif p == "Y" then
x = band(rshift(op, 12), 0xf0) + band(op, 0x0f)
elseif p == "K" then
x = "#0x"..tohex(band(rshift(op, 4), 0x0000fff0) + band(op, 15), 4)
elseif p == "s" then
if band(op, 0x00100000) ~= 0 then suffix = "s"..suffix end
else
assert(false)
end
if x then
last = x
if type(x) == "number" then x = "#"..x end
operands[#operands+1] = x
end
end
return putop(ctx, name..suffix, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
ctx.pos = ofs
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 16 then return map_gpr[r] end
return "d"..(r-16)
end
-- Public module functions.
return {
create = create,
disass = disass,
regname = regname
}
File diff suppressed because it is too large. Load diff
+12
View File
@@ -0,0 +1,12 @@
----------------------------------------------------------------------------
-- LuaJIT ARM64BE disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- ARM64 instructions are always little-endian. So just forward to the
-- common ARM64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
return require((string.match(..., ".*%.") or "").."dis_arm64")
+694
View File
@@ -0,0 +1,694 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles all standard MIPS32R1/R2 instructions.
-- Default mode is big-endian, but see: dis_mipsel.lua
------------------------------------------------------------------------------
local type = type
local byte, format = string.byte, string.format
local match, gmatch = string.match, string.gmatch
local concat = table.concat
local bit = require("bit")
local band, bor, tohex = bit.band, bit.bor, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Extended opcode maps common to all MIPS releases
------------------------------------------------------------------------------
local map_srl = { shift = 21, mask = 1, [0] = "srlDTA", "rotrDTA", }
local map_srlv = { shift = 6, mask = 1, [0] = "srlvDTS", "rotrvDTS", }
local map_cop0 = {
shift = 25, mask = 1,
[0] = {
shift = 21, mask = 15,
[0] = "mfc0TDW", [4] = "mtc0TDW",
[10] = "rdpgprDT",
[11] = { shift = 5, mask = 1, [0] = "diT0", "eiT0", },
[14] = "wrpgprDT",
}, {
shift = 0, mask = 63,
[1] = "tlbr", [2] = "tlbwi", [6] = "tlbwr", [8] = "tlbp",
[24] = "eret", [31] = "deret",
[32] = "wait",
},
}
------------------------------------------------------------------------------
-- Primary and extended opcode maps for MIPS R1-R5
------------------------------------------------------------------------------
local map_movci = { shift = 16, mask = 1, [0] = "movfDSC", "movtDSC", }
local map_special = {
shift = 0, mask = 63,
[0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
map_movci, map_srl, "sraDTA",
"sllvDTS", false, map_srlv, "sravDTS",
"jrS", "jalrD1S", "movzDST", "movnDST",
"syscallY", "breakY", false, "sync",
"mfhiD", "mthiS", "mfloD", "mtloS",
"dsllvDST", false, "dsrlvDST", "dsravDST",
"multST", "multuST", "divST", "divuST",
"dmultST", "dmultuST", "ddivST", "ddivuST",
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
false, false, "sltDST", "sltuDST",
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
"teqSTZ", false, "tneSTZ", false,
"dsllDTA", false, "dsrlDTA", "dsraDTA",
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
}
local map_special2 = {
shift = 0, mask = 63,
[0] = "maddST", "madduST", "mulDST", false,
"msubST", "msubuST",
[32] = "clzDS", [33] = "cloDS",
[63] = "sdbbpY",
}
local map_bshfl = {
shift = 6, mask = 31,
[2] = "wsbhDT",
[16] = "sebDT",
[24] = "sehDT",
}
local map_dbshfl = {
shift = 6, mask = 31,
[2] = "dsbhDT",
[5] = "dshdDT",
}
local map_special3 = {
shift = 0, mask = 63,
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
[32] = map_bshfl, [36] = map_dbshfl, [59] = "rdhwrTD",
}
local map_regimm = {
shift = 16, mask = 31,
[0] = "bltzSB", "bgezSB", "bltzlSB", "bgezlSB",
false, false, false, false,
"tgeiSI", "tgeiuSI", "tltiSI", "tltiuSI",
"teqiSI", false, "tneiSI", false,
"bltzalSB", "bgezalSB", "bltzallSB", "bgezallSB",
false, false, false, false,
false, false, false, false,
false, false, false, "synciSO",
}
local map_cop1s = {
shift = 0, mask = 63,
[0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH",
"sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG",
"round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG",
"round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG",
false,
{ shift = 16, mask = 1, [0] = "movf.sFGC", "movt.sFGC" },
"movz.sFGT", "movn.sFGT",
false, "recip.sFG", "rsqrt.sFG", false,
false, false, false, false,
false, false, false, false,
false, "cvt.d.sFG", false, false,
"cvt.w.sFG", "cvt.l.sFG", "cvt.ps.sFGH", false,
false, false, false, false,
false, false, false, false,
"c.f.sVGH", "c.un.sVGH", "c.eq.sVGH", "c.ueq.sVGH",
"c.olt.sVGH", "c.ult.sVGH", "c.ole.sVGH", "c.ule.sVGH",
"c.sf.sVGH", "c.ngle.sVGH", "c.seq.sVGH", "c.ngl.sVGH",
"c.lt.sVGH", "c.nge.sVGH", "c.le.sVGH", "c.ngt.sVGH",
}
local map_cop1d = {
shift = 0, mask = 63,
[0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH",
"sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG",
"round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG",
"round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG",
false,
{ shift = 16, mask = 1, [0] = "movf.dFGC", "movt.dFGC" },
"movz.dFGT", "movn.dFGT",
false, "recip.dFG", "rsqrt.dFG", false,
false, false, false, false,
false, false, false, false,
"cvt.s.dFG", false, false, false,
"cvt.w.dFG", "cvt.l.dFG", false, false,
false, false, false, false,
false, false, false, false,
"c.f.dVGH", "c.un.dVGH", "c.eq.dVGH", "c.ueq.dVGH",
"c.olt.dVGH", "c.ult.dVGH", "c.ole.dVGH", "c.ule.dVGH",
"c.df.dVGH", "c.ngle.dVGH", "c.deq.dVGH", "c.ngl.dVGH",
"c.lt.dVGH", "c.nge.dVGH", "c.le.dVGH", "c.ngt.dVGH",
}
local map_cop1ps = {
shift = 0, mask = 63,
[0] = "add.psFGH", "sub.psFGH", "mul.psFGH", false,
false, "abs.psFG", "mov.psFG", "neg.psFG",
false, false, false, false,
false, false, false, false,
false,
{ shift = 16, mask = 1, [0] = "movf.psFGC", "movt.psFGC" },
"movz.psFGT", "movn.psFGT",
false, false, false, false,
false, false, false, false,
false, false, false, false,
"cvt.s.puFG", false, false, false,
false, false, false, false,
"cvt.s.plFG", false, false, false,
"pll.psFGH", "plu.psFGH", "pul.psFGH", "puu.psFGH",
"c.f.psVGH", "c.un.psVGH", "c.eq.psVGH", "c.ueq.psVGH",
"c.olt.psVGH", "c.ult.psVGH", "c.ole.psVGH", "c.ule.psVGH",
"c.psf.psVGH", "c.ngle.psVGH", "c.pseq.psVGH", "c.ngl.psVGH",
"c.lt.psVGH", "c.nge.psVGH", "c.le.psVGH", "c.ngt.psVGH",
}
local map_cop1w = {
shift = 0, mask = 63,
[32] = "cvt.s.wFG", [33] = "cvt.d.wFG",
}
local map_cop1l = {
shift = 0, mask = 63,
[32] = "cvt.s.lFG", [33] = "cvt.d.lFG",
}
local map_cop1bc = {
shift = 16, mask = 3,
[0] = "bc1fCB", "bc1tCB", "bc1flCB", "bc1tlCB",
}
local map_cop1 = {
shift = 21, mask = 31,
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
map_cop1bc, false, false, false,
false, false, false, false,
map_cop1s, map_cop1d, false, false,
map_cop1w, map_cop1l, map_cop1ps,
}
local map_cop1x = {
shift = 0, mask = 63,
[0] = "lwxc1FSX", "ldxc1FSX", false, false,
false, "luxc1FSX", false, false,
"swxc1FSX", "sdxc1FSX", false, false,
false, "suxc1FSX", false, "prefxMSX",
false, false, false, false,
false, false, false, false,
false, false, false, false,
false, false, "alnv.psFGHS", false,
"madd.sFRGH", "madd.dFRGH", false, false,
false, false, "madd.psFRGH", false,
"msub.sFRGH", "msub.dFRGH", false, false,
false, false, "msub.psFRGH", false,
"nmadd.sFRGH", "nmadd.dFRGH", false, false,
false, false, "nmadd.psFRGH", false,
"nmsub.sFRGH", "nmsub.dFRGH", false, false,
false, false, "nmsub.psFRGH", false,
}
local map_pri = {
[0] = map_special, map_regimm, "jJ", "jalJ",
"beq|beqz|bST00B", "bne|bnezST0B", "blezSB", "bgtzSB",
"addiTSI", "addiu|liTS0I", "sltiTSI", "sltiuTSI",
"andiTSU", "ori|liTS0U", "xoriTSU", "luiTU",
map_cop0, map_cop1, false, map_cop1x,
"beql|beqzlST0B", "bnel|bnezlST0B", "blezlSB", "bgtzlSB",
"daddiTSI", "daddiuTSI", false, false,
map_special2, "jalxJ", false, map_special3,
"lbTSO", "lhTSO", "lwlTSO", "lwTSO",
"lbuTSO", "lhuTSO", "lwrTSO", false,
"sbTSO", "shTSO", "swlTSO", "swTSO",
false, false, "swrTSO", "cacheNSO",
"llTSO", "lwc1HSO", "lwc2TSO", "prefNSO",
false, "ldc1HSO", "ldc2TSO", "ldTSO",
"scTSO", "swc1HSO", "swc2TSO", false,
false, "sdc1HSO", "sdc2TSO", "sdTSO",
}
------------------------------------------------------------------------------
-- Primary and extended opcode maps for MIPS R6
------------------------------------------------------------------------------
local map_mul_r6 = { shift = 6, mask = 3, [2] = "mulDST", [3] = "muhDST" }
local map_mulu_r6 = { shift = 6, mask = 3, [2] = "muluDST", [3] = "muhuDST" }
local map_div_r6 = { shift = 6, mask = 3, [2] = "divDST", [3] = "modDST" }
local map_divu_r6 = { shift = 6, mask = 3, [2] = "divuDST", [3] = "moduDST" }
local map_dmul_r6 = { shift = 6, mask = 3, [2] = "dmulDST", [3] = "dmuhDST" }
local map_dmulu_r6 = { shift = 6, mask = 3, [2] = "dmuluDST", [3] = "dmuhuDST" }
local map_ddiv_r6 = { shift = 6, mask = 3, [2] = "ddivDST", [3] = "dmodDST" }
local map_ddivu_r6 = { shift = 6, mask = 3, [2] = "ddivuDST", [3] = "dmoduDST" }
local map_special_r6 = {
shift = 0, mask = 63,
[0] = { shift = 0, mask = -1, [0] = "nop", _ = "sllDTA" },
false, map_srl, "sraDTA",
"sllvDTS", false, map_srlv, "sravDTS",
"jrS", "jalrD1S", false, false,
"syscallY", "breakY", false, "sync",
"clzDS", "cloDS", "dclzDS", "dcloDS",
"dsllvDST", "dlsaDSTA", "dsrlvDST", "dsravDST",
map_mul_r6, map_mulu_r6, map_div_r6, map_divu_r6,
map_dmul_r6, map_dmulu_r6, map_ddiv_r6, map_ddivu_r6,
"addDST", "addu|moveDST0", "subDST", "subu|neguDS0T",
"andDST", "or|moveDST0", "xorDST", "nor|notDST0",
false, false, "sltDST", "sltuDST",
"daddDST", "dadduDST", "dsubDST", "dsubuDST",
"tgeSTZ", "tgeuSTZ", "tltSTZ", "tltuSTZ",
"teqSTZ", "seleqzDST", "tneSTZ", "selnezDST",
"dsllDTA", false, "dsrlDTA", "dsraDTA",
"dsll32DTA", false, "dsrl32DTA", "dsra32DTA",
}
local map_bshfl_r6 = {
shift = 9, mask = 3,
[1] = "alignDSTa",
_ = {
shift = 6, mask = 31,
[0] = "bitswapDT",
[2] = "wsbhDT",
[16] = "sebDT",
[24] = "sehDT",
}
}
local map_dbshfl_r6 = {
shift = 9, mask = 3,
[1] = "dalignDSTa",
_ = {
shift = 6, mask = 31,
[0] = "dbitswapDT",
[2] = "dsbhDT",
[5] = "dshdDT",
}
}
local map_special3_r6 = {
shift = 0, mask = 63,
[0] = "extTSAK", [1] = "dextmTSAP", [3] = "dextTSAK",
[4] = "insTSAL", [6] = "dinsuTSEQ", [7] = "dinsTSAL",
[32] = map_bshfl_r6, [36] = map_dbshfl_r6, [59] = "rdhwrTD",
}
local map_regimm_r6 = {
shift = 16, mask = 31,
[0] = "bltzSB", [1] = "bgezSB",
[6] = "dahiSI", [30] = "datiSI",
[23] = "sigrieI", [31] = "synciSO",
}
local map_pcrel_r6 = {
shift = 19, mask = 3,
[0] = "addiupcS2", "lwpcS2", "lwupcS2", {
shift = 18, mask = 1,
[0] = "ldpcS3", { shift = 16, mask = 3, [2] = "auipcSI", [3] = "aluipcSI" }
}
}
local map_cop1s_r6 = {
shift = 0, mask = 63,
[0] = "add.sFGH", "sub.sFGH", "mul.sFGH", "div.sFGH",
"sqrt.sFG", "abs.sFG", "mov.sFG", "neg.sFG",
"round.l.sFG", "trunc.l.sFG", "ceil.l.sFG", "floor.l.sFG",
"round.w.sFG", "trunc.w.sFG", "ceil.w.sFG", "floor.w.sFG",
"sel.sFGH", false, false, false,
"seleqz.sFGH", "recip.sFG", "rsqrt.sFG", "selnez.sFGH",
"maddf.sFGH", "msubf.sFGH", "rint.sFG", "class.sFG",
"min.sFGH", "mina.sFGH", "max.sFGH", "maxa.sFGH",
false, "cvt.d.sFG", false, false,
"cvt.w.sFG", "cvt.l.sFG",
}
local map_cop1d_r6 = {
shift = 0, mask = 63,
[0] = "add.dFGH", "sub.dFGH", "mul.dFGH", "div.dFGH",
"sqrt.dFG", "abs.dFG", "mov.dFG", "neg.dFG",
"round.l.dFG", "trunc.l.dFG", "ceil.l.dFG", "floor.l.dFG",
"round.w.dFG", "trunc.w.dFG", "ceil.w.dFG", "floor.w.dFG",
"sel.dFGH", false, false, false,
"seleqz.dFGH", "recip.dFG", "rsqrt.dFG", "selnez.dFGH",
"maddf.dFGH", "msubf.dFGH", "rint.dFG", "class.dFG",
"min.dFGH", "mina.dFGH", "max.dFGH", "maxa.dFGH",
"cvt.s.dFG", false, false, false,
"cvt.w.dFG", "cvt.l.dFG",
}
local map_cop1w_r6 = {
shift = 0, mask = 63,
[0] = "cmp.af.sFGH", "cmp.un.sFGH", "cmp.eq.sFGH", "cmp.ueq.sFGH",
"cmp.lt.sFGH", "cmp.ult.sFGH", "cmp.le.sFGH", "cmp.ule.sFGH",
"cmp.saf.sFGH", "cmp.sun.sFGH", "cmp.seq.sFGH", "cmp.sueq.sFGH",
"cmp.slt.sFGH", "cmp.sult.sFGH", "cmp.sle.sFGH", "cmp.sule.sFGH",
false, "cmp.or.sFGH", "cmp.une.sFGH", "cmp.ne.sFGH",
false, false, false, false,
false, "cmp.sor.sFGH", "cmp.sune.sFGH", "cmp.sne.sFGH",
false, false, false, false,
"cvt.s.wFG", "cvt.d.wFG",
}
local map_cop1l_r6 = {
shift = 0, mask = 63,
[0] = "cmp.af.dFGH", "cmp.un.dFGH", "cmp.eq.dFGH", "cmp.ueq.dFGH",
"cmp.lt.dFGH", "cmp.ult.dFGH", "cmp.le.dFGH", "cmp.ule.dFGH",
"cmp.saf.dFGH", "cmp.sun.dFGH", "cmp.seq.dFGH", "cmp.sueq.dFGH",
"cmp.slt.dFGH", "cmp.sult.dFGH", "cmp.sle.dFGH", "cmp.sule.dFGH",
false, "cmp.or.dFGH", "cmp.une.dFGH", "cmp.ne.dFGH",
false, false, false, false,
false, "cmp.sor.dFGH", "cmp.sune.dFGH", "cmp.sne.dFGH",
false, false, false, false,
"cvt.s.lFG", "cvt.d.lFG",
}
local map_cop1_r6 = {
shift = 21, mask = 31,
[0] = "mfc1TG", "dmfc1TG", "cfc1TG", "mfhc1TG",
"mtc1TG", "dmtc1TG", "ctc1TG", "mthc1TG",
false, "bc1eqzHB", false, false,
false, "bc1nezHB", false, false,
map_cop1s_r6, map_cop1d_r6, false, false,
map_cop1w_r6, map_cop1l_r6,
}
local function maprs_popTS(rs, rt)
if rt == 0 then return 0 elseif rs == 0 then return 1
elseif rs == rt then return 2 else return 3 end
end
local map_pop06_r6 = {
maprs = maprs_popTS, [0] = "blezSB", "blezalcTB", "bgezalcTB", "bgeucSTB"
}
local map_pop07_r6 = {
maprs = maprs_popTS, [0] = "bgtzSB", "bgtzalcTB", "bltzalcTB", "bltucSTB"
}
local map_pop26_r6 = {
maprs = maprs_popTS, "blezcTB", "bgezcTB", "bgecSTB"
}
local map_pop27_r6 = {
maprs = maprs_popTS, "bgtzcTB", "bltzcTB", "bltcSTB"
}
local function maprs_popS(rs, rt)
if rs == 0 then return 0 else return 1 end
end
local map_pop66_r6 = {
maprs = maprs_popS, [0] = "jicTI", "beqzcSb"
}
local map_pop76_r6 = {
maprs = maprs_popS, [0] = "jialcTI", "bnezcSb"
}
local function maprs_popST(rs, rt)
if rs >= rt then return 0 elseif rs == 0 then return 1 else return 2 end
end
local map_pop10_r6 = {
maprs = maprs_popST, [0] = "bovcSTB", "beqzalcTB", "beqcSTB"
}
local map_pop30_r6 = {
maprs = maprs_popST, [0] = "bnvcSTB", "bnezalcTB", "bnecSTB"
}
local map_pri_r6 = {
[0] = map_special_r6, map_regimm_r6, "jJ", "jalJ",
"beq|beqz|bST00B", "bne|bnezST0B", map_pop06_r6, map_pop07_r6,
map_pop10_r6, "addiu|liTS0I", "sltiTSI", "sltiuTSI",
"andiTSU", "ori|liTS0U", "xoriTSU", "aui|luiTS0U",
map_cop0, map_cop1_r6, false, false,
false, false, map_pop26_r6, map_pop27_r6,
map_pop30_r6, "daddiuTSI", false, false,
false, "dauiTSI", false, map_special3_r6,
"lbTSO", "lhTSO", false, "lwTSO",
"lbuTSO", "lhuTSO", false, false,
"sbTSO", "shTSO", false, "swTSO",
false, false, false, false,
false, "lwc1HSO", "bc#", false,
false, "ldc1HSO", map_pop66_r6, "ldTSO",
false, "swc1HSO", "balc#", map_pcrel_r6,
false, "sdc1HSO", map_pop76_r6, "sdTSO",
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "sp", "r30", "ra",
}
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then extra = "\t->"..sym end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-7s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-7s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
local function get_be(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
return bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
end
local function get_le(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
return bor(lshift(b3, 24), lshift(b2, 16), lshift(b1, 8), b0)
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local op = ctx:get()
local operands = {}
local last = nil
ctx.op = op
ctx.rel = nil
local opat = ctx.map_pri[rshift(op, 26)]
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
if opat.maprs then
opat = opat[opat.maprs(band(rshift(op,21),31), band(rshift(op,16),31))]
else
opat = opat[band(rshift(op, opat.shift), opat.mask)] or opat._
end
end
local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
local altname, pat2 = match(pat, "|([a-z0-9_.|]*)(.*)")
if altname then pat = pat2 end
for p in gmatch(pat, ".") do
local x = nil
if p == "S" then
x = map_gpr[band(rshift(op, 21), 31)]
elseif p == "T" then
x = map_gpr[band(rshift(op, 16), 31)]
elseif p == "D" then
x = map_gpr[band(rshift(op, 11), 31)]
elseif p == "F" then
x = "f"..band(rshift(op, 6), 31)
elseif p == "G" then
x = "f"..band(rshift(op, 11), 31)
elseif p == "H" then
x = "f"..band(rshift(op, 16), 31)
elseif p == "R" then
x = "f"..band(rshift(op, 21), 31)
elseif p == "A" then
x = band(rshift(op, 6), 31)
elseif p == "a" then
x = band(rshift(op, 6), 7)
elseif p == "E" then
x = band(rshift(op, 6), 31) + 32
elseif p == "M" then
x = band(rshift(op, 11), 31)
elseif p == "N" then
x = band(rshift(op, 16), 31)
elseif p == "C" then
x = band(rshift(op, 18), 7)
if x == 0 then x = nil end
elseif p == "K" then
x = band(rshift(op, 11), 31) + 1
elseif p == "P" then
x = band(rshift(op, 11), 31) + 33
elseif p == "L" then
x = band(rshift(op, 11), 31) - last + 1
elseif p == "Q" then
x = band(rshift(op, 11), 31) - last + 33
elseif p == "I" then
x = arshift(lshift(op, 16), 16)
elseif p == "2" then
x = arshift(lshift(op, 13), 11)
elseif p == "3" then
x = arshift(lshift(op, 14), 11)
elseif p == "U" then
x = band(op, 0xffff)
elseif p == "O" then
local disp = arshift(lshift(op, 16), 16)
operands[#operands] = format("%d(%s)", disp, last)
elseif p == "X" then
local index = map_gpr[band(rshift(op, 16), 31)]
operands[#operands] = format("%s(%s)", index, last)
elseif p == "B" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 16), 14) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "b" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 11), 9) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "#" then
x = ctx.addr + ctx.pos + arshift(lshift(op, 6), 4) + 4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "J" then
local a = ctx.addr + ctx.pos
x = a - band(a, 0x0fffffff) + band(op, 0x03ffffff)*4
ctx.rel = x
x = format("0x%08x", x)
elseif p == "V" then
x = band(rshift(op, 8), 7)
if x == 0 then x = nil end
elseif p == "W" then
x = band(op, 7)
if x == 0 then x = nil end
elseif p == "Y" then
x = band(rshift(op, 6), 0x000fffff)
if x == 0 then x = nil end
elseif p == "Z" then
x = band(rshift(op, 6), 1023)
if x == 0 then x = nil end
elseif p == "0" then
if last == "r0" or last == 0 then
local n = #operands
operands[n] = nil
last = operands[n-1]
if altname then
local a1, a2 = match(altname, "([^|]*)|(.*)")
if a1 then name, altname = a1, a2
else name = altname end
end
end
elseif p == "1" then
if last == "ra" then
operands[#operands] = nil
end
else
assert(false)
end
if x then operands[#operands+1] = x; last = x end
end
return putop(ctx, name, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
stop = stop - stop % 4
ctx.pos = ofs - ofs % 4
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
ctx.get = get_be
ctx.map_pri = map_pri
return ctx
end
local function create_el(code, addr, out)
local ctx = create(code, addr, out)
ctx.get = get_le
return ctx
end
local function create_r6(code, addr, out)
local ctx = create(code, addr, out)
ctx.map_pri = map_pri_r6
return ctx
end
local function create_r6_el(code, addr, out)
local ctx = create(code, addr, out)
ctx.get = get_le
ctx.map_pri = map_pri_r6
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass_el(code, addr, out)
create_el(code, addr, out):disass()
end
local function disass_r6(code, addr, out)
create_r6(code, addr, out):disass()
end
local function disass_r6_el(code, addr, out)
create_r6_el(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
return {
create = create,
create_el = create_el,
create_r6 = create_r6,
create_r6_el = create_r6_el,
disass = disass,
disass_el = disass_el,
disass_r6 = disass_r6,
disass_r6_el = disass_r6_el,
regname = regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the big-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create,
disass = dis_mips.disass,
regname = dis_mips.regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64EL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_el,
disass = dis_mips.disass_el,
regname = dis_mips.regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64R6 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the r6 big-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_r6,
disass = dis_mips.disass_r6,
regname = dis_mips.regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPS64R6EL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the r6 little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_r6_el,
disass = dis_mips.disass_r6_el,
regname = dis_mips.regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT MIPSEL disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the little-endian functions from the
-- MIPS disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
return {
create = dis_mips.create_el,
disass = dis_mips.disass_el,
regname = dis_mips.regname
}
+591
View File
@@ -0,0 +1,591 @@
----------------------------------------------------------------------------
-- LuaJIT PPC disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT/X license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- It disassembles all common, non-privileged 32/64 bit PowerPC instructions
-- plus the e500 SPE instructions and some Cell/Xenon extensions.
--
-- NYI: VMX, VMX128
------------------------------------------------------------------------------
local type = type
local byte, format = string.byte, string.format
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
local concat = table.concat
local bit = require("bit")
local band, bor, tohex = bit.band, bit.bor, bit.tohex
local lshift, rshift, arshift = bit.lshift, bit.rshift, bit.arshift
------------------------------------------------------------------------------
-- Primary and extended opcode maps
------------------------------------------------------------------------------
local map_crops = {
shift = 1, mask = 1023,
[0] = "mcrfXX",
[33] = "crnor|crnotCCC=", [129] = "crandcCCC",
[193] = "crxor|crclrCCC%", [225] = "crnandCCC",
[257] = "crandCCC", [289] = "creqv|crsetCCC%",
[417] = "crorcCCC", [449] = "cror|crmoveCCC=",
[16] = "b_lrKB", [528] = "b_ctrKB",
[150] = "isync",
}
local map_rlwinm = setmetatable({
shift = 0, mask = -1,
},
{ __index = function(t, x)
local rot = band(rshift(x, 11), 31)
local mb = band(rshift(x, 6), 31)
local me = band(rshift(x, 1), 31)
if mb == 0 and me == 31-rot then
return "slwiRR~A."
elseif me == 31 and mb == 32-rot then
return "srwiRR~-A."
else
return "rlwinmRR~AAA."
end
end
})
local map_rld = {
shift = 2, mask = 7,
[0] = "rldiclRR~HM.", "rldicrRR~HM.", "rldicRR~HM.", "rldimiRR~HM.",
{
shift = 1, mask = 1,
[0] = "rldclRR~RM.", "rldcrRR~RM.",
},
}
local map_ext = setmetatable({
shift = 1, mask = 1023,
[0] = "cmp_YLRR", [32] = "cmpl_YLRR",
[4] = "twARR", [68] = "tdARR",
[8] = "subfcRRR.", [40] = "subfRRR.",
[104] = "negRR.", [136] = "subfeRRR.",
[200] = "subfzeRR.", [232] = "subfmeRR.",
[520] = "subfcoRRR.", [552] = "subfoRRR.",
[616] = "negoRR.", [648] = "subfeoRRR.",
[712] = "subfzeoRR.", [744] = "subfmeoRR.",
[9] = "mulhduRRR.", [73] = "mulhdRRR.", [233] = "mulldRRR.",
[457] = "divduRRR.", [489] = "divdRRR.",
[745] = "mulldoRRR.",
[969] = "divduoRRR.", [1001] = "divdoRRR.",
[10] = "addcRRR.", [138] = "addeRRR.",
[202] = "addzeRR.", [234] = "addmeRR.", [266] = "addRRR.",
[522] = "addcoRRR.", [650] = "addeoRRR.",
[714] = "addzeoRR.", [746] = "addmeoRR.", [778] = "addoRRR.",
[11] = "mulhwuRRR.", [75] = "mulhwRRR.", [235] = "mullwRRR.",
[459] = "divwuRRR.", [491] = "divwRRR.",
[747] = "mullwoRRR.",
[971] = "divwouRRR.", [1003] = "divwoRRR.",
[15] = "iselltRRR", [47] = "iselgtRRR", [79] = "iseleqRRR",
[144] = { shift = 20, mask = 1, [0] = "mtcrfRZ~", "mtocrfRZ~", },
[19] = { shift = 20, mask = 1, [0] = "mfcrR", "mfocrfRZ", },
[371] = { shift = 11, mask = 1023, [392] = "mftbR", [424] = "mftbuR", },
[339] = {
shift = 11, mask = 1023,
[32] = "mferR", [256] = "mflrR", [288] = "mfctrR", [16] = "mfspefscrR",
},
[467] = {
shift = 11, mask = 1023,
[32] = "mtxerR", [256] = "mtlrR", [288] = "mtctrR", [16] = "mtspefscrR",
},
[20] = "lwarxRR0R", [84] = "ldarxRR0R",
[21] = "ldxRR0R", [53] = "lduxRRR",
[149] = "stdxRR0R", [181] = "stduxRRR",
[341] = "lwaxRR0R", [373] = "lwauxRRR",
[23] = "lwzxRR0R", [55] = "lwzuxRRR",
[87] = "lbzxRR0R", [119] = "lbzuxRRR",
[151] = "stwxRR0R", [183] = "stwuxRRR",
[215] = "stbxRR0R", [247] = "stbuxRRR",
[279] = "lhzxRR0R", [311] = "lhzuxRRR",
[343] = "lhaxRR0R", [375] = "lhauxRRR",
[407] = "sthxRR0R", [439] = "sthuxRRR",
[54] = "dcbst-R0R", [86] = "dcbf-R0R",
[150] = "stwcxRR0R.", [214] = "stdcxRR0R.",
[246] = "dcbtst-R0R", [278] = "dcbt-R0R",
[310] = "eciwxRR0R", [438] = "ecowxRR0R",
[470] = "dcbi-RR",
[598] = {
shift = 21, mask = 3,
[0] = "sync", "lwsync", "ptesync",
},
[758] = "dcba-RR",
[854] = "eieio", [982] = "icbi-R0R", [1014] = "dcbz-R0R",
[26] = "cntlzwRR~", [58] = "cntlzdRR~",
[122] = "popcntbRR~",
[154] = "prtywRR~", [186] = "prtydRR~",
[28] = "andRR~R.", [60] = "andcRR~R.", [124] = "nor|notRR~R=.",
[284] = "eqvRR~R.", [316] = "xorRR~R.",
[412] = "orcRR~R.", [444] = "or|mrRR~R=.", [476] = "nandRR~R.",
[508] = "cmpbRR~R",
[512] = "mcrxrX",
[532] = "ldbrxRR0R", [660] = "stdbrxRR0R",
[533] = "lswxRR0R", [597] = "lswiRR0A",
[661] = "stswxRR0R", [725] = "stswiRR0A",
[534] = "lwbrxRR0R", [662] = "stwbrxRR0R",
[790] = "lhbrxRR0R", [918] = "sthbrxRR0R",
[535] = "lfsxFR0R", [567] = "lfsuxFRR",
[599] = "lfdxFR0R", [631] = "lfduxFRR",
[663] = "stfsxFR0R", [695] = "stfsuxFRR",
[727] = "stfdxFR0R", [759] = "stfduxFR0R",
[855] = "lfiwaxFR0R",
[983] = "stfiwxFR0R",
[24] = "slwRR~R.",
[27] = "sldRR~R.", [536] = "srwRR~R.",
[792] = "srawRR~R.", [824] = "srawiRR~A.",
[794] = "sradRR~R.", [826] = "sradiRR~H.", [827] = "sradiRR~H.",
[922] = "extshRR~.", [954] = "extsbRR~.", [986] = "extswRR~.",
[539] = "srdRR~R.",
},
{ __index = function(t, x)
if band(x, 31) == 15 then return "iselRRRC" end
end
})
local map_ld = {
shift = 0, mask = 3,
[0] = "ldRRE", "lduRRE", "lwaRRE",
}
local map_std = {
shift = 0, mask = 3,
[0] = "stdRRE", "stduRRE",
}
local map_fps = {
shift = 5, mask = 1,
{
shift = 1, mask = 15,
[0] = false, false, "fdivsFFF.", false,
"fsubsFFF.", "faddsFFF.", "fsqrtsF-F.", false,
"fresF-F.", "fmulsFF-F.", "frsqrtesF-F.", false,
"fmsubsFFFF~.", "fmaddsFFFF~.", "fnmsubsFFFF~.", "fnmaddsFFFF~.",
}
}
local map_fpd = {
shift = 5, mask = 1,
[0] = {
shift = 1, mask = 1023,
[0] = "fcmpuXFF", [32] = "fcmpoXFF", [64] = "mcrfsXX",
[38] = "mtfsb1A.", [70] = "mtfsb0A.", [134] = "mtfsfiA>>-A>",
[8] = "fcpsgnFFF.", [40] = "fnegF-F.", [72] = "fmrF-F.",
[136] = "fnabsF-F.", [264] = "fabsF-F.",
[12] = "frspF-F.",
[14] = "fctiwF-F.", [15] = "fctiwzF-F.",
[583] = "mffsF.", [711] = "mtfsfZF.",
[392] = "frinF-F.", [424] = "frizF-F.",
[456] = "fripF-F.", [488] = "frimF-F.",
[814] = "fctidF-F.", [815] = "fctidzF-F.", [846] = "fcfidF-F.",
},
{
shift = 1, mask = 15,
[0] = false, false, "fdivFFF.", false,
"fsubFFF.", "faddFFF.", "fsqrtF-F.", "fselFFFF~.",
"freF-F.", "fmulFF-F.", "frsqrteF-F.", false,
"fmsubFFFF~.", "fmaddFFFF~.", "fnmsubFFFF~.", "fnmaddFFFF~.",
}
}
local map_spe = {
shift = 0, mask = 2047,
[512] = "evaddwRRR", [514] = "evaddiwRAR~",
[516] = "evsubwRRR~", [518] = "evsubiwRAR~",
[520] = "evabsRR", [521] = "evnegRR",
[522] = "evextsbRR", [523] = "evextshRR", [524] = "evrndwRR",
[525] = "evcntlzwRR", [526] = "evcntlswRR",
[527] = "brincRRR",
[529] = "evandRRR", [530] = "evandcRRR", [534] = "evxorRRR",
[535] = "evor|evmrRRR=", [536] = "evnor|evnotRRR=",
[537] = "eveqvRRR", [539] = "evorcRRR", [542] = "evnandRRR",
[544] = "evsrwuRRR", [545] = "evsrwsRRR",
[546] = "evsrwiuRRA", [547] = "evsrwisRRA",
[548] = "evslwRRR", [550] = "evslwiRRA",
[552] = "evrlwRRR", [553] = "evsplatiRS",
[554] = "evrlwiRRA", [555] = "evsplatfiRS",
[556] = "evmergehiRRR", [557] = "evmergeloRRR",
[558] = "evmergehiloRRR", [559] = "evmergelohiRRR",
[560] = "evcmpgtuYRR", [561] = "evcmpgtsYRR",
[562] = "evcmpltuYRR", [563] = "evcmpltsYRR",
[564] = "evcmpeqYRR",
[632] = "evselRRR", [633] = "evselRRRW",
[634] = "evselRRRW", [635] = "evselRRRW",
[636] = "evselRRRW", [637] = "evselRRRW",
[638] = "evselRRRW", [639] = "evselRRRW",
[640] = "evfsaddRRR", [641] = "evfssubRRR",
[644] = "evfsabsRR", [645] = "evfsnabsRR", [646] = "evfsnegRR",
[648] = "evfsmulRRR", [649] = "evfsdivRRR",
[652] = "evfscmpgtYRR", [653] = "evfscmpltYRR", [654] = "evfscmpeqYRR",
[656] = "evfscfuiR-R", [657] = "evfscfsiR-R",
[658] = "evfscfufR-R", [659] = "evfscfsfR-R",
[660] = "evfsctuiR-R", [661] = "evfsctsiR-R",
[662] = "evfsctufR-R", [663] = "evfsctsfR-R",
[664] = "evfsctuizR-R", [666] = "evfsctsizR-R",
[668] = "evfststgtYRR", [669] = "evfststltYRR", [670] = "evfststeqYRR",
[704] = "efsaddRRR", [705] = "efssubRRR",
[708] = "efsabsRR", [709] = "efsnabsRR", [710] = "efsnegRR",
[712] = "efsmulRRR", [713] = "efsdivRRR",
[716] = "efscmpgtYRR", [717] = "efscmpltYRR", [718] = "efscmpeqYRR",
[719] = "efscfdR-R",
[720] = "efscfuiR-R", [721] = "efscfsiR-R",
[722] = "efscfufR-R", [723] = "efscfsfR-R",
[724] = "efsctuiR-R", [725] = "efsctsiR-R",
[726] = "efsctufR-R", [727] = "efsctsfR-R",
[728] = "efsctuizR-R", [730] = "efsctsizR-R",
[732] = "efststgtYRR", [733] = "efststltYRR", [734] = "efststeqYRR",
[736] = "efdaddRRR", [737] = "efdsubRRR",
[738] = "efdcfuidR-R", [739] = "efdcfsidR-R",
[740] = "efdabsRR", [741] = "efdnabsRR", [742] = "efdnegRR",
[744] = "efdmulRRR", [745] = "efddivRRR",
[746] = "efdctuidzR-R", [747] = "efdctsidzR-R",
[748] = "efdcmpgtYRR", [749] = "efdcmpltYRR", [750] = "efdcmpeqYRR",
[751] = "efdcfsR-R",
[752] = "efdcfuiR-R", [753] = "efdcfsiR-R",
[754] = "efdcfufR-R", [755] = "efdcfsfR-R",
[756] = "efdctuiR-R", [757] = "efdctsiR-R",
[758] = "efdctufR-R", [759] = "efdctsfR-R",
[760] = "efdctuizR-R", [762] = "efdctsizR-R",
[764] = "efdtstgtYRR", [765] = "efdtstltYRR", [766] = "efdtsteqYRR",
[768] = "evlddxRR0R", [769] = "evlddRR8",
[770] = "evldwxRR0R", [771] = "evldwRR8",
[772] = "evldhxRR0R", [773] = "evldhRR8",
[776] = "evlhhesplatxRR0R", [777] = "evlhhesplatRR2",
[780] = "evlhhousplatxRR0R", [781] = "evlhhousplatRR2",
[782] = "evlhhossplatxRR0R", [783] = "evlhhossplatRR2",
[784] = "evlwhexRR0R", [785] = "evlwheRR4",
[788] = "evlwhouxRR0R", [789] = "evlwhouRR4",
[790] = "evlwhosxRR0R", [791] = "evlwhosRR4",
[792] = "evlwwsplatxRR0R", [793] = "evlwwsplatRR4",
[796] = "evlwhsplatxRR0R", [797] = "evlwhsplatRR4",
[800] = "evstddxRR0R", [801] = "evstddRR8",
[802] = "evstdwxRR0R", [803] = "evstdwRR8",
[804] = "evstdhxRR0R", [805] = "evstdhRR8",
[816] = "evstwhexRR0R", [817] = "evstwheRR4",
[820] = "evstwhoxRR0R", [821] = "evstwhoRR4",
[824] = "evstwwexRR0R", [825] = "evstwweRR4",
[828] = "evstwwoxRR0R", [829] = "evstwwoRR4",
[1027] = "evmhessfRRR", [1031] = "evmhossfRRR", [1032] = "evmheumiRRR",
[1033] = "evmhesmiRRR", [1035] = "evmhesmfRRR", [1036] = "evmhoumiRRR",
[1037] = "evmhosmiRRR", [1039] = "evmhosmfRRR", [1059] = "evmhessfaRRR",
[1063] = "evmhossfaRRR", [1064] = "evmheumiaRRR", [1065] = "evmhesmiaRRR",
[1067] = "evmhesmfaRRR", [1068] = "evmhoumiaRRR", [1069] = "evmhosmiaRRR",
[1071] = "evmhosmfaRRR", [1095] = "evmwhssfRRR", [1096] = "evmwlumiRRR",
[1100] = "evmwhumiRRR", [1101] = "evmwhsmiRRR", [1103] = "evmwhsmfRRR",
[1107] = "evmwssfRRR", [1112] = "evmwumiRRR", [1113] = "evmwsmiRRR",
[1115] = "evmwsmfRRR", [1127] = "evmwhssfaRRR", [1128] = "evmwlumiaRRR",
[1132] = "evmwhumiaRRR", [1133] = "evmwhsmiaRRR", [1135] = "evmwhsmfaRRR",
[1139] = "evmwssfaRRR", [1144] = "evmwumiaRRR", [1145] = "evmwsmiaRRR",
[1147] = "evmwsmfaRRR",
[1216] = "evaddusiaawRR", [1217] = "evaddssiaawRR",
[1218] = "evsubfusiaawRR", [1219] = "evsubfssiaawRR",
[1220] = "evmraRR",
[1222] = "evdivwsRRR", [1223] = "evdivwuRRR",
[1224] = "evaddumiaawRR", [1225] = "evaddsmiaawRR",
[1226] = "evsubfumiaawRR", [1227] = "evsubfsmiaawRR",
[1280] = "evmheusiaawRRR", [1281] = "evmhessiaawRRR",
[1283] = "evmhessfaawRRR", [1284] = "evmhousiaawRRR",
[1285] = "evmhossiaawRRR", [1287] = "evmhossfaawRRR",
[1288] = "evmheumiaawRRR", [1289] = "evmhesmiaawRRR",
[1291] = "evmhesmfaawRRR", [1292] = "evmhoumiaawRRR",
[1293] = "evmhosmiaawRRR", [1295] = "evmhosmfaawRRR",
[1320] = "evmhegumiaaRRR", [1321] = "evmhegsmiaaRRR",
[1323] = "evmhegsmfaaRRR", [1324] = "evmhogumiaaRRR",
[1325] = "evmhogsmiaaRRR", [1327] = "evmhogsmfaaRRR",
[1344] = "evmwlusiaawRRR", [1345] = "evmwlssiaawRRR",
[1352] = "evmwlumiaawRRR", [1353] = "evmwlsmiaawRRR",
[1363] = "evmwssfaaRRR", [1368] = "evmwumiaaRRR",
[1369] = "evmwsmiaaRRR", [1371] = "evmwsmfaaRRR",
[1408] = "evmheusianwRRR", [1409] = "evmhessianwRRR",
[1411] = "evmhessfanwRRR", [1412] = "evmhousianwRRR",
[1413] = "evmhossianwRRR", [1415] = "evmhossfanwRRR",
[1416] = "evmheumianwRRR", [1417] = "evmhesmianwRRR",
[1419] = "evmhesmfanwRRR", [1420] = "evmhoumianwRRR",
[1421] = "evmhosmianwRRR", [1423] = "evmhosmfanwRRR",
[1448] = "evmhegumianRRR", [1449] = "evmhegsmianRRR",
[1451] = "evmhegsmfanRRR", [1452] = "evmhogumianRRR",
[1453] = "evmhogsmianRRR", [1455] = "evmhogsmfanRRR",
[1472] = "evmwlusianwRRR", [1473] = "evmwlssianwRRR",
[1480] = "evmwlumianwRRR", [1481] = "evmwlsmianwRRR",
[1491] = "evmwssfanRRR", [1496] = "evmwumianRRR",
[1497] = "evmwsmianRRR", [1499] = "evmwsmfanRRR",
}
local map_pri = {
[0] = false, false, "tdiARI", "twiARI",
map_spe, false, false, "mulliRRI",
"subficRRI", false, "cmpl_iYLRU", "cmp_iYLRI",
"addicRRI", "addic.RRI", "addi|liRR0I", "addis|lisRR0I",
"b_KBJ", "sc", "bKJ", map_crops,
"rlwimiRR~AAA.", map_rlwinm, false, "rlwnmRR~RAA.",
"oriNRR~U", "orisRR~U", "xoriRR~U", "xorisRR~U",
"andi.RR~U", "andis.RR~U", map_rld, map_ext,
"lwzRRD", "lwzuRRD", "lbzRRD", "lbzuRRD",
"stwRRD", "stwuRRD", "stbRRD", "stbuRRD",
"lhzRRD", "lhzuRRD", "lhaRRD", "lhauRRD",
"sthRRD", "sthuRRD", "lmwRRD", "stmwRRD",
"lfsFRD", "lfsuFRD", "lfdFRD", "lfduFRD",
"stfsFRD", "stfsuFRD", "stfdFRD", "stfduFRD",
false, false, map_ld, map_fps,
false, false, map_std, map_fpd,
}
------------------------------------------------------------------------------
local map_gpr = {
[0] = "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
}
local map_cond = { [0] = "lt", "gt", "eq", "so", "ge", "le", "ne", "ns", }
-- Format a condition bit.
local function condfmt(cond)
if cond <= 3 then
return map_cond[band(cond, 3)]
else
return format("4*cr%d+%s", rshift(cond, 2), map_cond[band(cond, 3)])
end
end
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local pos = ctx.pos
local extra = ""
if ctx.rel then
local sym = ctx.symtab[ctx.rel]
if sym then extra = "\t->"..sym end
end
if ctx.hexdump > 0 then
ctx.out(format("%08x %s %-7s %s%s\n",
ctx.addr+pos, tohex(ctx.op), text, concat(operands, ", "), extra))
else
ctx.out(format("%08x %-7s %s%s\n",
ctx.addr+pos, text, concat(operands, ", "), extra))
end
ctx.pos = pos + 4
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
return putop(ctx, ".long", { "0x"..tohex(ctx.op) })
end
-- Disassemble a single instruction.
local function disass_ins(ctx)
local pos = ctx.pos
local b0, b1, b2, b3 = byte(ctx.code, pos+1, pos+4)
local op = bor(lshift(b0, 24), lshift(b1, 16), lshift(b2, 8), b3)
local operands = {}
local last = nil
local rs = 21
ctx.op = op
ctx.rel = nil
local opat = map_pri[rshift(b0, 2)]
while type(opat) ~= "string" do
if not opat then return unknown(ctx) end
opat = opat[band(rshift(op, opat.shift), opat.mask)]
end
local name, pat = match(opat, "^([a-z0-9_.]*)(.*)")
local altname, pat2 = match(pat, "|([a-z0-9_.]*)(.*)")
if altname then pat = pat2 end
for p in gmatch(pat, ".") do
local x = nil
if p == "R" then
x = map_gpr[band(rshift(op, rs), 31)]
rs = rs - 5
elseif p == "F" then
x = "f"..band(rshift(op, rs), 31)
rs = rs - 5
elseif p == "A" then
x = band(rshift(op, rs), 31)
rs = rs - 5
elseif p == "S" then
x = arshift(lshift(op, 27-rs), 27)
rs = rs - 5
elseif p == "I" then
x = arshift(lshift(op, 16), 16)
elseif p == "U" then
x = band(op, 0xffff)
elseif p == "D" or p == "E" then
local disp = arshift(lshift(op, 16), 16)
if p == "E" then disp = band(disp, -4) end
if last == "r0" then last = "0" end
operands[#operands] = format("%d(%s)", disp, last)
elseif p >= "2" and p <= "8" then
local disp = band(rshift(op, rs), 31) * p
if last == "r0" then last = "0" end
operands[#operands] = format("%d(%s)", disp, last)
elseif p == "H" then
x = band(rshift(op, rs), 31) + lshift(band(op, 2), 4)
rs = rs - 5
elseif p == "M" then
x = band(rshift(op, rs), 31) + band(op, 0x20)
elseif p == "C" then
x = condfmt(band(rshift(op, rs), 31))
rs = rs - 5
elseif p == "B" then
local bo = rshift(op, 21)
local cond = band(rshift(op, 16), 31)
local cn = ""
rs = rs - 10
if band(bo, 4) == 0 then
cn = band(bo, 2) == 0 and "dnz" or "dz"
if band(bo, 0x10) == 0 then
cn = cn..(band(bo, 8) == 0 and "f" or "t")
end
if band(bo, 0x10) == 0 then x = condfmt(cond) end
name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
elseif band(bo, 0x10) == 0 then
cn = map_cond[band(cond, 3) + (band(bo, 8) == 0 and 4 or 0)]
if cond > 3 then x = "cr"..rshift(cond, 2) end
name = name..(band(bo, 1) == band(rshift(op, 15), 1) and "-" or "+")
end
name = gsub(name, "_", cn)
elseif p == "J" then
x = arshift(lshift(op, 27-rs), 29-rs)*4
if band(op, 2) == 0 then x = ctx.addr + pos + x end
ctx.rel = x
x = "0x"..tohex(x)
elseif p == "K" then
if band(op, 1) ~= 0 then name = name.."l" end
if band(op, 2) ~= 0 then name = name.."a" end
elseif p == "X" or p == "Y" then
x = band(rshift(op, rs+2), 7)
if x == 0 and p == "Y" then x = nil else x = "cr"..x end
rs = rs - 5
elseif p == "W" then
x = "cr"..band(op, 7)
elseif p == "Z" then
x = band(rshift(op, rs-4), 255)
rs = rs - 10
elseif p == ">" then
operands[#operands] = rshift(operands[#operands], 1)
elseif p == "0" then
if last == "r0" then
operands[#operands] = nil
if altname then name = altname end
end
elseif p == "L" then
name = gsub(name, "_", band(op, 0x00200000) ~= 0 and "d" or "w")
elseif p == "." then
if band(op, 1) == 1 then name = name.."." end
elseif p == "N" then
if op == 0x60000000 then name = "nop"; break end
elseif p == "~" then
local n = #operands
operands[n-1], operands[n] = operands[n], operands[n-1]
elseif p == "=" then
local n = #operands
if last == operands[n-1] then
operands[n] = nil
name = altname
end
elseif p == "%" then
local n = #operands
if last == operands[n-1] and last == operands[n-2] then
operands[n] = nil
operands[n-1] = nil
name = altname
end
elseif p == "-" then
rs = rs - 5
else
assert(false)
end
if x then operands[#operands+1] = x; last = x end
end
return putop(ctx, name, operands)
end
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
stop = stop - stop % 4
ctx.pos = ofs - ofs % 4
ctx.rel = nil
while ctx.pos < stop do disass_ins(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = addr or 0
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 8
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 32 then return map_gpr[r] end
return "f"..(r-32)
end
-- Public module functions.
return {
create = create,
disass = disass,
regname = regname
}
+17
View File
@@ -0,0 +1,17 @@
----------------------------------------------------------------------------
-- LuaJIT x64 disassembler wrapper module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This module just exports the 64 bit functions from the combined
-- x86/x64 disassembler module. All the interesting stuff is there.
------------------------------------------------------------------------------
local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
return {
create = dis_x86.create64,
disass = dis_x86.disass64,
regname = dis_x86.regname64
}
+953
View File
@@ -0,0 +1,953 @@
----------------------------------------------------------------------------
-- LuaJIT x86/x64 disassembler module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
-- This is a helper module used by the LuaJIT machine code dumper module.
--
-- Sending small code snippets to an external disassembler and mixing the
-- output with our own stuff was too fragile. So I had to bite the bullet
-- and write yet another x86 disassembler. Oh well ...
--
-- The output format is very similar to what ndisasm generates. But it has
-- been developed independently by looking at the opcode tables from the
-- Intel and AMD manuals. The supported instruction set is quite extensive
-- and reflects what a current generation Intel or AMD CPU implements in
-- 32 bit and 64 bit mode. Yes, this includes MMX, SSE, SSE2, SSE3, SSSE3,
-- SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and even privileged and hypervisor
-- (VMX/SVM) instructions.
--
-- Notes:
-- * The (useless) a16 prefix, 3DNow and pre-586 opcodes are unsupported.
-- * No attempt at optimization has been made -- it's fast enough for my needs.
------------------------------------------------------------------------------
local type = type
local sub, byte, format = string.sub, string.byte, string.format
local match, gmatch, gsub = string.match, string.gmatch, string.gsub
local lower, rep = string.lower, string.rep
local bit = require("bit")
local tohex = bit.tohex
-- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on.
local map_opc1_32 = {
--0x
[0]="addBmr","addVmr","addBrm","addVrm","addBai","addVai","push es","pop es",
"orBmr","orVmr","orBrm","orVrm","orBai","orVai","push cs","opc2*",
--1x
"adcBmr","adcVmr","adcBrm","adcVrm","adcBai","adcVai","push ss","pop ss",
"sbbBmr","sbbVmr","sbbBrm","sbbVrm","sbbBai","sbbVai","push ds","pop ds",
--2x
"andBmr","andVmr","andBrm","andVrm","andBai","andVai","es:seg","daa",
"subBmr","subVmr","subBrm","subVrm","subBai","subVai","cs:seg","das",
--3x
"xorBmr","xorVmr","xorBrm","xorVrm","xorBai","xorVai","ss:seg","aaa",
"cmpBmr","cmpVmr","cmpBrm","cmpVrm","cmpBai","cmpVai","ds:seg","aas",
--4x
"incVR","incVR","incVR","incVR","incVR","incVR","incVR","incVR",
"decVR","decVR","decVR","decVR","decVR","decVR","decVR","decVR",
--5x
"pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR","pushUR",
"popUR","popUR","popUR","popUR","popUR","popUR","popUR","popUR",
--6x
"sz*pushaw,pusha","sz*popaw,popa","boundVrm","arplWmr",
"fs:seg","gs:seg","o16:","a16",
"pushUi","imulVrmi","pushBs","imulVrms",
"insb","insVS","outsb","outsVS",
--7x
"joBj","jnoBj","jbBj","jnbBj","jzBj","jnzBj","jbeBj","jaBj",
"jsBj","jnsBj","jpeBj","jpoBj","jlBj","jgeBj","jleBj","jgBj",
--8x
"arith!Bmi","arith!Vmi","arith!Bmi","arith!Vms",
"testBmr","testVmr","xchgBrm","xchgVrm",
"movBmr","movVmr","movBrm","movVrm",
"movVmg","leaVrm","movWgm","popUm",
--9x
"nop*xchgVaR|pause|xchgWaR|repne nop","xchgVaR","xchgVaR","xchgVaR",
"xchgVaR","xchgVaR","xchgVaR","xchgVaR",
"sz*cbw,cwde,cdqe","sz*cwd,cdq,cqo","call farViw","wait",
"sz*pushfw,pushf","sz*popfw,popf","sahf","lahf",
--Ax
"movBao","movVao","movBoa","movVoa",
"movsb","movsVS","cmpsb","cmpsVS",
"testBai","testVai","stosb","stosVS",
"lodsb","lodsVS","scasb","scasVS",
--Bx
"movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi","movBRi",
"movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI","movVRI",
--Cx
"shift!Bmu","shift!Vmu","retBw","ret","vex*3$lesVrm","vex*2$ldsVrm","movBmi","movVmi",
"enterBwu","leave","retfBw","retf","int3","intBu","into","iretVS",
--Dx
"shift!Bm1","shift!Vm1","shift!Bmc","shift!Vmc","aamBu","aadBu","salc","xlatb",
"fp*0","fp*1","fp*2","fp*3","fp*4","fp*5","fp*6","fp*7",
--Ex
"loopneBj","loopeBj","loopBj","sz*jcxzBj,jecxzBj,jrcxzBj",
"inBau","inVau","outBua","outVua",
"callVj","jmpVj","jmp farViw","jmpBj","inBad","inVad","outBda","outVda",
--Fx
"lock:","int1","repne:rep","rep:","hlt","cmc","testb!Bm","testv!Vm",
"clc","stc","cli","sti","cld","std","incb!Bm","incd!Vm",
}
assert(#map_opc1_32 == 255)
-- Map for 1st opcode byte in 64 bit mode (overrides only).
local map_opc1_64 = setmetatable({
[0x06]=false, [0x07]=false, [0x0e]=false,
[0x16]=false, [0x17]=false, [0x1e]=false, [0x1f]=false,
[0x27]=false, [0x2f]=false, [0x37]=false, [0x3f]=false,
[0x60]=false, [0x61]=false, [0x62]=false, [0x63]="movsxdVrDmt", [0x67]="a32:",
[0x40]="rex*", [0x41]="rex*b", [0x42]="rex*x", [0x43]="rex*xb",
[0x44]="rex*r", [0x45]="rex*rb", [0x46]="rex*rx", [0x47]="rex*rxb",
[0x48]="rex*w", [0x49]="rex*wb", [0x4a]="rex*wx", [0x4b]="rex*wxb",
[0x4c]="rex*wr", [0x4d]="rex*wrb", [0x4e]="rex*wrx", [0x4f]="rex*wrxb",
[0x82]=false, [0x9a]=false, [0xc4]="vex*3", [0xc5]="vex*2", [0xce]=false,
[0xd4]=false, [0xd5]=false, [0xd6]=false, [0xea]=false,
}, { __index = map_opc1_32 })
-- Map for 2nd opcode byte (0F xx). True CISC hell. Hey, I told you.
-- Prefix dependent MMX/SSE opcodes: (none)|rep|o16|repne, -|F3|66|F2
local map_opc2 = {
--0x
[0]="sldt!Dmp","sgdt!Ump","larVrm","lslVrm",nil,"syscall","clts","sysret",
"invd","wbinvd",nil,"ud1",nil,"$prefetch!Bm","femms","3dnowMrmu",
--1x
"movupsXrm|movssXrvm|movupdXrm|movsdXrvm",
"movupsXmr|movssXmvr|movupdXmr|movsdXmvr",
"movhlpsXrm$movlpsXrm|movsldupXrm|movlpdXrm|movddupXrm",
"movlpsXmr||movlpdXmr",
"unpcklpsXrvm||unpcklpdXrvm",
"unpckhpsXrvm||unpckhpdXrvm",
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
"movhpsXmr||movhpdXmr",
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
"hintnopVm","hintnopVm","hintnopVm","hintnopVm",
--2x
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
"movapsXrm||movapdXrm",
"movapsXmr||movapdXmr",
"cvtpi2psXrMm|cvtsi2ssXrvVmt|cvtpi2pdXrMm|cvtsi2sdXrvVmt",
"movntpsXmr|movntssXmr|movntpdXmr|movntsdXmr",
"cvttps2piMrXm|cvttss2siVrXm|cvttpd2piMrXm|cvttsd2siVrXm",
"cvtps2piMrXm|cvtss2siVrXm|cvtpd2piMrXm|cvtsd2siVrXm",
"ucomissXrm||ucomisdXrm",
"comissXrm||comisdXrm",
--3x
"wrmsr","rdtsc","rdmsr","rdpmc","sysenter","sysexit",nil,"getsec",
"opc3*38",nil,"opc3*3a",nil,nil,nil,nil,nil,
--4x
"cmovoVrm","cmovnoVrm","cmovbVrm","cmovnbVrm",
"cmovzVrm","cmovnzVrm","cmovbeVrm","cmovaVrm",
"cmovsVrm","cmovnsVrm","cmovpeVrm","cmovpoVrm",
"cmovlVrm","cmovgeVrm","cmovleVrm","cmovgVrm",
--5x
"movmskpsVrXm$||movmskpdVrXm$","sqrtpsXrm|sqrtssXrm|sqrtpdXrm|sqrtsdXrm",
"rsqrtpsXrm|rsqrtssXrvm","rcppsXrm|rcpssXrvm",
"andpsXrvm||andpdXrvm","andnpsXrvm||andnpdXrvm",
"orpsXrvm||orpdXrvm","xorpsXrvm||xorpdXrvm",
"addpsXrvm|addssXrvm|addpdXrvm|addsdXrvm","mulpsXrvm|mulssXrvm|mulpdXrvm|mulsdXrvm",
"cvtps2pdXrm|cvtss2sdXrvm|cvtpd2psXrm|cvtsd2ssXrvm",
"cvtdq2psXrm|cvttps2dqXrm|cvtps2dqXrm",
"subpsXrvm|subssXrvm|subpdXrvm|subsdXrvm","minpsXrvm|minssXrvm|minpdXrvm|minsdXrvm",
"divpsXrvm|divssXrvm|divpdXrvm|divsdXrvm","maxpsXrvm|maxssXrvm|maxpdXrvm|maxsdXrvm",
--6x
"punpcklbwPrvm","punpcklwdPrvm","punpckldqPrvm","packsswbPrvm",
"pcmpgtbPrvm","pcmpgtwPrvm","pcmpgtdPrvm","packuswbPrvm",
"punpckhbwPrvm","punpckhwdPrvm","punpckhdqPrvm","packssdwPrvm",
"||punpcklqdqXrvm","||punpckhqdqXrvm",
"movPrVSm","movqMrm|movdquXrm|movdqaXrm",
--7x
"pshufwMrmu|pshufhwXrmu|pshufdXrmu|pshuflwXrmu","pshiftw!Pvmu",
"pshiftd!Pvmu","pshiftq!Mvmu||pshiftdq!Xvmu",
"pcmpeqbPrvm","pcmpeqwPrvm","pcmpeqdPrvm","emms*|",
"vmreadUmr||extrqXmuu$|insertqXrmuu$","vmwriteUrm||extrqXrm$|insertqXrm$",
nil,nil,
"||haddpdXrvm|haddpsXrvm","||hsubpdXrvm|hsubpsXrvm",
"movVSmMr|movqXrm|movVSmXr","movqMmr|movdquXmr|movdqaXmr",
--8x
"joVj","jnoVj","jbVj","jnbVj","jzVj","jnzVj","jbeVj","jaVj",
"jsVj","jnsVj","jpeVj","jpoVj","jlVj","jgeVj","jleVj","jgVj",
--9x
"setoBm","setnoBm","setbBm","setnbBm","setzBm","setnzBm","setbeBm","setaBm",
"setsBm","setnsBm","setpeBm","setpoBm","setlBm","setgeBm","setleBm","setgBm",
--Ax
"push fs","pop fs","cpuid","btVmr","shldVmru","shldVmrc",nil,nil,
"push gs","pop gs","rsm","btsVmr","shrdVmru","shrdVmrc","fxsave!Dmp","imulVrm",
--Bx
"cmpxchgBmr","cmpxchgVmr","$lssVrm","btrVmr",
"$lfsVrm","$lgsVrm","movzxVrBmt","movzxVrWmt",
"|popcntVrm","ud2Dp","bt!Vmu","btcVmr",
"bsfVrm","bsrVrm|lzcntVrm|bsrWrm","movsxVrBmt","movsxVrWmt",
--Cx
"xaddBmr","xaddVmr",
"cmppsXrvmu|cmpssXrvmu|cmppdXrvmu|cmpsdXrvmu","$movntiVmr|",
"pinsrwPrvWmu","pextrwDrPmu",
"shufpsXrvmu||shufpdXrvmu","$cmpxchg!Qmp",
"bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR","bswapVR",
--Dx
"||addsubpdXrvm|addsubpsXrvm","psrlwPrvm","psrldPrvm","psrlqPrvm",
"paddqPrvm","pmullwPrvm",
"|movq2dqXrMm|movqXmr|movdq2qMrXm$","pmovmskbVrMm||pmovmskbVrXm",
"psubusbPrvm","psubuswPrvm","pminubPrvm","pandPrvm",
"paddusbPrvm","padduswPrvm","pmaxubPrvm","pandnPrvm",
--Ex
"pavgbPrvm","psrawPrvm","psradPrvm","pavgwPrvm",
"pmulhuwPrvm","pmulhwPrvm",
"|cvtdq2pdXrm|cvttpd2dqXrm|cvtpd2dqXrm","$movntqMmr||$movntdqXmr",
"psubsbPrvm","psubswPrvm","pminswPrvm","porPrvm",
"paddsbPrvm","paddswPrvm","pmaxswPrvm","pxorPrvm",
--Fx
"|||lddquXrm","psllwPrvm","pslldPrvm","psllqPrvm",
"pmuludqPrvm","pmaddwdPrvm","psadbwPrvm","maskmovqMrm||maskmovdquXrm$",
"psubbPrvm","psubwPrvm","psubdPrvm","psubqPrvm",
"paddbPrvm","paddwPrvm","padddPrvm","ud",
}
assert(map_opc2[255] == "ud")
-- Map for three-byte opcodes. Can't wait for their next invention.
local map_opc3 = {
["38"] = { -- [66] 0f 38 xx
--0x
[0]="pshufbPrvm","phaddwPrvm","phadddPrvm","phaddswPrvm",
"pmaddubswPrvm","phsubwPrvm","phsubdPrvm","phsubswPrvm",
"psignbPrvm","psignwPrvm","psigndPrvm","pmulhrswPrvm",
"||permilpsXrvm","||permilpdXrvm",nil,nil,
--1x
"||pblendvbXrma",nil,nil,nil,
"||blendvpsXrma","||blendvpdXrma","||permpsXrvm","||ptestXrm",
"||broadcastssXrm","||broadcastsdXrm","||broadcastf128XrlXm",nil,
"pabsbPrm","pabswPrm","pabsdPrm",nil,
--2x
"||pmovsxbwXrm","||pmovsxbdXrm","||pmovsxbqXrm","||pmovsxwdXrm",
"||pmovsxwqXrm","||pmovsxdqXrm",nil,nil,
"||pmuldqXrvm","||pcmpeqqXrvm","||$movntdqaXrm","||packusdwXrvm",
"||maskmovpsXrvm","||maskmovpdXrvm","||maskmovpsXmvr","||maskmovpdXmvr",
--3x
"||pmovzxbwXrm","||pmovzxbdXrm","||pmovzxbqXrm","||pmovzxwdXrm",
"||pmovzxwqXrm","||pmovzxdqXrm","||permdXrvm","||pcmpgtqXrvm",
"||pminsbXrvm","||pminsdXrvm","||pminuwXrvm","||pminudXrvm",
"||pmaxsbXrvm","||pmaxsdXrvm","||pmaxuwXrvm","||pmaxudXrvm",
--4x
"||pmulddXrvm","||phminposuwXrm",nil,nil,
nil,"||psrlvVSXrvm","||psravdXrvm","||psllvVSXrvm",
--5x
[0x58] = "||pbroadcastdXrlXm",[0x59] = "||pbroadcastqXrlXm",
[0x5a] = "||broadcasti128XrlXm",
--7x
[0x78] = "||pbroadcastbXrlXm",[0x79] = "||pbroadcastwXrlXm",
--8x
[0x8c] = "||pmaskmovXrvVSm",
[0x8e] = "||pmaskmovVSmXvr",
--9x
[0x96] = "||fmaddsub132pHXrvm",[0x97] = "||fmsubadd132pHXrvm",
[0x98] = "||fmadd132pHXrvm",[0x99] = "||fmadd132sHXrvm",
[0x9a] = "||fmsub132pHXrvm",[0x9b] = "||fmsub132sHXrvm",
[0x9c] = "||fnmadd132pHXrvm",[0x9d] = "||fnmadd132sHXrvm",
[0x9e] = "||fnmsub132pHXrvm",[0x9f] = "||fnmsub132sHXrvm",
--Ax
[0xa6] = "||fmaddsub213pHXrvm",[0xa7] = "||fmsubadd213pHXrvm",
[0xa8] = "||fmadd213pHXrvm",[0xa9] = "||fmadd213sHXrvm",
[0xaa] = "||fmsub213pHXrvm",[0xab] = "||fmsub213sHXrvm",
[0xac] = "||fnmadd213pHXrvm",[0xad] = "||fnmadd213sHXrvm",
[0xae] = "||fnmsub213pHXrvm",[0xaf] = "||fnmsub213sHXrvm",
--Bx
[0xb6] = "||fmaddsub231pHXrvm",[0xb7] = "||fmsubadd231pHXrvm",
[0xb8] = "||fmadd231pHXrvm",[0xb9] = "||fmadd231sHXrvm",
[0xba] = "||fmsub231pHXrvm",[0xbb] = "||fmsub231sHXrvm",
[0xbc] = "||fnmadd231pHXrvm",[0xbd] = "||fnmadd231sHXrvm",
[0xbe] = "||fnmsub231pHXrvm",[0xbf] = "||fnmsub231sHXrvm",
--Dx
[0xdc] = "||aesencXrvm", [0xdd] = "||aesenclastXrvm",
[0xde] = "||aesdecXrvm", [0xdf] = "||aesdeclastXrvm",
--Fx
[0xf0] = "|||crc32TrBmt",[0xf1] = "|||crc32TrVmt",
[0xf7] = "| sarxVrmv| shlxVrmv| shrxVrmv",
},
["3a"] = { -- [66] 0f 3a xx
--0x
[0x00]="||permqXrmu","||permpdXrmu","||pblenddXrvmu",nil,
"||permilpsXrmu","||permilpdXrmu","||perm2f128Xrvmu",nil,
"||roundpsXrmu","||roundpdXrmu","||roundssXrvmu","||roundsdXrvmu",
"||blendpsXrvmu","||blendpdXrvmu","||pblendwXrvmu","palignrPrvmu",
--1x
nil,nil,nil,nil,
"||pextrbVmXru","||pextrwVmXru","||pextrVmSXru","||extractpsVmXru",
"||insertf128XrvlXmu","||extractf128XlXmYru",nil,nil,
nil,nil,nil,nil,
--2x
"||pinsrbXrvVmu","||insertpsXrvmu","||pinsrXrvVmuS",nil,
--3x
[0x38] = "||inserti128Xrvmu",[0x39] = "||extracti128XlXmYru",
--4x
[0x40] = "||dppsXrvmu",
[0x41] = "||dppdXrvmu",
[0x42] = "||mpsadbwXrvmu",
[0x44] = "||pclmulqdqXrvmu",
[0x46] = "||perm2i128Xrvmu",
[0x4a] = "||blendvpsXrvmb",[0x4b] = "||blendvpdXrvmb",
[0x4c] = "||pblendvbXrvmb",
--6x
[0x60] = "||pcmpestrmXrmu",[0x61] = "||pcmpestriXrmu",
[0x62] = "||pcmpistrmXrmu",[0x63] = "||pcmpistriXrmu",
[0xdf] = "||aeskeygenassistXrmu",
--Fx
[0xf0] = "||| rorxVrmu",
},
}
-- Map for VMX/SVM opcodes 0F 01 C0-FF (sgdt group with register operands).
local map_opcvm = {
[0xc1]="vmcall",[0xc2]="vmlaunch",[0xc3]="vmresume",[0xc4]="vmxoff",
[0xc8]="monitor",[0xc9]="mwait",
[0xd8]="vmrun",[0xd9]="vmmcall",[0xda]="vmload",[0xdb]="vmsave",
[0xdc]="stgi",[0xdd]="clgi",[0xde]="skinit",[0xdf]="invlpga",
[0xf8]="swapgs",[0xf9]="rdtscp",
}
-- Map for FP opcodes. And you thought stack machines are simple?
local map_opcfp = {
-- D8-DF 00-BF: opcodes with a memory operand.
-- D8
[0]="faddFm","fmulFm","fcomFm","fcompFm","fsubFm","fsubrFm","fdivFm","fdivrFm",
"fldFm",nil,"fstFm","fstpFm","fldenvVm","fldcwWm","fnstenvVm","fnstcwWm",
-- DA
"fiaddDm","fimulDm","ficomDm","ficompDm",
"fisubDm","fisubrDm","fidivDm","fidivrDm",
-- DB
"fildDm","fisttpDm","fistDm","fistpDm",nil,"fld twordFmp",nil,"fstp twordFmp",
-- DC
"faddGm","fmulGm","fcomGm","fcompGm","fsubGm","fsubrGm","fdivGm","fdivrGm",
-- DD
"fldGm","fisttpQm","fstGm","fstpGm","frstorDmp",nil,"fnsaveDmp","fnstswWm",
-- DE
"fiaddWm","fimulWm","ficomWm","ficompWm",
"fisubWm","fisubrWm","fidivWm","fidivrWm",
-- DF
"fildWm","fisttpWm","fistWm","fistpWm",
"fbld twordFmp","fildQm","fbstp twordFmp","fistpQm",
-- xx C0-FF: opcodes with a pseudo-register operand.
-- D8
"faddFf","fmulFf","fcomFf","fcompFf","fsubFf","fsubrFf","fdivFf","fdivrFf",
-- D9
"fldFf","fxchFf",{"fnop"},nil,
{"fchs","fabs",nil,nil,"ftst","fxam"},
{"fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz"},
{"f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp"},
{"fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"},
-- DA
"fcmovbFf","fcmoveFf","fcmovbeFf","fcmovuFf",nil,{nil,"fucompp"},nil,nil,
-- DB
"fcmovnbFf","fcmovneFf","fcmovnbeFf","fcmovnuFf",
{nil,nil,"fnclex","fninit"},"fucomiFf","fcomiFf",nil,
-- DC
"fadd toFf","fmul toFf",nil,nil,
"fsub toFf","fsubr toFf","fdivr toFf","fdiv toFf",
-- DD
"ffreeFf",nil,"fstFf","fstpFf","fucomFf","fucompFf",nil,nil,
-- DE
"faddpFf","fmulpFf",nil,{nil,"fcompp"},
"fsubrpFf","fsubpFf","fdivrpFf","fdivpFf",
-- DF
nil,nil,nil,nil,{"fnstsw ax"},"fucomipFf","fcomipFf",nil,
}
assert(map_opcfp[126] == "fcomipFf")
-- Map for opcode groups. The subkey is sp from the ModRM byte.
local map_opcgroup = {
arith = { "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" },
shift = { "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar" },
testb = { "testBmi", "testBmi", "not", "neg", "mul", "imul", "div", "idiv" },
testv = { "testVmi", "testVmi", "not", "neg", "mul", "imul", "div", "idiv" },
incb = { "inc", "dec" },
incd = { "inc", "dec", "callUmp", "$call farDmp",
"jmpUmp", "$jmp farDmp", "pushUm" },
sldt = { "sldt", "str", "lldt", "ltr", "verr", "verw" },
sgdt = { "vm*$sgdt", "vm*$sidt", "$lgdt", "vm*$lidt",
"smsw", nil, "lmsw", "vm*$invlpg" },
bt = { nil, nil, nil, nil, "bt", "bts", "btr", "btc" },
cmpxchg = { nil, "sz*,cmpxchg8bQmp,cmpxchg16bXmp", nil, nil,
nil, nil, "vmptrld|vmxon|vmclear", "vmptrst" },
pshiftw = { nil, nil, "psrlw", nil, "psraw", nil, "psllw" },
pshiftd = { nil, nil, "psrld", nil, "psrad", nil, "pslld" },
pshiftq = { nil, nil, "psrlq", nil, nil, nil, "psllq" },
pshiftdq = { nil, nil, "psrlq", "psrldq", nil, nil, "psllq", "pslldq" },
fxsave = { "$fxsave", "$fxrstor", "$ldmxcsr", "$stmxcsr",
nil, "lfenceDp$", "mfenceDp$", "sfenceDp$clflush" },
prefetch = { "prefetch", "prefetchw" },
prefetcht = { "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2" },
}
------------------------------------------------------------------------------
-- Maps for register names.
local map_regs = {
B = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
B64 = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
W = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" },
D = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" },
Q = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" },
M = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" }, -- No x64 ext!
X = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" },
Y = { "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15" },
}
local map_segregs = { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
-- Maps for size names.
local map_sz2n = {
B = 1, W = 2, D = 4, Q = 8, M = 8, X = 16, Y = 32,
}
local map_sz2prefix = {
B = "byte", W = "word", D = "dword",
Q = "qword",
M = "qword", X = "xword", Y = "yword",
F = "dword", G = "qword", -- No need for sizes/register names for these two.
}
------------------------------------------------------------------------------
-- Output a nicely formatted line with an opcode and operands.
local function putop(ctx, text, operands)
local code, pos, hex = ctx.code, ctx.pos, ""
local hmax = ctx.hexdump
if hmax > 0 then
for i=ctx.start,pos-1 do
hex = hex..format("%02X", byte(code, i, i))
end
if #hex > hmax then hex = sub(hex, 1, hmax)..". "
else hex = hex..rep(" ", hmax-#hex+2) end
end
if operands then text = text.." "..operands end
if ctx.o16 then text = "o16 "..text; ctx.o16 = false end
if ctx.a32 then text = "a32 "..text; ctx.a32 = false end
if ctx.rep then text = ctx.rep.." "..text; ctx.rep = false end
if ctx.rex then
local t = (ctx.rexw and "w" or "")..(ctx.rexr and "r" or "")..
(ctx.rexx and "x" or "")..(ctx.rexb and "b" or "")..
(ctx.vexl and "l" or "")
if ctx.vexv and ctx.vexv ~= 0 then t = t.."v"..ctx.vexv end
if t ~= "" then text = ctx.rex.."."..t.." "..gsub(text, "^ ", "")
elseif ctx.rex == "vex" then text = gsub("v"..text, "^v ", "") end
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.vexl = false; ctx.vexv = false
end
if ctx.seg then
local text2, n = gsub(text, "%[", "["..ctx.seg..":")
if n == 0 then text = ctx.seg.." "..text else text = text2 end
ctx.seg = false
end
if ctx.lock then text = "lock "..text; ctx.lock = false end
local imm = ctx.imm
if imm then
local sym = ctx.symtab[imm]
if sym then text = text.."\t->"..sym end
end
ctx.out(format("%08x %s%s\n", ctx.addr+ctx.start, hex, text))
ctx.mrm = false
ctx.vexv = false
ctx.start = pos
ctx.imm = nil
end
-- Clear all prefix flags.
local function clearprefixes(ctx)
ctx.o16 = false; ctx.seg = false; ctx.lock = false; ctx.rep = false
ctx.rexw = false; ctx.rexr = false; ctx.rexx = false; ctx.rexb = false
ctx.rex = false; ctx.a32 = false; ctx.vexl = false
end
-- Fallback for incomplete opcodes at the end.
local function incomplete(ctx)
ctx.pos = ctx.stop+1
clearprefixes(ctx)
return putop(ctx, "(incomplete)")
end
-- Fallback for unknown opcodes.
local function unknown(ctx)
clearprefixes(ctx)
return putop(ctx, "(unknown)")
end
-- Return an immediate of the specified size.
local function getimm(ctx, pos, n)
if pos+n-1 > ctx.stop then return incomplete(ctx) end
local code = ctx.code
if n == 1 then
local b1 = byte(code, pos, pos)
return b1
elseif n == 2 then
local b1, b2 = byte(code, pos, pos+1)
return b1+b2*256
else
local b1, b2, b3, b4 = byte(code, pos, pos+3)
local imm = b1+b2*256+b3*65536+b4*16777216
ctx.imm = imm
return imm
end
end
-- Process pattern string and generate the operands.
local function putpat(ctx, name, pat)
local operands, regs, sz, mode, sp, rm, sc, rx, sdisp
local code, pos, stop, vexl = ctx.code, ctx.pos, ctx.stop, ctx.vexl
-- Chars used: 1DFGHIMPQRSTUVWXYabcdfgijlmoprstuvwxyz
for p in gmatch(pat, ".") do
local x = nil
if p == "V" or p == "U" then
if ctx.rexw then sz = "Q"; ctx.rexw = false
elseif ctx.o16 then sz = "W"; ctx.o16 = false
elseif p == "U" and ctx.x64 then sz = "Q"
else sz = "D" end
regs = map_regs[sz]
elseif p == "T" then
if ctx.rexw then sz = "Q"; ctx.rexw = false else sz = "D" end
regs = map_regs[sz]
elseif p == "B" then
sz = "B"
regs = ctx.rex and map_regs.B64 or map_regs.B
elseif match(p, "[WDQMXYFG]") then
sz = p
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "P" then
sz = ctx.o16 and "X" or "M"; ctx.o16 = false
if sz == "X" and vexl then sz = "Y"; ctx.vexl = false end
regs = map_regs[sz]
elseif p == "H" then
name = name..(ctx.rexw and "d" or "s")
ctx.rexw = false
elseif p == "S" then
name = name..lower(sz)
elseif p == "s" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = imm <= 127 and format("+0x%02x", imm)
or format("-0x%02x", 256-imm)
pos = pos+1
elseif p == "u" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = format("0x%02x", imm)
pos = pos+1
elseif p == "b" then
local imm = getimm(ctx, pos, 1); if not imm then return end
x = regs[imm/16+1]
pos = pos+1
elseif p == "w" then
local imm = getimm(ctx, pos, 2); if not imm then return end
x = format("0x%x", imm)
pos = pos+2
elseif p == "o" then -- [offset]
if ctx.x64 then
local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
x = format("[0x%08x%08x]", imm2, imm1)
pos = pos+8
else
local imm = getimm(ctx, pos, 4); if not imm then return end
x = format("[0x%08x]", imm)
pos = pos+4
end
elseif p == "i" or p == "I" then
local n = map_sz2n[sz]
if n == 8 and ctx.x64 and p == "I" then
local imm1 = getimm(ctx, pos, 4); if not imm1 then return end
local imm2 = getimm(ctx, pos+4, 4); if not imm2 then return end
x = format("0x%08x%08x", imm2, imm1)
else
if n == 8 then n = 4 end
local imm = getimm(ctx, pos, n); if not imm then return end
if sz == "Q" and (imm < 0 or imm > 0x7fffffff) then
imm = (0xffffffff+1)-imm
x = format(imm > 65535 and "-0x%08x" or "-0x%x", imm)
else
x = format(imm > 65535 and "0x%08x" or "0x%x", imm)
end
end
pos = pos+n
elseif p == "j" then
local n = map_sz2n[sz]
if n == 8 then n = 4 end
local imm = getimm(ctx, pos, n); if not imm then return end
if sz == "B" and imm > 127 then imm = imm-256
elseif imm > 2147483647 then imm = imm-4294967296 end
pos = pos+n
imm = imm + pos + ctx.addr
if imm > 4294967295 and not ctx.x64 then imm = imm-4294967296 end
ctx.imm = imm
if sz == "W" then
x = format("word 0x%04x", imm%65536)
elseif ctx.x64 then
local lo = imm % 0x1000000
x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo)
else
x = "0x"..tohex(imm)
end
elseif p == "R" then
local r = byte(code, pos-1, pos-1)%8
if ctx.rexb then r = r + 8; ctx.rexb = false end
x = regs[r+1]
elseif p == "a" then x = regs[1]
elseif p == "c" then x = "cl"
elseif p == "d" then x = "dx"
elseif p == "1" then x = "1"
else
if not mode then
mode = ctx.mrm
if not mode then
if pos > stop then return incomplete(ctx) end
mode = byte(code, pos, pos)
pos = pos+1
end
rm = mode%8; mode = (mode-rm)/8
sp = mode%8; mode = (mode-sp)/8
sdisp = ""
if mode < 3 then
if rm == 4 then
if pos > stop then return incomplete(ctx) end
sc = byte(code, pos, pos)
pos = pos+1
rm = sc%8; sc = (sc-rm)/8
rx = sc%8; sc = (sc-rx)/8
if ctx.rexx then rx = rx + 8; ctx.rexx = false end
if rx == 4 then rx = nil end
end
if mode > 0 or rm == 5 then
local dsz = mode
if dsz ~= 1 then dsz = 4 end
local disp = getimm(ctx, pos, dsz); if not disp then return end
if mode == 0 then rm = nil end
if rm or rx or (not sc and ctx.x64 and not ctx.a32) then
if dsz == 1 and disp > 127 then
sdisp = format("-0x%x", 256-disp)
elseif disp >= 0 and disp <= 0x7fffffff then
sdisp = format("+0x%x", disp)
else
sdisp = format("-0x%x", (0xffffffff+1)-disp)
end
else
sdisp = format(ctx.x64 and not ctx.a32 and
not (disp >= 0 and disp <= 0x7fffffff)
and "0xffffffff%08x" or "0x%08x", disp)
end
pos = pos+dsz
end
end
if rm and ctx.rexb then rm = rm + 8; ctx.rexb = false end
if ctx.rexr then sp = sp + 8; ctx.rexr = false end
end
if p == "m" then
if mode == 3 then x = regs[rm+1]
else
local aregs = ctx.a32 and map_regs.D or ctx.aregs
local srm, srx = "", ""
if rm then srm = aregs[rm+1]
elseif not sc and ctx.x64 and not ctx.a32 then srm = "rip" end
ctx.a32 = false
if rx then
if rm then srm = srm.."+" end
srx = aregs[rx+1]
if sc > 0 then srx = srx.."*"..(2^sc) end
end
x = format("[%s%s%s]", srm, srx, sdisp)
end
if mode < 3 and
(not match(pat, "[aRrgp]") or match(pat, "t")) then -- Yuck.
x = map_sz2prefix[sz].." "..x
end
elseif p == "r" then x = regs[sp+1]
elseif p == "g" then x = map_segregs[sp+1]
elseif p == "p" then -- Suppress prefix.
elseif p == "f" then x = "st"..rm
elseif p == "x" then
if sp == 0 and ctx.lock and not ctx.x64 then
x = "CR8"; ctx.lock = false
else
x = "CR"..sp
end
elseif p == "v" then
if ctx.vexv then
x = regs[ctx.vexv+1]; ctx.vexv = false
end
elseif p == "y" then x = "DR"..sp
elseif p == "z" then x = "TR"..sp
elseif p == "l" then vexl = false
elseif p == "t" then
else
error("bad pattern `"..pat.."'")
end
end
if x then operands = operands and operands..", "..x or x end
end
ctx.pos = pos
return putop(ctx, name, operands)
end
-- Forward declaration.
local map_act
-- Fetch and cache MRM byte.
local function getmrm(ctx)
local mrm = ctx.mrm
if not mrm then
local pos = ctx.pos
if pos > ctx.stop then return nil end
mrm = byte(ctx.code, pos, pos)
ctx.pos = pos+1
ctx.mrm = mrm
end
return mrm
end
-- Dispatch to handler depending on pattern.
local function dispatch(ctx, opat, patgrp)
if not opat then return unknown(ctx) end
if match(opat, "%|") then -- MMX/SSE variants depending on prefix.
local p
if ctx.rep then
p = ctx.rep=="rep" and "%|([^%|]*)" or "%|[^%|]*%|[^%|]*%|([^%|]*)"
ctx.rep = false
elseif ctx.o16 then p = "%|[^%|]*%|([^%|]*)"; ctx.o16 = false
else p = "^[^%|]*" end
opat = match(opat, p)
if not opat then return unknown(ctx) end
-- ctx.rep = false; ctx.o16 = false
--XXX fails for 66 f2 0f 38 f1 06 crc32 eax,WORD PTR [esi]
--XXX remove in branches?
end
if match(opat, "%$") then -- reg$mem variants.
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
opat = match(opat, mrm >= 192 and "^[^%$]*" or "%$(.*)")
if opat == "" then return unknown(ctx) end
end
if opat == "" then return unknown(ctx) end
local name, pat = match(opat, "^([a-z0-9 ]*)(.*)")
if pat == "" and patgrp then pat = patgrp end
return map_act[sub(pat, 1, 1)](ctx, name, pat)
end
-- Get a pattern from an opcode map and dispatch to handler.
local function dispatchmap(ctx, opcmap)
local pos = ctx.pos
local opat = opcmap[byte(ctx.code, pos, pos)]
pos = pos + 1
ctx.pos = pos
return dispatch(ctx, opat)
end
-- Map for action codes. The key is the first char after the name.
map_act = {
-- Simple opcodes without operands.
[""] = function(ctx, name, pat)
return putop(ctx, name)
end,
-- Operand size chars fall right through.
B = putpat, W = putpat, D = putpat, Q = putpat,
V = putpat, U = putpat, T = putpat,
M = putpat, X = putpat, P = putpat,
F = putpat, G = putpat, Y = putpat,
H = putpat,
-- Collect prefixes.
[":"] = function(ctx, name, pat)
ctx[pat == ":" and name or sub(pat, 2)] = name
if ctx.pos - ctx.start > 5 then return unknown(ctx) end -- Limit #prefixes.
end,
-- Chain to special handler specified by name.
["*"] = function(ctx, name, pat)
return map_act[name](ctx, name, sub(pat, 2))
end,
-- Use named subtable for opcode group.
["!"] = function(ctx, name, pat)
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
return dispatch(ctx, map_opcgroup[name][((mrm-(mrm%8))/8)%8+1], sub(pat, 2))
end,
-- o16,o32[,o64] variants.
sz = function(ctx, name, pat)
if ctx.o16 then ctx.o16 = false
else
pat = match(pat, ",(.*)")
if ctx.rexw then
local p = match(pat, ",(.*)")
if p then pat = p; ctx.rexw = false end
end
end
pat = match(pat, "^[^,]*")
return dispatch(ctx, pat)
end,
-- Two-byte opcode dispatch.
opc2 = function(ctx, name, pat)
return dispatchmap(ctx, map_opc2)
end,
-- Three-byte opcode dispatch.
opc3 = function(ctx, name, pat)
return dispatchmap(ctx, map_opc3[pat])
end,
-- VMX/SVM dispatch.
vm = function(ctx, name, pat)
return dispatch(ctx, map_opcvm[ctx.mrm])
end,
-- Floating point opcode dispatch.
fp = function(ctx, name, pat)
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
local rm = mrm%8
local idx = pat*8 + ((mrm-rm)/8)%8
if mrm >= 192 then idx = idx + 64 end
local opat = map_opcfp[idx]
if type(opat) == "table" then opat = opat[rm+1] end
return dispatch(ctx, opat)
end,
-- REX prefix.
rex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
for p in gmatch(pat, ".") do ctx["rex"..p] = true end
ctx.rex = "rex"
end,
-- VEX prefix.
vex = function(ctx, name, pat)
if ctx.rex then return unknown(ctx) end -- Only 1 REX or VEX prefix allowed.
ctx.rex = "vex"
local pos = ctx.pos
if ctx.mrm then
ctx.mrm = nil
pos = pos-1
end
local b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b < 128 then ctx.rexr = true end
local m = 1
if pat == "3" then
m = b%32; b = (b-m)/32
local nb = b%2; b = (b-nb)/2
if nb == 0 then ctx.rexb = true end
local nx = b%2
if nx == 0 then ctx.rexx = true end
b = byte(ctx.code, pos, pos)
if not b then return incomplete(ctx) end
pos = pos+1
if b >= 128 then ctx.rexw = true end
end
ctx.pos = pos
local map
if m == 1 then map = map_opc2
elseif m == 2 then map = map_opc3["38"]
elseif m == 3 then map = map_opc3["3a"]
else return unknown(ctx) end
local p = b%4; b = (b-p)/4
if p == 1 then ctx.o16 = "o16"
elseif p == 2 then ctx.rep = "rep"
elseif p == 3 then ctx.rep = "repne" end
local l = b%2; b = (b-l)/2
if l ~= 0 then ctx.vexl = true end
ctx.vexv = (-1-b)%16
return dispatchmap(ctx, map)
end,
-- Special case for nop with REX prefix.
nop = function(ctx, name, pat)
return dispatch(ctx, ctx.rex and pat or "nop")
end,
-- Special case for 0F 77.
emms = function(ctx, name, pat)
if ctx.rex ~= "vex" then
return putop(ctx, "emms")
elseif ctx.vexl then
ctx.vexl = false
return putop(ctx, "zeroall")
else
return putop(ctx, "zeroupper")
end
end,
}
------------------------------------------------------------------------------
-- Disassemble a block of code.
local function disass_block(ctx, ofs, len)
if not ofs then ofs = 0 end
local stop = len and ofs+len or #ctx.code
ofs = ofs + 1
ctx.start = ofs
ctx.pos = ofs
ctx.stop = stop
ctx.imm = nil
ctx.mrm = false
clearprefixes(ctx)
while ctx.pos <= stop do dispatchmap(ctx, ctx.map1) end
if ctx.pos ~= ctx.start then incomplete(ctx) end
end
-- Extended API: create a disassembler context. Then call ctx:disass(ofs, len).
local function create(code, addr, out)
local ctx = {}
ctx.code = code
ctx.addr = (addr or 0) - 1
ctx.out = out or io.write
ctx.symtab = {}
ctx.disass = disass_block
ctx.hexdump = 16
ctx.x64 = false
ctx.map1 = map_opc1_32
ctx.aregs = map_regs.D
return ctx
end
local function create64(code, addr, out)
local ctx = create(code, addr, out)
ctx.x64 = true
ctx.map1 = map_opc1_64
ctx.aregs = map_regs.Q
return ctx
end
-- Simple API: disassemble code (a string) at address and output via out.
local function disass(code, addr, out)
create(code, addr, out):disass()
end
local function disass64(code, addr, out)
create64(code, addr, out):disass()
end
-- Return register name for RID.
local function regname(r)
if r < 8 then return map_regs.D[r+1] end
return map_regs.X[r-7]
end
local function regname64(r)
if r < 16 then return map_regs.Q[r+1] end
return map_regs.X[r-15]
end
-- Public module functions.
return {
create = create,
create64 = create64,
disass = disass,
disass64 = disass64,
regname = regname,
regname64 = regname64
}
+731
View File
@@ -0,0 +1,731 @@
----------------------------------------------------------------------------
-- LuaJIT compiler dump module.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module can be used to debug the JIT compiler itself. It dumps the
-- code representations and structures used in various compiler stages.
--
-- Example usage:
--
-- luajit -jdump -e "local x=0; for i=1,1e6 do x=x+i end; print(x)"
-- luajit -jdump=im -e "for i=1,1000 do for j=1,1000 do end end" | less -R
-- luajit -jdump=is myapp.lua | less -R
-- luajit -jdump=-b myapp.lua
-- luajit -jdump=+aH,myapp.html myapp.lua
-- luajit -jdump=ixT,myapp.dump myapp.lua
--
-- The first argument specifies the dump mode. The second argument gives
-- the output file name. Default output is to stdout, unless the environment
-- variable LUAJIT_DUMPFILE is set. The file is overwritten every time the
-- module is started.
--
-- Different features can be turned on or off with the dump mode. If the
-- mode starts with a '+', the following features are added to the default
-- set of features; a '-' removes them. Otherwise the features are replaced.
--
-- The following dump features are available (* marks the default):
--
-- * t Print a line for each started, ended or aborted trace (see also -jv).
-- * b Dump the traced bytecode.
-- * i Dump the IR (intermediate representation).
-- r Augment the IR with register/stack slots.
-- s Dump the snapshot map.
-- * m Dump the generated machine code.
-- x Print each taken trace exit.
-- X Print each taken trace exit and the contents of all registers.
-- a Print the IR of aborted traces, too.
--
-- The output format can be set with the following characters:
--
-- T Plain text output.
-- A ANSI-colored text output
-- H Colorized HTML + CSS output.
--
-- The default output format is plain text. It's set to ANSI-colored text
-- if the COLORTERM variable is set. Note: this is independent of any output
-- redirection, which is actually considered a feature.
--
-- You probably want to use less -R to enjoy viewing ANSI-colored text from
-- a pipe or a file. Add this to your ~/.bashrc: export LESS="-R"
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
local bit = require("bit")
local band, shr, tohex = bit.band, bit.rshift, bit.tohex
local sub, gsub, format = string.sub, string.gsub, string.format
local byte, rep = string.byte, string.rep
local type, tostring = type, tostring
local stdout, stderr = io.stdout, io.stderr
-- Load other modules on-demand.
local bcline, disass
-- Active flag, output file handle and dump mode.
local active, out, dumpmode
------------------------------------------------------------------------------
local symtabmt = { __index = false }
local symtab = {}
local nexitsym = 0
-- Fill nested symbol table with per-trace exit stub addresses.
local function fillsymtab_tr(tr, nexit)
local t = {}
symtabmt.__index = t
if jit.arch:sub(1, 4) == "mips" then
t[traceexitstub(tr, 0)] = "exit"
return
end
for i=0,nexit-1 do
local addr = traceexitstub(tr, i)
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
local addr = traceexitstub(tr, nexit)
if addr then t[addr] = "stack_check" end
end
-- Fill symbol table with trace exit stub addresses.
local function fillsymtab(tr, nexit)
local t = symtab
if nexitsym == 0 then
local maskaddr = jit.arch == "arm" and -2
local ircall = vmdef.ircall
for i=0,#ircall do
local addr = ircalladdr(i)
if addr ~= 0 then
if maskaddr then addr = band(addr, maskaddr) end
if addr < 0 then addr = addr + 2^32 end
t[addr] = ircall[i]
end
end
end
if nexitsym == 1000000 then -- Per-trace exit stubs.
fillsymtab_tr(tr, nexit)
elseif nexit > nexitsym then -- Shared exit stubs.
for i=nexitsym,nexit-1 do
local addr = traceexitstub(i)
if addr == nil then -- Fall back to per-trace exit stubs.
fillsymtab_tr(tr, nexit)
setmetatable(symtab, symtabmt)
nexit = 1000000
break
end
if addr < 0 then addr = addr + 2^32 end
t[addr] = tostring(i)
end
nexitsym = nexit
end
return t
end
local function dumpwrite(s)
out:write(s)
end
-- Disassemble machine code.
local function dump_mcode(tr)
local info = traceinfo(tr)
if not info then return end
local mcode, addr, loop = tracemc(tr)
if not mcode then return end
if not disass then disass = require("jit.dis_"..jit.arch) end
if addr < 0 then addr = addr + 2^32 end
out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
local ctx = disass.create(mcode, addr, dumpwrite)
ctx.hexdump = 0
ctx.symtab = fillsymtab(tr, info.nexit)
if loop ~= 0 then
symtab[addr+loop] = "LOOP"
ctx:disass(0, loop)
out:write("->LOOP:\n")
ctx:disass(loop, #mcode-loop)
symtab[addr+loop] = nil
else
ctx:disass(0, #mcode)
end
end
------------------------------------------------------------------------------
local irtype_text = {
[0] = "nil",
"fal",
"tru",
"lud",
"str",
"p32",
"thr",
"pro",
"fun",
"p64",
"cdt",
"tab",
"udt",
"flt",
"num",
"i8 ",
"u8 ",
"i16",
"u16",
"int",
"u32",
"i64",
"u64",
"sfp",
}
local colortype_ansi = {
[0] = "%s",
"%s",
"%s",
"\027[36m%s\027[m",
"\027[32m%s\027[m",
"%s",
"\027[1m%s\027[m",
"%s",
"\027[1m%s\027[m",
"%s",
"\027[33m%s\027[m",
"\027[31m%s\027[m",
"\027[36m%s\027[m",
"\027[34m%s\027[m",
"\027[34m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
"\027[35m%s\027[m",
}
local function colorize_text(s)
return s
end
local function colorize_ansi(s, t, extra)
local out = format(colortype_ansi[t], s)
if extra then out = "\027[3m"..out end
return out
end
local irtype_ansi = setmetatable({},
{ __index = function(tab, t)
local s = colorize_ansi(irtype_text[t], t); tab[t] = s; return s; end })
local html_escape = { ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;", }
local function colorize_html(s, t, extra)
s = gsub(s, "[<>&]", html_escape)
return format('<span class="irt_%s%s">%s</span>',
irtype_text[t], extra and " irt_extra" or "", s)
end
local irtype_html = setmetatable({},
{ __index = function(tab, t)
local s = colorize_html(irtype_text[t], t); tab[t] = s; return s; end })
local header_html = [[
<style type="text/css">
background { background: #ffffff; color: #000000; }
pre.ljdump {
font-size: 10pt;
background: #f0f4ff;
color: #000000;
border: 1px solid #bfcfff;
padding: 0.5em;
margin-left: 2em;
margin-right: 2em;
}
span.irt_str { color: #00a000; }
span.irt_thr, span.irt_fun { color: #404040; font-weight: bold; }
span.irt_tab { color: #c00000; }
span.irt_udt, span.irt_lud { color: #00c0c0; }
span.irt_num { color: #4040c0; }
span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; }
span.irt_extra { font-style: italic; }
</style>
]]
local colorize, irtype
-- Lookup tables to convert some literals into names.
local litname = {
["SLOAD "] = setmetatable({}, { __index = function(t, mode)
local s = ""
if band(mode, 1) ~= 0 then s = s.."P" end
if band(mode, 2) ~= 0 then s = s.."F" end
if band(mode, 4) ~= 0 then s = s.."T" end
if band(mode, 8) ~= 0 then s = s.."C" end
if band(mode, 16) ~= 0 then s = s.."R" end
if band(mode, 32) ~= 0 then s = s.."I" end
if band(mode, 64) ~= 0 then s = s.."K" end
t[mode] = s
return s
end}),
["XLOAD "] = { [0] = "", "R", "V", "RV", "U", "RU", "VU", "RVU", },
["CONV "] = setmetatable({}, { __index = function(t, mode)
local s = irtype[band(mode, 31)]
s = irtype[band(shr(mode, 5), 31)].."."..s
if band(mode, 0x800) ~= 0 then s = s.." sext" end
local c = shr(mode, 12)
if c == 1 then s = s.." none"
elseif c == 2 then s = s.." index"
elseif c == 3 then s = s.." check" end
t[mode] = s
return s
end}),
["FLOAD "] = vmdef.irfield,
["FREF "] = vmdef.irfield,
["FPMATH"] = vmdef.irfpm,
["TMPREF"] = { [0] = "", "IN", "OUT", "INOUT", "", "", "OUT2", "INOUT2" },
["BUFHDR"] = { [0] = "RESET", "APPEND", "WRITE" },
["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
}
local function ctlsub(c)
if c == "\n" then return "\\n"
elseif c == "\r" then return "\\r"
elseif c == "\t" then return "\\t"
else return format("\\%03d", byte(c))
end
end
local function fmtfunc(func, pc)
local fi = funcinfo(func, pc)
if fi.loc then
return fi.loc
elseif fi.ffid then
return vmdef.ffnames[fi.ffid]
elseif fi.addr then
return format("C:%x", fi.addr)
else
return "(?)"
end
end
local function formatk(tr, idx, sn)
local k, t, slot = tracek(tr, idx)
local tn = type(k)
local s
if tn == "number" then
if t < 12 then
s = k == 0 and "NULL" or format("[0x%08x]", k)
elseif band(sn or 0, 0x30000) ~= 0 then
s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz"
elseif k == 2^52+2^51 then
s = "bias"
else
local m = tonumber("0x1p-1026")
s = format(m ~= nil and 0 < k and k < m and "%+a" or "%+.14g", k)
end
elseif tn == "string" then
s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub))
elseif tn == "function" then
s = fmtfunc(k)
elseif tn == "table" then
s = format("{%p}", k)
elseif tn == "userdata" then
if t == 12 then
s = format("userdata:%p", k)
else
s = format("[%p]", k)
if s == "[NULL]" then s = "NULL" end
end
elseif t == 21 then -- int64_t
s = sub(tostring(k), 1, -3)
if sub(s, 1, 1) ~= "-" then s = "+"..s end
elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL)
return "----" -- Special case for LJ_FR2 slot 1.
else
s = tostring(k) -- For primitives.
end
s = colorize(format("%-4s", s), t, band(sn or 0, 0x100000) ~= 0)
if slot then
s = format("%s @%d", s, slot)
end
return s
end
local function printsnap(tr, snap)
local n = 2
for s=0,snap[1]-1 do
local sn = snap[n]
if shr(sn, 24) == s then
n = n + 1
local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS
if ref < 0 then
out:write(formatk(tr, ref, sn))
elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM
out:write(colorize(format("%04d/%04d", ref, ref+1), 14))
else
local m, ot, op1, op2 = traceir(tr, ref)
out:write(colorize(format("%04d", ref), band(ot, 31), band(sn, 0x100000) ~= 0))
end
out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME
else
out:write("---- ")
end
end
out:write("]\n")
end
-- Dump snapshots (not interleaved with IR).
local function dump_snap(tr)
out:write("---- TRACE ", tr, " snapshots\n")
for i=0,1000000000 do
local snap = tracesnap(tr, i)
if not snap then break end
out:write(format("#%-3d %04d [ ", i, snap[0]))
printsnap(tr, snap)
end
end
-- Return a register name or stack slot for a rid/sp location.
local function ridsp_name(ridsp, ins)
if not disass then disass = require("jit.dis_"..jit.arch) end
local rid, slot = band(ridsp, 0xff), shr(ridsp, 8)
if rid == 253 or rid == 254 then
return (slot == 0 or slot == 255) and " {sink" or format(" {%04d", ins-slot)
end
if ridsp > 255 then return format("[%x]", slot*4) end
if rid < 128 then return disass.regname(rid) end
return ""
end
-- Dump CALL* function ref and return optional ctype.
local function dumpcallfunc(tr, ins)
local ctype
if ins > 0 then
local m, ot, op1, op2 = traceir(tr, ins)
if band(ot, 31) == 0 then -- nil type means CARG(func, ctype).
ins = op1
ctype = formatk(tr, op2)
end
end
if ins < 0 then
out:write(format("[0x%x](", tonumber((tracek(tr, ins)))))
else
out:write(format("%04d (", ins))
end
return ctype
end
-- Recursively gather CALL* args and dump them.
local function dumpcallargs(tr, ins)
if ins < 0 then
out:write(formatk(tr, ins))
else
local m, ot, op1, op2 = traceir(tr, ins)
local oidx = 6*shr(ot, 8)
local op = sub(vmdef.irnames, oidx+1, oidx+6)
if op == "CARG " then
dumpcallargs(tr, op1)
if op2 < 0 then
out:write(" ", formatk(tr, op2))
else
out:write(" ", format("%04d", op2))
end
else
out:write(format("%04d", ins))
end
end
end
-- Dump IR and interleaved snapshots.
local function dump_ir(tr, dumpsnap, dumpreg)
local info = traceinfo(tr)
if not info then return end
local nins = info.nins
out:write("---- TRACE ", tr, " IR\n")
local irnames = vmdef.irnames
local snapref = 65536
local snap, snapno
if dumpsnap then
snap = tracesnap(tr, 0)
snapref = snap[0]
snapno = 0
end
for ins=1,nins do
if ins >= snapref then
if dumpreg then
out:write(format(".... SNAP #%-3d [ ", snapno))
else
out:write(format(".... SNAP #%-3d [ ", snapno))
end
printsnap(tr, snap)
snapno = snapno + 1
snap = tracesnap(tr, snapno)
snapref = snap and snap[0] or 65536
end
local m, ot, op1, op2, ridsp = traceir(tr, ins)
local oidx, t = 6*shr(ot, 8), band(ot, 31)
local op = sub(irnames, oidx+1, oidx+6)
if op == "LOOP " then
if dumpreg then
out:write(format("%04d ------------ LOOP ------------\n", ins))
else
out:write(format("%04d ------ LOOP ------------\n", ins))
end
elseif op ~= "NOP " and op ~= "CARG " and
(dumpreg or op ~= "RENAME") then
local rid = band(ridsp, 255)
if dumpreg then
out:write(format("%04d %-6s", ins, ridsp_name(ridsp, ins)))
else
out:write(format("%04d ", ins))
end
out:write(format("%s%s %s %s ",
(rid == 254 or rid == 253) and "}" or
(band(ot, 128) == 0 and " " or ">"),
band(ot, 64) == 0 and " " or "+",
irtype[t], op))
local m1, m2 = band(m, 3), band(m, 3*4)
if sub(op, 1, 4) == "CALL" then
local ctype
if m2 == 1*4 then -- op2 == IRMlit
out:write(format("%-10s (", vmdef.ircall[op2]))
else
ctype = dumpcallfunc(tr, op2)
end
if op1 ~= -1 then dumpcallargs(tr, op1) end
out:write(")")
if ctype then out:write(" ctype ", ctype) end
elseif op == "CNEW " and op2 == -1 then
out:write(formatk(tr, op1))
elseif m1 ~= 3 then -- op1 != IRMnone
if op1 < 0 then
out:write(formatk(tr, op1))
else
out:write(format(m1 == 0 and "%04d" or "#%-3d", op1))
end
if m2 ~= 3*4 then -- op2 != IRMnone
if m2 == 1*4 then -- op2 == IRMlit
local litn = litname[op]
if litn and litn[op2] then
out:write(" ", litn[op2])
elseif op == "UREFO " or op == "UREFC " then
out:write(format(" #%-3d", shr(op2, 8)))
else
out:write(format(" #%-3d", op2))
end
elseif op2 < 0 then
out:write(" ", formatk(tr, op2))
else
out:write(format(" %04d", op2))
end
end
end
out:write("\n")
end
end
if snap then
if dumpreg then
out:write(format(".... SNAP #%-3d [ ", snapno))
else
out:write(format(".... SNAP #%-3d [ ", snapno))
end
printsnap(tr, snap)
end
end
------------------------------------------------------------------------------
local recprefix = ""
local recdepth = 0
-- Format trace error message.
local function fmterr(err, info)
if type(err) == "number" then
if type(info) == "function" then info = fmtfunc(info) end
local fmt = vmdef.traceerr[err]
if fmt == "NYI: bytecode %s" then
local oidx = 6 * info
info = sub(vmdef.bcnames, oidx+1, oidx+6)
end
err = format(fmt, info)
end
return err
end
-- Dump trace states.
local function dump_trace(what, tr, func, pc, otr, oex)
if what == "stop" or (what == "abort" and dumpmode.a) then
if dumpmode.i then dump_ir(tr, dumpmode.s, dumpmode.r and what == "stop")
elseif dumpmode.s then dump_snap(tr) end
if dumpmode.m then dump_mcode(tr) end
end
if what == "start" then
if dumpmode.H then out:write('<pre class="ljdump">\n') end
out:write("---- TRACE ", tr, " ", what)
if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end
out:write(" ", fmtfunc(func, pc), "\n")
elseif what == "stop" or what == "abort" then
out:write("---- TRACE ", tr, " ", what)
if what == "abort" then
out:write(" ", fmtfunc(func, pc), " -- ", fmterr(otr, oex), "\n")
else
local info = traceinfo(tr)
local link, ltype = info.link, info.linktype
if link == tr or link == 0 then
out:write(" -> ", ltype, "\n")
elseif ltype == "root" then
out:write(" -> ", link, "\n")
else
out:write(" -> ", link, " ", ltype, "\n")
end
end
if dumpmode.H then out:write("</pre>\n\n") else out:write("\n") end
else
if what == "flush" then symtab, nexitsym = {}, 0 end
out:write("---- TRACE ", what, "\n\n")
end
out:flush()
end
-- Dump recorded bytecode.
local function dump_record(tr, func, pc, depth)
if depth ~= recdepth then
recdepth = depth
recprefix = rep(" .", depth)
end
local line
if pc >= 0 then
line = bcline(func, pc, recprefix)
if dumpmode.H then line = gsub(line, "[<>&]", html_escape) end
else
line = "0000 "..recprefix.." FUNCC \n"
end
if pc <= 0 then
out:write(sub(line, 1, -2), " ; ", fmtfunc(func), "\n")
else
out:write(line)
end
if pc >= 0 and band(funcbc(func, pc), 0xff) < 16 then -- ORDER BC
out:write(bcline(func, pc+1, recprefix)) -- Write JMP for cond.
end
end
------------------------------------------------------------------------------
local gpr64 = jit.arch:match("64")
local fprmips32 = jit.arch == "mips" or jit.arch == "mipsel"
-- Dump taken trace exits.
local function dump_texit(tr, ex, ngpr, nfpr, ...)
out:write("---- TRACE ", tr, " exit ", ex, "\n")
if dumpmode.X then
local regs = {...}
if gpr64 then
for i=1,ngpr do
out:write(format(" %016x", regs[i]))
if i % 4 == 0 then out:write("\n") end
end
else
for i=1,ngpr do
out:write(" ", tohex(regs[i]))
if i % 8 == 0 then out:write("\n") end
end
end
if fprmips32 then
for i=1,nfpr,2 do
out:write(format(" %+17.14g", regs[ngpr+i]))
if i % 8 == 7 then out:write("\n") end
end
else
for i=1,nfpr do
out:write(format(" %+17.14g", regs[ngpr+i]))
if i % 4 == 0 then out:write("\n") end
end
end
end
end
------------------------------------------------------------------------------
-- Detach dump handlers.
local function dumpoff()
if active then
active = false
jit.attach(dump_texit)
jit.attach(dump_record)
jit.attach(dump_trace)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach dump handlers.
local function dumpon(opt, outfile)
if active then dumpoff() end
local term = os.getenv("TERM")
local colormode = (term and term:match("color") or os.getenv("COLORTERM")) and "A" or "T"
if opt then
opt = gsub(opt, "[TAH]", function(mode) colormode = mode; return ""; end)
end
local m = { t=true, b=true, i=true, m=true, }
if opt and opt ~= "" then
local o = sub(opt, 1, 1)
if o ~= "+" and o ~= "-" then m = {} end
for i=1,#opt do m[sub(opt, i, i)] = (o ~= "-") end
end
dumpmode = m
if m.t or m.b or m.i or m.s or m.m then
jit.attach(dump_trace, "trace")
end
if m.b then
jit.attach(dump_record, "record")
if not bcline then bcline = require("jit.bc").line end
end
if m.x or m.X then
jit.attach(dump_texit, "texit")
end
if not outfile then outfile = os.getenv("LUAJIT_DUMPFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stdout
end
m[colormode] = true
if colormode == "A" then
colorize = colorize_ansi
irtype = irtype_ansi
elseif colormode == "H" then
colorize = colorize_html
irtype = irtype_html
out:write(header_html)
else
colorize = colorize_text
irtype = irtype_text
end
active = true
end
-- Public module functions.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}
+309
View File
@@ -0,0 +1,309 @@
----------------------------------------------------------------------------
-- LuaJIT profiler.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module is a simple command line interface to the built-in
-- low-overhead profiler of LuaJIT.
--
-- The lower-level API of the profiler is accessible via the "jit.profile"
-- module or the luaJIT_profile_* C API.
--
-- Example usage:
--
-- luajit -jp myapp.lua
-- luajit -jp=s myapp.lua
-- luajit -jp=-s myapp.lua
-- luajit -jp=vl myapp.lua
-- luajit -jp=G,profile.txt myapp.lua
--
-- The following dump features are available:
--
-- f Stack dump: function name, otherwise module:line. Default mode.
-- F Stack dump: ditto, but always prepend module.
-- l Stack dump: module:line.
-- <number> stack dump depth (callee < caller). Default: 1.
-- -<number> Inverse stack dump depth (caller > callee).
-- s Split stack dump after first stack level. Implies abs(depth) >= 2.
-- p Show full path for module names.
-- v Show VM states. Can be combined with stack dumps, e.g. vf or fv.
-- z Show zones. Can be combined with stack dumps, e.g. zf or fz.
-- r Show raw sample counts. Default: show percentages.
-- a Annotate excerpts from source code files.
-- A Annotate complete source code files.
-- G Produce raw output suitable for graphical tools (e.g. flame graphs).
-- m<number> Minimum sample percentage to be shown. Default: 3.
-- i<number> Sampling interval in milliseconds. Default: 10.
--
----------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local profile = require("jit.profile")
local vmdef = require("jit.vmdef")
local math = math
local pairs, ipairs, tonumber, floor = pairs, ipairs, tonumber, math.floor
local sort, format = table.sort, string.format
local stdout = io.stdout
local zone -- Load jit.zone module on demand.
-- Output file handle.
local out
------------------------------------------------------------------------------
local prof_ud
local prof_states, prof_split, prof_min, prof_raw, prof_fmt, prof_depth
local prof_ann, prof_count1, prof_count2, prof_samples
local map_vmmode = {
N = "Compiled",
I = "Interpreted",
C = "C code",
G = "Garbage Collector",
J = "JIT Compiler",
}
-- Profiler callback.
local function prof_cb(th, samples, vmmode)
prof_samples = prof_samples + samples
local key_stack, key_stack2, key_state
-- Collect keys for sample.
if prof_states then
if prof_states == "v" then
key_state = map_vmmode[vmmode] or vmmode
else
key_state = zone:get() or "(none)"
end
end
if prof_fmt then
key_stack = profile.dumpstack(th, prof_fmt, prof_depth)
key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x)
return vmdef.ffnames[tonumber(x)]
end)
if prof_split == 2 then
local k1, k2 = key_stack:match("(.-) [<>] (.*)")
if k2 then key_stack, key_stack2 = k1, k2 end
elseif prof_split == 3 then
key_stack2 = profile.dumpstack(th, "l", 1)
end
end
-- Order keys.
local k1, k2
if prof_split == 1 then
if key_state then
k1 = key_state
if key_stack then k2 = key_stack end
end
elseif key_stack then
k1 = key_stack
if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end
end
-- Coalesce samples in one or two levels.
if k1 then
local t1 = prof_count1
t1[k1] = (t1[k1] or 0) + samples
if k2 then
local t2 = prof_count2
local t3 = t2[k1]
if not t3 then t3 = {}; t2[k1] = t3 end
t3[k2] = (t3[k2] or 0) + samples
end
end
end
------------------------------------------------------------------------------
-- Show top N list.
local function prof_top(count1, count2, samples, indent)
local t, n = {}, 0
for k in pairs(count1) do
n = n + 1
t[n] = k
end
sort(t, function(a, b) return count1[a] > count1[b] end)
for i=1,n do
local k = t[i]
local v = count1[k]
local pct = floor(v*100/samples + 0.5)
if pct < prof_min then break end
if not prof_raw then
out:write(format("%s%2d%% %s\n", indent, pct, k))
elseif prof_raw == "r" then
out:write(format("%s%5d %s\n", indent, v, k))
else
out:write(format("%s %d\n", k, v))
end
if count2 then
local r = count2[k]
if r then
prof_top(r, nil, v, (prof_split == 3 or prof_split == 1) and " -- " or
(prof_depth < 0 and " -> " or " <- "))
end
end
end
end
-- Annotate source code
local function prof_annotate(count1, samples)
local files = {}
local ms = 0
for k, v in pairs(count1) do
local pct = floor(v*100/samples + 0.5)
ms = math.max(ms, v)
if pct >= prof_min then
local file, line = k:match("^(.*):(%d+)$")
if not file then file = k; line = 0 end
local fl = files[file]
if not fl then fl = {}; files[file] = fl; files[#files+1] = file end
line = tonumber(line)
fl[line] = prof_raw and v or pct
end
end
sort(files)
local fmtv, fmtn = " %3d%% | %s\n", " | %s\n"
if prof_raw then
local n = math.max(5, math.ceil(math.log10(ms)))
fmtv = "%"..n.."d | %s\n"
fmtn = (" "):rep(n).." | %s\n"
end
local ann = prof_ann
for _, file in ipairs(files) do
local f0 = file:byte()
if f0 == 40 or f0 == 91 then
out:write(format("\n====== %s ======\n[Cannot annotate non-file]\n", file))
break
end
local fp, err = io.open(file)
if not fp then
out:write(format("====== ERROR: %s: %s\n", file, err))
break
end
out:write(format("\n====== %s ======\n", file))
local fl = files[file]
local n, show = 1, false
if ann ~= 0 then
for i=1,ann do
if fl[i] then show = true; out:write("@@ 1 @@\n"); break end
end
end
for line in fp:lines() do
if line:byte() == 27 then
out:write("[Cannot annotate bytecode file]\n")
break
end
local v = fl[n]
if ann ~= 0 then
local v2 = fl[n+ann]
if show then
if v2 then show = n+ann elseif v then show = n
elseif show+ann < n then show = false end
elseif v2 then
show = n+ann
out:write(format("@@ %d @@\n", n))
end
if not show then goto next end
end
if v then
out:write(format(fmtv, v, line))
else
out:write(format(fmtn, line))
end
::next::
n = n + 1
end
fp:close()
end
end
------------------------------------------------------------------------------
-- Finish profiling and dump result.
local function prof_finish()
if prof_ud then
profile.stop()
local samples = prof_samples
if samples == 0 then
if prof_raw ~= true then out:write("[No samples collected]\n") end
elseif prof_ann then
prof_annotate(prof_count1, samples)
else
prof_top(prof_count1, prof_count2, samples, "")
end
prof_count1 = nil
prof_count2 = nil
prof_ud = nil
if out ~= stdout then out:close() end
end
end
-- Start profiling.
local function prof_start(mode)
local interval = ""
mode = mode:gsub("i%d*", function(s) interval = s; return "" end)
prof_min = 3
mode = mode:gsub("m(%d+)", function(s) prof_min = tonumber(s); return "" end)
prof_depth = 1
mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end)
local m = {}
for c in mode:gmatch(".") do m[c] = c end
prof_states = m.z or m.v
if prof_states == "z" then zone = require("jit.zone") end
local scope = m.l or m.f or m.F or (prof_states and "" or "f")
local flags = (m.p or "")
prof_raw = m.r
if m.s then
prof_split = 2
if prof_depth == -1 or m["-"] then prof_depth = -2
elseif prof_depth == 1 then prof_depth = 2 end
elseif mode:find("[fF].*l") then
scope = "l"
prof_split = 3
else
prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0
end
prof_ann = m.A and 0 or (m.a and 3)
if prof_ann then
scope = "l"
prof_fmt = "pl"
prof_split = 0
prof_depth = 1
elseif m.G and scope ~= "" then
prof_fmt = flags..scope.."Z;"
prof_depth = -100
prof_raw = true
prof_min = 0
elseif scope == "" then
prof_fmt = false
else
local sc = prof_split == 3 and m.f or m.F or scope
prof_fmt = flags..sc..(prof_depth >= 0 and "Z < " or "Z > ")
end
prof_count1 = {}
prof_count2 = {}
prof_samples = 0
profile.start(scope:lower()..interval, prof_cb)
prof_ud = newproxy(true)
getmetatable(prof_ud).__gc = prof_finish
end
------------------------------------------------------------------------------
local function start(mode, outfile)
if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stdout
end
prof_start(mode or "f")
end
-- Public module functions.
return {
start = start, -- For -j command line option.
stop = prof_finish
}
+174
View File
@@ -0,0 +1,174 @@
----------------------------------------------------------------------------
-- Verbose mode of the LuaJIT compiler.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module shows verbose information about the progress of the
-- JIT compiler. It prints one line for each generated trace. This module
-- is useful to see which code has been compiled or where the compiler
-- punts and falls back to the interpreter.
--
-- Example usage:
--
-- luajit -jv -e "for i=1,1000 do for j=1,1000 do end end"
-- luajit -jv=myapp.out myapp.lua
--
-- Default output is to stderr. To redirect the output to a file, pass a
-- filename as an argument (use '-' for stdout) or set the environment
-- variable LUAJIT_VERBOSEFILE. The file is overwritten every time the
-- module is started.
--
-- The output from the first example should look like this:
--
-- [TRACE 1 (command line):1 loop]
-- [TRACE 2 (1/3) (command line):1 -> 1]
--
-- The first number in each line is the internal trace number. Next are
-- the file name ('(command line)') and the line number (':1') where the
-- trace has started. Side traces also show the parent trace number and
-- the exit number where they are attached to in parentheses ('(1/3)').
-- An arrow at the end shows where the trace links to ('-> 1'), unless
-- it loops to itself.
--
-- In this case the inner loop gets hot and is traced first, generating
-- a root trace. Then the last exit from the 1st trace gets hot, too,
-- and triggers generation of the 2nd trace. The side trace follows the
-- path along the outer loop and *around* the inner loop, back to its
-- start, and then links to the 1st trace. Yes, this may seem unusual,
-- if you know how traditional compilers work. Trace compilers are full
-- of surprises like this -- have fun! :-)
--
-- Aborted traces are shown like this:
--
-- [TRACE --- foo.lua:44 -- leaving loop in root trace at foo:lua:50]
--
-- Don't worry -- trace aborts are quite common, even in programs which
-- can be fully compiled. The compiler may retry several times until it
-- finds a suitable trace.
--
-- Of course this doesn't work with features that are not-yet-implemented
-- (NYI error messages). The VM simply falls back to the interpreter. This
-- may not matter at all if the particular trace is not very high up in
-- the CPU usage profile. Oh, and the interpreter is quite fast, too.
--
-- Also check out the -jdump module, which prints all the gory details.
--
------------------------------------------------------------------------------
-- Cache some library functions and objects.
local jit = require("jit")
local jutil = require("jit.util")
local vmdef = require("jit.vmdef")
local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
local type, sub, format = type, string.sub, string.format
local stdout, stderr = io.stdout, io.stderr
-- Active flag and output file handle.
local active, out
------------------------------------------------------------------------------
local startloc, startex
local function fmtfunc(func, pc)
local fi = funcinfo(func, pc)
if fi.loc then
return fi.loc
elseif fi.ffid then
return vmdef.ffnames[fi.ffid]
elseif fi.addr then
return format("C:%x", fi.addr)
else
return "(?)"
end
end
-- Format trace error message.
local function fmterr(err, info)
if type(err) == "number" then
if type(info) == "function" then info = fmtfunc(info) end
local fmt = vmdef.traceerr[err]
if fmt == "NYI: bytecode %s" then
local oidx = 6 * info
info = sub(vmdef.bcnames, oidx+1, oidx+6)
end
err = format(fmt, info)
end
return err
end
-- Dump trace states.
local function dump_trace(what, tr, func, pc, otr, oex)
if what == "start" then
startloc = fmtfunc(func, pc)
startex = otr and "("..otr.."/"..(oex == -1 and "stitch" or oex)..") " or ""
else
if what == "abort" then
local loc = fmtfunc(func, pc)
if loc ~= startloc then
out:write(format("[TRACE --- %s%s -- %s at %s]\n",
startex, startloc, fmterr(otr, oex), loc))
else
out:write(format("[TRACE --- %s%s -- %s]\n",
startex, startloc, fmterr(otr, oex)))
end
elseif what == "stop" then
local info = traceinfo(tr)
local link, ltype = info.link, info.linktype
if ltype == "interpreter" then
out:write(format("[TRACE %3s %s%s -- fallback to interpreter]\n",
tr, startex, startloc))
elseif ltype == "stitch" then
out:write(format("[TRACE %3s %s%s %s %s]\n",
tr, startex, startloc, ltype, fmtfunc(func, pc)))
elseif link == tr or link == 0 then
out:write(format("[TRACE %3s %s%s %s]\n",
tr, startex, startloc, ltype))
elseif ltype == "root" then
out:write(format("[TRACE %3s %s%s -> %d]\n",
tr, startex, startloc, link))
else
out:write(format("[TRACE %3s %s%s -> %d %s]\n",
tr, startex, startloc, link, ltype))
end
else
out:write(format("[TRACE %s]\n", what))
end
out:flush()
end
end
------------------------------------------------------------------------------
-- Detach dump handlers.
local function dumpoff()
if active then
active = false
jit.attach(dump_trace)
if out and out ~= stdout and out ~= stderr then out:close() end
out = nil
end
end
-- Open the output file and attach dump handlers.
local function dumpon(outfile)
if active then dumpoff() end
if not outfile then outfile = os.getenv("LUAJIT_VERBOSEFILE") end
if outfile then
out = outfile == "-" and stdout or assert(io.open(outfile, "w"))
else
out = stderr
end
jit.attach(dump_trace, "trace")
active = true
end
-- Public module functions.
return {
on = dumpon,
off = dumpoff,
start = dumpon -- For -j command line option.
}
+45
View File
@@ -0,0 +1,45 @@
----------------------------------------------------------------------------
-- LuaJIT profiler zones.
--
-- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
-- Released under the MIT license. See Copyright Notice in luajit.h
----------------------------------------------------------------------------
--
-- This module implements a simple hierarchical zone model.
--
-- Example usage:
--
-- local zone = require("jit.zone")
-- zone("AI")
-- ...
-- zone("A*")
-- ...
-- print(zone:get()) --> "A*"
-- ...
-- zone()
-- ...
-- print(zone:get()) --> "AI"
-- ...
-- zone()
--
----------------------------------------------------------------------------
local remove = table.remove
return setmetatable({
flush = function(t)
for i=#t,1,-1 do t[i] = nil end
end,
get = function(t)
return t[#t]
end
}, {
__call = function(t, zone)
if zone then
t[#t+1] = zone
else
return (assert(remove(t), "empty zone stack"))
end
end
})
+180
View File
@@ -0,0 +1,180 @@
/*
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#ifndef lauxlib_h
#define lauxlib_h
#include <stddef.h>
#include <stdio.h>
#include "lua.h"
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
#ifdef LUAJIT_INTONLY
#define luaL_checknumber luaL_checkinteger
#define luaL_optnumber luaL_optinteger
#else
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
#endif
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname, int szhint);
/* From Lua 5.2. */
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
LUALIB_API int luaL_execresult(lua_State *L, int stat);
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
const char *mode);
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
const char *name, const char *mode);
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
/* From Lua 5.2. */
#define luaL_newlibtable(L, l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int lvl; /* number of strings in the stack (level) */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;
#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))
/* compatibility only */
#define luaL_putchar(B,c) luaL_addchar(B,c)
#define luaL_addsize(B,n) ((B)->p += (n))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
/* compatibility with ref system */
/* pre-defined references */
#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))
#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
#define luaL_reg luaL_Reg
/* }====================================================== */
#endif
+401
View File
@@ -0,0 +1,401 @@
/*
** Auxiliary library for the Lua/C API.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major parts taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#define lib_aux_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_state.h"
#include "lj_trace.h"
#include "lj_lib.h"
#include "lj_vmevent.h"
#if LJ_TARGET_POSIX
#include <sys/wait.h>
#endif
/* -- I/O error handling -------------------------------------------------- */
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname)
{
if (stat) {
setboolV(L->top++, 1);
return 1;
} else {
int en = errno; /* Lua API calls may change this value. */
setnilV(L->top++);
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
setintV(L->top++, en);
lj_trace_abort(G(L));
return 3;
}
}
LUALIB_API int luaL_execresult(lua_State *L, int stat)
{
if (stat != -1) {
#if LJ_TARGET_POSIX
if (WIFSIGNALED(stat)) {
stat = WTERMSIG(stat);
setnilV(L->top++);
lua_pushliteral(L, "signal");
} else {
if (WIFEXITED(stat))
stat = WEXITSTATUS(stat);
if (stat == 0)
setboolV(L->top++, 1);
else
setnilV(L->top++);
lua_pushliteral(L, "exit");
}
#else
if (stat == 0)
setboolV(L->top++, 1);
else
setnilV(L->top++);
lua_pushliteral(L, "exit");
#endif
setintV(L->top++, stat);
return 3;
}
return luaL_fileresult(L, 0, NULL);
}
/* -- Module registration ------------------------------------------------- */
LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
const char *fname, int szhint)
{
const char *e;
lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, (size_t)(e - fname));
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, (size_t)(e - fname));
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
} else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
lua_remove(L, -2); /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}
static int libsize(const luaL_Reg *l)
{
int size = 0;
for (; l && l->name; l++) size++;
return size;
}
LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint)
{
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
lua_getfield(L, -1, modname);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL)
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */
}
lua_remove(L, -2); /* Remove _LOADED table. */
}
LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
const luaL_Reg *l, int nup)
{
lj_lib_checkfpu(L);
if (libname) {
luaL_pushmodule(L, libname, libsize(l));
lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */
}
if (l)
luaL_setfuncs(L, l, nup);
else
lua_pop(L, nup); /* Remove upvalues. */
}
LUALIB_API void luaL_register(lua_State *L, const char *libname,
const luaL_Reg *l)
{
luaL_openlib(L, libname, l, 0);
}
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
{
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name; l++) {
int i;
for (i = 0; i < nup; i++) /* Copy upvalues to the top. */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup + 2), l->name);
}
lua_pop(L, nup); /* Remove upvalues. */
}
LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
const char *p, const char *r)
{
const char *wild;
size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &b);
while ((wild = strstr(s, p)) != NULL) {
luaL_addlstring(&b, s, (size_t)(wild - s)); /* push prefix */
luaL_addstring(&b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
luaL_addstring(&b, s); /* push last suffix */
luaL_pushresult(&b);
return lua_tostring(L, -1);
}
/* -- Buffer handling ----------------------------------------------------- */
#define bufflen(B) ((size_t)((B)->p - (B)->buffer))
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
static int emptybuffer(luaL_Buffer *B)
{
size_t l = bufflen(B);
if (l == 0)
return 0; /* put nothing on stack */
lua_pushlstring(B->L, B->buffer, l);
B->p = B->buffer;
B->lvl++;
return 1;
}
static void adjuststack(luaL_Buffer *B)
{
if (B->lvl > 1) {
lua_State *L = B->L;
int toget = 1; /* number of levels to concat */
size_t toplen = lua_strlen(L, -1);
do {
size_t l = lua_strlen(L, -(toget+1));
if (!(B->lvl - toget + 1 >= LUA_MINSTACK/2 || toplen > l))
break;
toplen += l;
toget++;
} while (toget < B->lvl);
lua_concat(L, toget);
B->lvl = B->lvl - toget + 1;
}
}
LUALIB_API char *luaL_prepbuffer(luaL_Buffer *B)
{
if (emptybuffer(B))
adjuststack(B);
return B->buffer;
}
LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
{
if (l <= bufffree(B)) {
memcpy(B->p, s, l);
B->p += l;
} else {
emptybuffer(B);
lua_pushlstring(B->L, s, l);
B->lvl++;
adjuststack(B);
}
}
LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s)
{
luaL_addlstring(B, s, strlen(s));
}
LUALIB_API void luaL_pushresult(luaL_Buffer *B)
{
emptybuffer(B);
lua_concat(B->L, B->lvl);
B->lvl = 1;
}
LUALIB_API void luaL_addvalue(luaL_Buffer *B)
{
lua_State *L = B->L;
size_t vl;
const char *s = lua_tolstring(L, -1, &vl);
if (vl <= bufffree(B)) { /* fit into buffer? */
memcpy(B->p, s, vl); /* put it there */
B->p += vl;
lua_pop(L, 1); /* remove from stack */
} else {
if (emptybuffer(B))
lua_insert(L, -2); /* put buffer before new value */
B->lvl++; /* add new value into B stack */
adjuststack(B);
}
}
LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
{
B->L = L;
B->p = B->buffer;
B->lvl = 0;
}
/* -- Reference management ------------------------------------------------ */
#define FREELIST_REF 0
/* Convert a stack index to an absolute index. */
#define abs_index(L, i) \
((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
LUALIB_API int luaL_ref(lua_State *L, int t)
{
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
} else { /* no free elements */
ref = (int)lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
return ref;
}
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
{
if (ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}
/* -- Default allocator and panic function -------------------------------- */
static int panic(lua_State *L)
{
const char *s = lua_tostring(L, -1);
fputs("PANIC: unprotected error in call to Lua API (", stderr);
fputs(s ? s : "?", stderr);
fputc(')', stderr); fputc('\n', stderr);
fflush(stderr);
return 0;
}
#ifndef LUAJIT_DISABLE_VMEVENT
static int error_finalizer(lua_State *L)
{
const char *s = lua_tostring(L, -1);
fputs("ERROR in finalizer: ", stderr);
fputs(s ? s : "?", stderr);
fputc('\n', stderr);
fflush(stderr);
return 0;
}
#endif
#ifdef LUAJIT_USE_SYSMALLOC
#if LJ_64 && !LJ_GC64 && !defined(LUAJIT_USE_VALGRIND)
#error "Must use builtin allocator for 64 bit target"
#endif
static void *mem_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
(void)ud;
(void)osize;
if (nsize == 0) {
free(ptr);
return NULL;
} else {
return realloc(ptr, nsize);
}
}
LUALIB_API lua_State *luaL_newstate(void)
{
lua_State *L = lua_newstate(mem_alloc, NULL);
if (L) {
G(L)->panic = panic;
#ifndef LUAJIT_DISABLE_VMEVENT
luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
lua_pushcfunction(L, error_finalizer);
lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN));
G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN);
L->top--;
#endif
}
return L;
}
#else
LUALIB_API lua_State *luaL_newstate(void)
{
lua_State *L;
#if LJ_64 && !LJ_GC64
L = lj_state_newstate(LJ_ALLOCF_INTERNAL, NULL);
#else
L = lua_newstate(LJ_ALLOCF_INTERNAL, NULL);
#endif
if (L) {
G(L)->panic = panic;
#ifndef LUAJIT_DISABLE_VMEVENT
luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
lua_pushcfunction(L, error_finalizer);
lua_rawseti(L, -2, VMEVENT_HASH(LJ_VMEVENT_ERRFIN));
G(L)->vmevmask = VMEVENT_MASK(LJ_VMEVENT_ERRFIN);
L->top--;
#endif
}
return L;
}
#if LJ_64 && !LJ_GC64
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
{
UNUSED(f); UNUSED(ud);
fputs("Must use luaL_newstate() for 64 bit target\n", stderr);
return NULL;
}
#endif
#endif
+709
View File
@@ -0,0 +1,709 @@
/*
** Base and coroutine library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#include <stdio.h>
#define lib_base_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_debug.h"
#include "lj_buf.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_meta.h"
#include "lj_state.h"
#include "lj_frame.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#include "lj_cconv.h"
#endif
#include "lj_bc.h"
#include "lj_ff.h"
#include "lj_dispatch.h"
#include "lj_char.h"
#include "lj_strscan.h"
#include "lj_strfmt.h"
#include "lj_lib.h"
/* -- Base library: checks ------------------------------------------------ */
#define LJLIB_MODULE_base
LJLIB_ASM(assert) LJLIB_REC(.)
{
lj_lib_checkany(L, 1);
if (L->top == L->base+1)
lj_err_caller(L, LJ_ERR_ASSERT);
else if (tvisstr(L->base+1) || tvisnumber(L->base+1))
lj_err_callermsg(L, strdata(lj_lib_checkstr(L, 2)));
else
lj_err_run(L);
return FFH_UNREACHABLE;
}
/* ORDER LJ_T */
LJLIB_PUSH("nil")
LJLIB_PUSH("boolean")
LJLIB_PUSH(top-1) /* boolean */
LJLIB_PUSH("userdata")
LJLIB_PUSH("string")
LJLIB_PUSH("upval")
LJLIB_PUSH("thread")
LJLIB_PUSH("proto")
LJLIB_PUSH("function")
LJLIB_PUSH("trace")
LJLIB_PUSH("cdata")
LJLIB_PUSH("table")
LJLIB_PUSH(top-9) /* userdata */
LJLIB_PUSH("number")
LJLIB_ASM_(type) LJLIB_REC(.)
/* Recycle the lj_lib_checkany(L, 1) from assert. */
/* -- Base library: iterators --------------------------------------------- */
/* This solves a circular dependency problem -- change FF_next_N as needed. */
LJ_STATIC_ASSERT((int)FF_next == FF_next_N);
LJLIB_ASM(next) LJLIB_REC(.)
{
lj_lib_checktab(L, 1);
lj_err_msg(L, LJ_ERR_NEXTIDX);
return FFH_UNREACHABLE;
}
#if LJ_52 || LJ_HASFFI
static int ffh_pairs(lua_State *L, MMS mm)
{
TValue *o = lj_lib_checkany(L, 1);
cTValue *mo = lj_meta_lookup(L, o, mm);
if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) {
L->top = o+1; /* Only keep one argument. */
copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
return FFH_TAILCALL;
} else {
if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE);
if (LJ_FR2) { copyTV(L, o-1, o); o--; }
setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1)));
if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0);
return FFH_RES(3);
}
}
#else
#define ffh_pairs(L, mm) (lj_lib_checktab(L, 1), FFH_UNREACHABLE)
#endif
LJLIB_PUSH(lastcl)
LJLIB_ASM(pairs) LJLIB_REC(xpairs 0)
{
return ffh_pairs(L, MM_pairs);
}
LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.)
{
lj_lib_checktab(L, 1);
lj_lib_checkint(L, 2);
return FFH_UNREACHABLE;
}
LJLIB_PUSH(lastcl)
LJLIB_ASM(ipairs) LJLIB_REC(xpairs 1)
{
return ffh_pairs(L, MM_ipairs);
}
/* -- Base library: getters and setters ----------------------------------- */
LJLIB_ASM_(getmetatable) LJLIB_REC(.)
/* Recycle the lj_lib_checkany(L, 1) from assert. */
LJLIB_ASM(setmetatable) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
GCtab *mt = lj_lib_checktabornil(L, 2);
if (!tvisnil(lj_meta_lookup(L, L->base, MM_metatable)))
lj_err_caller(L, LJ_ERR_PROTMT);
setgcref(t->metatable, obj2gco(mt));
if (mt) { lj_gc_objbarriert(L, t, mt); }
settabV(L, L->base-1-LJ_FR2, t);
return FFH_RES(1);
}
LJLIB_CF(getfenv) LJLIB_REC(.)
{
GCfunc *fn;
cTValue *o = L->base;
if (!(o < L->top && tvisfunc(o))) {
int level = lj_lib_optint(L, 1, 1);
o = lj_debug_frame(L, level, &level);
if (o == NULL)
lj_err_arg(L, 1, LJ_ERR_INVLVL);
if (LJ_FR2) o--;
}
fn = &gcval(o)->fn;
settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env));
return 1;
}
LJLIB_CF(setfenv)
{
GCfunc *fn;
GCtab *t = lj_lib_checktab(L, 2);
cTValue *o = L->base;
if (!(o < L->top && tvisfunc(o))) {
int level = lj_lib_checkint(L, 1);
if (level == 0) {
/* NOBARRIER: A thread (i.e. L) is never black. */
setgcref(L->env, obj2gco(t));
return 0;
}
o = lj_debug_frame(L, level, &level);
if (o == NULL)
lj_err_arg(L, 1, LJ_ERR_INVLVL);
if (LJ_FR2) o--;
}
fn = &gcval(o)->fn;
if (!isluafunc(fn))
lj_err_caller(L, LJ_ERR_SETFENV);
setgcref(fn->l.env, obj2gco(t));
lj_gc_objbarrier(L, obj2gco(fn), t);
setfuncV(L, L->top++, fn);
return 1;
}
LJLIB_ASM(rawget) LJLIB_REC(.)
{
lj_lib_checktab(L, 1);
lj_lib_checkany(L, 2);
return FFH_UNREACHABLE;
}
LJLIB_CF(rawset) LJLIB_REC(.)
{
lj_lib_checktab(L, 1);
lj_lib_checkany(L, 2);
L->top = 1+lj_lib_checkany(L, 3);
lua_rawset(L, 1);
return 1;
}
LJLIB_CF(rawequal) LJLIB_REC(.)
{
cTValue *o1 = lj_lib_checkany(L, 1);
cTValue *o2 = lj_lib_checkany(L, 2);
setboolV(L->top-1, lj_obj_equal(o1, o2));
return 1;
}
#if LJ_52
LJLIB_CF(rawlen) LJLIB_REC(.)
{
cTValue *o = L->base;
int32_t len;
if (L->top > o && tvisstr(o))
len = (int32_t)strV(o)->len;
else
len = (int32_t)lj_tab_len(lj_lib_checktab(L, 1));
setintV(L->top-1, len);
return 1;
}
#endif
LJLIB_CF(unpack)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n, i = lj_lib_optint(L, 2, 1);
int32_t e = (L->base+3-1 < L->top && !tvisnil(L->base+3-1)) ?
lj_lib_checkint(L, 3) : (int32_t)lj_tab_len(t);
uint32_t nu;
if (i > e) return 0;
nu = (uint32_t)e - (uint32_t)i;
n = (int32_t)(nu+1);
if (nu >= LUAI_MAXCSTACK || !lua_checkstack(L, n))
lj_err_caller(L, LJ_ERR_UNPACK);
do {
cTValue *tv = lj_tab_getint(t, i);
if (tv) {
copyTV(L, L->top++, tv);
} else {
setnilV(L->top++);
}
} while (i++ < e);
return n;
}
LJLIB_CF(select) LJLIB_REC(.)
{
int32_t n = (int32_t)(L->top - L->base);
if (n >= 1 && tvisstr(L->base) && *strVdata(L->base) == '#') {
setintV(L->top-1, n-1);
return 1;
} else {
int32_t i = lj_lib_checkint(L, 1);
if (i < 0) i = n + i; else if (i > n) i = n;
if (i < 1)
lj_err_arg(L, 1, LJ_ERR_IDXRNG);
return n - i;
}
}
/* -- Base library: conversions ------------------------------------------- */
LJLIB_ASM(tonumber) LJLIB_REC(.)
{
int32_t base = lj_lib_optint(L, 2, 10);
if (base == 10) {
TValue *o = lj_lib_checkany(L, 1);
if (lj_strscan_numberobj(o)) {
copyTV(L, L->base-1-LJ_FR2, o);
return FFH_RES(1);
}
#if LJ_HASFFI
if (tviscdata(o)) {
CTState *cts = ctype_cts(L);
CType *ct = lj_ctype_rawref(cts, cdataV(o)->ctypeid);
if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
if (ctype_isnum(ct->info) || ctype_iscomplex(ct->info)) {
if (LJ_DUALNUM && ctype_isinteger_or_bool(ct->info) &&
ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) {
int32_t i;
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0);
setintV(L->base-1-LJ_FR2, i);
return FFH_RES(1);
}
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE),
(uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0);
return FFH_RES(1);
}
}
#endif
} else {
const char *p = strdata(lj_lib_checkstr(L, 1));
char *ep;
unsigned int neg = 0;
unsigned long ul;
if (base < 2 || base > 36)
lj_err_arg(L, 2, LJ_ERR_BASERNG);
while (lj_char_isspace((unsigned char)(*p))) p++;
if (*p == '-') { p++; neg = 1; } else if (*p == '+') { p++; }
if (lj_char_isalnum((unsigned char)(*p))) {
ul = strtoul(p, &ep, base);
if (p != ep) {
while (lj_char_isspace((unsigned char)(*ep))) ep++;
if (*ep == '\0') {
if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) {
if (neg) ul = ~ul+1u;
setintV(L->base-1-LJ_FR2, (int32_t)ul);
} else {
lua_Number n = (lua_Number)ul;
if (neg) n = -n;
setnumV(L->base-1-LJ_FR2, n);
}
return FFH_RES(1);
}
}
}
}
setnilV(L->base-1-LJ_FR2);
return FFH_RES(1);
}
LJLIB_ASM(tostring) LJLIB_REC(.)
{
TValue *o = lj_lib_checkany(L, 1);
cTValue *mo;
L->top = o+1; /* Only keep one argument. */
if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */
return FFH_TAILCALL;
}
lj_gc_check(L);
setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base));
return FFH_RES(1);
}
/* -- Base library: throw and catch errors -------------------------------- */
LJLIB_CF(error)
{
int32_t level = lj_lib_optint(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) {
luaL_where(L, level);
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
return lua_error(L);
}
LJLIB_ASM(pcall) LJLIB_REC(.)
{
lj_lib_checkany(L, 1);
lj_lib_checkfunc(L, 2); /* For xpcall only. */
return FFH_UNREACHABLE;
}
LJLIB_ASM_(xpcall) LJLIB_REC(.)
/* -- Base library: load Lua code ----------------------------------------- */
#if !LJ_SRB2LIB
static int load_aux(lua_State *L, int status, int envarg)
{
if (status == LUA_OK) {
/*
** Set environment table for top-level function.
** Don't do this for non-native bytecode, which returns a prototype.
*/
if (tvistab(L->base+envarg-1) && tvisfunc(L->top-1)) {
GCfunc *fn = funcV(L->top-1);
GCtab *t = tabV(L->base+envarg-1);
setgcref(fn->c.env, obj2gco(t));
lj_gc_objbarrier(L, fn, t);
}
return 1;
} else {
setnilV(L->top-2);
return 2;
}
}
LJLIB_CF(loadfile)
{
GCstr *fname = lj_lib_optstr(L, 1);
GCstr *mode = lj_lib_optstr(L, 2);
int status;
lua_settop(L, 3); /* Ensure env arg exists. */
status = luaL_loadfilex(L, fname ? strdata(fname) : NULL,
mode ? strdata(mode) : NULL);
return load_aux(L, status, 3);
}
static const char *reader_func(lua_State *L, void *ud, size_t *size)
{
UNUSED(ud);
luaL_checkstack(L, 2, "too many nested functions");
copyTV(L, L->top++, L->base);
lua_call(L, 0, 1); /* Call user-supplied function. */
L->top--;
if (tvisnil(L->top)) {
*size = 0;
return NULL;
} else if (tvisstr(L->top) || tvisnumber(L->top)) {
copyTV(L, L->base+4, L->top); /* Anchor string in reserved stack slot. */
return lua_tolstring(L, 5, size);
} else {
lj_err_caller(L, LJ_ERR_RDRSTR);
return NULL;
}
}
LJLIB_CF(load)
{
GCstr *name = lj_lib_optstr(L, 2);
GCstr *mode = lj_lib_optstr(L, 3);
int status;
if (L->base < L->top &&
(tvisstr(L->base) || tvisnumber(L->base) || tvisbuf(L->base))) {
const char *s;
MSize len;
if (tvisbuf(L->base)) {
SBufExt *sbx = bufV(L->base);
s = sbx->r;
len = sbufxlen(sbx);
if (!name) name = &G(L)->strempty; /* Buffers are not NUL-terminated. */
} else {
GCstr *str = lj_lib_checkstr(L, 1);
s = strdata(str);
len = str->len;
}
lua_settop(L, 4); /* Ensure env arg exists. */
status = luaL_loadbufferx(L, s, len, name ? strdata(name) : s,
mode ? strdata(mode) : NULL);
} else {
lj_lib_checkfunc(L, 1);
lua_settop(L, 5); /* Reserve a slot for the string from the reader. */
status = lua_loadx(L, reader_func, NULL, name ? strdata(name) : "=(load)",
mode ? strdata(mode) : NULL);
}
return load_aux(L, status, 4);
}
LJLIB_CF(loadstring)
{
return lj_cf_load(L);
}
LJLIB_CF(dofile)
{
GCstr *fname = lj_lib_optstr(L, 1);
setnilV(L->top);
L->top = L->base+1;
if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != LUA_OK)
lua_error(L);
lua_call(L, 0, LUA_MULTRET);
return (int)(L->top - L->base) - 1;
}
#endif
/* -- Base library: GC control -------------------------------------------- */
LJLIB_CF(gcinfo)
{
setintV(L->top++, (int32_t)(G(L)->gc.total >> 10));
return 1;
}
LJLIB_CF(collectgarbage)
{
int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */
"\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning");
int32_t data = lj_lib_optint(L, 2, 0);
if (opt == LUA_GCCOUNT) {
#if LJ_INTONLY
setintV(L->top, G(L)->gc.total/1024);
#else
setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0);
#endif
} else {
int res = lua_gc(L, opt, data);
if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING)
setboolV(L->top, res);
else
setintV(L->top, res);
}
L->top++;
return 1;
}
/* -- Base library: miscellaneous functions ------------------------------- */
LJLIB_PUSH(top-2) /* Upvalue holds weak table. */
LJLIB_CF(newproxy)
{
lua_settop(L, 1);
lua_newuserdata(L, 0);
if (lua_toboolean(L, 1) == 0) { /* newproxy(): without metatable. */
return 1;
} else if (lua_isboolean(L, 1)) { /* newproxy(true): with metatable. */
lua_newtable(L);
lua_pushvalue(L, -1);
lua_pushboolean(L, 1);
lua_rawset(L, lua_upvalueindex(1)); /* Remember mt in weak table. */
} else { /* newproxy(proxy): inherit metatable. */
int validproxy = 0;
if (lua_getmetatable(L, 1)) {
lua_rawget(L, lua_upvalueindex(1));
validproxy = lua_toboolean(L, -1);
lua_pop(L, 1);
}
if (!validproxy)
lj_err_arg(L, 1, LJ_ERR_NOPROXY);
lua_getmetatable(L, 1);
}
lua_setmetatable(L, 2);
return 1;
}
LJLIB_PUSH("tostring")
LJLIB_CF(print)
{
ptrdiff_t i, nargs = L->top - L->base;
cTValue *tv = lj_tab_getstr(tabref(L->env), strV(lj_lib_upvalue(L, 1)));
int shortcut;
if (tv && !tvisnil(tv)) {
copyTV(L, L->top++, tv);
} else {
setstrV(L, L->top++, strV(lj_lib_upvalue(L, 1)));
lua_gettable(L, LUA_GLOBALSINDEX);
tv = L->top-1;
}
shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring) &&
!gcrefu(basemt_it(G(L), LJ_TNUMX));
for (i = 0; i < nargs; i++) {
cTValue *o = &L->base[i];
const char *str;
size_t size;
MSize len;
if (shortcut && (str = lj_strfmt_wstrnum(L, o, &len)) != NULL) {
size = len;
} else {
copyTV(L, L->top+1, o);
copyTV(L, L->top, L->top-1);
L->top += 2;
lua_call(L, 1, 1);
str = lua_tolstring(L, -1, &size);
if (!str)
lj_err_caller(L, LJ_ERR_PRTOSTR);
L->top--;
}
if (i)
putchar('\t');
fwrite(str, 1, size, stdout);
}
putchar('\n');
return 0;
}
LJLIB_PUSH(top-3)
LJLIB_SET(_VERSION)
#include "lj_libdef.h"
/* -- Coroutine library --------------------------------------------------- */
#define LJLIB_MODULE_coroutine
LJLIB_CF(coroutine_status)
{
const char *s;
lua_State *co;
if (!(L->top > L->base && tvisthread(L->base)))
lj_err_arg(L, 1, LJ_ERR_NOCORO);
co = threadV(L->base);
if (co == L) s = "running";
else if (co->status == LUA_YIELD) s = "suspended";
else if (co->status != LUA_OK) s = "dead";
else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal";
else if (co->top == co->base) s = "dead";
else s = "suspended";
lua_pushstring(L, s);
return 1;
}
LJLIB_CF(coroutine_running)
{
#if LJ_52
int ismain = lua_pushthread(L);
setboolV(L->top++, ismain);
return 2;
#else
if (lua_pushthread(L))
setnilV(L->top++);
return 1;
#endif
}
LJLIB_CF(coroutine_isyieldable)
{
setboolV(L->top++, cframe_canyield(L->cframe));
return 1;
}
LJLIB_CF(coroutine_create)
{
lua_State *L1;
if (!(L->base < L->top && tvisfunc(L->base)))
lj_err_argt(L, 1, LUA_TFUNCTION);
L1 = lua_newthread(L);
setfuncV(L, L1->top++, funcV(L->base));
return 1;
}
LJLIB_ASM(coroutine_yield)
{
lj_err_caller(L, LJ_ERR_CYIELD);
return FFH_UNREACHABLE;
}
static int ffh_resume(lua_State *L, lua_State *co, int wrap)
{
if (co->cframe != NULL || co->status > LUA_YIELD ||
(co->status == LUA_OK && co->top == co->base)) {
ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD;
if (wrap) lj_err_caller(L, em);
setboolV(L->base-1-LJ_FR2, 0);
setstrV(L, L->base-LJ_FR2, lj_err_str(L, em));
return FFH_RES(2);
}
if (lj_state_cpgrowstack(co, (MSize)(L->top - L->base)) != LUA_OK) {
cTValue *msg = --co->top;
lj_err_callermsg(L, strVdata(msg));
}
return FFH_RETRY;
}
LJLIB_ASM(coroutine_resume)
{
if (!(L->top > L->base && tvisthread(L->base)))
lj_err_arg(L, 1, LJ_ERR_NOCORO);
return ffh_resume(L, threadV(L->base), 0);
}
LJLIB_NOREG LJLIB_ASM(coroutine_wrap_aux)
{
return ffh_resume(L, threadV(lj_lib_upvalue(L, 1)), 1);
}
/* Inline declarations. */
LJ_ASMF void lj_ff_coroutine_wrap_aux(void);
#if !(LJ_TARGET_MIPS && defined(ljamalg_c))
LJ_FUNCA_NORET void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L,
lua_State *co);
#endif
/* Error handler, called from assembler VM. */
void LJ_FASTCALL lj_ffh_coroutine_wrap_err(lua_State *L, lua_State *co)
{
co->top--; copyTV(L, L->top, co->top); L->top++;
if (tvisstr(L->top-1))
lj_err_callermsg(L, strVdata(L->top-1));
else
lj_err_run(L);
}
/* Forward declaration. */
static void setpc_wrap_aux(lua_State *L, GCfunc *fn);
LJLIB_CF(coroutine_wrap)
{
GCfunc *fn;
lj_cf_coroutine_create(L);
fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1);
setpc_wrap_aux(L, fn);
return 1;
}
#include "lj_libdef.h"
/* Fix the PC of wrap_aux. Really ugly workaround. */
static void setpc_wrap_aux(lua_State *L, GCfunc *fn)
{
setmref(fn->c.pc, &L2GG(L)->bcff[lj_lib_init_coroutine[1]+2]);
}
/* ------------------------------------------------------------------------ */
static void newproxy_weaktable(lua_State *L)
{
/* NOBARRIER: The table is new (marked white). */
GCtab *t = lj_tab_new(L, 0, 1);
settabV(L, L->top++, t);
setgcref(t->metatable, obj2gco(t));
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "__mode")),
lj_str_newlit(L, "kv"));
t->nomm = (uint8_t)(~(1u<<MM_mode));
}
LUALIB_API int luaopen_base(lua_State *L)
{
/* NOBARRIER: Table and value are the same. */
GCtab *env = tabref(L->env);
settabV(L, lj_tab_setstr(L, env, lj_str_newlit(L, "_G")), env);
lua_pushliteral(L, LUA_VERSION); /* top-3. */
newproxy_weaktable(L); /* top-2. */
LJ_LIB_REG(L, "_G", base);
LJ_LIB_REG(L, LUA_COLIBNAME, coroutine);
return 2;
}
+181
View File
@@ -0,0 +1,181 @@
/*
** Bit manipulation library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#define lib_bit_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_strscan.h"
#include "lj_strfmt.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#include "lj_cdata.h"
#include "lj_cconv.h"
#include "lj_carith.h"
#endif
#include "lj_ff.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_bit
#if LJ_HASFFI
static int bit_result64(lua_State *L, CTypeID id, uint64_t x)
{
GCcdata *cd = lj_cdata_new_(L, id, 8);
*(uint64_t *)cdataptr(cd) = x;
setcdataV(L, L->base-1-LJ_FR2, cd);
return FFH_RES(1);
}
#else
static int32_t bit_checkbit(lua_State *L, int narg)
{
TValue *o = L->base + narg-1;
if (!(o < L->top && lj_strscan_numberobj(o)))
lj_err_argt(L, narg, LUA_TNUMBER);
if (LJ_LIKELY(tvisint(o))) {
return intV(o);
} else {
int32_t i = lj_num2bit(numV(o));
if (LJ_DUALNUM) setintV(o, i);
return i;
}
}
#endif
LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit)
{
#if LJ_HASFFI
CTypeID id = 0;
setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id));
return FFH_RES(1);
#else
lj_lib_checknumber(L, 1);
return FFH_RETRY;
#endif
}
LJLIB_ASM(bit_bnot) LJLIB_REC(bit_unary IR_BNOT)
{
#if LJ_HASFFI
CTypeID id = 0;
uint64_t x = lj_carith_check64(L, 1, &id);
return id ? bit_result64(L, id, ~x) : FFH_RETRY;
#else
lj_lib_checknumber(L, 1);
return FFH_RETRY;
#endif
}
LJLIB_ASM(bit_bswap) LJLIB_REC(bit_unary IR_BSWAP)
{
#if LJ_HASFFI
CTypeID id = 0;
uint64_t x = lj_carith_check64(L, 1, &id);
return id ? bit_result64(L, id, lj_bswap64(x)) : FFH_RETRY;
#else
lj_lib_checknumber(L, 1);
return FFH_RETRY;
#endif
}
LJLIB_ASM(bit_lshift) LJLIB_REC(bit_shift IR_BSHL)
{
#if LJ_HASFFI
CTypeID id = 0, id2 = 0;
uint64_t x = lj_carith_check64(L, 1, &id);
int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
if (id) {
x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
return bit_result64(L, id, x);
}
setintV(L->base+1, sh);
return FFH_RETRY;
#else
lj_lib_checknumber(L, 1);
bit_checkbit(L, 2);
return FFH_RETRY;
#endif
}
LJLIB_ASM_(bit_rshift) LJLIB_REC(bit_shift IR_BSHR)
LJLIB_ASM_(bit_arshift) LJLIB_REC(bit_shift IR_BSAR)
LJLIB_ASM_(bit_rol) LJLIB_REC(bit_shift IR_BROL)
LJLIB_ASM_(bit_ror) LJLIB_REC(bit_shift IR_BROR)
LJLIB_ASM(bit_band) LJLIB_REC(bit_nary IR_BAND)
{
#if LJ_HASFFI
CTypeID id = 0;
TValue *o = L->base, *top = L->top;
int i = 0;
do { lj_carith_check64(L, ++i, &id); } while (++o < top);
if (id) {
CTState *cts = ctype_cts(L);
CType *ct = ctype_get(cts, id);
int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
o = L->base;
do {
lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
} while (++o < top);
return bit_result64(L, id, y);
}
return FFH_RETRY;
#else
int i = 0;
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
return FFH_RETRY;
#endif
}
LJLIB_ASM_(bit_bor) LJLIB_REC(bit_nary IR_BOR)
LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR)
/* ------------------------------------------------------------------------ */
LJLIB_CF(bit_tohex) LJLIB_REC(.)
{
#if LJ_HASFFI
CTypeID id = 0, id2 = 0;
uint64_t b = lj_carith_check64(L, 1, &id);
int32_t n = L->base+1>=L->top ? (id ? 16 : 8) :
(int32_t)lj_carith_check64(L, 2, &id2);
#else
uint32_t b = (uint32_t)bit_checkbit(L, 1);
int32_t n = L->base+1>=L->top ? 8 : bit_checkbit(L, 2);
#endif
SBuf *sb = lj_buf_tmp_(L);
SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
if (n < 0) { n = (int32_t)(~(uint32_t)n+1u); sf |= STRFMT_F_UPPER; }
if ((uint32_t)n > 254) n = 254;
sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
#if LJ_HASFFI
if (n < 16) b &= ((uint64_t)1 << 4*n)-1;
#else
if (n < 8) b &= (1u << 4*n)-1;
#endif
sb = lj_strfmt_putfxint(sb, sf, b);
setstrV(L, L->top-1, lj_buf_str(L, sb));
lj_gc_check(L);
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_bit(lua_State *L)
{
LJ_LIB_REG(L, LUA_BITLIBNAME, bit);
return 1;
}
+360
View File
@@ -0,0 +1,360 @@
/*
** Buffer library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#define lib_buffer_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#if LJ_HASBUFFER
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_udata.h"
#include "lj_meta.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#include "lj_cdata.h"
#include "lj_cconv.h"
#endif
#include "lj_strfmt.h"
#include "lj_serialize.h"
#include "lj_lib.h"
/* -- Helper functions ---------------------------------------------------- */
/* Check that the first argument is a string buffer. */
static SBufExt *buffer_tobuf(lua_State *L)
{
if (!(L->base < L->top && tvisbuf(L->base)))
lj_err_argtype(L, 1, "buffer");
return bufV(L->base);
}
/* Ditto, but for writers. */
static LJ_AINLINE SBufExt *buffer_tobufw(lua_State *L)
{
SBufExt *sbx = buffer_tobuf(L);
setsbufXL_(sbx, L);
return sbx;
}
#define buffer_toudata(sbx) ((GCudata *)(sbx)-1)
/* -- Buffer methods ------------------------------------------------------ */
#define LJLIB_MODULE_buffer_method
LJLIB_CF(buffer_method_free)
{
SBufExt *sbx = buffer_tobuf(L);
lj_bufx_free(L, sbx);
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_reset) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
lj_bufx_reset(sbx);
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_skip) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
MSize n = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
MSize len = sbufxlen(sbx);
if (n < len) {
sbx->r += n;
} else if (sbufiscow(sbx)) {
sbx->r = sbx->w;
} else {
sbx->r = sbx->w = sbx->b;
}
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_set) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
GCobj *ref;
const char *p;
MSize len;
#if LJ_HASFFI
if (tviscdata(L->base+1)) {
CTState *cts = ctype_cts(L);
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p,
L->base+1, CCF_ARG(2));
len = (MSize)lj_lib_checkintrange(L, 3, 0, LJ_MAX_BUF);
} else
#endif
{
GCstr *str = lj_lib_checkstrx(L, 2);
p = strdata(str);
len = str->len;
}
lj_bufx_free(L, sbx);
lj_bufx_set_cow(L, sbx, p, len);
ref = gcV(L->base+1);
setgcref(sbx->cowref, ref);
lj_gc_objbarrier(L, buffer_toudata(sbx), ref);
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_put) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
ptrdiff_t arg, narg = L->top - L->base;
for (arg = 1; arg < narg; arg++) {
cTValue *o = &L->base[arg], *mo = NULL;
retry:
if (tvisstr(o)) {
lj_buf_putstr((SBuf *)sbx, strV(o));
} else if (tvisint(o)) {
lj_strfmt_putint((SBuf *)sbx, intV(o));
} else if (tvisnum(o)) {
lj_strfmt_putfnum((SBuf *)sbx, STRFMT_G14, numV(o));
} else if (tvisbuf(o)) {
SBufExt *sbx2 = bufV(o);
if (sbx2 == sbx) lj_err_arg(L, (int)(arg+1), LJ_ERR_BUFFER_SELF);
lj_buf_putmem((SBuf *)sbx, sbx2->r, sbufxlen(sbx2));
} else if (!mo && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) {
/* Call __tostring metamethod inline. */
copyTV(L, L->top++, mo);
copyTV(L, L->top++, o);
lua_call(L, 1, 1);
o = &L->base[arg]; /* The stack may have been reallocated. */
copyTV(L, &L->base[arg], L->top-1);
L->top = L->base + narg;
goto retry; /* Retry with the result. */
} else {
lj_err_argtype(L, (int)(arg+1), "string/number/__tostring");
}
/* Probably not useful to inline other __tostring MMs, e.g. FFI numbers. */
}
L->top = L->base+1; /* Chain buffer object. */
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_method_putf) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
lj_strfmt_putarg(L, (SBuf *)sbx, 2, 2);
L->top = L->base+1; /* Chain buffer object. */
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_method_get) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
ptrdiff_t arg, narg = L->top - L->base;
if (narg == 1) {
narg++;
setnilV(L->top++); /* get() is the same as get(nil). */
}
for (arg = 1; arg < narg; arg++) {
TValue *o = &L->base[arg];
MSize n = tvisnil(o) ? LJ_MAX_BUF :
(MSize) lj_lib_checkintrange(L, (int)(arg+1), 0, LJ_MAX_BUF);
MSize len = sbufxlen(sbx);
if (n > len) n = len;
setstrV(L, o, lj_str_new(L, sbx->r, n));
sbx->r += n;
}
if (sbx->r == sbx->w && !sbufiscow(sbx)) sbx->r = sbx->w = sbx->b;
lj_gc_check(L);
return (int)(narg-1);
}
#if LJ_HASFFI
LJLIB_CF(buffer_method_putcdata) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
const char *p;
MSize len;
if (tviscdata(L->base+1)) {
CTState *cts = ctype_cts(L);
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p,
L->base+1, CCF_ARG(2));
} else {
lj_err_argtype(L, 2, "cdata");
}
len = (MSize)lj_lib_checkintrange(L, 3, 0, LJ_MAX_BUF);
lj_buf_putmem((SBuf *)sbx, p, len);
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_reserve) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
MSize sz = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
GCcdata *cd;
lj_buf_more((SBuf *)sbx, sz);
ctype_loadffi(L);
cd = lj_cdata_new_(L, CTID_P_UINT8, CTSIZE_PTR);
*(void **)cdataptr(cd) = sbx->w;
setcdataV(L, L->top++, cd);
setintV(L->top++, sbufleft(sbx));
return 2;
}
LJLIB_CF(buffer_method_commit) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
MSize len = (MSize)lj_lib_checkintrange(L, 2, 0, LJ_MAX_BUF);
if (len > sbufleft(sbx)) lj_err_arg(L, 2, LJ_ERR_NUMRNG);
sbx->w += len;
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_ref) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
GCcdata *cd;
ctype_loadffi(L);
cd = lj_cdata_new_(L, CTID_P_UINT8, CTSIZE_PTR);
*(void **)cdataptr(cd) = sbx->r;
setcdataV(L, L->top++, cd);
setintV(L->top++, sbufxlen(sbx));
return 2;
}
#endif
LJLIB_CF(buffer_method_encode) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
cTValue *o = lj_lib_checkany(L, 2);
lj_serialize_put(sbx, o);
lj_gc_check(L);
L->top = L->base+1; /* Chain buffer object. */
return 1;
}
LJLIB_CF(buffer_method_decode) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobufw(L);
setnilV(L->top++);
sbx->r = lj_serialize_get(sbx, L->top-1);
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_method___gc)
{
SBufExt *sbx = buffer_tobuf(L);
lj_bufx_free(L, sbx);
return 0;
}
LJLIB_CF(buffer_method___tostring) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
setstrV(L, L->top-1, lj_str_new(L, sbx->r, sbufxlen(sbx)));
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_method___len) LJLIB_REC(.)
{
SBufExt *sbx = buffer_tobuf(L);
setintV(L->top-1, (int32_t)sbufxlen(sbx));
return 1;
}
LJLIB_PUSH("buffer") LJLIB_SET(__metatable)
LJLIB_PUSH(top-1) LJLIB_SET(__index)
/* -- Buffer library functions -------------------------------------------- */
#define LJLIB_MODULE_buffer
LJLIB_PUSH(top-2) LJLIB_SET(!) /* Set environment. */
LJLIB_CF(buffer_new)
{
MSize sz = 0;
int targ = 1;
GCtab *env, *dict_str = NULL, *dict_mt = NULL;
GCudata *ud;
SBufExt *sbx;
if (L->base < L->top && !tvistab(L->base)) {
targ = 2;
if (!tvisnil(L->base))
sz = (MSize)lj_lib_checkintrange(L, 1, 0, LJ_MAX_BUF);
}
if (L->base+targ-1 < L->top) {
GCtab *options = lj_lib_checktab(L, targ);
cTValue *opt_dict, *opt_mt;
opt_dict = lj_tab_getstr(options, lj_str_newlit(L, "dict"));
if (opt_dict && tvistab(opt_dict)) {
dict_str = tabV(opt_dict);
lj_serialize_dict_prep_str(L, dict_str);
}
opt_mt = lj_tab_getstr(options, lj_str_newlit(L, "metatable"));
if (opt_mt && tvistab(opt_mt)) {
dict_mt = tabV(opt_mt);
lj_serialize_dict_prep_mt(L, dict_mt);
}
}
env = tabref(curr_func(L)->c.env);
ud = lj_udata_new(L, sizeof(SBufExt), env);
ud->udtype = UDTYPE_BUFFER;
/* NOBARRIER: The GCudata is new (marked white). */
setgcref(ud->metatable, obj2gco(env));
setudataV(L, L->top++, ud);
sbx = (SBufExt *)uddata(ud);
lj_bufx_init(L, sbx);
setgcref(sbx->dict_str, obj2gco(dict_str));
setgcref(sbx->dict_mt, obj2gco(dict_mt));
if (sz > 0) lj_buf_need2((SBuf *)sbx, sz);
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_encode) LJLIB_REC(.)
{
cTValue *o = lj_lib_checkany(L, 1);
setstrV(L, L->top++, lj_serialize_encode(L, o));
lj_gc_check(L);
return 1;
}
LJLIB_CF(buffer_decode) LJLIB_REC(.)
{
GCstr *str = lj_lib_checkstrx(L, 1);
setnilV(L->top++);
lj_serialize_decode(L, L->top-1, str);
lj_gc_check(L);
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
int luaopen_string_buffer(lua_State *L)
{
LJ_LIB_REG(L, NULL, buffer_method);
lua_getfield(L, -1, "__tostring");
lua_setfield(L, -2, "tostring");
LJ_LIB_REG(L, NULL, buffer);
return 1;
}
#endif
+414
View File
@@ -0,0 +1,414 @@
/*
** Debug library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_debug_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_debug.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_debug
#if !LJ_SRB2LIB
LJLIB_CF(debug_getregistry)
{
copyTV(L, L->top++, registry(L));
return 1;
}
LJLIB_CF(debug_getmetatable) LJLIB_REC(.)
{
lj_lib_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
setnilV(L->top-1);
}
return 1;
}
LJLIB_CF(debug_setmetatable)
{
lj_lib_checktabornil(L, 2);
L->top = L->base+2;
lua_setmetatable(L, 1);
#if !LJ_52
setboolV(L->top-1, 1);
#endif
return 1;
}
LJLIB_CF(debug_getfenv)
{
lj_lib_checkany(L, 1);
lua_getfenv(L, 1);
return 1;
}
LJLIB_CF(debug_setfenv)
{
lj_lib_checktab(L, 2);
L->top = L->base+2;
if (!lua_setfenv(L, 1))
lj_err_caller(L, LJ_ERR_SETFENV);
return 1;
}
#endif
/* ------------------------------------------------------------------------ */
static void settabss(lua_State *L, const char *i, const char *v)
{
lua_pushstring(L, v);
lua_setfield(L, -2, i);
}
static void settabsi(lua_State *L, const char *i, int v)
{
lua_pushinteger(L, v);
lua_setfield(L, -2, i);
}
static void settabsb(lua_State *L, const char *i, int v)
{
lua_pushboolean(L, v);
lua_setfield(L, -2, i);
}
static lua_State *getthread(lua_State *L, int *arg)
{
if (L->base < L->top && tvisthread(L->base)) {
*arg = 1;
return threadV(L->base);
} else {
*arg = 0;
return L;
}
}
static void treatstackoption(lua_State *L, lua_State *L1, const char *fname)
{
if (L == L1) {
lua_pushvalue(L, -2);
lua_remove(L, -3);
}
else
lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname);
}
LJLIB_CF(debug_getinfo)
{
lj_Debug ar;
int arg, opt_f = 0, opt_L = 0;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnSu");
if (lua_isnumber(L, arg+1)) {
if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), (lua_Debug *)&ar)) {
setnilV(L->top-1);
return 1;
}
} else if (L->base+arg < L->top && tvisfunc(L->base+arg)) {
options = lua_pushfstring(L, ">%s", options);
setfuncV(L1, L1->top++, funcV(L->base+arg));
} else {
lj_err_arg(L, arg+1, LJ_ERR_NOFUNCL);
}
if (!lj_debug_getinfo(L1, options, &ar, 1))
lj_err_arg(L, arg+2, LJ_ERR_INVOPT);
lua_createtable(L, 0, 16); /* Create result table. */
for (; *options; options++) {
switch (*options) {
case 'S':
settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
break;
case 'l':
settabsi(L, "currentline", ar.currentline);
break;
case 'u':
settabsi(L, "nups", ar.nups);
settabsi(L, "nparams", ar.nparams);
settabsb(L, "isvararg", ar.isvararg);
break;
case 'n':
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
break;
case 'f': opt_f = 1; break;
case 'L': opt_L = 1; break;
default: break;
}
}
if (opt_L) treatstackoption(L, L1, "activelines");
if (opt_f) treatstackoption(L, L1, "func");
return 1; /* Return result table. */
}
LJLIB_CF(debug_getlocal)
{
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
int slot = lj_lib_checkint(L, arg+2);
if (tvisfunc(L->base+arg)) {
L->top = L->base+arg+1;
lua_pushstring(L, lua_getlocal(L, NULL, slot));
return 1;
}
if (!lua_getstack(L1, lj_lib_checkint(L, arg+1), &ar))
lj_err_arg(L, arg+1, LJ_ERR_LVLRNG);
name = lua_getlocal(L1, &ar, slot);
if (name) {
lua_xmove(L1, L, 1);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
} else {
setnilV(L->top-1);
return 1;
}
}
#if !LJ_SRB2LIB
LJLIB_CF(debug_setlocal)
{
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
TValue *tv;
if (!lua_getstack(L1, lj_lib_checkint(L, arg+1), &ar))
lj_err_arg(L, arg+1, LJ_ERR_LVLRNG);
tv = lj_lib_checkany(L, arg+3);
copyTV(L1, L1->top++, tv);
lua_pushstring(L, lua_setlocal(L1, &ar, lj_lib_checkint(L, arg+2)));
return 1;
}
#endif
static int debug_getupvalue(lua_State *L, int get)
{
int32_t n = lj_lib_checkint(L, 2);
const char *name;
lj_lib_checkfunc(L, 1);
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name) {
lua_pushstring(L, name);
if (!get) return 1;
copyTV(L, L->top, L->top-2);
L->top++;
return 2;
}
return 0;
}
LJLIB_CF(debug_getupvalue)
{
return debug_getupvalue(L, 1);
}
#if !LJ_SRB2LIB
LJLIB_CF(debug_setupvalue)
{
lj_lib_checkany(L, 3);
return debug_getupvalue(L, 0);
}
LJLIB_CF(debug_upvalueid)
{
GCfunc *fn = lj_lib_checkfunc(L, 1);
int32_t n = lj_lib_checkint(L, 2) - 1;
if ((uint32_t)n >= fn->l.nupvalues)
lj_err_arg(L, 2, LJ_ERR_IDXRNG);
lua_pushlightuserdata(L, isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
(void *)&fn->c.upvalue[n]);
return 1;
}
LJLIB_CF(debug_upvaluejoin)
{
GCfunc *fn[2];
GCRef *p[2];
int i;
for (i = 0; i < 2; i++) {
int32_t n;
fn[i] = lj_lib_checkfunc(L, 2*i+1);
if (!isluafunc(fn[i]))
lj_err_arg(L, 2*i+1, LJ_ERR_NOLFUNC);
n = lj_lib_checkint(L, 2*i+2) - 1;
if ((uint32_t)n >= fn[i]->l.nupvalues)
lj_err_arg(L, 2*i+2, LJ_ERR_IDXRNG);
p[i] = &fn[i]->l.uvptr[n];
}
setgcrefr(*p[0], *p[1]);
lj_gc_objbarrier(L, fn[0], gcref(*p[1]));
return 0;
}
#if LJ_52
LJLIB_CF(debug_getuservalue)
{
TValue *o = L->base;
if (o < L->top && tvisudata(o))
settabV(L, o, tabref(udataV(o)->env));
else
setnilV(o);
L->top = o+1;
return 1;
}
LJLIB_CF(debug_setuservalue)
{
TValue *o = L->base;
if (!(o < L->top && tvisudata(o)))
lj_err_argt(L, 1, LUA_TUSERDATA);
if (!(o+1 < L->top && tvistab(o+1)))
lj_err_argt(L, 2, LUA_TTABLE);
L->top = o+2;
lua_setfenv(L, 1);
return 1;
}
#endif
#endif
/* ------------------------------------------------------------------------ */
#define KEY_HOOK (U64x(80000000,00000000)|'h')
static void hookf(lua_State *L, lua_Debug *ar)
{
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail return"};
(L->top++)->u64 = KEY_HOOK;
lua_rawget(L, LUA_REGISTRYINDEX);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
lua_pushinteger(L, ar->currentline);
else lua_pushnil(L);
lua_call(L, 2, 0);
}
}
static int makemask(const char *smask, int count)
{
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT;
return mask;
}
static char *unmakemask(int mask, char *smask)
{
int i = 0;
if (mask & LUA_MASKCALL) smask[i++] = 'c';
if (mask & LUA_MASKRET) smask[i++] = 'r';
if (mask & LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}
LJLIB_CF(debug_sethook)
{
int arg, mask, count;
lua_Hook func;
(void)getthread(L, &arg);
if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1);
func = NULL; mask = 0; count = 0; /* turn off hooks */
} else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
(L->top++)->u64 = KEY_HOOK;
lua_pushvalue(L, arg+1);
lua_rawset(L, LUA_REGISTRYINDEX);
lua_sethook(L, func, mask, count);
return 0;
}
LJLIB_CF(debug_gethook)
{
char buff[5];
int mask = lua_gethookmask(L);
lua_Hook hook = lua_gethook(L);
if (hook != NULL && hook != hookf) { /* external hook? */
lua_pushliteral(L, "external hook");
} else {
(L->top++)->u64 = KEY_HOOK;
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L));
return 3;
}
/* ------------------------------------------------------------------------ */
#if !LJ_SRB2LIB
LJLIB_CF(debug_debug)
{
for (;;) {
char buffer[250];
fputs("lua_debug> ", stderr);
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0)) {
const char *s = lua_tostring(L, -1);
fputs(s ? s : "(error object is not a string)", stderr);
fputs("\n", stderr);
}
lua_settop(L, 0); /* remove eventual returns */
}
}
#endif
/* ------------------------------------------------------------------------ */
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
LJLIB_CF(debug_traceback)
{
int arg;
lua_State *L1 = getthread(L, &arg);
const char *msg = lua_tostring(L, arg+1);
if (msg == NULL && L->top > L->base+arg)
L->top = L->base+arg+1;
else
luaL_traceback(L, L1, msg, lj_lib_optint(L, arg+2, (L == L1)));
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_debug(lua_State *L)
{
LJ_LIB_REG(L, LUA_DBLIBNAME, debug);
return 1;
}
+857
View File
@@ -0,0 +1,857 @@
/*
** FFI library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#define lib_ffi_c
#define LUA_LIB
#include <errno.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#if LJ_HASFFI
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_meta.h"
#include "lj_ctype.h"
#include "lj_cparse.h"
#include "lj_cdata.h"
#include "lj_cconv.h"
#include "lj_carith.h"
#include "lj_ccall.h"
#include "lj_ccallback.h"
#include "lj_clib.h"
#include "lj_strfmt.h"
#include "lj_ff.h"
#include "lj_lib.h"
/* -- C type checks ------------------------------------------------------- */
/* Check first argument for a C type and returns its ID. */
static CTypeID ffi_checkctype(lua_State *L, CTState *cts, TValue *param)
{
TValue *o = L->base;
if (!(o < L->top)) {
err_argtype:
lj_err_argtype(L, 1, "C type");
}
if (tvisstr(o)) { /* Parse an abstract C type declaration. */
GCstr *s = strV(o);
CPState cp;
int errcode;
cp.L = L;
cp.cts = cts;
cp.srcname = strdata(s);
cp.p = strdata(s);
cp.param = param;
cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT;
errcode = lj_cparse(&cp);
if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */
return cp.val.id;
} else {
GCcdata *cd;
if (!tviscdata(o)) goto err_argtype;
if (param && param < L->top) lj_err_arg(L, 1, LJ_ERR_FFI_NUMPARAM);
cd = cdataV(o);
return cd->ctypeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->ctypeid;
}
}
/* Check argument for C data and return it. */
static GCcdata *ffi_checkcdata(lua_State *L, int narg)
{
TValue *o = L->base + narg-1;
if (!(o < L->top && tviscdata(o)))
lj_err_argt(L, narg, LUA_TCDATA);
return cdataV(o);
}
/* Convert argument to C pointer. */
static void *ffi_checkptr(lua_State *L, int narg, CTypeID id)
{
CTState *cts = ctype_cts(L);
TValue *o = L->base + narg-1;
void *p;
if (o >= L->top)
lj_err_arg(L, narg, LJ_ERR_NOVAL);
lj_cconv_ct_tv(cts, ctype_get(cts, id), (uint8_t *)&p, o, CCF_ARG(narg));
return p;
}
/* Convert argument to int32_t. */
static int32_t ffi_checkint(lua_State *L, int narg)
{
CTState *cts = ctype_cts(L);
TValue *o = L->base + narg-1;
int32_t i;
if (o >= L->top)
lj_err_arg(L, narg, LJ_ERR_NOVAL);
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o,
CCF_ARG(narg));
return i;
}
/* -- C type metamethods -------------------------------------------------- */
#define LJLIB_MODULE_ffi_meta
/* Handle ctype __index/__newindex metamethods. */
static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm)
{
CTypeID id = ctype_typeid(cts, ct);
cTValue *tv = lj_ctype_meta(cts, id, mm);
TValue *base = L->base;
if (!tv) {
const char *s;
err_index:
s = strdata(lj_ctype_repr(L, id, NULL));
if (tvisstr(L->base+1)) {
lj_err_callerv(L, LJ_ERR_FFI_BADMEMBER, s, strVdata(L->base+1));
} else {
const char *key = tviscdata(L->base+1) ?
strdata(lj_ctype_repr(L, cdataV(L->base+1)->ctypeid, NULL)) :
lj_typename(L->base+1);
lj_err_callerv(L, LJ_ERR_FFI_BADIDXW, s, key);
}
}
if (!tvisfunc(tv)) {
if (mm == MM_index) {
cTValue *o = lj_meta_tget(L, tv, base+1);
if (o) {
if (tvisnil(o)) goto err_index;
copyTV(L, L->top-1, o);
return 1;
}
} else {
TValue *o = lj_meta_tset(L, tv, base+1);
if (o) {
copyTV(L, o, base+2);
return 0;
}
}
copyTV(L, base, L->top);
tv = L->top-1-LJ_FR2;
}
return lj_meta_tailcall(L, tv);
}
LJLIB_CF(ffi_meta___index) LJLIB_REC(cdata_index 0)
{
CTState *cts = ctype_cts(L);
CTInfo qual = 0;
CType *ct;
uint8_t *p;
TValue *o = L->base;
if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */
lj_err_argt(L, 1, LUA_TCDATA);
ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual);
if ((qual & 1))
return ffi_index_meta(L, cts, ct, MM_index);
if (lj_cdata_get(cts, ct, L->top-1, p))
lj_gc_check(L);
return 1;
}
LJLIB_CF(ffi_meta___newindex) LJLIB_REC(cdata_index 1)
{
CTState *cts = ctype_cts(L);
CTInfo qual = 0;
CType *ct;
uint8_t *p;
TValue *o = L->base;
if (!(o+2 < L->top && tviscdata(o))) /* Also checks for key and value. */
lj_err_argt(L, 1, LUA_TCDATA);
ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual);
if ((qual & 1)) {
if ((qual & CTF_CONST))
lj_err_caller(L, LJ_ERR_FFI_WRCONST);
return ffi_index_meta(L, cts, ct, MM_newindex);
}
lj_cdata_set(cts, ct, p, o+2, qual);
return 0;
}
/* Common handler for cdata arithmetic. */
static int ffi_arith(lua_State *L)
{
MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq);
return lj_carith_op(L, mm);
}
/* The following functions must be in contiguous ORDER MM. */
LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___len) LJLIB_REC(cdata_arith MM_len)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___le) LJLIB_REC(cdata_arith MM_le)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___concat) LJLIB_REC(cdata_arith MM_concat)
{
return ffi_arith(L);
}
/* Forward declaration. */
static int lj_cf_ffi_new(lua_State *L);
LJLIB_CF(ffi_meta___call) LJLIB_REC(cdata_call)
{
CTState *cts = ctype_cts(L);
GCcdata *cd = ffi_checkcdata(L, 1);
CTypeID id = cd->ctypeid;
CType *ct;
cTValue *tv;
MMS mm = MM_call;
if (cd->ctypeid == CTID_CTYPEID) {
id = *(CTypeID *)cdataptr(cd);
mm = MM_new;
} else {
int ret = lj_ccall_func(L, cd);
if (ret >= 0)
return ret;
}
/* Handle ctype __call/__new metamethod. */
ct = ctype_raw(cts, id);
if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
tv = lj_ctype_meta(cts, id, mm);
if (tv)
return lj_meta_tailcall(L, tv);
else if (mm == MM_call)
lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL)));
return lj_cf_ffi_new(L);
}
LJLIB_CF(ffi_meta___add) LJLIB_REC(cdata_arith MM_add)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___sub) LJLIB_REC(cdata_arith MM_sub)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___mul) LJLIB_REC(cdata_arith MM_mul)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___div) LJLIB_REC(cdata_arith MM_div)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___mod) LJLIB_REC(cdata_arith MM_mod)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___pow) LJLIB_REC(cdata_arith MM_pow)
{
return ffi_arith(L);
}
LJLIB_CF(ffi_meta___unm) LJLIB_REC(cdata_arith MM_unm)
{
return ffi_arith(L);
}
/* End of contiguous ORDER MM. */
LJLIB_CF(ffi_meta___tostring)
{
GCcdata *cd = ffi_checkcdata(L, 1);
const char *msg = "cdata<%s>: %p";
CTypeID id = cd->ctypeid;
void *p = cdataptr(cd);
if (id == CTID_CTYPEID) {
msg = "ctype<%s>";
id = *(CTypeID *)p;
} else {
CTState *cts = ctype_cts(L);
CType *ct = ctype_raw(cts, id);
if (ctype_isref(ct->info)) {
p = *(void **)p;
ct = ctype_rawchild(cts, ct);
}
if (ctype_iscomplex(ct->info)) {
setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size));
goto checkgc;
} else if (ct->size == 8 && ctype_isinteger(ct->info)) {
setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd),
(ct->info & CTF_UNSIGNED)));
goto checkgc;
} else if (ctype_isfunc(ct->info)) {
p = *(void **)p;
} else if (ctype_isenum(ct->info)) {
msg = "cdata<%s>: %d";
p = (void *)(uintptr_t)*(uint32_t *)p;
} else {
if (ctype_isptr(ct->info)) {
p = cdata_getptr(p, ct->size);
ct = ctype_rawchild(cts, ct);
}
if (ctype_isstruct(ct->info) || ctype_isvector(ct->info)) {
/* Handle ctype __tostring metamethod. */
cTValue *tv = lj_ctype_meta(cts, ctype_typeid(cts, ct), MM_tostring);
if (tv)
return lj_meta_tailcall(L, tv);
}
}
}
lj_strfmt_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p);
checkgc:
lj_gc_check(L);
return 1;
}
static int ffi_pairs(lua_State *L, MMS mm)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkcdata(L, 1)->ctypeid;
CType *ct = ctype_raw(cts, id);
cTValue *tv;
if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
tv = lj_ctype_meta(cts, id, mm);
if (!tv)
lj_err_callerv(L, LJ_ERR_FFI_BADMM, strdata(lj_ctype_repr(L, id, NULL)),
strdata(mmname_str(G(L), mm)));
return lj_meta_tailcall(L, tv);
}
LJLIB_CF(ffi_meta___pairs)
{
return ffi_pairs(L, MM_pairs);
}
LJLIB_CF(ffi_meta___ipairs)
{
return ffi_pairs(L, MM_ipairs);
}
LJLIB_PUSH("ffi") LJLIB_SET(__metatable)
#include "lj_libdef.h"
/* -- C library metamethods ----------------------------------------------- */
#define LJLIB_MODULE_ffi_clib
/* Index C library by a name. */
static TValue *ffi_clib_index(lua_State *L)
{
TValue *o = L->base;
CLibrary *cl;
if (!(o < L->top && tvisudata(o) && udataV(o)->udtype == UDTYPE_FFI_CLIB))
lj_err_argt(L, 1, LUA_TUSERDATA);
cl = (CLibrary *)uddata(udataV(o));
if (!(o+1 < L->top && tvisstr(o+1)))
lj_err_argt(L, 2, LUA_TSTRING);
return lj_clib_index(L, cl, strV(o+1));
}
LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index 1)
{
TValue *tv = ffi_clib_index(L);
if (tviscdata(tv)) {
CTState *cts = ctype_cts(L);
GCcdata *cd = cdataV(tv);
CType *s = ctype_get(cts, cd->ctypeid);
if (ctype_isextern(s->info)) {
CTypeID sid = ctype_cid(s->info);
void *sp = *(void **)cdataptr(cd);
CType *ct = ctype_raw(cts, sid);
if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp))
lj_gc_check(L);
return 1;
}
}
copyTV(L, L->top-1, tv);
return 1;
}
LJLIB_CF(ffi_clib___newindex) LJLIB_REC(clib_index 0)
{
TValue *tv = ffi_clib_index(L);
TValue *o = L->base+2;
if (o < L->top && tviscdata(tv)) {
CTState *cts = ctype_cts(L);
GCcdata *cd = cdataV(tv);
CType *d = ctype_get(cts, cd->ctypeid);
if (ctype_isextern(d->info)) {
CTInfo qual = 0;
for (;;) { /* Skip attributes and collect qualifiers. */
d = ctype_child(cts, d);
if (!ctype_isattrib(d->info)) break;
if (ctype_attrib(d->info) == CTA_QUAL) qual |= d->size;
}
if (!((d->info|qual) & CTF_CONST)) {
lj_cconv_ct_tv(cts, d, *(void **)cdataptr(cd), o, 0);
return 0;
}
}
}
lj_err_caller(L, LJ_ERR_FFI_WRCONST);
return 0; /* unreachable */
}
LJLIB_CF(ffi_clib___gc)
{
TValue *o = L->base;
if (o < L->top && tvisudata(o) && udataV(o)->udtype == UDTYPE_FFI_CLIB)
lj_clib_unload((CLibrary *)uddata(udataV(o)));
return 0;
}
#include "lj_libdef.h"
/* -- Callback function metamethods --------------------------------------- */
#define LJLIB_MODULE_ffi_callback
static int ffi_callback_set(lua_State *L, GCfunc *fn)
{
GCcdata *cd = ffi_checkcdata(L, 1);
CTState *cts = ctype_cts(L);
CType *ct = ctype_raw(cts, cd->ctypeid);
if (ctype_isptr(ct->info) && (LJ_32 || ct->size == 8)) {
MSize slot = lj_ccallback_ptr2slot(cts, *(void **)cdataptr(cd));
if (slot < cts->cb.sizeid && cts->cb.cbid[slot] != 0) {
GCtab *t = cts->miscmap;
TValue *tv = lj_tab_setint(L, t, (int32_t)slot);
if (fn) {
setfuncV(L, tv, fn);
lj_gc_anybarriert(L, t);
} else {
setnilV(tv);
cts->cb.cbid[slot] = 0;
cts->cb.topid = slot < cts->cb.topid ? slot : cts->cb.topid;
}
return 0;
}
}
lj_err_caller(L, LJ_ERR_FFI_BADCBACK);
return 0;
}
LJLIB_CF(ffi_callback_free)
{
return ffi_callback_set(L, NULL);
}
LJLIB_CF(ffi_callback_set)
{
GCfunc *fn = lj_lib_checkfunc(L, 2);
return ffi_callback_set(L, fn);
}
LJLIB_PUSH(top-1) LJLIB_SET(__index)
#include "lj_libdef.h"
/* -- FFI library functions ----------------------------------------------- */
#define LJLIB_MODULE_ffi
LJLIB_CF(ffi_cdef)
{
GCstr *s = lj_lib_checkstr(L, 1);
CPState cp;
int errcode;
cp.L = L;
cp.cts = ctype_cts(L);
cp.srcname = strdata(s);
cp.p = strdata(s);
cp.param = L->base+1;
cp.mode = CPARSE_MODE_MULTI|CPARSE_MODE_DIRECT;
errcode = lj_cparse(&cp);
if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */
lj_gc_check(L);
return 0;
}
LJLIB_CF(ffi_new) LJLIB_REC(.)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
CType *ct = ctype_raw(cts, id);
CTSize sz;
CTInfo info = lj_ctype_info(cts, id, &sz);
TValue *o = L->base+1;
GCcdata *cd;
if ((info & CTF_VLA)) {
o++;
sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2));
}
if (sz == CTSIZE_INVALID)
lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE);
cd = lj_cdata_newx(cts, id, sz, info);
setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */
lj_cconv_ct_init(cts, ct, sz, cdataptr(cd),
o, (MSize)(L->top - o)); /* Initialize cdata. */
if (ctype_isstruct(ct->info)) {
/* Handle ctype __gc metamethod. Use the fast lookup here. */
cTValue *tv = lj_tab_getinth(cts->miscmap, -(int32_t)id);
if (tv && tvistab(tv) && (tv = lj_meta_fast(L, tabV(tv), MM_gc))) {
GCtab *t = tabref(G(L)->gcroot[GCROOT_FFI_FIN]);
if (gcref(t->metatable)) {
/* Add to finalizer table, if still enabled. */
copyTV(L, lj_tab_set(L, t, o-1), tv);
lj_gc_anybarriert(L, t);
cd->marked |= LJ_GC_CDATA_FIN;
}
}
}
L->top = o; /* Only return the cdata itself. */
lj_gc_check(L);
return 1;
}
LJLIB_CF(ffi_cast) LJLIB_REC(ffi_new)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
CType *d = ctype_raw(cts, id);
TValue *o = lj_lib_checkany(L, 2);
L->top = o+1; /* Make sure this is the last item on the stack. */
if (!(ctype_isnum(d->info) || ctype_isptr(d->info) || ctype_isenum(d->info)))
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
if (!(tviscdata(o) && cdataV(o)->ctypeid == id)) {
GCcdata *cd = lj_cdata_new(cts, id, d->size);
lj_cconv_ct_tv(cts, d, cdataptr(cd), o, CCF_CAST);
setcdataV(L, o, cd);
lj_gc_check(L);
}
return 1;
}
LJLIB_CF(ffi_typeof) LJLIB_REC(.)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, L->base+1);
GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4);
*(CTypeID *)cdataptr(cd) = id;
setcdataV(L, L->top-1, cd);
lj_gc_check(L);
return 1;
}
/* Internal and unsupported API. */
LJLIB_CF(ffi_typeinfo)
{
CTState *cts = ctype_cts(L);
CTypeID id = (CTypeID)ffi_checkint(L, 1);
if (id > 0 && id < cts->top) {
CType *ct = ctype_get(cts, id);
GCtab *t;
lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
t = tabV(L->top-1);
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "info")), (int32_t)ct->info);
if (ct->size != CTSIZE_INVALID)
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "size")), (int32_t)ct->size);
if (ct->sib)
setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "sib")), (int32_t)ct->sib);
if (gcref(ct->name)) {
GCstr *s = gco2str(gcref(ct->name));
if (isdead(G(L), obj2gco(s))) flipwhite(obj2gco(s));
setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s);
}
lj_gc_check(L);
return 1;
}
return 0;
}
LJLIB_CF(ffi_istype) LJLIB_REC(.)
{
CTState *cts = ctype_cts(L);
CTypeID id1 = ffi_checkctype(L, cts, NULL);
TValue *o = lj_lib_checkany(L, 2);
int b = 0;
if (tviscdata(o)) {
GCcdata *cd = cdataV(o);
CTypeID id2 = cd->ctypeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) :
cd->ctypeid;
CType *ct1 = lj_ctype_rawref(cts, id1);
CType *ct2 = lj_ctype_rawref(cts, id2);
if (ct1 == ct2) {
b = 1;
} else if (ctype_type(ct1->info) == ctype_type(ct2->info) &&
ct1->size == ct2->size) {
if (ctype_ispointer(ct1->info))
b = lj_cconv_compatptr(cts, ct1, ct2, CCF_IGNQUAL);
else if (ctype_isnum(ct1->info) || ctype_isvoid(ct1->info))
b = (((ct1->info ^ ct2->info) & ~(CTF_QUAL|CTF_LONG)) == 0);
} else if (ctype_isstruct(ct1->info) && ctype_isptr(ct2->info) &&
ct1 == ctype_rawchild(cts, ct2)) {
b = 1;
}
}
setboolV(L->top-1, b);
setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
return 1;
}
LJLIB_CF(ffi_sizeof) LJLIB_REC(ffi_xof FF_ffi_sizeof)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
CTSize sz;
if (LJ_UNLIKELY(tviscdata(L->base) && cdataisv(cdataV(L->base)))) {
sz = cdatavlen(cdataV(L->base));
} else {
CType *ct = lj_ctype_rawref(cts, id);
if (ctype_isvltype(ct->info))
sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2));
else
sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID;
if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) {
setnilV(L->top-1);
return 1;
}
}
setintV(L->top-1, (int32_t)sz);
return 1;
}
LJLIB_CF(ffi_alignof) LJLIB_REC(ffi_xof FF_ffi_alignof)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
CTSize sz = 0;
CTInfo info = lj_ctype_info_raw(cts, id, &sz);
setintV(L->top-1, 1 << ctype_align(info));
return 1;
}
LJLIB_CF(ffi_offsetof) LJLIB_REC(ffi_xof FF_ffi_offsetof)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
GCstr *name = lj_lib_checkstr(L, 2);
CType *ct = lj_ctype_rawref(cts, id);
CTSize ofs;
if (ctype_isstruct(ct->info) && ct->size != CTSIZE_INVALID) {
CType *fct = lj_ctype_getfield(cts, ct, name, &ofs);
if (fct) {
setintV(L->top-1, ofs);
if (ctype_isfield(fct->info)) {
return 1;
} else if (ctype_isbitfield(fct->info)) {
setintV(L->top++, ctype_bitpos(fct->info));
setintV(L->top++, ctype_bitbsz(fct->info));
return 3;
}
}
}
return 0;
}
LJLIB_CF(ffi_errno) LJLIB_REC(.)
{
int err = errno;
if (L->top > L->base)
errno = ffi_checkint(L, 1);
setintV(L->top++, err);
return 1;
}
LJLIB_CF(ffi_string) LJLIB_REC(.)
{
CTState *cts = ctype_cts(L);
TValue *o = lj_lib_checkany(L, 1);
const char *p;
size_t len;
if (o+1 < L->top && !tvisnil(o+1)) {
len = (size_t)ffi_checkint(L, 2);
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o,
CCF_ARG(1));
} else {
lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o,
CCF_ARG(1));
len = strlen(p);
}
L->top = o+1; /* Make sure this is the last item on the stack. */
setstrV(L, o, lj_str_new(L, p, len));
lj_gc_check(L);
return 1;
}
LJLIB_CF(ffi_copy) LJLIB_REC(.)
{
void *dp = ffi_checkptr(L, 1, CTID_P_VOID);
void *sp = ffi_checkptr(L, 2, CTID_P_CVOID);
TValue *o = L->base+1;
CTSize len;
if (tvisstr(o) && o+1 >= L->top)
len = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */
else
len = (CTSize)ffi_checkint(L, 3);
memcpy(dp, sp, len);
return 0;
}
LJLIB_CF(ffi_fill) LJLIB_REC(.)
{
void *dp = ffi_checkptr(L, 1, CTID_P_VOID);
CTSize len = (CTSize)ffi_checkint(L, 2);
int32_t fill = 0;
if (L->base+2 < L->top && !tvisnil(L->base+2)) fill = ffi_checkint(L, 3);
memset(dp, fill, len);
return 0;
}
/* Test ABI string. */
LJLIB_CF(ffi_abi) LJLIB_REC(.)
{
GCstr *s = lj_lib_checkstr(L, 1);
int b = lj_cparse_case(s,
#if LJ_64
"\00564bit"
#else
"\00532bit"
#endif
#if LJ_ARCH_HASFPU
"\003fpu"
#endif
#if LJ_ABI_SOFTFP
"\006softfp"
#else
"\006hardfp"
#endif
#if LJ_ABI_EABI
"\004eabi"
#endif
#if LJ_ABI_WIN
"\003win"
#endif
#if LJ_ABI_PAUTH
"\005pauth"
#endif
#if LJ_TARGET_UWP
"\003uwp"
#endif
#if LJ_LE
"\002le"
#else
"\002be"
#endif
#if LJ_GC64
"\004gc64"
#endif
) >= 0;
setboolV(L->top-1, b);
setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
return 1;
}
LJLIB_PUSH(top-7) LJLIB_SET(!) /* Store reference to miscmap table. */
LJLIB_CF(ffi_metatype)
{
CTState *cts = ctype_cts(L);
CTypeID id = ffi_checkctype(L, cts, NULL);
GCtab *mt = lj_lib_checktab(L, 2);
GCtab *t = cts->miscmap;
CType *ct = ctype_raw(cts, id);
TValue *tv;
GCcdata *cd;
if (!(ctype_isstruct(ct->info) || ctype_iscomplex(ct->info) ||
ctype_isvector(ct->info)))
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
tv = lj_tab_setinth(L, t, -(int32_t)ctype_typeid(cts, ct));
if (!tvisnil(tv))
lj_err_caller(L, LJ_ERR_PROTMT);
settabV(L, tv, mt);
lj_gc_anybarriert(L, t);
cd = lj_cdata_new(cts, CTID_CTYPEID, 4);
*(CTypeID *)cdataptr(cd) = id;
setcdataV(L, L->top-1, cd);
lj_gc_check(L);
return 1;
}
LJLIB_CF(ffi_gc) LJLIB_REC(.)
{
GCcdata *cd = ffi_checkcdata(L, 1);
TValue *fin = lj_lib_checkany(L, 2);
CTState *cts = ctype_cts(L);
CType *ct = ctype_raw(cts, cd->ctypeid);
if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) ||
ctype_isrefarray(ct->info)))
lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
lj_cdata_setfin(L, cd, gcval(fin), itype(fin));
L->top = L->base+1; /* Pass through the cdata object. */
return 1;
}
LJLIB_PUSH(top-5) LJLIB_SET(!) /* Store clib metatable in func environment. */
LJLIB_CF(ffi_load)
{
GCstr *name = lj_lib_checkstr(L, 1);
int global = (L->base+1 < L->top && tvistruecond(L->base+1));
lj_clib_load(L, tabref(curr_func(L)->c.env), name, global);
return 1;
}
LJLIB_PUSH(top-4) LJLIB_SET(C)
LJLIB_PUSH(top-3) LJLIB_SET(os)
LJLIB_PUSH(top-2) LJLIB_SET(arch)
#include "lj_libdef.h"
/* ------------------------------------------------------------------------ */
/* Register FFI module as loaded. */
static void ffi_register_module(lua_State *L)
{
cTValue *tmp = lj_tab_getstr(tabV(registry(L)), lj_str_newlit(L, "_LOADED"));
if (tmp && tvistab(tmp)) {
GCtab *t = tabV(tmp);
copyTV(L, lj_tab_setstr(L, t, lj_str_newlit(L, LUA_FFILIBNAME)), L->top-1);
lj_gc_anybarriert(L, t);
}
}
LUALIB_API int luaopen_ffi(lua_State *L)
{
CTState *cts = lj_ctype_init(L);
settabV(L, L->top++, (cts->miscmap = lj_tab_new(L, 0, 1)));
LJ_LIB_REG(L, NULL, ffi_meta);
/* NOBARRIER: basemt is a GC root. */
setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1)));
LJ_LIB_REG(L, NULL, ffi_clib);
LJ_LIB_REG(L, NULL, ffi_callback);
/* NOBARRIER: the key is new and lj_tab_newkey() handles the barrier. */
settabV(L, lj_tab_setstr(L, cts->miscmap, &cts->g->strempty), tabV(L->top-1));
L->top--;
lj_clib_default(L, tabV(L->top-1)); /* Create ffi.C default namespace. */
lua_pushliteral(L, LJ_OS_NAME);
lua_pushliteral(L, LJ_ARCH_NAME);
LJ_LIB_REG(L, NULL, ffi); /* Note: no global "ffi" created! */
ffi_register_module(L);
return 1;
}
#endif
+65
View File
@@ -0,0 +1,65 @@
/*
** Library initialization.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major parts taken verbatim from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_init_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_arch.h"
static const luaL_Reg lj_lib_load[] = {
{ "", luaopen_base },
#if !LJ_SRB2LIB
{ LUA_LOADLIBNAME, luaopen_package },
#endif
{ LUA_TABLIBNAME, luaopen_table },
{ LUA_IOLIBNAME, luaopen_io },
#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2OS)
{ LUA_OSLIBNAME, luaopen_os },
#endif
{ LUA_STRLIBNAME, luaopen_string },
#if !LJ_SRB2LIB
{ LUA_MATHLIBNAME, luaopen_math },
#endif
#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2DEBUG)
{ LUA_DBLIBNAME, luaopen_debug },
#endif
#if !LJ_SRB2LIB
{ LUA_BITLIBNAME, luaopen_bit },
#endif
{ LUA_JITLIBNAME, luaopen_jit },
{ NULL, NULL }
};
static const luaL_Reg lj_lib_preload[] = {
#if LJ_HASFFI
{ LUA_FFILIBNAME, luaopen_ffi },
#endif
{ NULL, NULL }
};
LUALIB_API void luaL_openlibs(lua_State *L)
{
const luaL_Reg *lib;
for (lib = lj_lib_load; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD",
sizeof(lj_lib_preload)/sizeof(lj_lib_preload[0])-1);
for (lib = lj_lib_preload; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1);
}
+559
View File
@@ -0,0 +1,559 @@
/*
** I/O library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2011 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdio.h>
#define lib_io_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_str.h"
#include "lj_state.h"
#include "lj_strfmt.h"
#include "lj_ff.h"
#include "lj_lib.h"
/* Userdata payload for I/O file. */
typedef struct IOFileUD {
FILE *fp; /* File handle. */
uint32_t type; /* File type. */
} IOFileUD;
#define IOFILE_TYPE_FILE 0 /* Regular file. */
#define IOFILE_TYPE_PIPE 1 /* Pipe. */
#define IOFILE_TYPE_STDF 2 /* Standard file handle. */
#define IOFILE_TYPE_MASK 3
#define IOFILE_FLAG_CLOSE 4 /* Close after io.lines() iterator. */
#define IOSTDF_UD(L, id) (&gcref(G(L)->gcroot[(id)])->ud)
#define IOSTDF_IOF(L, id) ((IOFileUD *)uddata(IOSTDF_UD(L, (id))))
/* -- Open/close helpers -------------------------------------------------- */
static IOFileUD *io_tofilep(lua_State *L)
{
if (!(L->base < L->top && tvisudata(L->base) &&
udataV(L->base)->udtype == UDTYPE_IO_FILE))
lj_err_argtype(L, 1, "FILE*");
return (IOFileUD *)uddata(udataV(L->base));
}
static IOFileUD *io_tofile(lua_State *L)
{
IOFileUD *iof = io_tofilep(L);
if (iof->fp == NULL)
lj_err_caller(L, LJ_ERR_IOCLFL);
return iof;
}
#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2IO)
static IOFileUD *io_stdfile(lua_State *L, ptrdiff_t id)
{
IOFileUD *iof = IOSTDF_IOF(L, id);
if (iof->fp == NULL)
lj_err_caller(L, LJ_ERR_IOSTDCL);
return iof;
}
#endif
static IOFileUD *io_file_new(lua_State *L)
{
IOFileUD *iof = (IOFileUD *)lua_newuserdata(L, sizeof(IOFileUD));
GCudata *ud = udataV(L->top-1);
ud->udtype = UDTYPE_IO_FILE;
/* NOBARRIER: The GCudata is new (marked white). */
setgcrefr(ud->metatable, curr_func(L)->c.env);
iof->fp = NULL;
iof->type = IOFILE_TYPE_FILE;
return iof;
}
#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2IO)
static IOFileUD *io_file_open(lua_State *L, const char *mode)
{
const char *fname = strdata(lj_lib_checkstr(L, 1));
IOFileUD *iof = io_file_new(L);
iof->fp = fopen(fname, mode);
if (iof->fp == NULL)
luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
return iof;
}
#endif
static int io_file_close(lua_State *L, IOFileUD *iof)
{
int ok;
if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_FILE) {
ok = (fclose(iof->fp) == 0);
} else if ((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_PIPE) {
int stat = -1;
#if LJ_TARGET_POSIX
stat = pclose(iof->fp);
#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
stat = _pclose(iof->fp);
#endif
#if LJ_52
iof->fp = NULL;
return luaL_execresult(L, stat);
#else
ok = (stat != -1);
#endif
} else {
lj_assertL((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF,
"close of unknown FILE* type");
setnilV(L->top++);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
iof->fp = NULL;
return luaL_fileresult(L, ok, NULL);
}
/* -- Read/write helpers -------------------------------------------------- */
static int io_file_readnum(lua_State *L, FILE *fp)
{
lua_Number d;
if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
if (LJ_DUALNUM) {
int32_t i = lj_num2int(d);
if (d == (lua_Number)i && !tvismzero((cTValue *)&d)) {
setintV(L->top++, i);
return 1;
}
}
setnumV(L->top++, d);
return 1;
} else {
setnilV(L->top++);
return 0;
}
}
static int io_file_readline(lua_State *L, FILE *fp, MSize chop)
{
MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0;
char *buf;
for (;;) {
buf = lj_buf_tmp(L, m);
if (fgets(buf+n, m-n, fp) == NULL) break;
n += (MSize)strlen(buf+n);
ok |= n;
if (n && buf[n-1] == '\n') { n -= chop; break; }
if (n >= m - 64) m += m;
}
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
lj_gc_check(L);
return (int)ok;
}
static void io_file_readall(lua_State *L, FILE *fp)
{
MSize m, n;
for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
char *buf = lj_buf_tmp(L, m);
n += (MSize)fread(buf+n, 1, m-n, fp);
if (n != m) {
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
lj_gc_check(L);
return;
}
}
}
static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
{
if (m) {
char *buf = lj_buf_tmp(L, m);
MSize n = (MSize)fread(buf, 1, m, fp);
setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
lj_gc_check(L);
return n > 0;
} else {
int c = getc(fp);
ungetc(c, fp);
setstrV(L, L->top++, &G(L)->strempty);
return (c != EOF);
}
}
static int io_file_read(lua_State *L, IOFileUD *iof, int start)
{
FILE *fp = iof->fp;
int ok, n, nargs = (int)(L->top - L->base) - start;
clearerr(fp);
if (nargs == 0) {
ok = io_file_readline(L, fp, 1);
n = start+1; /* Return 1 result. */
} else {
/* The results plus the buffers go on top of the args. */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
ok = 1;
for (n = start; nargs-- && ok; n++) {
if (tvisstr(L->base+n)) {
const char *p = strVdata(L->base+n);
if (p[0] == '*') p++;
if (p[0] == 'n')
ok = io_file_readnum(L, fp);
else if ((p[0] & ~0x20) == 'L')
ok = io_file_readline(L, fp, (p[0] == 'l'));
else if (p[0] == 'a')
io_file_readall(L, fp);
else
lj_err_arg(L, n+1, LJ_ERR_INVFMT);
} else if (tvisnumber(L->base+n)) {
ok = io_file_readlen(L, fp, (MSize)lj_lib_checkint(L, n+1));
} else {
lj_err_arg(L, n+1, LJ_ERR_INVOPT);
}
}
}
if (ferror(fp))
return luaL_fileresult(L, 0, NULL);
if (!ok)
setnilV(L->top-1); /* Replace last result with nil. */
return n - start;
}
static int io_file_write(lua_State *L, IOFileUD *iof, int start)
{
FILE *fp = iof->fp;
cTValue *tv;
int status = 1;
for (tv = L->base+start; tv < L->top; tv++) {
MSize len;
const char *p = lj_strfmt_wstrnum(L, tv, &len);
if (!p)
lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
status = status && (fwrite(p, 1, len, fp) == len);
}
if (LJ_52 && status) {
L->top = L->base+1;
if (start == 0)
setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_OUTPUT));
return 1;
}
return luaL_fileresult(L, status, NULL);
}
static int io_file_iter(lua_State *L)
{
GCfunc *fn = curr_func(L);
IOFileUD *iof = uddata(udataV(&fn->c.upvalue[0]));
int n = fn->c.nupvalues - 1;
if (iof->fp == NULL)
lj_err_caller(L, LJ_ERR_IOCLFL);
L->top = L->base;
if (n) { /* Copy upvalues with options to stack. */
lj_state_checkstack(L, (MSize)n);
memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue));
L->top += n;
}
n = io_file_read(L, iof, 0);
if (ferror(iof->fp))
lj_err_callermsg(L, strVdata(L->top-2));
if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) {
io_file_close(L, iof); /* Return values are ignored. */
return 0;
}
return n;
}
static int io_file_lines(lua_State *L)
{
int n = (int)(L->top - L->base);
if (n > LJ_MAX_UPVAL)
lj_err_caller(L, LJ_ERR_UNPACK);
lua_pushcclosure(L, io_file_iter, n);
return 1;
}
/* -- I/O file methods ---------------------------------------------------- */
#define LJLIB_MODULE_io_method
LJLIB_CF(io_method_close)
{
IOFileUD *iof;
if (L->base < L->top) {
iof = io_tofile(L);
} else {
iof = IOSTDF_IOF(L, GCROOT_IO_OUTPUT);
if (iof->fp == NULL)
lj_err_caller(L, LJ_ERR_IOCLFL);
}
return io_file_close(L, iof);
}
LJLIB_CF(io_method_read)
{
return io_file_read(L, io_tofile(L), 1);
}
LJLIB_CF(io_method_write) LJLIB_REC(io_write 0)
{
return io_file_write(L, io_tofile(L), 1);
}
LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
{
return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
}
#if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24
/* The Android NDK is such an unmatched marvel of engineering. */
extern int fseeko32(FILE *, long int, int) __asm__("fseeko");
extern long int ftello32(FILE *) __asm__("ftello");
#define fseeko(fp, pos, whence) (fseeko32((fp), (pos), (whence)))
#define ftello(fp) (ftello32((fp)))
#endif
LJLIB_CF(io_method_seek)
{
FILE *fp = io_tofile(L)->fp;
int opt = lj_lib_checkopt(L, 2, 1, "\3set\3cur\3end");
int64_t ofs = 0;
cTValue *o;
int res;
if (opt == 0) opt = SEEK_SET;
else if (opt == 1) opt = SEEK_CUR;
else if (opt == 2) opt = SEEK_END;
o = L->base+2;
if (o < L->top) {
if (tvisint(o))
ofs = (int64_t)intV(o);
else if (tvisnum(o))
ofs = (int64_t)numV(o);
else if (!tvisnil(o))
lj_err_argt(L, 3, LUA_TNUMBER);
}
#if LJ_TARGET_POSIX
res = fseeko(fp, ofs, opt);
#elif _MSC_VER >= 1400
res = _fseeki64(fp, ofs, opt);
#elif defined(__MINGW32__)
res = fseeko64(fp, ofs, opt);
#else
res = fseek(fp, (long)ofs, opt);
#endif
if (res)
return luaL_fileresult(L, 0, NULL);
#if LJ_TARGET_POSIX
ofs = ftello(fp);
#elif _MSC_VER >= 1400
ofs = _ftelli64(fp);
#elif defined(__MINGW32__)
ofs = ftello64(fp);
#else
ofs = (int64_t)ftell(fp);
#endif
setint64V(L->top-1, ofs);
return 1;
}
LJLIB_CF(io_method_setvbuf)
{
FILE *fp = io_tofile(L)->fp;
int opt = lj_lib_checkopt(L, 2, -1, "\4full\4line\2no");
size_t sz = (size_t)lj_lib_optint(L, 3, LUAL_BUFFERSIZE);
if (opt == 0) opt = _IOFBF;
else if (opt == 1) opt = _IOLBF;
else if (opt == 2) opt = _IONBF;
return luaL_fileresult(L, setvbuf(fp, NULL, opt, sz) == 0, NULL);
}
LJLIB_CF(io_method_lines)
{
io_tofile(L);
return io_file_lines(L);
}
LJLIB_CF(io_method___gc)
{
IOFileUD *iof = io_tofilep(L);
if (iof->fp != NULL && (iof->type & IOFILE_TYPE_MASK) != IOFILE_TYPE_STDF)
io_file_close(L, iof);
return 0;
}
LJLIB_CF(io_method___tostring)
{
IOFileUD *iof = io_tofilep(L);
if (iof->fp != NULL)
lua_pushfstring(L, "file (%p)", iof->fp);
else
lua_pushliteral(L, "file (closed)");
return 1;
}
LJLIB_PUSH(top-1) LJLIB_SET(__index)
#include "lj_libdef.h"
/* -- I/O library functions ----------------------------------------------- */
#define LJLIB_MODULE_io
LJLIB_PUSH(top-2) LJLIB_SET(!) /* Set environment. */
LJLIB_CF(io_open)
{
const char *fname = strdata(lj_lib_checkstr(L, 1));
GCstr *s = lj_lib_optstr(L, 2);
const char *mode = s ? strdata(s) : "r";
IOFileUD *iof = io_file_new(L);
iof->fp = fopen(fname, mode);
return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
}
#if !LJ_SRB2LIB
LJLIB_CF(io_popen)
{
#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP)
const char *fname = strdata(lj_lib_checkstr(L, 1));
GCstr *s = lj_lib_optstr(L, 2);
const char *mode = s ? strdata(s) : "r";
IOFileUD *iof = io_file_new(L);
iof->type = IOFILE_TYPE_PIPE;
#if LJ_TARGET_POSIX
fflush(NULL);
iof->fp = popen(fname, mode);
#else
iof->fp = _popen(fname, mode);
#endif
return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, fname);
#else
return luaL_error(L, LUA_QL("popen") " not supported");
#endif
}
#endif
LJLIB_CF(io_tmpfile)
{
IOFileUD *iof = io_file_new(L);
#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PS5 || LJ_TARGET_PSVITA || LJ_TARGET_NX
iof->fp = NULL; errno = ENOSYS;
#else
iof->fp = tmpfile();
#endif
return iof->fp != NULL ? 1 : luaL_fileresult(L, 0, NULL);
}
LJLIB_CF(io_close)
{
return lj_cf_io_method_close(L);
}
#if !LJ_SRB2LIB || (LJ_SRB2LIB && LJ_SRB2IO)
LJLIB_CF(io_read)
{
return io_file_read(L, io_stdfile(L, GCROOT_IO_INPUT), 0);
}
LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT)
{
return io_file_write(L, io_stdfile(L, GCROOT_IO_OUTPUT), 0);
}
LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT)
{
return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)->fp) == 0, NULL);
}
static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode)
{
if (L->base < L->top && !tvisnil(L->base)) {
if (tvisudata(L->base)) {
io_tofile(L);
L->top = L->base+1;
} else {
io_file_open(L, mode);
}
/* NOBARRIER: The standard I/O handles are GC roots. */
setgcref(G(L)->gcroot[id], gcV(L->top-1));
} else {
setudataV(L, L->top++, IOSTDF_UD(L, id));
}
return 1;
}
LJLIB_CF(io_input)
{
return io_std_getset(L, GCROOT_IO_INPUT, "r");
}
LJLIB_CF(io_output)
{
return io_std_getset(L, GCROOT_IO_OUTPUT, "w");
}
LJLIB_CF(io_lines)
{
if (L->base == L->top) setnilV(L->top++);
if (!tvisnil(L->base)) { /* io.lines(fname) */
IOFileUD *iof = io_file_open(L, "r");
iof->type = IOFILE_TYPE_FILE|IOFILE_FLAG_CLOSE;
L->top--;
setudataV(L, L->base, udataV(L->top));
} else { /* io.lines() iterates over stdin. */
setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_INPUT));
}
return io_file_lines(L);
}
#endif
LJLIB_CF(io_type)
{
cTValue *o = lj_lib_checkany(L, 1);
if (!(tvisudata(o) && udataV(o)->udtype == UDTYPE_IO_FILE))
setnilV(L->top++);
else if (((IOFileUD *)uddata(udataV(o)))->fp != NULL)
lua_pushliteral(L, "file");
else
lua_pushliteral(L, "closed file");
return 1;
}
#include "lj_libdef.h"
/* ------------------------------------------------------------------------ */
static GCobj *io_std_new(lua_State *L, FILE *fp, const char *name)
{
IOFileUD *iof = (IOFileUD *)lua_newuserdata(L, sizeof(IOFileUD));
GCudata *ud = udataV(L->top-1);
ud->udtype = UDTYPE_IO_FILE;
/* NOBARRIER: The GCudata is new (marked white). */
setgcref(ud->metatable, gcV(L->top-3));
iof->fp = fp;
iof->type = IOFILE_TYPE_STDF;
lua_setfield(L, -2, name);
return obj2gco(ud);
}
LUALIB_API int luaopen_io(lua_State *L)
{
LJ_LIB_REG(L, NULL, io_method);
copyTV(L, L->top, L->top-1); L->top++;
lua_setfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
LJ_LIB_REG(L, LUA_IOLIBNAME, io);
setgcref(G(L)->gcroot[GCROOT_IO_INPUT], io_std_new(L, stdin, "stdin"));
setgcref(G(L)->gcroot[GCROOT_IO_OUTPUT], io_std_new(L, stdout, "stdout"));
io_std_new(L, stderr, "stderr");
return 1;
}
+744
View File
@@ -0,0 +1,744 @@
/*
** JIT library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#define lib_jit_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_debug.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_state.h"
#include "lj_bc.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#endif
#if LJ_HASJIT
#include "lj_ir.h"
#include "lj_jit.h"
#include "lj_ircall.h"
#include "lj_iropt.h"
#include "lj_target.h"
#endif
#include "lj_trace.h"
#include "lj_dispatch.h"
#include "lj_vm.h"
#include "lj_vmevent.h"
#include "lj_lib.h"
#include "luajit.h"
/* -- jit.* functions ----------------------------------------------------- */
#define LJLIB_MODULE_jit
static int setjitmode(lua_State *L, int mode)
{
int idx = 0;
if (L->base == L->top || tvisnil(L->base)) { /* jit.on/off/flush([nil]) */
mode |= LUAJIT_MODE_ENGINE;
} else {
/* jit.on/off/flush(func|proto, nil|true|false) */
if (tvisfunc(L->base) || tvisproto(L->base))
idx = 1;
else if (!tvistrue(L->base)) /* jit.on/off/flush(true, nil|true|false) */
goto err;
if (L->base+1 < L->top && tvisbool(L->base+1))
mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC;
else
mode |= LUAJIT_MODE_FUNC;
}
if (luaJIT_setmode(L, idx, mode) != 1) {
if ((mode & LUAJIT_MODE_MASK) == LUAJIT_MODE_ENGINE)
lj_err_caller(L, LJ_ERR_NOJIT);
err:
lj_err_argt(L, 1, LUA_TFUNCTION);
}
return 0;
}
LJLIB_CF(jit_on)
{
return setjitmode(L, LUAJIT_MODE_ON);
}
LJLIB_CF(jit_off)
{
return setjitmode(L, LUAJIT_MODE_OFF);
}
LJLIB_CF(jit_flush)
{
#if LJ_HASJIT
if (L->base < L->top && tvisnumber(L->base)) {
int traceno = lj_lib_checkint(L, 1);
luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE);
return 0;
}
#endif
return setjitmode(L, LUAJIT_MODE_FLUSH);
}
#if LJ_HASJIT
/* Push a string for every flag bit that is set. */
static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base,
const char *str)
{
for (; *str; base <<= 1, str += 1+*str)
if (flags & base)
setstrV(L, L->top++, lj_str_new(L, str+1, *(uint8_t *)str));
}
#endif
LJLIB_CF(jit_status)
{
#if LJ_HASJIT
jit_State *J = L2J(L);
L->top = L->base;
setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
flagbits_to_strings(L, J->flags, JIT_F_CPU, JIT_F_CPUSTRING);
flagbits_to_strings(L, J->flags, JIT_F_OPT, JIT_F_OPTSTRING);
return (int)(L->top - L->base);
#else
setboolV(L->top++, 0);
return 1;
#endif
}
LJLIB_CF(jit_security)
{
int idx = lj_lib_checkopt(L, 1, -1, LJ_SECURITY_MODESTRING);
setintV(L->top++, ((LJ_SECURITY_MODE >> (2*idx)) & 3));
return 1;
}
LJLIB_CF(jit_attach)
{
#ifdef LUAJIT_DISABLE_VMEVENT
luaL_error(L, "vmevent API disabled");
#else
GCfunc *fn = lj_lib_checkfunc(L, 1);
GCstr *s = lj_lib_optstr(L, 2);
luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE);
if (s) { /* Attach to given event. */
const uint8_t *p = (const uint8_t *)strdata(s);
uint32_t h = s->len;
while (*p) h = h ^ (lj_rol(h, 6) + *p++);
lua_pushvalue(L, 1);
lua_rawseti(L, -2, VMEVENT_HASHIDX(h));
G(L)->vmevmask = VMEVENT_NOCACHE; /* Invalidate cache. */
} else { /* Detach if no event given. */
setnilV(L->top++);
while (lua_next(L, -2)) {
L->top--;
if (tvisfunc(L->top) && funcV(L->top) == fn) {
setnilV(lj_tab_set(L, tabV(L->top-2), L->top-1));
}
}
}
#endif
return 0;
}
LJLIB_PUSH(top-5) LJLIB_SET(os)
LJLIB_PUSH(top-4) LJLIB_SET(arch)
LJLIB_PUSH(top-3) LJLIB_SET(version_num)
LJLIB_PUSH(top-2) LJLIB_SET(version)
#include "lj_libdef.h"
/* -- jit.util.* functions ------------------------------------------------ */
#define LJLIB_MODULE_jit_util
/* -- Reflection API for Lua functions ------------------------------------ */
static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val)
{
setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val);
}
/* local info = jit.util.funcinfo(func [,pc]) */
LJLIB_CF(jit_util_funcinfo)
{
GCproto *pt = lj_lib_checkLproto(L, 1, 1);
if (pt) {
BCPos pc = (BCPos)lj_lib_optint(L, 2, 0);
GCtab *t;
lua_createtable(L, 0, 16); /* Increment hash size if fields are added. */
t = tabV(L->top-1);
setintfield(L, t, "linedefined", pt->firstline);
setintfield(L, t, "lastlinedefined", pt->firstline + pt->numline);
setintfield(L, t, "stackslots", pt->framesize);
setintfield(L, t, "params", pt->numparams);
setintfield(L, t, "bytecodes", (int32_t)pt->sizebc);
setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc);
setintfield(L, t, "nconsts", (int32_t)pt->sizekn);
setintfield(L, t, "upvalues", (int32_t)pt->sizeuv);
if (pc < pt->sizebc)
setintfield(L, t, "currentline", lj_debug_line(pt, pc));
lua_pushboolean(L, (pt->flags & PROTO_VARARG));
lua_setfield(L, -2, "isvararg");
lua_pushboolean(L, (pt->flags & PROTO_CHILD));
lua_setfield(L, -2, "children");
setstrV(L, L->top++, proto_chunkname(pt));
lua_setfield(L, -2, "source");
lj_debug_pushloc(L, pt, pc);
lua_setfield(L, -2, "loc");
setprotoV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "proto")), pt);
} else {
GCfunc *fn = funcV(L->base);
GCtab *t;
lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */
t = tabV(L->top-1);
if (!iscfunc(fn))
setintfield(L, t, "ffid", fn->c.ffid);
setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")),
(intptr_t)(void *)fn->c.f);
setintfield(L, t, "upvalues", fn->c.nupvalues);
}
return 1;
}
/* local ins, m = jit.util.funcbc(func, pc) */
LJLIB_CF(jit_util_funcbc)
{
GCproto *pt = lj_lib_checkLproto(L, 1, 0);
BCPos pc = (BCPos)lj_lib_checkint(L, 2);
if (pc < pt->sizebc) {
BCIns ins = proto_bc(pt)[pc];
BCOp op = bc_op(ins);
lj_assertL(op < BC__MAX, "bad bytecode op %d", op);
setintV(L->top, ins);
setintV(L->top+1, lj_bc_mode[op]);
L->top += 2;
return 2;
}
return 0;
}
/* local k = jit.util.funck(func, idx) */
LJLIB_CF(jit_util_funck)
{
GCproto *pt = lj_lib_checkLproto(L, 1, 0);
ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
if (idx >= 0) {
if (idx < (ptrdiff_t)pt->sizekn) {
copyTV(L, L->top-1, proto_knumtv(pt, idx));
return 1;
}
} else {
if (~idx < (ptrdiff_t)pt->sizekgc) {
GCobj *gc = proto_kgc(pt, idx);
setgcV(L, L->top-1, gc, ~gc->gch.gct);
return 1;
}
}
return 0;
}
/* local name = jit.util.funcuvname(func, idx) */
LJLIB_CF(jit_util_funcuvname)
{
GCproto *pt = lj_lib_checkLproto(L, 1, 0);
uint32_t idx = (uint32_t)lj_lib_checkint(L, 2);
if (idx < pt->sizeuv) {
setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx)));
return 1;
}
return 0;
}
/* -- Reflection API for traces ------------------------------------------- */
#if LJ_HASJIT
/* Check trace argument. Must not throw for non-existent trace numbers. */
static GCtrace *jit_checktrace(lua_State *L)
{
TraceNo tr = (TraceNo)lj_lib_checkint(L, 1);
jit_State *J = L2J(L);
if (tr > 0 && tr < J->sizetrace)
return traceref(J, tr);
return NULL;
}
/* Names of link types. ORDER LJ_TRLINK */
static const char *const jit_trlinkname[] = {
"none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
"interpreter", "return", "stitch"
};
/* local info = jit.util.traceinfo(tr) */
LJLIB_CF(jit_util_traceinfo)
{
GCtrace *T = jit_checktrace(L);
if (T) {
GCtab *t;
lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */
t = tabV(L->top-1);
setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1);
setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk);
setintfield(L, t, "link", T->link);
setintfield(L, t, "nexit", T->nsnap);
setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype]));
lua_setfield(L, -2, "linktype");
/* There are many more fields. Add them only when needed. */
return 1;
}
return 0;
}
/* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */
LJLIB_CF(jit_util_traceir)
{
GCtrace *T = jit_checktrace(L);
IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
if (T && ref >= REF_BIAS && ref < T->nins) {
IRIns *ir = &T->ir[ref];
int32_t m = lj_ir_mode[ir->o];
setintV(L->top-2, m);
setintV(L->top-1, ir->ot);
setintV(L->top++, (int32_t)ir->op1 - (irm_op1(m)==IRMref ? REF_BIAS : 0));
setintV(L->top++, (int32_t)ir->op2 - (irm_op2(m)==IRMref ? REF_BIAS : 0));
setintV(L->top++, ir->prev);
return 5;
}
return 0;
}
/* local k, t [, slot] = jit.util.tracek(tr, idx) */
LJLIB_CF(jit_util_tracek)
{
GCtrace *T = jit_checktrace(L);
IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS;
if (T && ref >= T->nk && ref < REF_BIAS) {
IRIns *ir = &T->ir[ref];
int32_t slot = -1;
if (ir->o == IR_KSLOT) {
slot = ir->op2;
ir = &T->ir[ir->op1];
}
#if LJ_HASFFI
if (ir->o == IR_KINT64) ctype_loadffi(L);
#endif
lj_ir_kvalue(L, L->top-2, ir);
setintV(L->top-1, (int32_t)irt_type(ir->t));
if (slot == -1)
return 2;
setintV(L->top++, slot);
return 3;
}
return 0;
}
/* local snap = jit.util.tracesnap(tr, sn) */
LJLIB_CF(jit_util_tracesnap)
{
GCtrace *T = jit_checktrace(L);
SnapNo sn = (SnapNo)lj_lib_checkint(L, 2);
if (T && sn < T->nsnap) {
SnapShot *snap = &T->snap[sn];
SnapEntry *map = &T->snapmap[snap->mapofs];
MSize n, nent = snap->nent;
GCtab *t;
lua_createtable(L, nent+2, 0);
t = tabV(L->top-1);
setintV(lj_tab_setint(L, t, 0), (int32_t)snap->ref - REF_BIAS);
setintV(lj_tab_setint(L, t, 1), (int32_t)snap->nslots);
for (n = 0; n < nent; n++)
setintV(lj_tab_setint(L, t, (int32_t)(n+2)), (int32_t)map[n]);
setintV(lj_tab_setint(L, t, (int32_t)(nent+2)), (int32_t)SNAP(255, 0, 0));
return 1;
}
return 0;
}
/* local mcode, addr, loop = jit.util.tracemc(tr) */
LJLIB_CF(jit_util_tracemc)
{
GCtrace *T = jit_checktrace(L);
if (T && T->mcode != NULL) {
setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode));
setintptrV(L->top++, (intptr_t)(void *)T->mcode);
setintV(L->top++, T->mcloop);
return 3;
}
return 0;
}
/* local addr = jit.util.traceexitstub([tr,] exitno) */
LJLIB_CF(jit_util_traceexitstub)
{
#ifdef EXITSTUBS_PER_GROUP
ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
jit_State *J = L2J(L);
if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
return 1;
}
#else
if (L->top > L->base+1) { /* Don't throw for one-argument variant. */
GCtrace *T = jit_checktrace(L);
ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
if (T && T->mcode != NULL && exitno < maxexit) {
setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
return 1;
}
}
#endif
return 0;
}
/* local addr = jit.util.ircalladdr(idx) */
LJLIB_CF(jit_util_ircalladdr)
{
uint32_t idx = (uint32_t)lj_lib_checkint(L, 1);
if (idx < IRCALL__MAX) {
ASMFunction func = lj_ir_callinfo[idx].func;
setintptrV(L->top-1, (intptr_t)(void *)lj_ptr_strip(func));
return 1;
}
return 0;
}
#endif
#include "lj_libdef.h"
static int luaopen_jit_util(lua_State *L)
{
LJ_LIB_REG(L, NULL, jit_util);
return 1;
}
/* -- jit.opt module ------------------------------------------------------ */
#if LJ_HASJIT
#define LJLIB_MODULE_jit_opt
/* Parse optimization level. */
static int jitopt_level(jit_State *J, const char *str)
{
if (str[0] >= '0' && str[0] <= '9' && str[1] == '\0') {
uint32_t flags;
if (str[0] == '0') flags = JIT_F_OPT_0;
else if (str[0] == '1') flags = JIT_F_OPT_1;
else if (str[0] == '2') flags = JIT_F_OPT_2;
else flags = JIT_F_OPT_3;
J->flags = (J->flags & ~JIT_F_OPT_MASK) | flags;
return 1; /* Ok. */
}
return 0; /* No match. */
}
/* Parse optimization flag. */
static int jitopt_flag(jit_State *J, const char *str)
{
const char *lst = JIT_F_OPTSTRING;
uint32_t opt;
int set = 1;
if (str[0] == '+') {
str++;
} else if (str[0] == '-') {
str++;
set = 0;
} else if (str[0] == 'n' && str[1] == 'o') {
str += str[2] == '-' ? 3 : 2;
set = 0;
}
for (opt = JIT_F_OPT; ; opt <<= 1) {
size_t len = *(const uint8_t *)lst;
if (len == 0)
break;
if (strncmp(str, lst+1, len) == 0 && str[len] == '\0') {
if (set) J->flags |= opt; else J->flags &= ~opt;
return 1; /* Ok. */
}
lst += 1+len;
}
return 0; /* No match. */
}
/* Parse optimization parameter. */
static int jitopt_param(jit_State *J, const char *str)
{
const char *lst = JIT_P_STRING;
int i;
for (i = 0; i < JIT_P__MAX; i++) {
size_t len = *(const uint8_t *)lst;
lj_assertJ(len != 0, "bad JIT_P_STRING");
if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
int32_t n = 0;
const char *p = &str[len+1];
while (*p >= '0' && *p <= '9')
n = n*10 + (*p++ - '0');
if (*p) return 0; /* Malformed number. */
J->param[i] = n;
if (i == JIT_P_hotloop)
lj_dispatch_init_hotcount(J2G(J));
return 1; /* Ok. */
}
lst += 1+len;
}
return 0; /* No match. */
}
/* jit.opt.start(flags...) */
LJLIB_CF(jit_opt_start)
{
jit_State *J = L2J(L);
int nargs = (int)(L->top - L->base);
if (nargs == 0) {
J->flags = (J->flags & ~JIT_F_OPT_MASK) | JIT_F_OPT_DEFAULT;
} else {
int i;
for (i = 1; i <= nargs; i++) {
const char *str = strdata(lj_lib_checkstr(L, i));
if (!jitopt_level(J, str) &&
!jitopt_flag(J, str) &&
!jitopt_param(J, str))
lj_err_callerv(L, LJ_ERR_JITOPT, str);
}
}
return 0;
}
#include "lj_libdef.h"
#endif
/* -- jit.profile module -------------------------------------------------- */
#if LJ_HASPROFILE
#define LJLIB_MODULE_jit_profile
/* Not loaded by default, use: local profile = require("jit.profile") */
#define KEY_PROFILE_THREAD (U64x(80000000,00000000)|'t')
#define KEY_PROFILE_FUNC (U64x(80000000,00000000)|'f')
static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
int vmstate)
{
TValue key;
cTValue *tv;
key.u64 = KEY_PROFILE_FUNC;
tv = lj_tab_get(L, tabV(registry(L)), &key);
if (tvisfunc(tv)) {
char vmst = (char)vmstate;
int status;
setfuncV(L2, L2->top++, funcV(tv));
setthreadV(L2, L2->top++, L);
setintV(L2->top++, samples);
setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1));
status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */
if (status) {
if (G(L2)->panic) G(L2)->panic(L2);
exit(EXIT_FAILURE);
}
lj_trace_abort(G(L2));
}
}
/* profile.start(mode, cb) */
LJLIB_CF(jit_profile_start)
{
GCtab *registry = tabV(registry(L));
GCstr *mode = lj_lib_optstr(L, 1);
GCfunc *func = lj_lib_checkfunc(L, 2);
lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */
TValue key;
/* Anchor thread and function in registry. */
key.u64 = KEY_PROFILE_THREAD;
setthreadV(L, lj_tab_set(L, registry, &key), L2);
key.u64 = KEY_PROFILE_FUNC;
setfuncV(L, lj_tab_set(L, registry, &key), func);
lj_gc_anybarriert(L, registry);
luaJIT_profile_start(L, mode ? strdata(mode) : "",
(luaJIT_profile_callback)jit_profile_callback, L2);
return 0;
}
/* profile.stop() */
LJLIB_CF(jit_profile_stop)
{
GCtab *registry;
TValue key;
luaJIT_profile_stop(L);
registry = tabV(registry(L));
key.u64 = KEY_PROFILE_THREAD;
setnilV(lj_tab_set(L, registry, &key));
key.u64 = KEY_PROFILE_FUNC;
setnilV(lj_tab_set(L, registry, &key));
lj_gc_anybarriert(L, registry);
return 0;
}
/* dump = profile.dumpstack([thread,] fmt, depth) */
LJLIB_CF(jit_profile_dumpstack)
{
lua_State *L2 = L;
int arg = 0;
size_t len;
int depth;
GCstr *fmt;
const char *p;
if (L->top > L->base && tvisthread(L->base)) {
L2 = threadV(L->base);
arg = 1;
}
fmt = lj_lib_checkstr(L, arg+1);
depth = lj_lib_checkint(L, arg+2);
p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len);
lua_pushlstring(L, p, len);
return 1;
}
#include "lj_libdef.h"
static int luaopen_jit_profile(lua_State *L)
{
LJ_LIB_REG(L, NULL, jit_profile);
return 1;
}
#endif
/* -- JIT compiler initialization ----------------------------------------- */
#if LJ_HASJIT
/* Default values for JIT parameters. */
static const int32_t jit_param_default[JIT_P__MAX+1] = {
#define JIT_PARAMINIT(len, name, value) (value),
JIT_PARAMDEF(JIT_PARAMINIT)
#undef JIT_PARAMINIT
0
};
#if LJ_TARGET_ARM && LJ_TARGET_LINUX
#include <sys/utsname.h>
#endif
/* Arch-dependent CPU feature detection. */
static uint32_t jit_cpudetect(void)
{
uint32_t flags = 0;
#if LJ_TARGET_X86ORX64
uint32_t vendor[4];
uint32_t features[4];
if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
if (vendor[0] >= 7) {
uint32_t xfeatures[4];
lj_vm_cpuid(7, xfeatures);
flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
}
}
/* Don't bother checking for SSE2 -- the VM will crash before getting here. */
#elif LJ_TARGET_ARM
int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */
#if LJ_TARGET_LINUX
if (ver < 70) { /* Runtime ARM CPU detection. */
struct utsname ut;
uname(&ut);
if (strncmp(ut.machine, "armv", 4) == 0) {
if (ut.machine[4] >= '8') ver = 80;
else if (ut.machine[4] == '7') ver = 70;
else if (ut.machine[4] == '6') ver = 60;
}
}
#endif
flags |= ver >= 70 ? JIT_F_ARMV7 :
ver >= 61 ? JIT_F_ARMV6T2_ :
ver >= 60 ? JIT_F_ARMV6_ : 0;
flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
#elif LJ_TARGET_ARM64
/* No optional CPU features to detect (for now). */
#elif LJ_TARGET_PPC
#if LJ_ARCH_SQRT
flags |= JIT_F_SQRT;
#endif
#if LJ_ARCH_ROUND
flags |= JIT_F_ROUND;
#endif
#elif LJ_TARGET_MIPS
/* Compile-time MIPS CPU detection. */
#if LJ_ARCH_VERSION >= 20
flags |= JIT_F_MIPSXXR2;
#endif
/* Runtime MIPS CPU detection. */
#if defined(__GNUC__)
if (!(flags & JIT_F_MIPSXXR2)) {
int x;
#ifdef __mips16
x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */
#else
/* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
__asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2");
#endif
if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */
}
#endif
#else
#error "Missing CPU detection for this architecture"
#endif
return flags;
}
/* Initialize JIT compiler. */
static void jit_init(lua_State *L)
{
jit_State *J = L2J(L);
J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT;
memcpy(J->param, jit_param_default, sizeof(J->param));
lj_dispatch_update(G(L));
}
#endif
LUALIB_API int luaopen_jit(lua_State *L)
{
#if LJ_HASJIT
jit_init(L);
#endif
lua_pushliteral(L, LJ_OS_NAME);
lua_pushliteral(L, LJ_ARCH_NAME);
lua_pushinteger(L, LUAJIT_VERSION_NUM); /* Deprecated. */
lua_pushliteral(L, LUAJIT_VERSION);
LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
#if LJ_HASPROFILE
lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile,
tabref(L->env));
#endif
#ifndef LUAJIT_DISABLE_JITUTIL
lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env));
#endif
#if LJ_HASJIT
LJ_LIB_REG(L, "jit.opt", jit_opt);
#endif
L->top -= 2;
return 1;
}
+205
View File
@@ -0,0 +1,205 @@
/*
** Math library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
*/
#include <math.h>
#define lib_math_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_lib.h"
#include "lj_vm.h"
#include "lj_prng.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_math
LJLIB_ASM(math_abs) LJLIB_REC(.)
{
lj_lib_checknumber(L, 1);
return FFH_RETRY;
}
LJLIB_ASM_(math_floor) LJLIB_REC(math_round IRFPM_FLOOR)
LJLIB_ASM_(math_ceil) LJLIB_REC(math_round IRFPM_CEIL)
LJLIB_ASM(math_sqrt) LJLIB_REC(math_unary IRFPM_SQRT)
{
lj_lib_checknum(L, 1);
return FFH_RETRY;
}
LJLIB_ASM_(math_log10) LJLIB_REC(math_call IRCALL_log10)
LJLIB_ASM_(math_exp) LJLIB_REC(math_call IRCALL_exp)
LJLIB_ASM_(math_sin) LJLIB_REC(math_call IRCALL_sin)
LJLIB_ASM_(math_cos) LJLIB_REC(math_call IRCALL_cos)
LJLIB_ASM_(math_tan) LJLIB_REC(math_call IRCALL_tan)
LJLIB_ASM_(math_asin) LJLIB_REC(math_call IRCALL_asin)
LJLIB_ASM_(math_acos) LJLIB_REC(math_call IRCALL_acos)
LJLIB_ASM_(math_atan) LJLIB_REC(math_call IRCALL_atan)
LJLIB_ASM_(math_sinh) LJLIB_REC(math_call IRCALL_sinh)
LJLIB_ASM_(math_cosh) LJLIB_REC(math_call IRCALL_cosh)
LJLIB_ASM_(math_tanh) LJLIB_REC(math_call IRCALL_tanh)
LJLIB_ASM_(math_frexp)
LJLIB_ASM_(math_modf)
LJLIB_ASM(math_log) LJLIB_REC(math_log)
{
double x = lj_lib_checknum(L, 1);
if (L->base+1 < L->top) {
double y = lj_lib_checknum(L, 2);
#ifdef LUAJIT_NO_LOG2
x = log(x); y = 1.0 / log(y);
#else
x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y);
#endif
setnumV(L->base-1-LJ_FR2, x*y); /* Do NOT join the expression to x / y. */
return FFH_RES(1);
}
return FFH_RETRY;
}
LJLIB_LUA(math_deg) /* function(x) return x * 57.29577951308232 end */
LJLIB_LUA(math_rad) /* function(x) return x * 0.017453292519943295 end */
LJLIB_ASM(math_atan2) LJLIB_REC(.)
{
lj_lib_checknum(L, 1);
lj_lib_checknum(L, 2);
return FFH_RETRY;
}
LJLIB_ASM_(math_pow) LJLIB_REC(.)
LJLIB_ASM_(math_fmod)
LJLIB_ASM(math_ldexp) LJLIB_REC(.)
{
lj_lib_checknum(L, 1);
#if LJ_DUALNUM && !LJ_TARGET_X86ORX64
lj_lib_checkint(L, 2);
#else
lj_lib_checknum(L, 2);
#endif
return FFH_RETRY;
}
LJLIB_ASM(math_min) LJLIB_REC(math_minmax IR_MIN)
{
int i = 0;
do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
return FFH_RETRY;
}
LJLIB_ASM_(math_max) LJLIB_REC(math_minmax IR_MAX)
LJLIB_PUSH(3.14159265358979323846) LJLIB_SET(pi)
LJLIB_PUSH(1e310) LJLIB_SET(huge)
/* ------------------------------------------------------------------------ */
/* This implements a Tausworthe PRNG with period 2^223. Based on:
** Tables of maximally-equidistributed combined LFSR generators,
** Pierre L'Ecuyer, 1991, table 3, 1st entry.
** Full-period ME-CF generator with L=64, J=4, k=223, N1=49.
*/
/* Union needed for bit-pattern conversion between uint64_t and double. */
typedef union { uint64_t u64; double d; } U64double;
/* PRNG seeding function. */
static void random_seed(PRNGState *rs, double d)
{
uint32_t r = 0x11090601; /* 64-k[i] as four 8 bit constants. */
int i;
for (i = 0; i < 4; i++) {
U64double u;
uint32_t m = 1u << (r&255);
r >>= 8;
u.d = d = d * 3.14159265358979323846 + 2.7182818284590452354;
if (u.u64 < m) u.u64 += m; /* Ensure k[i] MSB of u[i] are non-zero. */
rs->u[i] = u.u64;
}
for (i = 0; i < 10; i++)
(void)lj_prng_u64(rs);
}
/* PRNG extract function. */
LJLIB_PUSH(top-2) /* Upvalue holds userdata with PRNGState. */
LJLIB_CF(math_random) LJLIB_REC(.)
{
int n = (int)(L->top - L->base);
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
U64double u;
double d;
u.u64 = lj_prng_u64d(rs);
d = u.d - 1.0;
if (n > 0) {
#if LJ_DUALNUM
int isint = 1;
double r1;
lj_lib_checknumber(L, 1);
if (tvisint(L->base)) {
r1 = (lua_Number)intV(L->base);
} else {
isint = 0;
r1 = numV(L->base);
}
#else
double r1 = lj_lib_checknum(L, 1);
#endif
if (n == 1) {
d = lj_vm_floor(d*r1) + 1.0; /* d is an int in range [1, r1] */
} else {
#if LJ_DUALNUM
double r2;
lj_lib_checknumber(L, 2);
if (tvisint(L->base+1)) {
r2 = (lua_Number)intV(L->base+1);
} else {
isint = 0;
r2 = numV(L->base+1);
}
#else
double r2 = lj_lib_checknum(L, 2);
#endif
d = lj_vm_floor(d*(r2-r1+1.0)) + r1; /* d is an int in range [r1, r2] */
}
#if LJ_DUALNUM
if (isint) {
setintV(L->top-1, lj_num2int(d));
return 1;
}
#endif
} /* else: d is a double in range [0, 1] */
setnumV(L->top++, d);
return 1;
}
/* PRNG seed function. */
LJLIB_PUSH(top-2) /* Upvalue holds userdata with PRNGState. */
LJLIB_CF(math_randomseed)
{
PRNGState *rs = (PRNGState *)(uddata(udataV(lj_lib_upvalue(L, 1))));
if (L->base != L->top)
random_seed(rs, lj_lib_checknum(L, 1));
else if (!lj_prng_seed_secure(rs))
lj_err_caller(L, LJ_ERR_PRNGSD);
return 0;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_math(lua_State *L)
{
PRNGState *rs = (PRNGState *)lua_newuserdata(L, sizeof(PRNGState));
lj_prng_seed_fixed(rs);
LJ_LIB_REG(L, LUA_MATHLIBNAME, math);
return 1;
}
+296
View File
@@ -0,0 +1,296 @@
/*
** OS library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#include <errno.h>
#include <time.h>
#define lib_os_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_str.h"
#include "lj_lib.h"
#if LJ_TARGET_POSIX
#include <unistd.h>
#else
#include <stdio.h>
#endif
#if !LJ_TARGET_PSVITA
#include <locale.h>
#endif
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_os
#if !LJ_SRB2LIB
LJLIB_CF(os_execute)
{
#if LJ_NO_SYSTEM
#if LJ_52
errno = ENOSYS;
return luaL_fileresult(L, 0, NULL);
#else
lua_pushinteger(L, -1);
return 1;
#endif
#else
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd);
#if LJ_52
if (cmd)
return luaL_execresult(L, stat);
setboolV(L->top++, 1);
#else
setintV(L->top++, stat);
#endif
return 1;
#endif
}
LJLIB_CF(os_remove)
{
const char *filename = luaL_checkstring(L, 1);
return luaL_fileresult(L, remove(filename) == 0, filename);
}
LJLIB_CF(os_rename)
{
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
}
LJLIB_CF(os_tmpname)
{
#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PS5 || LJ_TARGET_PSVITA || LJ_TARGET_NX
lj_err_caller(L, LJ_ERR_OSUNIQF);
return 0;
#else
#if LJ_TARGET_POSIX
char buf[15+1];
int fp;
strcpy(buf, "/tmp/lua_XXXXXX");
fp = mkstemp(buf);
if (fp != -1)
close(fp);
else
lj_err_caller(L, LJ_ERR_OSUNIQF);
#else
char buf[L_tmpnam];
if (tmpnam(buf) == NULL)
lj_err_caller(L, LJ_ERR_OSUNIQF);
#endif
lua_pushstring(L, buf);
return 1;
#endif
}
LJLIB_CF(os_getenv)
{
#if LJ_TARGET_CONSOLE
lua_pushnil(L);
#else
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
#endif
return 1;
}
LJLIB_CF(os_exit)
{
int status;
if (L->base < L->top && tvisbool(L->base))
status = boolV(L->base) ? EXIT_SUCCESS : EXIT_FAILURE;
else
status = lj_lib_optint(L, 1, EXIT_SUCCESS);
if (L->base+1 < L->top && tvistruecond(L->base+1))
lua_close(L);
exit(status);
return 0; /* Unreachable. */
}
#endif
LJLIB_CF(os_clock)
{
setnumV(L->top++, ((lua_Number)clock())*(1.0/(lua_Number)CLOCKS_PER_SEC));
return 1;
}
/* ------------------------------------------------------------------------ */
static void setfield(lua_State *L, const char *key, int value)
{
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield(lua_State *L, const char *key, int value)
{
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
static int getboolfield(lua_State *L, const char *key)
{
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int getfield(lua_State *L, const char *key, int d)
{
int res;
lua_getfield(L, -1, key);
if (lua_isnumber(L, -1)) {
res = (int)lua_tointeger(L, -1);
} else {
if (d < 0)
lj_err_callerv(L, LJ_ERR_OSDATEF, key);
res = d;
}
lua_pop(L, 1);
return res;
}
LJLIB_CF(os_date)
{
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
#if LJ_TARGET_POSIX
struct tm rtm;
#endif
if (*s == '!') { /* UTC? */
s++; /* Skip '!' */
#if LJ_TARGET_POSIX
stm = gmtime_r(&t, &rtm);
#else
stm = gmtime(&t);
#endif
} else {
#if LJ_TARGET_POSIX
stm = localtime_r(&t, &rtm);
#else
stm = localtime(&t);
#endif
}
if (stm == NULL) { /* Invalid date? */
setnilV(L->top++);
} else if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
} else if (*s) {
SBuf *sb = &G(L)->tmpbuf;
MSize sz = 0, retry = 4;
const char *q;
for (q = s; *q; q++)
sz += (*q == '%') ? 30 : 1; /* Overflow doesn't matter. */
setsbufL(sb, L);
while (retry--) { /* Limit growth for invalid format or empty result. */
char *buf = lj_buf_need(sb, sz);
size_t len = strftime(buf, sbufsz(sb), s, stm);
if (len) {
setstrV(L, L->top++, lj_str_new(L, buf, len));
lj_gc_check(L);
break;
}
sz += (sz|1);
}
} else {
setstrV(L, L->top++, &G(L)->strempty);
}
return 1;
}
LJLIB_CF(os_time)
{
time_t t;
if (lua_isnoneornil(L, 1)) { /* called without args? */
t = time(NULL); /* get current time */
} else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0);
ts.tm_min = getfield(L, "min", 0);
ts.tm_hour = getfield(L, "hour", 12);
ts.tm_mday = getfield(L, "day", -1);
ts.tm_mon = getfield(L, "month", -1) - 1;
ts.tm_year = getfield(L, "year", -1) - 1900;
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
}
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)t);
return 1;
}
LJLIB_CF(os_difftime)
{
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, (lua_Number)0))));
return 1;
}
/* ------------------------------------------------------------------------ */
#if !LJ_SRB2LIB
LJLIB_CF(os_setlocale)
{
#if LJ_TARGET_PSVITA
lua_pushliteral(L, "C");
#else
GCstr *s = lj_lib_optstr(L, 1);
const char *str = s ? strdata(s) : NULL;
int opt = lj_lib_checkopt(L, 2, 6,
"\5ctype\7numeric\4time\7collate\10monetary\1\377\3all");
if (opt == 0) opt = LC_CTYPE;
else if (opt == 1) opt = LC_NUMERIC;
else if (opt == 2) opt = LC_TIME;
else if (opt == 3) opt = LC_COLLATE;
else if (opt == 4) opt = LC_MONETARY;
else if (opt == 6) opt = LC_ALL;
lua_pushstring(L, setlocale(opt, str));
#endif
return 1;
}
#endif
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_os(lua_State *L)
{
LJ_LIB_REG(L, LUA_OSLIBNAME, os);
return 1;
}
+628
View File
@@ -0,0 +1,628 @@
/*
** Package library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2012 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_package_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_err.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
/* Error codes for ll_loadfunc. */
#define PACKAGE_ERR_LIB 1
#define PACKAGE_ERR_FUNC 2
#define PACKAGE_ERR_LOAD 3
/* Redefined in platform specific part. */
#define PACKAGE_LIB_FAIL "open"
#define setprogdir(L) ((void)0)
/* Symbol name prefixes. */
#define SYMPREFIX_CF "luaopen_%s"
#define SYMPREFIX_BC "luaJIT_BC_%s"
#if LJ_TARGET_DLOPEN
#include <dlfcn.h>
static void ll_unloadlib(void *lib)
{
dlclose(lib);
}
static void *ll_load(lua_State *L, const char *path, int gl)
{
void *lib = dlopen(path, RTLD_NOW | (gl ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
{
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
}
static const char *ll_bcsym(void *lib, const char *sym)
{
#if defined(RTLD_DEFAULT) && !defined(NO_RTLD_DEFAULT)
if (lib == NULL) lib = RTLD_DEFAULT;
#elif LJ_TARGET_OSX || LJ_TARGET_BSD
if (lib == NULL) lib = (void *)(intptr_t)-2;
#endif
return (const char *)dlsym(lib, sym);
}
#elif LJ_TARGET_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
#define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
#define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
BOOL WINAPI GetModuleHandleExA(DWORD, LPCSTR, HMODULE*);
#endif
#if LJ_TARGET_UWP
void *LJ_WIN_LOADLIBA(const char *path)
{
DWORD err = GetLastError();
wchar_t wpath[256];
HANDLE lib = NULL;
if (MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, 256) > 0) {
lib = LoadPackagedLibrary(wpath, 0);
}
SetLastError(err);
return lib;
}
#endif
#undef setprogdir
static void setprogdir(lua_State *L)
{
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) {
luaL_error(L, "unable to get ModuleFileName");
} else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror(lua_State *L)
{
DWORD error = GetLastError();
#if LJ_TARGET_XBOXONE
wchar_t wbuffer[128];
char buffer[128*2];
if (FormatMessageW(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, wbuffer, sizeof(wbuffer)/sizeof(wchar_t), NULL) &&
WideCharToMultiByte(CP_ACP, 0, wbuffer, 128, buffer, 128*2, NULL, NULL))
#else
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer), NULL))
#endif
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d\n", error);
}
static void ll_unloadlib(void *lib)
{
FreeLibrary((HINSTANCE)lib);
}
static void *ll_load(lua_State *L, const char *path, int gl)
{
HINSTANCE lib = LJ_WIN_LOADLIBA(path);
if (lib == NULL) pusherror(L);
UNUSED(gl);
return lib;
}
static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
{
lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
if (f == NULL) pusherror(L);
return f;
}
#if LJ_TARGET_UWP
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#endif
static const char *ll_bcsym(void *lib, const char *sym)
{
if (lib) {
return (const char *)GetProcAddress((HINSTANCE)lib, sym);
} else {
#if LJ_TARGET_UWP
return (const char *)GetProcAddress((HINSTANCE)&__ImageBase, sym);
#else
HINSTANCE h = GetModuleHandleA(NULL);
const char *p = (const char *)GetProcAddress(h, sym);
if (p == NULL && GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(const char *)ll_bcsym, &h))
p = (const char *)GetProcAddress(h, sym);
return p;
#endif
}
}
#else
#undef PACKAGE_LIB_FAIL
#define PACKAGE_LIB_FAIL "absent"
#define DLMSG "dynamic libraries not enabled; no support for target OS"
static void ll_unloadlib(void *lib)
{
UNUSED(lib);
}
static void *ll_load(lua_State *L, const char *path, int gl)
{
UNUSED(path); UNUSED(gl);
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym)
{
UNUSED(lib); UNUSED(sym);
lua_pushliteral(L, DLMSG);
return NULL;
}
static const char *ll_bcsym(void *lib, const char *sym)
{
UNUSED(lib); UNUSED(sym);
return NULL;
}
#endif
/* ------------------------------------------------------------------------ */
static void **ll_register(lua_State *L, const char *path)
{
void **plib;
lua_pushfstring(L, "LOADLIB: %s", path);
lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
if (!lua_isnil(L, -1)) { /* is there an entry? */
plib = (void **)lua_touserdata(L, -1);
} else { /* no entry yet; create one */
lua_pop(L, 1);
plib = (void **)lua_newuserdata(L, sizeof(void *));
*plib = NULL;
luaL_setmetatable(L, "_LOADLIB");
lua_pushfstring(L, "LOADLIB: %s", path);
lua_pushvalue(L, -2);
lua_settable(L, LUA_REGISTRYINDEX);
}
return plib;
}
static const char *mksymname(lua_State *L, const char *modname,
const char *prefix)
{
const char *funcname;
const char *mark = strchr(modname, *LUA_IGMARK);
if (mark) modname = mark + 1;
funcname = luaL_gsub(L, modname, ".", "_");
funcname = lua_pushfstring(L, prefix, funcname);
lua_remove(L, -2); /* remove 'gsub' result */
return funcname;
}
static int ll_loadfunc(lua_State *L, const char *path, const char *name, int r)
{
void **reg;
if (strlen(path) >= 4096) {
lua_pushliteral(L, "path too long");
return PACKAGE_ERR_LIB;
}
reg = ll_register(L, path);
if (*reg == NULL) *reg = ll_load(L, path, (*name == '*'));
if (*reg == NULL) {
return PACKAGE_ERR_LIB; /* Unable to load library. */
} else if (*name == '*') { /* Only load library into global namespace. */
lua_pushboolean(L, 1);
return 0;
} else {
const char *sym = r ? name : mksymname(L, name, SYMPREFIX_CF);
lua_CFunction f = ll_sym(L, *reg, sym);
if (f) {
lua_pushcfunction(L, f);
return 0;
}
if (!r) {
const char *bcdata = ll_bcsym(*reg, mksymname(L, name, SYMPREFIX_BC));
lua_pop(L, 1);
if (bcdata) {
if (luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
return PACKAGE_ERR_LOAD;
return 0;
}
}
return PACKAGE_ERR_FUNC; /* Unable to find function. */
}
}
static int lj_cf_package_loadlib(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int st = ll_loadfunc(L, path, init, 1);
if (st == 0) { /* no errors? */
return 1; /* return the loaded function */
} else { /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (st == PACKAGE_ERR_LIB) ? PACKAGE_LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
}
static int lj_cf_package_unloadlib(lua_State *L)
{
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}
/* ------------------------------------------------------------------------ */
static int readable(const char *filename)
{
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}
static const char *pushnexttemplate(lua_State *L, const char *path)
{
const char *l;
while (*path == *LUA_PATHSEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATHSEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, (size_t)(l - path)); /* template */
return l;
}
static const char *searchpath (lua_State *L, const char *name,
const char *path, const char *sep,
const char *dirsep)
{
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
static int lj_cf_package_searchpath(lua_State *L)
{
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
luaL_optstring(L, 3, "."),
luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) {
return 1;
} else { /* error message is on top of the stack */
lua_pushnil(L);
lua_insert(L, -2);
return 2; /* return nil + error message */
}
}
static const char *findfile(lua_State *L, const char *name,
const char *pname)
{
const char *path;
lua_getfield(L, LUA_ENVIRONINDEX, pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
return searchpath(L, name, path, ".", LUA_DIRSEP);
}
static void loaderror(lua_State *L, const char *filename)
{
luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
static int lj_cf_package_loader_lua(lua_State *L)
{
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path");
if (filename == NULL) return 1; /* library not found in this path */
if (luaL_loadfile(L, filename) != 0)
loaderror(L, filename);
return 1; /* library loaded successfully */
}
static int lj_cf_package_loader_c(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, "cpath");
if (filename == NULL) return 1; /* library not found in this path */
if (ll_loadfunc(L, filename, name, 0) != 0)
loaderror(L, filename);
return 1; /* library loaded successfully */
}
static int lj_cf_package_loader_croot(lua_State *L)
{
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int st;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, (size_t)(p - name));
filename = findfile(L, lua_tostring(L, -1), "cpath");
if (filename == NULL) return 1; /* root not found */
if ((st = ll_loadfunc(L, filename, name, 0)) != 0) {
if (st != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */
lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
name, filename);
return 1; /* function not found */
}
return 1;
}
static int lj_cf_package_loader_preload(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_ENVIRONINDEX, "preload");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.preload") " must be a table");
lua_getfield(L, -1, name);
if (lua_isnil(L, -1)) { /* Not found? */
const char *bcname = mksymname(L, name, SYMPREFIX_BC);
const char *bcdata = ll_bcsym(NULL, bcname);
if (bcdata == NULL || luaL_loadbuffer(L, bcdata, ~(size_t)0, name) != 0)
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
}
return 1;
}
/* ------------------------------------------------------------------------ */
#define KEY_SENTINEL (U64x(80000000,00000000)|'s')
static int lj_cf_package_require(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
int i;
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name);
if (lua_toboolean(L, -1)) { /* is it there? */
if ((L->top-1)->u64 == KEY_SENTINEL) /* check loops */
luaL_error(L, "loop or previous error loading module " LUA_QS, name);
return 1; /* package is already loaded */
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL("package.loaders") " must be a table");
lua_pushliteral(L, ""); /* error message accumulator */
for (i = 1; ; i++) {
lua_rawgeti(L, -2, i); /* get a loader */
if (lua_isnil(L, -1))
luaL_error(L, "module " LUA_QS " not found:%s",
name, lua_tostring(L, -2));
lua_pushstring(L, name);
lua_call(L, 1, 1); /* call it */
if (lua_isfunction(L, -1)) /* did it find module? */
break; /* module loaded successfully */
else if (lua_isstring(L, -1)) /* loader returned error message? */
lua_concat(L, 2); /* accumulate it */
else
lua_pop(L, 1);
}
(L->top++)->u64 = KEY_SENTINEL;
lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
lua_pushstring(L, name); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_getfield(L, 2, name);
if ((L->top-1)->u64 == KEY_SENTINEL) { /* module did not set a value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
lj_lib_checkfpu(L);
return 1;
}
/* ------------------------------------------------------------------------ */
static void setfenv(lua_State *L)
{
lua_Debug ar;
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
luaL_error(L, LUA_QL("module") " not called from a Lua function");
lua_pushvalue(L, -2);
lua_setfenv(L, -2);
lua_pop(L, 1);
}
static void dooptions(lua_State *L, int n)
{
int i;
for (i = 2; i <= n; i++) {
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}
static void modinit(lua_State *L, const char *modname)
{
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME");
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname; else dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, (size_t)(dot - modname));
lua_setfield(L, -2, "_PACKAGE");
}
static int lj_cf_package_module(lua_State *L)
{
const char *modname = luaL_checkstring(L, 1);
int lastarg = (int)(L->top - L->base);
luaL_pushmodule(L, modname, 1);
lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) { /* Module already initialized? */
lua_pop(L, 1);
} else {
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
setfenv(L);
dooptions(L, lastarg);
return LJ_52;
}
static int lj_cf_package_seeall(lua_State *L)
{
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
/* ------------------------------------------------------------------------ */
#define AUXMARK "\1"
static void setpath(lua_State *L, const char *fieldname, const char *envname,
const char *def, int noenv)
{
#if LJ_TARGET_CONSOLE
const char *path = NULL;
UNUSED(envname);
#else
const char *path = getenv(envname);
#endif
if (path == NULL || noenv) {
lua_pushstring(L, def);
} else {
path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
LUA_PATHSEP AUXMARK LUA_PATHSEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg package_lib[] = {
{ "loadlib", lj_cf_package_loadlib },
{ "searchpath", lj_cf_package_searchpath },
{ "seeall", lj_cf_package_seeall },
{ NULL, NULL }
};
static const luaL_Reg package_global[] = {
{ "module", lj_cf_package_module },
{ "require", lj_cf_package_require },
{ NULL, NULL }
};
static const lua_CFunction package_loaders[] =
{
lj_cf_package_loader_preload,
lj_cf_package_loader_lua,
lj_cf_package_loader_c,
lj_cf_package_loader_croot,
NULL
};
LUALIB_API int luaopen_package(lua_State *L)
{
int i;
int noenv;
luaL_newmetatable(L, "_LOADLIB");
lj_lib_pushcf(L, lj_cf_package_unloadlib, 1);
lua_setfield(L, -2, "__gc");
luaL_register(L, LUA_LOADLIBNAME, package_lib);
lua_copy(L, -1, LUA_ENVIRONINDEX);
lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0);
for (i = 0; package_loaders[i] != NULL; i++) {
lj_lib_pushcf(L, package_loaders[i], 1);
lua_rawseti(L, -2, i+1);
}
#if LJ_52
lua_pushvalue(L, -1);
lua_setfield(L, -3, "searchers");
#endif
lua_setfield(L, -2, "loaders");
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
noenv = lua_toboolean(L, -1);
lua_pop(L, 1);
setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT, noenv);
setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT, noenv);
lua_pushliteral(L, LUA_PATH_CONFIG);
lua_setfield(L, -2, "config");
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
lua_setfield(L, -2, "loaded");
luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD", 4);
lua_setfield(L, -2, "preload");
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_register(L, NULL, package_global);
lua_pop(L, 1);
return 1;
}
+696
View File
@@ -0,0 +1,696 @@
/*
** String library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_string_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_str.h"
#include "lj_tab.h"
#include "lj_meta.h"
#include "lj_state.h"
#include "lj_ff.h"
#include "lj_bcdump.h"
#include "lj_char.h"
#include "lj_strfmt.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_string
LJLIB_LUA(string_len) /*
function(s)
CHECK_str(s)
return #s
end
*/
LJLIB_ASM(string_byte) LJLIB_REC(string_range 0)
{
GCstr *s = lj_lib_checkstr(L, 1);
int32_t len = (int32_t)s->len;
int32_t start = lj_lib_optint(L, 2, 1);
int32_t stop = lj_lib_optint(L, 3, start);
int32_t n, i;
const unsigned char *p;
if (stop < 0) stop += len+1;
if (start < 0) start += len+1;
if (start <= 0) start = 1;
if (stop > len) stop = len;
if (start > stop) return FFH_RES(0); /* Empty interval: return no results. */
start--;
n = stop - start;
if ((uint32_t)n > LUAI_MAXCSTACK)
lj_err_caller(L, LJ_ERR_STRSLC);
lj_state_checkstack(L, (MSize)n);
p = (const unsigned char *)strdata(s) + start;
for (i = 0; i < n; i++)
setintV(L->base + i-1-LJ_FR2, p[i]);
return FFH_RES(n);
}
LJLIB_ASM(string_char) LJLIB_REC(.)
{
int i, nargs = (int)(L->top - L->base);
char *buf = lj_buf_tmp(L, (MSize)nargs);
for (i = 1; i <= nargs; i++) {
int32_t k = lj_lib_checkint(L, i);
if (!checku8(k))
lj_err_arg(L, i, LJ_ERR_BADVAL);
buf[i-1] = (char)k;
}
setstrV(L, L->base-1-LJ_FR2, lj_str_new(L, buf, (size_t)nargs));
return FFH_RES(1);
}
LJLIB_ASM(string_sub) LJLIB_REC(string_range 1)
{
lj_lib_checkstr(L, 1);
lj_lib_checkint(L, 2);
setintV(L->base+2, lj_lib_optint(L, 3, -1));
return FFH_RETRY;
}
LJLIB_CF(string_rep) LJLIB_REC(.)
{
GCstr *s = lj_lib_checkstr(L, 1);
int32_t rep = lj_lib_checkint(L, 2);
GCstr *sep = lj_lib_optstr(L, 3);
SBuf *sb = lj_buf_tmp_(L);
if (sep && rep > 1) {
GCstr *s2 = lj_buf_cat2str(L, sep, s);
lj_buf_reset(sb);
lj_buf_putstr(sb, s);
s = s2;
rep--;
}
sb = lj_buf_putstr_rep(sb, s, rep);
setstrV(L, L->top-1, lj_buf_str(L, sb));
lj_gc_check(L);
return 1;
}
LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse)
{
lj_lib_checkstr(L, 1);
return FFH_RETRY;
}
LJLIB_ASM_(string_lower) LJLIB_REC(string_op IRCALL_lj_buf_putstr_lower)
LJLIB_ASM_(string_upper) LJLIB_REC(string_op IRCALL_lj_buf_putstr_upper)
/* ------------------------------------------------------------------------ */
#if !LJ_SRB2LIB
static int writer_buf(lua_State *L, const void *p, size_t size, void *sb)
{
lj_buf_putmem((SBuf *)sb, p, (MSize)size);
UNUSED(L);
return 0;
}
LJLIB_CF(string_dump)
{
GCproto *pt = lj_lib_checkLproto(L, 1, 1);
uint32_t flags = 0;
SBuf *sb;
TValue *o = L->base+1;
if (o < L->top) {
if (tvisstr(o)) {
const char *mode = strVdata(o);
char c;
while ((c = *mode++)) {
if (c == 's') flags |= BCDUMP_F_STRIP;
if (c == 'd') flags |= BCDUMP_F_DETERMINISTIC;
}
} else if (tvistruecond(o)) {
flags |= BCDUMP_F_STRIP;
}
}
sb = lj_buf_tmp_(L); /* Assumes lj_bcwrite() doesn't use tmpbuf. */
L->top = L->base+1;
if (!pt || lj_bcwrite(L, pt, writer_buf, sb, flags))
lj_err_caller(L, LJ_ERR_STRDUMP);
setstrV(L, L->top-1, lj_buf_str(L, sb));
lj_gc_check(L);
return 1;
}
#endif
/* ------------------------------------------------------------------------ */
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
#define CAP_UNFINISHED (-1)
#define CAP_POSITION (-2)
typedef struct MatchState {
const char *src_init; /* init of source string */
const char *src_end; /* end (`\0') of source string */
lua_State *L;
int level; /* total number of captures (finished or unfinished) */
int depth;
struct {
const char *init;
ptrdiff_t len;
} capture[LUA_MAXCAPTURES];
} MatchState;
#define L_ESC '%'
static int check_capture(MatchState *ms, int l)
{
l -= '1';
if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
lj_err_caller(ms->L, LJ_ERR_STRCAPI);
return l;
}
static int capture_to_close(MatchState *ms)
{
int level = ms->level;
for (level--; level>=0; level--)
if (ms->capture[level].len == CAP_UNFINISHED) return level;
lj_err_caller(ms->L, LJ_ERR_STRPATC);
return 0; /* unreachable */
}
static const char *classend(MatchState *ms, const char *p)
{
switch (*p++) {
case L_ESC:
if (*p == '\0')
lj_err_caller(ms->L, LJ_ERR_STRPATE);
return p+1;
case '[':
if (*p == '^') p++;
do { /* look for a `]' */
if (*p == '\0')
lj_err_caller(ms->L, LJ_ERR_STRPATM);
if (*(p++) == L_ESC && *p != '\0')
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
return p+1;
default:
return p;
}
}
static const unsigned char match_class_map[32] = {
0,LJ_CHAR_ALPHA,0,LJ_CHAR_CNTRL,LJ_CHAR_DIGIT,0,0,LJ_CHAR_GRAPH,0,0,0,0,
LJ_CHAR_LOWER,0,0,0,LJ_CHAR_PUNCT,0,0,LJ_CHAR_SPACE,0,
LJ_CHAR_UPPER,0,LJ_CHAR_ALNUM,LJ_CHAR_XDIGIT,0,0,0,0,0,0,0
};
static int match_class(int c, int cl)
{
if ((cl & 0xc0) == 0x40) {
int t = match_class_map[(cl&0x1f)];
if (t) {
t = lj_char_isa(c, t);
return (cl & 0x20) ? t : !t;
}
if (cl == 'z') return c == 0;
if (cl == 'Z') return c != 0;
}
return (cl == c);
}
static int matchbracketclass(int c, const char *p, const char *ec)
{
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the `^' */
}
while (++p < ec) {
if (*p == L_ESC) {
p++;
if (match_class(c, uchar(*p)))
return sig;
}
else if ((*(p+1) == '-') && (p+2 < ec)) {
p+=2;
if (uchar(*(p-2)) <= c && c <= uchar(*p))
return sig;
}
else if (uchar(*p) == c) return sig;
}
return !sig;
}
static int singlematch(int c, const char *p, const char *ep)
{
switch (*p) {
case '.': return 1; /* matches any char */
case L_ESC: return match_class(c, uchar(*(p+1)));
case '[': return matchbracketclass(c, p, ep-1);
default: return (uchar(*p) == c);
}
}
static const char *match(MatchState *ms, const char *s, const char *p);
static const char *matchbalance(MatchState *ms, const char *s, const char *p)
{
if (*p == 0 || *(p+1) == 0)
lj_err_caller(ms->L, LJ_ERR_STRPATU);
if (*s != *p) {
return NULL;
} else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s < ms->src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
} else if (*s == b) {
cont++;
}
}
}
return NULL; /* string ends out of balance */
}
static const char *max_expand(MatchState *ms, const char *s,
const char *p, const char *ep)
{
ptrdiff_t i = 0; /* counts maximum expand for item */
while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i>=0) {
const char *res = match(ms, (s+i), ep+1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return NULL;
}
static const char *min_expand(MatchState *ms, const char *s,
const char *p, const char *ep)
{
for (;;) {
const char *res = match(ms, s, ep+1);
if (res != NULL)
return res;
else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
s++; /* try with one more repetition */
else
return NULL;
}
}
static const char *start_capture(MatchState *ms, const char *s,
const char *p, int what)
{
const char *res;
int level = ms->level;
if (level >= LUA_MAXCAPTURES) lj_err_caller(ms->L, LJ_ERR_STRCAPN);
ms->capture[level].init = s;
ms->capture[level].len = what;
ms->level = level+1;
if ((res=match(ms, s, p)) == NULL) /* match failed? */
ms->level--; /* undo capture */
return res;
}
static const char *end_capture(MatchState *ms, const char *s,
const char *p)
{
int l = capture_to_close(ms);
const char *res;
ms->capture[l].len = s - ms->capture[l].init; /* close capture */
if ((res = match(ms, s, p)) == NULL) /* match failed? */
ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
}
static const char *match_capture(MatchState *ms, const char *s, int l)
{
size_t len;
l = check_capture(ms, l);
len = (size_t)ms->capture[l].len;
if ((size_t)(ms->src_end-s) >= len &&
memcmp(ms->capture[l].init, s, len) == 0)
return s+len;
else
return NULL;
}
static const char *match(MatchState *ms, const char *s, const char *p)
{
if (++ms->depth > LJ_MAX_XLEVEL)
lj_err_caller(ms->L, LJ_ERR_STRPATX);
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': /* start capture */
if (*(p+1) == ')') /* position capture? */
s = start_capture(ms, s, p+2, CAP_POSITION);
else
s = start_capture(ms, s, p+1, CAP_UNFINISHED);
break;
case ')': /* end capture */
s = end_capture(ms, s, p+1);
break;
case L_ESC:
switch (*(p+1)) {
case 'b': /* balanced string? */
s = matchbalance(ms, s, p+2);
if (s == NULL) break;
p+=4;
goto init; /* else s = match(ms, s, p+4); */
case 'f': { /* frontier? */
const char *ep; char previous;
p += 2;
if (*p != '[')
lj_err_caller(ms->L, LJ_ERR_STRPATB);
ep = classend(ms, p); /* points to what is next */
previous = (s == ms->src_init) ? '\0' : *(s-1);
if (matchbracketclass(uchar(previous), p, ep-1) ||
!matchbracketclass(uchar(*s), p, ep-1)) { s = NULL; break; }
p=ep;
goto init; /* else s = match(ms, s, ep); */
}
default:
if (lj_char_isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
s = match_capture(ms, s, uchar(*(p+1)));
if (s == NULL) break;
p+=2;
goto init; /* else s = match(ms, s, p+2) */
}
goto dflt; /* case default */
}
break;
case '\0': /* end of pattern */
break; /* match succeeded */
case '$':
/* is the `$' the last char in pattern? */
if (*(p+1) != '\0') goto dflt;
if (s != ms->src_end) s = NULL; /* check end of string */
break;
default: dflt: { /* it is a pattern item */
const char *ep = classend(ms, p); /* points to what is next */
int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
switch (*ep) {
case '?': { /* optional */
const char *res;
if (m && ((res=match(ms, s+1, ep+1)) != NULL)) {
s = res;
break;
}
p=ep+1;
goto init; /* else s = match(ms, s, ep+1); */
}
case '*': /* 0 or more repetitions */
s = max_expand(ms, s, p, ep);
break;
case '+': /* 1 or more repetitions */
s = (m ? max_expand(ms, s+1, p, ep) : NULL);
break;
case '-': /* 0 or more repetitions (minimum) */
s = min_expand(ms, s, p, ep);
break;
default:
if (m) { s++; p=ep; goto init; } /* else s = match(ms, s+1, ep); */
s = NULL;
break;
}
break;
}
}
ms->depth--;
return s;
}
static void push_onecapture(MatchState *ms, int i, const char *s, const char *e)
{
if (i >= ms->level) {
if (i == 0) /* ms->level == 0, too */
lua_pushlstring(ms->L, s, (size_t)(e - s)); /* add whole match */
else
lj_err_caller(ms->L, LJ_ERR_STRCAPI);
} else {
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) lj_err_caller(ms->L, LJ_ERR_STRCAPU);
if (l == CAP_POSITION)
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
else
lua_pushlstring(ms->L, ms->capture[i].init, (size_t)l);
}
}
static int push_captures(MatchState *ms, const char *s, const char *e)
{
int i;
int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
luaL_checkstack(ms->L, nlevels, "too many captures");
for (i = 0; i < nlevels; i++)
push_onecapture(ms, i, s, e);
return nlevels; /* number of strings pushed */
}
static int str_find_aux(lua_State *L, int find)
{
GCstr *s = lj_lib_checkstr(L, 1);
GCstr *p = lj_lib_checkstr(L, 2);
int32_t start = lj_lib_optint(L, 3, 1);
MSize st;
if (start < 0) start += (int32_t)s->len; else start--;
if (start < 0) start = 0;
st = (MSize)start;
if (st > s->len) {
#if LJ_52
setnilV(L->top-1);
return 1;
#else
st = s->len;
#endif
}
if (find && ((L->base+3 < L->top && tvistruecond(L->base+3)) ||
!lj_str_haspattern(p))) { /* Search for fixed string. */
const char *q = lj_str_find(strdata(s)+st, strdata(p), s->len-st, p->len);
if (q) {
setintV(L->top-2, (int32_t)(q-strdata(s)) + 1);
setintV(L->top-1, (int32_t)(q-strdata(s)) + (int32_t)p->len);
return 2;
}
} else { /* Search for pattern. */
MatchState ms;
const char *pstr = strdata(p);
const char *sstr = strdata(s) + st;
int anchor = 0;
if (*pstr == '^') { pstr++; anchor = 1; }
ms.L = L;
ms.src_init = strdata(s);
ms.src_end = strdata(s) + s->len;
do { /* Loop through string and try to match the pattern. */
const char *q;
ms.level = ms.depth = 0;
q = match(&ms, sstr, pstr);
if (q) {
if (find) {
setintV(L->top++, (int32_t)(sstr-(strdata(s)-1)));
setintV(L->top++, (int32_t)(q-strdata(s)));
return push_captures(&ms, NULL, NULL) + 2;
} else {
return push_captures(&ms, sstr, q);
}
}
} while (sstr++ < ms.src_end && !anchor);
}
setnilV(L->top-1); /* Not found. */
return 1;
}
LJLIB_CF(string_find) LJLIB_REC(.)
{
return str_find_aux(L, 1);
}
LJLIB_CF(string_match)
{
return str_find_aux(L, 0);
}
LJLIB_NOREG LJLIB_CF(string_gmatch_aux)
{
const char *p = strVdata(lj_lib_upvalue(L, 2));
GCstr *str = strV(lj_lib_upvalue(L, 1));
const char *s = strdata(str);
TValue *tvpos = lj_lib_upvalue(L, 3);
const char *src = s + tvpos->u32.lo;
MatchState ms;
ms.L = L;
ms.src_init = s;
ms.src_end = s + str->len;
for (; src <= ms.src_end; src++) {
const char *e;
ms.level = ms.depth = 0;
if ((e = match(&ms, src, p)) != NULL) {
int32_t pos = (int32_t)(e - s);
if (e == src) pos++; /* Ensure progress for empty match. */
tvpos->u32.lo = (uint32_t)pos;
return push_captures(&ms, src, e);
}
}
return 0; /* not found */
}
LJLIB_CF(string_gmatch)
{
lj_lib_checkstr(L, 1);
lj_lib_checkstr(L, 2);
L->top = L->base+3;
(L->top-1)->u64 = 0;
lj_lib_pushcc(L, lj_cf_string_gmatch_aux, FF_string_gmatch_aux, 3);
return 1;
}
static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
{
size_t l, i;
const char *news = lua_tolstring(ms->L, 3, &l);
for (i = 0; i < l; i++) {
if (news[i] != L_ESC) {
luaL_addchar(b, news[i]);
} else {
i++; /* skip ESC */
if (!lj_char_isdigit(uchar(news[i]))) {
luaL_addchar(b, news[i]);
} else if (news[i] == '0') {
luaL_addlstring(b, s, (size_t)(e - s));
} else {
push_onecapture(ms, news[i] - '1', s, e);
luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
}
static void add_value(MatchState *ms, luaL_Buffer *b,
const char *s, const char *e)
{
lua_State *L = ms->L;
switch (lua_type(L, 3)) {
case LUA_TNUMBER:
case LUA_TSTRING: {
add_s(ms, b, s, e);
return;
}
case LUA_TFUNCTION: {
int n;
lua_pushvalue(L, 3);
n = push_captures(ms, s, e);
lua_call(L, n, 1);
break;
}
case LUA_TTABLE: {
push_onecapture(ms, 0, s, e);
lua_gettable(L, 3);
break;
}
}
if (!lua_toboolean(L, -1)) { /* nil or false? */
lua_pop(L, 1);
lua_pushlstring(L, s, (size_t)(e - s)); /* keep original text */
} else if (!lua_isstring(L, -1)) {
lj_err_callerv(L, LJ_ERR_STRGSRV, luaL_typename(L, -1));
}
luaL_addvalue(b); /* add result to accumulator */
}
LJLIB_CF(string_gsub)
{
size_t srcl;
const char *src = luaL_checklstring(L, 1, &srcl);
const char *p = luaL_checkstring(L, 2);
int tr = lua_type(L, 3);
int max_s = luaL_optint(L, 4, (int)(srcl+1));
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
MatchState ms;
luaL_Buffer b;
if (!(tr == LUA_TNUMBER || tr == LUA_TSTRING ||
tr == LUA_TFUNCTION || tr == LUA_TTABLE))
lj_err_arg(L, 3, LJ_ERR_NOSFT);
luaL_buffinit(L, &b);
ms.L = L;
ms.src_init = src;
ms.src_end = src+srcl;
while (n < max_s) {
const char *e;
ms.level = ms.depth = 0;
e = match(&ms, src, p);
if (e) {
n++;
add_value(&ms, &b, src, e);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
else if (src < ms.src_end)
luaL_addchar(&b, *src++);
else
break;
if (anchor)
break;
}
luaL_addlstring(&b, src, (size_t)(ms.src_end-src));
luaL_pushresult(&b);
lua_pushinteger(L, n); /* number of substitutions */
return 2;
}
/* ------------------------------------------------------------------------ */
LJLIB_CF(string_format) LJLIB_REC(.)
{
int retry = 0;
SBuf *sb;
do {
sb = lj_buf_tmp_(L);
retry = lj_strfmt_putarg(L, sb, 1, -retry);
} while (retry > 0);
setstrV(L, L->top-1, lj_buf_str(L, sb));
lj_gc_check(L);
return 1;
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_string(lua_State *L)
{
GCtab *mt;
global_State *g;
LJ_LIB_REG(L, LUA_STRLIBNAME, string);
mt = lj_tab_new(L, 0, 1);
/* NOBARRIER: basemt is a GC root. */
g = G(L);
setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt));
settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1));
mt->nomm = (uint8_t)(~(1u<<MM_index));
#if LJ_HASBUFFER
lj_lib_prereg(L, LUA_STRLIBNAME ".buffer", luaopen_string_buffer, tabV(L->top-1));
#endif
#if LJ_SRB2LIB
lua_getfield(L, -1, "gmatch");
lua_setfield(L, -2, "gfind"); /* Ugh, can we get rid of this already? */
#endif
return 1;
}
+331
View File
@@ -0,0 +1,331 @@
/*
** Table library.
** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
**
** Major portions taken verbatim or adapted from the Lua interpreter.
** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
*/
#define lib_table_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lj_obj.h"
#include "lj_gc.h"
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_tab.h"
#include "lj_ff.h"
#include "lj_lib.h"
/* ------------------------------------------------------------------------ */
#define LJLIB_MODULE_table
LJLIB_LUA(table_foreachi) /*
function(t, f)
CHECK_tab(t)
CHECK_func(f)
for i=1,#t do
local r = f(i, t[i])
if r ~= nil then return r end
end
end
*/
LJLIB_LUA(table_foreach) /*
function(t, f)
CHECK_tab(t)
CHECK_func(f)
for k, v in PAIRS(t) do
local r = f(k, v)
if r ~= nil then return r end
end
end
*/
LJLIB_LUA(table_getn) /*
function(t)
CHECK_tab(t)
return #t
end
*/
LJLIB_CF(table_maxn)
{
GCtab *t = lj_lib_checktab(L, 1);
TValue *array = tvref(t->array);
Node *node;
lua_Number m = 0;
ptrdiff_t i;
for (i = (ptrdiff_t)t->asize - 1; i >= 0; i--)
if (!tvisnil(&array[i])) {
m = (lua_Number)(int32_t)i;
break;
}
node = noderef(t->node);
for (i = (ptrdiff_t)t->hmask; i >= 0; i--)
if (!tvisnil(&node[i].val) && tvisnumber(&node[i].key)) {
lua_Number n = numberVnum(&node[i].key);
if (n > m) m = n;
}
#if LJ_INTONLY
setintV(L->top-1, lj_num2int(m));
#else
setnumV(L->top-1, m);
#endif
return 1;
}
LJLIB_CF(table_insert) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n, i = (int32_t)lj_tab_len(t) + 1;
int nargs = (int)((char *)L->top - (char *)L->base);
if (nargs != 2*sizeof(TValue)) {
if (nargs != 3*sizeof(TValue))
lj_err_caller(L, LJ_ERR_TABINS);
/* NOBARRIER: This just moves existing elements around. */
for (n = lj_lib_checkint(L, 2); i > n; i--) {
/* The set may invalidate the get pointer, so need to do it first! */
TValue *dst = lj_tab_setint(L, t, i);
cTValue *src = lj_tab_getint(t, i-1);
if (src) {
copyTV(L, dst, src);
} else {
setnilV(dst);
}
}
i = n;
}
{
TValue *dst = lj_tab_setint(L, t, i);
copyTV(L, dst, L->top-1); /* Set new value. */
lj_gc_barriert(L, t, dst);
}
return 0;
}
LJLIB_LUA(table_remove) /*
function(t, pos)
CHECK_tab(t)
local len = #t
if pos == nil then
if len ~= 0 then
local old = t[len]
t[len] = nil
return old
end
else
CHECK_int(pos)
if pos >= 1 and pos <= len then
local old = t[pos]
for i=pos+1,len do
t[i-1] = t[i]
end
t[len] = nil
return old
end
end
end
*/
LJLIB_LUA(table_move) /*
function(a1, f, e, t, a2)
CHECK_tab(a1)
CHECK_int(f)
CHECK_int(e)
CHECK_int(t)
if a2 == nil then a2 = a1 end
CHECK_tab(a2)
if e >= f then
local d = t - f
if t > e or t <= f or a2 ~= a1 then
for i=f,e do a2[i+d] = a1[i] end
else
for i=e,f,-1 do a2[i+d] = a1[i] end
end
end
return a2
end
*/
LJLIB_CF(table_concat) LJLIB_REC(.)
{
GCtab *t = lj_lib_checktab(L, 1);
GCstr *sep = lj_lib_optstr(L, 2);
int32_t i = lj_lib_optint(L, 3, 1);
int32_t e = (L->base+3 < L->top && !tvisnil(L->base+3)) ?
lj_lib_checkint(L, 4) : (int32_t)lj_tab_len(t);
SBuf *sb = lj_buf_tmp_(L);
SBuf *sbx = lj_buf_puttab(sb, t, sep, i, e);
if (LJ_UNLIKELY(!sbx)) { /* Error: bad element type. */
int32_t idx = (int32_t)(intptr_t)sb->w;
cTValue *o = lj_tab_getint(t, idx);
lj_err_callerv(L, LJ_ERR_TABCAT,
lj_obj_itypename[o ? itypemap(o) : ~LJ_TNIL], idx);
}
setstrV(L, L->top-1, lj_buf_str(L, sbx));
lj_gc_check(L);
return 1;
}
/* ------------------------------------------------------------------------ */
static void set2(lua_State *L, int i, int j)
{
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}
static int sort_comp(lua_State *L, int a, int b)
{
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_call(L, 2, 1);
res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
} else { /* a < b? */
return lua_lessthan(L, a, b);
}
}
static void auxsort(lua_State *L, int l, int u)
{
while (l < u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) { /* a[i]<a[l]? */
set2(L, i, l);
} else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u]<a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i>=u) lj_err_caller(L, LJ_ERR_TABSORT);
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j<=l) lj_err_caller(L, LJ_ERR_TABSORT);
lua_pop(L, 1); /* remove a[j] */
}
if (j<i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] <= a[i] == P <= a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l < u-i) {
j=l; i=i-1; l=i+2;
} else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}
LJLIB_CF(table_sort)
{
GCtab *t = lj_lib_checktab(L, 1);
int32_t n = (int32_t)lj_tab_len(t);
lua_settop(L, 2);
if (!tvisnil(L->base+1))
lj_lib_checkfunc(L, 2);
auxsort(L, 1, n);
return 0;
}
#if LJ_52
LJLIB_PUSH("n")
LJLIB_CF(table_pack)
{
TValue *array, *base = L->base;
MSize i, n = (uint32_t)(L->top - base);
GCtab *t = lj_tab_new(L, n ? n+1 : 0, 1);
/* NOBARRIER: The table is new (marked white). */
setintV(lj_tab_setstr(L, t, strV(lj_lib_upvalue(L, 1))), (int32_t)n);
for (array = tvref(t->array) + 1, i = 0; i < n; i++)
copyTV(L, &array[i], &base[i]);
settabV(L, base, t);
L->top = base+1;
lj_gc_check(L);
return 1;
}
#endif
LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.)
{
int32_t a = lj_lib_checkint(L, 1);
int32_t h = lj_lib_checkint(L, 2);
lua_createtable(L, a, h);
return 1;
}
LJLIB_NOREG LJLIB_CF(table_clear) LJLIB_REC(.)
{
lj_tab_clear(lj_lib_checktab(L, 1));
return 0;
}
static int luaopen_table_new(lua_State *L)
{
return lj_lib_postreg(L, lj_cf_table_new, FF_table_new, "new");
}
static int luaopen_table_clear(lua_State *L)
{
return lj_lib_postreg(L, lj_cf_table_clear, FF_table_clear, "clear");
}
/* ------------------------------------------------------------------------ */
#include "lj_libdef.h"
LUALIB_API int luaopen_table(lua_State *L)
{
LJ_LIB_REG(L, LUA_TABLIBNAME, table);
#if LJ_52
lua_getglobal(L, "unpack");
lua_setfield(L, -2, "unpack");
#endif
lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1));
lj_lib_prereg(L, LUA_TABLIBNAME ".clear", luaopen_table_clear, tabV(L->top-1));
return 1;
}
File diff suppressed because it is too large. Load diff
+18
View File
@@ -0,0 +1,18 @@
/*
** Bundled memory allocator.
** Donated to the public domain.
*/
#ifndef _LJ_ALLOC_H
#define _LJ_ALLOC_H
#include "lj_def.h"
#ifndef LUAJIT_USE_SYSMALLOC
LJ_FUNC void *lj_alloc_create(PRNGState *rs);
LJ_FUNC void lj_alloc_setprng(void *msp, PRNGState *rs);
LJ_FUNC void lj_alloc_destroy(void *msp);
LJ_FUNC void *lj_alloc_f(void *msp, void *ptr, size_t osize, size_t nsize);
#endif
#endif
Loaded 100 of 421 files, more files were not shown because too many files have changed in this diff. Show more