Compare commits

...
580 Commits
Author SHA1 Message Date
Twinaphex cf97f39cac Update .travis.yml 2019-12-25 21:26:17 +01:00
Twinaphex b6a45645d8 Update AndroidManifest.xml 2019-12-25 09:33:43 +01:00
Twinaphex 3d3c848ba7 Update AndroidManifest.xml 2019-12-25 09:33:27 +01:00
twinaphex c98dc7ef34 Update CHANGES.md 2019-12-25 09:15:46 +01:00
twinaphex 586f54a0f7 Fix C89_BUILD 2019-12-25 09:08:50 +01:00
twinaphex 75f3a79aa6 (MaterialUI) Add icons 2019-12-25 08:49:52 +01:00
Twinaphex 27c3c1f684 Update CHANGES.md 2019-12-25 08:37:01 +01:00
Twinaphex 5ee803682f Update CHANGES.md 2019-12-25 08:36:46 +01:00
Twinaphex e52daa8602 - use MIN macro instead of min for portability
- remove unused variable
2019-12-25 08:31:18 +01:00
twinaphex 65cddce865 (OSX/iOS) Forcibly disable Threaded Video until UIWindow/NSWindow
concurrency issues are fixed
2019-12-25 08:28:43 +01:00
twinaphex 973ae36fe5 (MaterialUI) Add missing icons 2019-12-25 08:24:08 +01:00
Twinaphex 7b1819e988 Update CHANGES.md 2019-12-25 07:43:45 +01:00
twinaphex 538f0c534f Backport Added alternate Turbo-Mode 'Single Button' -
For systems supporting only a single button, the turbo-button will toggle firing that button without the need to hold it.
When holding the button turbo will be suspended and resumed when the button is released. Holding the button may have a different function to just tapping it, e.g. charging the beam in R-Type on C64/Amiga.
The original implementation in RA is named 'Classic' because I have no
idea where it originates from.
2019-12-25 07:13:01 +01:00
twinaphex 921e470b05 Bump up to 1.8.2 2019-12-25 07:00:45 +01:00
Twinaphex ea4e5ab9ef Merge pull request #9889 from fpscan/turkish
Turkish language updates
2019-12-24 23:25:04 +01:00
Ömercan Kömür 96d0de4e7c Update msg_hash_tr.h
update for 1.8.2
2019-12-25 00:44:45 +03:00
Ömercan Kömür 04bd684258 Merge pull request #2 from libretro/master
updates
2019-12-25 00:27:33 +03:00
twinaphex 58852ec9bb (Menu) Selectively hide 'Disallow Non-Slave Mode Clients' if 'Allow SLave-Mode
Clients' is disabled
2019-12-24 17:38:07 +01:00
twinaphex e4fcce118c (Menu) Hide 'Show desktop menu on startup' if 'Desktop menu' setting
itself is disabled
2019-12-24 17:24:48 +01:00
twinaphex ef149605cd (Menu) Reimplement Quick Menu - > Shaders -> Watch shader files for
changes - can now be turned on/off through touch
2019-12-24 17:19:23 +01:00
Twinaphex c240449b10 Merge pull request #9888 from hasenbanck/ass-fix
Fix ASS rendering assertion on seeking.
2019-12-24 16:56:32 +01:00
twinaphex 8d63faa74d C89_BUILD fix 2019-12-24 16:53:13 +01:00
Nils Hasenbanck 226f2d52ff Fix ASS rendering assertion on seeking.
ASS needs some locking.
2019-12-24 12:16:52 +01:00
twinaphex 1165f8dfe9 (Menu) Remove duplicates 2019-12-24 08:29:06 +01:00
twinaphex 4e34611d1d (Menu) Add title for Remap Binds Port 2019-12-24 08:10:20 +01:00
twinaphex 0df043aff1 (Menu) Refactor Quick Menu - Controls - each port now has its own
submenu
2019-12-24 07:36:01 +01:00
twinaphex 9573b53390 Put ifdefs around core_updater_list_free_cached for targets
that don't define HAVE_NETWORKING
2019-12-24 05:36:54 +01:00
twinaphex ca0edad8c2 (Menu) don't hide logging settings anymore 2019-12-24 05:29:15 +01:00
twinaphex f47b07e35a (Menu) Quick Menu - Cheats - Delete All no longer requires five
right button presses - this should fix this functionality for mobile
touch users too
2019-12-24 05:13:24 +01:00
Twinaphex 45db2122c9 Merge pull request #9887 from WeedyWeedSmoker/French-update
French update - core updater newest additions!
2019-12-24 04:58:38 +01:00
twinaphex d33624c623 (Menu) Hide Refresh Rate options when Threaded Video is enabled -
these settings do nothing with Threaded Video
2019-12-24 04:29:12 +01:00
twinaphex abb1b28e96 Hide Logging Verbosity levels behind Logging Verbosity 2019-12-24 04:18:38 +01:00
twinaphex a19da4bf22 (Menu) No longer hide Logging behind Advanced 2019-12-24 04:09:34 +01:00
Weedy Weed Smoker 347cb15722 French update - core updater newest additions! 2019-12-24 09:53:57 +07:00
twinaphex 20f3b8d404 Buildfix for non-shader targets 2019-12-24 03:15:51 +01:00
twinaphex 31a7f2b4d9 Add missing ifdef 2019-12-24 02:17:48 +01:00
twinaphex e5a6517897 (MSVC UWP) Generate new pfx key 2019-12-23 23:04:56 +01:00
twinaphex 80f3f99845 Merge branch 'master' of https://github.com/libretro/RetroArch 2019-12-23 20:18:35 +01:00
Twinaphex 4322d0c3fe Merge pull request #9885 from jdgleaver/core-update
(Core Updater) Only download when new core is available + add option to update all installed cores
2019-12-23 20:02:43 +01:00
twinaphex 764f1d846e Merge branch 'master' of https://github.com/libretro/RetroArch 2019-12-23 19:58:42 +01:00
Twinaphex 1d0be580c5 (Menu) Remove unused variables 2019-12-23 19:43:09 +01:00
twinaphex 44f2986665 Merge branch 'master' of https://github.com/libretro/RetroArch 2019-12-23 19:19:26 +01:00
Twinaphex 9d6490e38a Merge pull request #9881 from hasenbanck/no-video-fifo
Remove video fifo in ffmpeg core.
2019-12-23 19:18:59 +01:00
twinaphex 7aa914fde7 Merge branch 'no-video-fifo' of git://github.com/hasenbanck/RetroArch 2019-12-23 19:04:54 +01:00
Twinaphex 0930cd29fb Merge pull request #9884 from WeedyWeedSmoker/French-update
French translation - Latest additions!
2019-12-23 18:56:12 +01:00
jdgleaver 695749f155 (Core Updater) Only download when new core is available + add option to update all installed cores 2019-12-23 17:34:44 +00:00
Weedy Weed Smoker 3ca8623b29 French translation - Latest additions! 2019-12-23 22:41:49 +07:00
Nils Hasenbanck c6309d963d Remove video fifo in ffmpeg core.
The video fifo can be removed, since we have a ring buffer in it's
place. This removes unneeded copy operations and as a positive side
improves overall decoding speed.

Makes 8k60p SW and 4k60p HW decoding possible on my system.

For now the ring buffer is 32 images deep. This limitation will
be removed, once audio and video decoder have their own
packet handling.
2019-12-23 16:07:34 +01:00
twinaphex 305aee2c33 (Menu) Get rid of 'Port Number' label for Port Binds screen 2019-12-23 08:21:44 +01:00
twinaphex cbcdfa572a (Mobile) Should no longer crash when clicking on a cheat entry 2019-12-23 07:49:29 +01:00
twinaphex 2512365012 (Menu) Displaylist - Get rid of global 2019-12-23 06:34:58 +01:00
twinaphex 9988bae6f4 (Shader) Implement shader parameter action OK callbacks 2019-12-23 05:39:10 +01:00
twinaphex 18f2b9c63e Reimplement shader preset parameter functions 2019-12-22 22:45:08 +01:00
twinaphex b5cc71720c (Menu) Move FORCE_SRGB_DISABLE to Video Output 2019-12-22 22:10:45 +01:00
twinaphex 6eed40f80c More warning fixes for non-shader target platforms 2019-12-22 08:18:00 +01:00
twinaphex e93d90bc45 Fix build on platforms that don't have shader support 2019-12-22 08:12:42 +01:00
twinaphex d057d2a202 (Menu) Implement action OK callback for Quick Menu -> Shaders -> Passes 2019-12-22 07:14:20 +01:00
twinaphex cb67ace703 (Menu) Hide Windowed Mode settings selectively 2019-12-22 06:26:42 +01:00
twinaphex 759724facb (Menu) Hide Fullscreen Mode settings if windowed mode is not supported
by context driver
2019-12-22 06:22:05 +01:00
twinaphex 3033491f3d Turn HAVE_EASTEREGG into HAVE_GONG 2019-12-22 03:08:02 +01:00
twinaphex 751ff8f72c (Menu) Selectively hide Network Command Port 2019-12-21 21:08:37 +01:00
twinaphex d6d76a53b9 (Menu) Selectively hide Relay Server Location 2019-12-21 19:56:33 +01:00
twinaphex 3224eefdf1 (Menu) Selectively hide Video Layout 2019-12-21 18:39:34 +01:00
twinaphex 776ae626a6 (Menu) User Interface - selectively hide Kiosk Mode Password 2019-12-21 18:23:25 +01:00
twinaphex 8ad44acc5d (Menu) Action start callback - do a refresh at the end 2019-12-21 18:13:01 +01:00
twinaphex ecbbf1e3bb (Menu) Selectively hide Settings -> Accessibility 2019-12-21 17:59:56 +01:00
twinaphex 2d31377ba8 (Menu) User Interface -> Appearance - Selectively hide XMB Horizontal
Animation setting
2019-12-21 17:49:39 +01:00
twinaphex e55692d74f (Desktop Menu) Prevent hidden settings for desktop menu -
add third parameter that when set to true, will include everything
in the list - this way we can show greyed out settings
2019-12-21 17:33:50 +01:00
twinaphex 6164e33b07 (Menu) Settings -> Playlists - more selective hiding 2019-12-21 17:22:43 +01:00
twinaphex 4850cc0f97 (Menu) Aspect Ratio - implement dropdown box again 2019-12-21 16:54:42 +01:00
twinaphex 5674c46f38 (Menu) Don't hide Config Aspect Ratio for advanced 2019-12-21 16:44:47 +01:00
twinaphex a33280b08e (Menu) Implement touch/OK callbacks 2019-12-21 07:00:27 +01:00
twinaphex 48799b73d5 Standardize function signature for action_select 2019-12-21 06:01:38 +01:00
twinaphex 7c028596fb (Menu) Selectively hide Overlay Settings and Rewind 2019-12-21 05:35:46 +01:00
twinaphex d93200d2eb (Menu) Selectively hide 'Rewind' settings 2019-12-21 05:27:42 +01:00
twinaphex aafee65238 (Menu) Selectively hide 'FPS Update Interval' 2019-12-21 05:22:18 +01:00
twinaphex f5a7504c38 (Menu) Selectively hide Onscreen Notifications BG Color Settings 2019-12-21 05:10:22 +01:00
twinaphex ef4d24600e (Menu) Settings -> Logging - Hide 'Log To File Timestamp' if 'Log To File' is disabled 2019-12-21 04:49:30 +01:00
twinaphex 28ec64e200 (Menu) Video -> Scaling - Hide Custom Viewport X/Y when Integer
Scale is enabled as description indicates
2019-12-21 04:32:56 +01:00
twinaphex 1fcded67ef (Menu) Achievement submenu - selectively hide 2019-12-21 03:10:15 +01:00
twinaphex 3be60539ce (Menu) Aspect ratio - selectively hide/show values based on whether
you have Custom or Config selected
2019-12-21 01:27:28 +01:00
twinaphex 779c0a01d3 Selectively hide Hard Sync 2019-12-21 00:39:30 +01:00
twinaphex e1a5b80ae1 (Menu) Implement selective hiding for VSync and Hard Sync 2019-12-21 00:24:29 +01:00
twinaphex 021102c62d (Menu) Runahead global setting now hides the related options 2019-12-20 23:10:35 +01:00
twinaphex de1e66f7a9 (Menu) Add Input -> Haptic Feedback submenu 2019-12-20 20:49:30 +01:00
twinaphex 13793885f3 (Menu) Add Input -> Menu Controls settings submenu 2019-12-20 19:24:35 +01:00
twinaphex cdeef9dc95 (Menu) Implement action OK for Bind Hold, Turbo Period and Duty Cycle 2019-12-20 15:29:15 +01:00
twinaphex 55400e9b42 (Menu) Max Swapchain Images - implement action OK callback 2019-12-20 15:18:44 +01:00
twinaphex 110bc5abbe (Menu) Settings - Implement action OK callback for custom viewport width/height 2019-12-20 15:14:13 +01:00
twinaphex 21ffbc0cca (Menu) Netplay submenu - don't show 'No Settings found'
(Menu/Misc) Some more icons
2019-12-20 14:37:44 +01:00
twinaphex 559c6df0c3 (Desktop Menu) Cleanups 2019-12-20 14:19:11 +01:00
twinaphex b7b0348c3c (Desktop Menu) Input -> Hotkey Binds refactor 2019-12-20 14:17:16 +01:00
twinaphex 779b8b32cf Move 'Press Quit Twice' and 'Menu Toggle Gamepad Combo' to Input ->
Hotkey Binds
2019-12-20 13:56:31 +01:00
twinaphex a73555f672 (Menu) Add sublabel for Video Output submenu 2019-12-20 13:50:20 +01:00
twinaphex 03d0e0d799 (MaterialUI) Add icons for submenus 2019-12-20 13:48:38 +01:00
twinaphex 64597e47c6 (Menu Usability) If 'Favorites Tab' is disabled, don't show
'Add To Favorites' option in Quick Menu/Playlist menu
2019-12-20 07:21:15 +01:00
twinaphex 6713c6ebed (Menu) If On-Demand Thumbnail Downloader is enabled, hide
'Download Thumbnails' from playlist menu screen
2019-12-20 07:15:04 +01:00
twinaphex 051342cc8b Rewrite win32_get_video_output 2019-12-20 07:15:03 +01:00
Twinaphex 94cf920751 Merge pull request #9879 from Jamiras/cdfs_track_start
proper calculation of offset to track 2 when sector sizes vary
2019-12-20 04:02:53 +01:00
twinaphex dcac9de58b Add Audio Driver setting to Audio -> Output 2019-12-20 02:30:05 +01:00
twinaphex 23ce202d38 (Menu) Add Audio -> Resampler settings 2019-12-20 02:16:31 +01:00
Twinaphex 362dd7241a Merge pull request #9878 from Jamiras/cheevos_segacd_bin_hash
(cheevos) fix hashing of raw bin file for Sega CD
2019-12-20 01:19:13 +01:00
twinaphex 94907678eb (Menu) Add Audio -> output and Audio -> Synchronization 2019-12-20 01:18:28 +01:00
Jamiras 9cb94e00b0 fix hashing of raw bin file for sega cd 2019-12-19 13:19:43 -07:00
Jamiras 3b4e55d0e5 proper calculation of offset to track 2 when sector sizes vary 2019-12-19 13:17:32 -07:00
Twinaphex 8779151fef Merge pull request #9877 from DEX357/patch-49
Update msg_hash_pl.h
2019-12-19 21:04:38 +01:00
twinaphex 923c19356b (ffmpeg) - Fix CXX_BUILD errors - see
https://github.com/ZoneMinder/zoneminder/blob/master/src/zm_ffmpeg.h
(comment on av_err2str)
2019-12-19 20:43:59 +01:00
DEX357 3d95f3c7b1 Update msg_hash_pl.h
Please fix the displayed translations
2019-12-19 20:37:30 +01:00
twinaphex 6f6bd95a84 move Crop Overscan to Video Scaling; add Sync to Exact Content Framerate
option to Video Synchronization
2019-12-19 20:00:19 +01:00
twinaphex aa537310ad (Menu) Create Video -> Synchronization 2019-12-19 19:39:02 +01:00
twinaphex 39ebd6e8d1 (Settings) Add Video -> Output 2019-12-19 19:15:57 +01:00
twinaphex faf8c83f54 (Menu) Set video submenu titles 2019-12-19 19:01:32 +01:00
twinaphex e8babede53 (Menu) Create Settings -> Video -> Fullscreen and Windowed submenus 2019-12-19 18:53:51 +01:00
twinaphex 36af159991 (Menu) Settings - Video - Add Scaling subsection 2019-12-19 18:22:22 +01:00
twinaphex 7150d6ef59 Bind start callback for playlist entries in Playlist Screen 2019-12-19 16:37:39 +01:00
twinaphex 2a500baaca Change start callback signatuer to OK callback signature 2019-12-19 16:30:53 +01:00
twinaphex cb85b3e8dd Put this behind ifdef 2019-12-19 13:24:39 +01:00
Twinaphex ea9d5e3a5e Merge pull request #9875 from negativeExponent/patch-1
Fix heap-use-after-free found when using asan
2019-12-18 23:31:56 +01:00
negativeExponent d96409ff37 Fix heap-use-after-free found when using asan
Fix https://github.com/libretro/RetroArch/issues/9871
2019-12-19 04:44:34 +08:00
Twinaphex 95e11234a7 Merge pull request #9874 from fpscan/3ds-missing-images
3ds missing images
2019-12-18 19:07:41 +01:00
Ömercan Kömür 97329367e4 Merge pull request #1 from fpscan/master
Add files via upload
2019-12-18 20:59:51 +03:00
Ömercan Kömür 4217369709 Add files via upload
@SpardaXV works.
2019-12-18 20:58:03 +03:00
Ömercan Kömür 09832d09fb Update Makefile.cores 2019-12-18 20:56:59 +03:00
twinaphex 168395af74 (libretro-common) Update 2019-12-18 18:25:54 +01:00
twinaphex 60b182b821 Promote tpool as libretro-common component 2019-12-18 18:21:03 +01:00
twinaphex 587a56026e Disable HAVE_UPDATE_CORES for Steam too 2019-12-18 18:13:05 +01:00
twinaphex 3e8e6d35d6 (tpool.c) Code style nits 2019-12-18 18:11:18 +01:00
twinaphex 9a7a8efb39 Hide this setting behind HAVE_UPDATE_CORES 2019-12-18 17:45:14 +01:00
Twinaphex 4db4d5e8bc Merge pull request #9869 from hasenbanck/frame-conversion
FFMPEG core frame based color conversion
2019-12-18 15:55:24 +01:00
Nils Hasenbanck d046594591 Fix ffmpeg core memory leak when using pthreads. 2019-12-18 15:05:01 +01:00
Nils Hasenbanck 417d1b7de7 Color space conversion using frame based MT.
Using a ordered ring buffer and a thread pool, the color space
conversion is not multi-threaded based on frames. I tried
to implement slice based threading, but libswscale did produced
highly distorted pictures without obvious reason.

This approach introduces some more "lag" when decoding and skipping,
but shouldn't be affect the user negatively, since movie
watching is not lag sensitive, as long as the A/V is synchronized.

Change default to software decoding.

SW decoding is the most robust and fasted method of decoding right now.
Users should enable hw based decoding if their system requires it
and it's actually beneficial for them.

Fix deadlocks when seeking and decrease RAM usage.

Decrease memory allocation by reusing AVFrames.
2019-12-18 11:46:49 +01:00
Twinaphex a88e6f4e1f Merge pull request #9867 from jdgleaver/ozone-fullscreen-thumbs
(Ozone) Add fullscreen thumbnail viewer
2019-12-17 22:24:17 +01:00
Hans-Kristian Arntzen 96723c6f70 Vulkan/Android: Workaround weird WSI return codes in landscape mode.
Android WSI wants you to use preTransform, and if it is not used
correctly, Android 10 will return VK_SUBOPTIMAL_KHR, and we would create
a new swapchain every frame.

This workaround just ignores this error, since it's not really an error.
A more "proper" fix is to use prerotate and modify the MVP matrices,
which might help certain devices with crummy display processors.
2019-12-17 19:08:20 +01:00
Twinaphex 5062374c72 Merge pull request #9868 from jdgleaver/database-fix
Fix database entry display
2019-12-17 15:25:26 +01:00
jdgleaver 76bb0031cb Fix database entry display 2019-12-17 14:07:35 +00:00
jdgleaver 8ba17dd985 (Ozone) Add fullscreen thumbnail viewer 2019-12-17 11:41:01 +00:00
Hans-Kristian Arntzen 4437cd1eac Attempt to workaround odd crashes in glslang.
I accidentally managed to reproduce an issue which has been plaguing
users for a while, where glslang throws an assert after closing a game
(and starting a new one).

pthread_setspecific was somehow failing with an EINVAL call, despite the
key never having been freed. I suspect some kind of corruption happening
when dynamic libraries are unloaded, but I doubt this is a bug in either
RetroArch or glslang per-se.

My workaround here is to tear down all TLS use in glslang after we're
done compiling. Somehow this works around the problem for me, and I
don't really see another viable fix. Valgrind does not say anything about the
issue, so doubt it's memory corruption either.

I had to fix a minor TLS leak in glslang as DetachProcess does not free
the PoolIndex TLS.
2019-12-16 22:27:13 +01:00
Twinaphex 3cfed7ba01 Merge pull request #9677 from orbea/travis
travis: Log configure arguments + use before_script.
2019-12-16 14:40:17 +01:00
Twinaphex e9a264217a Merge pull request #9860 from Themaister/master
Android/Vulkan: Recreate swapchain on orientation change.
2019-12-15 16:51:55 +01:00
Themaister 15ffffa835 Android/Vulkan: Recreate swapchain on orientation change.
ANativeWindow getWidth/Height does not detect any changes when using
Vulkan, so use the old onContentRectChanged callback to get notified
when size changed. Use those values instead when figuring out how large
swapchain to create.

Tested trivially on Galaxy S9+ Exynos model.
2019-12-15 16:46:41 +01:00
twinaphex 79ce997156 Fix potential bug with analog deadzones - should be fabs 2019-12-15 16:21:27 +01:00
Twinaphex 15838c2850 Merge pull request #9858 from ToadKing/emscripten-upgrades
fix bug in emscripten input code
2019-12-15 15:40:00 +01:00
Francisco José García García 0545c42db9 (Vita) Fix duplicate symbols with some cores 2019-12-15 11:05:22 +01:00
Toad King f3001c9bba fix bug in emscripten input code 2019-12-14 20:57:10 -06:00
Twinaphex 42aa83b2a5 Merge pull request #9857 from ToadKing/emscripten-upgrades
changes to support upgraded emscripten SDK
2019-12-15 03:32:13 +01:00
Toad King 15e8be4074 changes to support upgraded emscripten SDK 2019-12-14 20:24:41 -06:00
ThePhxRises 3c27300a4e [VITA] Enable touch regardless of MiniVitaTV 2019-12-14 20:50:17 +01:00
ThePhxRises 65f406a39e [VITA] MiniVitaTV Support
Set kernel model manually with sceCtrlIsMultiControllerSupported()
2019-12-14 20:50:17 +01:00
Twinaphex 0d06dfa948 Merge pull request #9854 from frangarcj/upstream
(VITA) Fixes for non working cores and VITA2D (GXM) Improvements
2019-12-14 16:07:03 +01:00
Francisco José García García b4be7b0c74 (Vita) Several improvements to vita2d driver 2019-12-14 14:11:47 +01:00
Francisco José García García 9ad874eef8 (Vita) Add new function to draw textured arrays of vertices 2019-12-14 14:11:47 +01:00
Francisco José García García d52f3ba3e9 (Vita) Fix clipping and reduce number of calls 2019-12-14 14:11:46 +01:00
Francisco José García García 3d44faf6c3 (Vita) New set viewport function 2019-12-14 14:11:46 +01:00
Francisco José García García 8ad3cb14f8 (Vita) Changes for new tint shaders 2019-12-14 14:11:46 +01:00
Francisco José García García 0be7e96437 (Vita) Disable lto 2019-12-14 14:11:46 +01:00
Francisco José García García d1aa7dbedc Disable not compilable sqrtfv_neon 2019-12-14 14:11:46 +01:00
Francisco José García García eef7611cf1 Fix for duplicated error symbol 2019-12-14 14:11:46 +01:00
Francisco José García García 758b3ad2cc (VITA) Make VITA2D the default driver 2019-12-14 14:11:46 +01:00
hizzlekizzle b468aa8c01 Merge pull request #9852 from realnc/swap-interval-drc
Support DRC even when using a vsync swap interval higher than 1
2019-12-13 22:16:25 -06:00
Nikos Chantziaras 31d86e6e78 Update CHANGES.md 2019-12-13 23:29:43 +02:00
Nikos Chantziaras 1617cd7e2a Support DRC even when using a vsync swap interval higher than 1 2019-12-13 23:27:23 +02:00
Twinaphex ac318f2c8c Merge pull request #9851 from rsn8887/master
Fix radial analog deadzone scaling
2019-12-13 20:32:41 +01:00
rsn8887 42d02565af Fix radial analog deadzone scaling 2019-12-13 13:29:28 -06:00
Twinaphex 18d3eba614 Merge pull request #9842 from rsn8887/master
Implement proper analog button deadzone
2019-12-13 19:15:52 +01:00
Twinaphex 3171c71639 Merge pull request #9850 from jdgleaver/dropdown-list-fix
Fix 'currently selected item' indicator in dropdown lists
2019-12-13 12:11:10 +01:00
jdgleaver 32444f8188 Fix 'currently selected item' indicator in dropdown lists 2019-12-13 10:49:52 +00:00
Twinaphex 73729e7a33 Merge pull request #9848 from BarryJRowe/master
Fixed a segfault and an issue with AI Service overlay's image mode.
2019-12-13 07:04:25 +01:00
Barry Rowe c6f55eeb94 Fixed a segfault and an issue with AI Service overlay's image mode. 2019-12-12 16:31:18 -08:00
Twinaphex 5e156b9d73 Merge pull request #9847 from jdgleaver/xmb-fullscreen-thumbs
(XMB) Add fullscreen thumbnail viewer
2019-12-12 20:08:20 +01:00
jdgleaver 004d100ed8 (XMB) Add fullscreen thumbnail viewer 2019-12-12 17:01:37 +00:00
Twinaphex 1f866dbad4 Merge pull request #9844 from Jamiras/cheevos_pce_cd_memory
support for extended PC-Engine memory map
2019-12-11 21:08:46 +01:00
Twinaphex 127e07c210 Merge pull request #9845 from jdgleaver/ozone-thumb-tweaks
(Ozone) Minor thumbnail optimisations
2019-12-11 21:08:34 +01:00
rsn8887 745fb4b40c Implement proper analog button deadzone 2019-12-11 10:06:08 -06:00
Jamiras a96ea2492d support for extended PC-Engine memory map 2019-12-11 08:53:06 -07:00
jdgleaver 3b8e3c613f (Ozone) Minor thumbnail optimisations 2019-12-11 13:44:59 +00:00
Twinaphex f7445bcc98 Merge pull request #9843 from DEX357/patch-48
Update msg_hash_pl.h
2019-12-11 06:19:46 +01:00
DEX357 0fd2cfbab6 Update msg_hash_pl.h 2019-12-10 21:26:19 +01:00
Twinaphex d5d643ca28 Merge pull request #9841 from jdgleaver/xmb-thumbnails
(XMB) Use new 'menu_thumbnail' library for loading/rendering thumbnails
2019-12-10 20:04:54 +01:00
jdgleaver 2dc9616509 (XMB) Use new 'menu_thumbnail' library for loading/rendering thumbnails 2019-12-10 17:03:47 +00:00
Twinaphex 739f7b47fe Update CHANGES.md 2019-12-10 06:12:48 +01:00
Twinaphex 82df0c3aa3 Merge pull request #9838 from dobyrch/master
(Menu) Analog stick controls menu even if autoconfig disabled
2019-12-10 06:12:18 +01:00
twinaphex 3e22d7bbd5 (UWP) Cleanups/build fixes 2019-12-10 06:03:25 +01:00
Douglas Christman b67894586f (Menu) Analog stick controls menu even if autoconfig disabled
Fixes #9089 and #8192
2019-12-09 23:14:47 +08:00
Twinaphex 5e20d16ef8 Merge pull request #9837 from jdgleaver/glui-accessibility-icon
(GLUI) Use default icon for 'Accessibility' settings menu entry
2019-12-09 11:28:29 +01:00
jdgleaver 83235dc484 (GLUI) Use default icon for 'Accessibility' settings menu entry 2019-12-09 10:12:19 +00:00
Twinaphex bd0d8fd8ea Merge pull request #9836 from BarryJRowe/master
Fixed MacOSX defines for accessibility.
2019-12-09 00:47:24 +01:00
Barry Rowe ec7faddd26 Fixed MacOSX defines for accessibility. 2019-12-08 11:12:16 -08:00
twinaphex 6591844b3e (ANGLE) Don't need to link against GLESv2 explicitly 2019-12-07 21:14:37 +01:00
twinaphex 14c5825769 (Qb) Add ANGLE build option - currently requires you to put the required
libs in angle-x64 dir and then have the shared libs inside the main root
dir - after this, we want to try static linking
2019-12-07 21:01:44 +01:00
Twinaphex dfda4f3519 Merge pull request #9830 from WeedyWeedSmoker/french-translation-update
French translation update…
2019-12-07 20:58:12 +01:00
Twinaphex 7117cb8f8e Merge pull request #9833 from hasenbanck/ffmpeg-sw-mt
ffmpeg core implements MT for SW decoding.
2019-12-07 18:39:35 +01:00
Nils Hasenbanck 00f755a822 ffmpeg core implements MT for SW decoding.
This change will activate multi-threading for software based
decoder. Color conversion is still single threaded and also not
being performed by OpenGL.

Since the way ffmpeg inits the HW decoding, we can't 100% valdiate
if a hw decoder will play a file or not. Since we need to know
before calling avcodec_open2() if we want to either multi-thread via
software or HW decode, we will only run single-threaded in case of a
late fallback.

This happens for example in off cases when my AMD vega based graphic
card reports that it could HW decode VP9 video but in reality can't
(which is catched in callback get_format() and after avcodec_open2(().

There is currently no good solution in sight, since we can't
reconfigure the decoding context at that point of time.
2019-12-07 17:45:41 +01:00
twinaphex 328d5bf648 For ANGLE, point the EGL include dir to our copied files on
the repo
2019-12-07 10:52:14 +01:00
twinaphex 7f1c1db651 Now that we can build with ANGLE, we have to take this out 2019-12-07 10:30:28 +01:00
twinaphex b90bd91731 Bake out accessibility for iOS 2019-12-07 09:51:51 +01:00
twinaphex 5aa87c1734 Add HAVE_ANGLE switch 2019-12-07 08:16:00 +01:00
twinaphex 1fd6d024eb More buildfixes for ANGLE 2019-12-07 07:24:20 +01:00
twinaphex c6b325e4d6 Add more headers 2019-12-07 07:17:21 +01:00
twinaphex df588ca422 (ANGLE) Move headers to gfx/include/ANGLE 2019-12-07 07:09:49 +01:00
twinaphex 17a161afa2 Add missing header 2019-12-07 07:04:26 +01:00
Twinaphex 5628d3ba91 Merge pull request #9832 from libretro/angle-headers
Add more required headers
2019-12-07 07:01:45 +01:00
twinaphex 94f82ece4e Add more required headers 2019-12-07 07:01:11 +01:00
Twinaphex 6b2ac3afcd Merge pull request #9831 from libretro/angle-headers
Add EGL headers
2019-12-07 06:55:50 +01:00
twinaphex 1aaf933a1a Add EGL headers 2019-12-07 06:55:16 +01:00
Weedy Weed Smoker 3af86cab07 French update last minute typo…
Now ready to merge!
2019-12-07 12:38:37 +07:00
Weedy Weed Smoker d0ed4e90b3 Style unification for the US file…
Unifies the last lines with the style used throughout the US file
2019-12-07 12:35:32 +07:00
Weedy Weed Smoker 355aaac73a Minor update to french file 2019-12-07 12:31:09 +07:00
Weedy Weed Smoker fbd973147b French translation update…
Implements all the latest additions from the english file!
2019-12-07 12:19:42 +07:00
Twinaphex 6d2b81c6b3 Merge pull request #9828 from BarryJRowe/master
Fixed narrator speed on mac.
2019-12-07 04:08:44 +01:00
Barry Rowe b01b4de91d Fixed narrator speed on mac. 2019-12-06 13:16:30 -08:00
Twinaphex 36e7cc4bbd Merge pull request #9826 from jdgleaver/show-playlists
Enable playlist/add content functionality on platforms without database support
2019-12-06 14:26:39 +01:00
Twinaphex 7429124cd4 Update CHANGES.md 2019-12-06 14:24:40 +01:00
Twinaphex e3658cbc7b Merge pull request #9823 from driver1998/angle
[Win32 & UWP] ANGLE OpenGL ES support
2019-12-06 14:23:53 +01:00
jdgleaver 3031556e73 Enable playlist/add content functionality on platforms without database support 2019-12-06 10:49:27 +00:00
driver1998 105fadd668 [ANGLE] Add HAVE_ANGLE 2019-12-06 15:43:19 +08:00
driver1998 a8a4e60171 [ANGLE] Cleanup 2019-12-06 13:59:22 +08:00
driver1998 bfe167fae8 [UWP] Add ANGLE context 2019-12-06 13:24:18 +08:00
driver1998 7cbdd845ad [Win32] Add ANGLE context 2019-12-06 13:24:17 +08:00
driver1998 de203390be [Windows] Add ANGLE support 2019-12-06 13:24:17 +08:00
Twinaphex 55916a40ab Update CHANGES.md 2019-12-05 23:59:11 +01:00
Twinaphex 002f2ab6e7 Merge pull request #9801 from cmitu/kms-video-mode-selection
KMSDRM: better detection for the current video mode
2019-12-05 23:39:02 +01:00
Twinaphex e61fc4e427 Merge pull request #9822 from driver1998/uwp-fixes
Multiple UWP Fixes
2019-12-05 23:38:47 +01:00
Twinaphex c198c0737a Merge pull request #9825 from hasenbanck/ffmpeg-deps
Fix ffmpeg core build under linux.
2019-12-05 23:37:01 +01:00
Nils Hasenbanck 03b18dbfc4 Disable HW acceleration with ffmpeg 3.4. 2019-12-05 20:11:29 +01:00
Nils Hasenbanck c88f2b31ee Fix ffmpeg core build under linux.
Libass is optional again. This build will also compile with
ffmpeg 3.4 again, but HW acceleration is not guaranteed to work,
since it hasn't been tested well enough.
2019-12-05 19:39:56 +01:00
Twinaphex a01e99aa63 Update .travis.yml 2019-12-05 10:29:32 +01:00
Twinaphex 1ea82b8b5d Merge pull request #9821 from BarryJRowe/master
Removed narrator for emscripten case.
2019-12-05 10:27:04 +01:00
driver1998 4b393eb22a [UWP] Enable menu touch input 2019-12-05 17:15:27 +08:00
driver1998 bb6f13a725 [UWP] Fix keyboard input hang 2019-12-05 17:15:02 +08:00
driver1998 7519d3562b [UWP] Use GLUI on Windows 10 Mobile 2019-12-05 16:32:38 +08:00
driver1998 0f924bd083 [UWP] expand custom.ini to absolute path, prevent crashing 2019-12-05 16:32:38 +08:00
driver1998 004d782323 [UWP] Mouse fix on high DPI, multi touch support 2019-12-05 16:32:38 +08:00
driver1998 1bd9d503f0 [UWP] Add trailing backsplash to default dirs 2019-12-05 16:32:38 +08:00
driver1998 918b08e910 [UWP] Add ARM64 detection in get_os 2019-12-05 16:32:38 +08:00
driver1998 83cb526153 [UWP] Add get_user_language and get_cpu_model_name 2019-12-05 16:32:38 +08:00
driver1998 aa19d5180b [UWP] Move RunAsync out of VFS implementation 2019-12-05 16:32:38 +08:00
Barry Rowe d44d1537d9 Removed narrator for emscripten case. 2019-12-04 22:51:59 -08:00
Twinaphex 1392143d14 Merge pull request #9820 from BarryJRowe/master
Fix to audiomixer ifdef.
2019-12-05 07:47:40 +01:00
Barry Rowe ca03491e63 Fix to audiomixer. 2019-12-04 21:05:44 -08:00
Twinaphex 25fb69a7a5 Update CONTRIBUTING.md 2019-12-05 06:00:02 +01:00
twinaphex c1717fc028 Cleanups 2019-12-05 05:53:36 +01:00
twinaphex 49fb0d7909 Fix --disable-audiomixer 2019-12-05 05:48:26 +01:00
twinaphex 28e88c95ec Fix --disable-menu 2019-12-05 05:44:26 +01:00
Twinaphex 4c198a7cb3 Merge pull request #9819 from BarryJRowe/master
More build fixes.
2019-12-05 05:36:28 +01:00
Barry Rowe e1f8b66c05 More build fixes. 2019-12-04 20:11:02 -08:00
Twinaphex f03f6d6a63 Update CHANGES.md 2019-12-05 04:05:42 +01:00
Twinaphex b06314cda3 Merge pull request #9681 from fpscan/flux
New RGUI theme: Flux
2019-12-05 04:05:03 +01:00
Twinaphex fc6580200a Update CHANGES.md 2019-12-05 04:02:57 +01:00
Twinaphex ed20c14f23 Merge pull request #9816 from jdgleaver/manual-scan-arcade-dat
(Manual Content Scanner) Enable automatic naming of arcade content via DAT files
2019-12-05 04:02:15 +01:00
Twinaphex cbe46dfd99 Merge pull request #9818 from BarryJRowe/master
Removed C99 styled literals.
2019-12-05 03:58:45 +01:00
Barry Rowe 1223f74f5c Removed C99 styled literals. 2019-12-04 16:38:25 -08:00
twinaphex 8c2135f2bb Buildfix 2019-12-04 23:53:02 +01:00
Twinaphex d20dc01aff Merge pull request #9817 from BarryJRowe/master
Accessibility settings and narrator speed.
2019-12-04 23:30:15 +01:00
Barry Rowe cd29485d6e Removed extra prototypes. 2019-12-04 14:19:54 -08:00
Barry Rowe a8430acd66 Merge remote-tracking branch 'upstream/master' 2019-12-04 13:23:08 -08:00
Barry Rowe 3a67e072bb Added in fixes for accessibility feature. 2019-12-04 10:51:50 -08:00
twinaphex 535f2f23f3 Implement remaining accessibility settings 2019-12-04 18:11:25 +01:00
jdgleaver a27ee73622 Manual content scan arcade DAT files: Add support for MAME 'Software List' XML format 2019-12-04 16:19:32 +00:00
jdgleaver 9b012e907a (Manual Content Scanner) Enable automatic naming of arcade content via DAT files 2019-12-04 12:46:04 +00:00
twinaphex ebe9f1861e Implement more settings for Accessibility 2019-12-04 09:24:27 +01:00
twinaphex 9462fd301a (Accessibility) Add the two new Accessibility settings 2019-12-04 08:57:10 +01:00
twinaphex 6992f580e8 (Accessibility) Implement Narrator mode setting 2019-12-04 08:46:51 +01:00
twinaphex 6dd7f65322 (Accessibility) Update 2019-12-04 08:41:20 +01:00
twinaphex 72e6601702 C89 buildfix 2019-12-04 08:25:54 +01:00
twinaphex cab8663713 (Accessibility) Start adding Accessibility settings - empty for now 2019-12-04 08:25:24 +01:00
twinaphex 8d9419128e Add TODO/FIXME comment 2019-12-04 07:35:05 +01:00
twinaphex e3bf70dc10 Fix Linux build 2019-12-04 07:33:33 +01:00
twinaphex 0647e0d2c2 (Cheevos) Turn strncpy functions into strlcpy
(Translation/Accessibility) Turn functions static
2019-12-04 06:21:16 +01:00
twinaphex 2f43a1b5f4 Remove unused variable 2019-12-04 05:20:52 +01:00
twinaphex 831e33739e Replace some usage of strcpy and strcat 2019-12-04 05:17:53 +01:00
twinaphex 90008242eb Put this behind HAVE_TRANSLATE ifdef 2019-12-04 05:12:30 +01:00
twinaphex 43017cb65b Fix targets that don't have HAVE_NETWORKING 2019-12-04 05:10:56 +01:00
Twinaphex 2f17cbaef3 Merge pull request #9768 from BarryJRowe/master
Added in accessibility. (DO NOT MERGE)
2019-12-04 04:06:39 +01:00
twinaphex 688acb1e41 Refactor build_list 2019-12-03 03:26:54 +01:00
twinaphex 7b2d7a9ec7 Cleanups 2019-12-03 03:14:39 +01:00
twinaphex 01e62efb72 move more code to build_list 2019-12-03 02:17:43 +01:00
twinaphex 82391b6ac1 move more code to build_list 2019-12-03 02:09:55 +01:00
twinaphex 2ad2983b25 Move HELP_SCREEN_LIST to build_list 2019-12-03 01:53:00 +01:00
twinaphex 5df0516318 Move these to build_list 2019-12-03 01:50:14 +01:00
twinaphex 56014a6bf7 Change the sublabel for User Binds / Port Binds as well 2019-12-03 00:49:12 +01:00
twinaphex dd923d55f2 Change 'User % Binds' To 'Port % Binds' 2019-12-03 00:37:11 +01:00
twinaphex 3c2d30c510 Move DISPLAYLIST_OPTIONS_REMAPPINGS to build_list 2019-12-03 00:26:39 +01:00
twinaphex a4982cd460 (Menu displaylist) Cleanup 2019-12-02 23:45:21 +01:00
twinaphex e6a3785b01 Cleanups 2019-12-02 23:39:46 +01:00
twinaphex d09ae22147 Fix return values 2019-12-02 23:16:35 +01:00
twinaphex d2e83df498 Refactor menu_displaylist_parse_load_content_settings - should now
properly report count
2019-12-02 22:50:33 +01:00
twinaphex c490b06fe9 (menu_displaylist) build_list - add more entries 2019-12-02 22:35:02 +01:00
twinaphex c9a97d255c (menu_cbs_title) Cleanups 2019-12-02 22:20:36 +01:00
Twinaphex f0a9f4e6a4 Merge pull request #9812 from libretro/menu-actionok-refactors
Menu actionok refactors
2019-12-02 21:11:33 +01:00
twinaphex 177ca956f1 Code de-duplication 2019-12-02 21:08:21 +01:00
twinaphex e13febc82b (menu cbs ok) Code de-duplication 2019-12-02 21:05:04 +01:00
twinaphex 04ee55f202 Add NOTE/TODO about globals 2019-12-02 20:52:23 +01:00
twinaphex ee6c2393c1 (menu_cbs_ok.c) Cut down on some code duplication 2019-12-02 20:47:50 +01:00
Twinaphex 52fe3d2c7d Merge pull request #9810 from hasenbanck/ffmpeg-version
ffmpeg core prints out the ffmpeg library version
2019-12-02 19:41:00 +01:00
Nils Hasenbanck 1dbc7cdc9a ffmpeg core prints out the ffmpeg library version
For better debugging and supporting of the users, we will print
out the library versions that the ffmpeg core is currently using.
2019-12-02 18:50:44 +01:00
twinaphex 07f3abfda1 (madmonkey) Proposed fix for Mali GPUs 2019-12-02 16:28:35 +01:00
Twinaphex a2c7b17cd3 Update CHANGES.md 2019-12-02 16:25:55 +01:00
Twinaphex 56393bd253 Merge pull request #9808 from jdgleaver/manual-scan-archives
(Manual Content Scanner) Add option to scan inside archives
2019-12-02 16:25:27 +01:00
jdgleaver 3d52d7a8f6 (Manual Content Scanner) Add option to scan inside archives 2019-12-02 11:49:41 +00:00
Twinaphex b5958359d2 Update CHANGES.md 2019-12-02 09:27:57 +01:00
Twinaphex e7257c1855 Update CHANGES.md 2019-12-02 07:35:44 +01:00
Twinaphex 6329b28e4a Update CHANGES.md 2019-12-02 07:35:12 +01:00
twinaphex c3743a74f6 Refactor menu_cbs_sublabel.c 2019-12-02 07:20:01 +01:00
twinaphex e7d2e7ebcb Refactor menu_cbs_get_value.c 2019-12-02 06:47:51 +01:00
Twinaphex 71f4ff6b84 Merge pull request #9777 from DEX357/patch-47
FIXME Update msg_hash_pl.h
2019-12-02 06:17:47 +01:00
Twinaphex bfe00ac6f3 Merge pull request #9807 from libretro/deferred-refactors-pt2
(menu_cbs_ok) Cleanups
2019-12-02 06:17:30 +01:00
Twinaphex 2b2d6742e0 Merge pull request #9805 from libretro/deferred-refactors-pt2
Deferred refactors pt2
2019-12-02 06:16:48 +01:00
Twinaphex aa9934a722 Merge pull request #9806 from libretro/revert-9561-patch-6
Revert "iOS - Bump GCC Optimization level to-0s for Release Builds. "
2019-12-02 06:16:38 +01:00
Twinaphex ec4ecb5d34 Revert "iOS - Bump GCC Optimization level to-0s for Release Builds. " 2019-12-02 06:16:28 +01:00
twinaphex 8551d175ab (menu_cbs_ok) Cleanups 2019-12-02 06:10:32 +01:00
twinaphex d0bce8bc9f Refactor menu_cbs_title 2019-12-02 05:50:32 +01:00
Twinaphex 12ae92ef66 Merge pull request #9786 from hasenbanck/ffmpeg-amf
Implement ffmpeg send/receive encoding API
2019-12-02 05:35:37 +01:00
Twinaphex c1a2dd81c7 Merge pull request #9798 from libretro/kivutar/makeosx
[WIP] Allow building using make on OSX
2019-12-02 05:24:29 +01:00
Twinaphex a4d8ecf2b8 Merge pull request #9561 from mrjschulte/patch-6
iOS - Bump GCC Optimization level to-0s for Release Builds.
2019-12-02 05:24:07 +01:00
twinaphex c80d18c446 Refactor DEFERRED_RECORDING_SETTINGS_LIST 2019-12-02 02:33:09 +01:00
twinaphex 2a41f1fb99 Change type to enum - should silence C89 build errors 2019-12-02 01:21:42 +01:00
Twinaphex 901932a8e1 Merge pull request #9804 from libretro/deferred-push-refactor
Refactor deferred push callbacks
2019-12-01 23:23:23 +01:00
Twinaphex e57e4dbf57 Merge branch 'master' into deferred-push-refactor 2019-12-01 23:22:18 +01:00
Twinaphex 00ca7297f3 Merge pull request #9795 from jdgleaver/manual-scan
Add manual content scanner
2019-12-01 23:11:45 +01:00
twinaphex cfc2a15d41 Refactor the other entries as well 2019-12-01 22:57:18 +01:00
twinaphex e8f55e8b24 Refactor deferred push callbacks 2019-12-01 22:38:53 +01:00
Twinaphex c09c4299ba Merge pull request #9803 from libretro/flowchart-controls
Change 'User' terminology to 'Port' for input binding stuff
2019-12-01 21:40:17 +01:00
Twinaphex dda12da672 Merge pull request #9799 from hasenbanck/ffmpeg-hw
FFMPEG Core HW accelerated decoding
2019-12-01 20:32:50 +01:00
Twinaphex 96b6789855 Merge pull request #9800 from Tatsuya79/patch-3
fix dock titles getting cut off
2019-12-01 19:52:58 +01:00
Nils Hasenbanck 17107a1563 Fix decoder switching and context re-usage.
The re-usage of the decoder context is not properly implemented.
Restart options will only be applied when the core is started.
2019-12-01 12:49:37 +01:00
Nils Hasenbanck c3c2f5bfb6 Implement HW based decoding for the ffmpeg core.
The ffmpeg core not support the usage of HW based video decoders.

Core options to configure the HW decoder to use is provided.
Proper fallback to the SW based decoder is implemented.

Currently the decoder loop in single threaded and is limited by
the color conversion that is done in software.
The frame based threading provided by ffmpeg also currently doesn't
seem to provide any benefits in configuring it.
2019-12-01 12:11:14 +01:00
cmitu 3953659901 KMSDRM: better detection for the current video mode 2019-12-01 06:45:43 +00:00
DEX357 c3f2469832 Update msg_hash_pl.h 2019-11-30 22:25:23 +01:00
Tatsuya79 2e0c1daf1b fix dock titles getting cut off 2019-11-30 19:06:59 +01:00
Jean-André Santoni 93df88a5d6 Typo 2019-11-30 14:24:38 +07:00
Jean-André Santoni 3ed2cf7812 CI 2019-11-30 13:01:43 +07:00
Jean-André Santoni c0dfcd2adf Fix Metal build 2019-11-30 12:49:52 +07:00
Jean-André Santoni f349784bd6 Fix the xcode build 2019-11-30 12:43:38 +07:00
Jean-André Santoni ba2c870d95 Allow building using make on OSX 2019-11-30 12:37:58 +07:00
Twinaphex b382ea2a33 Merge pull request #9797 from Tatsuya79/patch-2
fix search dock title
2019-11-29 23:25:45 +01:00
Tatsuya79 b6094d6f3b fix search dock title 2019-11-29 22:48:18 +01:00
jdgleaver 170397456c Add manual content scanner 2019-11-29 17:14:46 +00:00
Twinaphex 944485b9ae Update Makefile.libnx 2019-11-29 05:23:00 +01:00
Twinaphex c8adaaaab2 Merge pull request #9789 from jdgleaver/ozone-thumbnails
(Ozone) Use new 'menu_thumbnail' library for loading/rendering thumbnails
2019-11-28 18:06:06 +01:00
Twinaphex d8ba2839c4 Merge pull request #9794 from Jamiras/cheevos_unsupported_core_hardcore_pause
(cheevos) pause hardcore if core doesn't support achievements
2019-11-28 18:05:53 +01:00
DEX357 576213b048 FIXME 2019-11-27 19:41:17 +01:00
Jamiras 1f97d31f2a pause hardcore if core doesn't support achievements 2019-11-27 07:38:41 -07:00
Barry Rowe 1e6e7a698f Added in accessibility. 2019-11-26 15:19:21 -08:00
jdgleaver 9170bca9b3 (Ozone) Use new 'menu_thumbnail' library for loading/rendering thumbnails 2019-11-25 13:14:25 +00:00
twinaphex 388879da38 Change 'User' terminology to 'Port' for input binding stuff 2019-11-24 20:11:49 +01:00
DEX357 4476d3e971 Update msg_hash_pl.h 2019-11-24 18:32:59 +01:00
Nils Hasenbanck 4e4802e5c6 Implement ffmpeg send/receive encoding API
This is implementing the send/receive encoding API of ffmpeg in the
ffmpeg record backend.

Newer encoder do need the client to use this API to use them (for
example h264_amf and hvec_amf). "Old" encoders should work fine
(Tested x264 and webm profiles).

The biggest change is the handling of the encoded packets, since
the API can return multiple packets in it's queue. As a positive
side-effect the code for flushing is much more easier.
2019-11-24 17:41:22 +01:00
Twinaphex 203a80aeaa Merge pull request #9785 from Jamiras/nds_hash
(cheevos) add hashing for Nintendo DS
2019-11-24 16:59:04 +01:00
Twinaphex 50a50b8519 Merge pull request #9784 from jdgleaver/thumbnail-upscaling-settings-fix
Fix 'Thumbnail Upscaling Threshold' setting drop-down list
2019-11-24 16:58:35 +01:00
DEX357 4203b4fb78 Update msg_hash_pl.h 2019-11-24 16:05:09 +01:00
Jamiras a990c0bca4 add hashing for Nintendo DS 2019-11-24 07:59:59 -07:00
jdgleaver 4eec21b4d1 Fix 'Thumbnail Upscaling Threshold' setting drop-down list 2019-11-24 14:39:08 +00:00
DEX357 6625eff3d8 Update msg_hash_pl.h 2019-11-24 03:56:11 +01:00
DEX357 677f13a2fe Update msg_hash_pl.h 2019-11-24 03:15:54 +01:00
twinaphex ba74747860 (ffmpeg core) Update Makefile 2019-11-23 22:39:50 +01:00
Twinaphex de3ac2c549 Merge pull request #9775 from Jamiras/chd_pregap
(cheevos) fix hash calculation for some PCEngine CHD files
2019-11-23 21:08:47 +01:00
Twinaphex ccaba7d465 Merge pull request #9776 from fjtrujy/psp/PThread
[PSP] Solving issue Exiting RetroArch by HOME button
2019-11-23 12:59:14 +01:00
Francisco Javier Trujillo Mata e553e19996 Call pthread_terminate is if it is NO SALAMANDER 2019-11-23 12:54:45 +01:00
twinaphex ce9ba045ff This can be unreverted after we bake in the pthreads implementation for PSP and Vita
Revert "Call to the terminate function for the pthread on the deinit of the PSP platform"

This reverts commit 1671f16b0c.
2019-11-23 12:36:31 +01:00
Jamiras c69a11a219 better detection of pregap data in file 2019-11-22 19:36:38 -07:00
Twinaphex 4aa936ce33 Merge pull request #9772 from DuMOHsmol/xbox_one_bluetooth_fix
Get rid of 128 byte device name limit for XInput device discover
2019-11-22 19:50:58 +01:00
Twinaphex f09561026a Merge pull request #9771 from jdgleaver/pointer-msgbox-inhibit
(Menu) Ensure pointer input is handled correctly when showing message boxes
2019-11-22 19:50:13 +01:00
Dmitry Sergeenkov 5cdef89b86 Get rid of 128 byte device name limit for XInput device discover 2019-11-22 21:15:58 +03:00
jdgleaver b1d5542d77 (Menu) Ensure pointer input is handled correctly when showing message boxes 2019-11-22 15:10:28 +00:00
Francisco Javier Trujillo Mata 1671f16b0c Call to the terminate function for the pthread on the deinit of the PSP platform 2019-11-21 19:25:02 +01:00
Francisco Javier Trujillo Mata 5a5640155a Call to the terminate function for the pthread on the deinit of the PSP platform 2019-11-21 19:13:33 +01:00
Twinaphex 822eb3bb86 Merge pull request #9759 from Jamiras/rcheevos_81
(cheevos) update rcheevos to v8.1
2019-11-21 16:39:58 +01:00
Twinaphex 3e55d598db Merge pull request #9762 from gblues/gblues/default-asset-directory
Gblues/default asset directory
2019-11-21 15:45:17 +01:00
Twinaphex def1e352d4 Merge pull request #9763 from jdgleaver/glui-fs-thumbs-enable-select
(GLUI) Enable pass-through of [RetroPad A]/[Keyboard Return key] when viewing fullscreen thumbnails
2019-11-21 15:34:30 +01:00
jdgleaver 34b744aff6 (GLUI) Enable pass-through of [RetroPad A]/[Keyboard Return key] when viewing fullscreen thumbnails 2019-11-21 12:45:03 +00:00
Nathan Strong bff8e8204d Automatically rename asset directory
== DETAILS
For users upgrading--particularly via the online updater--we should
smoothly migrate them to the new name. If the "media" directory
exists and the "assets" directory doesn't, then rename "media" to
"assets".

== TESTING
none yet
2019-11-20 23:33:20 -08:00
Nathan Strong 4cd3934610 Change the default asset directory
On every other platform, retroarch uses "assets" but wiiu got stuck with "media"
and it's never been fixed.

So I'm fixing it.
2019-11-20 23:33:20 -08:00
Jean-André Santoni 33206b8847 Wait longer for the notarization server 2019-11-21 11:12:54 +07:00
Jamiras b26fa714a8 more descriptive error string 2019-11-20 18:19:35 -07:00
Jamiras 9983976ddb update rcheevos to v8.1 2019-11-20 14:40:34 -07:00
Twinaphex d3ed02dd87 Update Makefile.common 2019-11-20 20:38:28 +01:00
jdgleaver d392d90a6e (GLUI) Add fullscreen thumbnail viewer (#9758) 2019-11-20 19:09:02 +01:00
Francisco José García García c8067ba0c0 (VITA) Baked math-neon and vitaGL (#9757)
* Squashed 'deps/math-neon/' content from commit 0050735

git-subtree-dir: deps/math-neon
git-subtree-split: 0050735ae8f18281c1e6fbe2dc80546e402b7fc5

* Squashed 'deps/vitaGL/' content from commit 694b387

git-subtree-dir: deps/vitaGL
git-subtree-split: 694b387a6eacf7e179f07ff621e5772ae4253315

* (Vita) Add baked math-neon and vitaGL
2019-11-20 12:13:33 +01:00
Twinaphex 932071952d (OSX) Buildfix 2019-11-20 11:19:18 +01:00
Twinaphex f081cfa314 Merge pull request #9756 from libretro/iosfix
Revert code in hopes iOS works again
2019-11-20 11:11:23 +01:00
twinaphex 861379d8e3 Revert code in hopes iOS works again 2019-11-20 06:25:40 +01:00
Twinaphex 64b23937d3 Merge pull request #9690 from libretro/kivutar/codesign
Code sign OSX release
2019-11-20 05:44:23 +01:00
Jean-André Santoni 11a4a4cffb Code cleaning 2019-11-20 10:45:14 +07:00
Jean-André Santoni 8da54e2349 Uncomment stuff 2019-11-20 10:09:24 +07:00
Jean-André Santoni 87cc90741d Deep sign 2019-11-20 09:59:34 +07:00
Jean-André Santoni 27da1c94f2 Enable hardened runtime for the Qt build 2019-11-20 09:09:27 +07:00
Twinaphex d2d240ecf5 (iOS) Should fix iOS build problems 2019-11-20 02:58:17 +01:00
Twinaphex 540edd7b5d (iOS) Buildfix #1 2019-11-20 02:51:18 +01:00
Twinaphex 81c020d300 Replace g_instance with CocoaView get 2019-11-20 02:24:03 +01:00
twinaphex e3506ed06b Move nsview_get_ptr to cocoa_common 2019-11-20 02:24:03 +01:00
Twinaphex 387e18b528 cocoagl_gfx_ctx_set_video_mode - go through [CocoaView get] here 2019-11-20 02:24:03 +01:00
Twinaphex bac58c99c4 Buildfix 2019-11-20 02:24:03 +01:00
twinaphex 964fcda79a Move glkitview_init to cocoa_common.m 2019-11-20 02:24:02 +01:00
Twinaphex b241b5769b Merge pull request #9754 from realnc/fix-null-deref
Fix null pointer deref
2019-11-19 23:58:23 +01:00
Nikos Chantziaras 376598a6e0 Fix null pointer deref 2019-11-20 00:41:38 +02:00
twinaphex ed8e440b0d Revert "Move update_window_title to main thread - this should resolve some"
This reverts commit 442608981d.
2019-11-19 22:48:35 +01:00
twinaphex 442608981d Move update_window_title to main thread - this should resolve some
concurrency issues on OSX as well
2019-11-19 22:13:51 +01:00
Jean-André Santoni 8191f2775f Add Qt back 2019-11-19 17:46:35 +07:00
Jean-André Santoni f142caea11 Disable some other builds for now 2019-11-19 17:40:01 +07:00
Jean-André Santoni d2f381d121 Try to take qt5 out 2019-11-19 17:39:19 +07:00
Jean-André Santoni 90b56fb487 Move back code signing to travis 2019-11-19 17:38:19 +07:00
Jean-André Santoni 8533512a82 Revert "Remove project changes"
This reverts commit f5dac2859ff029c7e836264cccf6cb28b146c308.
2019-11-19 17:38:19 +07:00
Jean-André Santoni dbe4be7e7f Remove project changes 2019-11-19 17:38:19 +07:00
Jean-André Santoni 912ab4ff00 Fix QT build 2019-11-19 17:38:19 +07:00
Jean-André Santoni 460cfc9efd Fix QT build 2019-11-19 17:38:19 +07:00
Jean-André Santoni 309045e0ac Move the logic to the shell script 2019-11-19 17:38:18 +07:00
Jean-André Santoni 944e89bdc8 Enable hardened runtime 2019-11-19 17:38:18 +07:00
Jean-André Santoni 885eb4f15b Fix signing conflict 2019-11-19 17:38:18 +07:00
Jean-André Santoni 27ecc119e0 Try to set the team ID there 2019-11-19 17:38:18 +07:00
Jean-André Santoni ded406984f Don't codesign this way 2019-11-19 17:38:18 +07:00
Jean-André Santoni 2a7b76249c Use xcode 11.2 and attempt to notarize the .app 2019-11-19 17:38:18 +07:00
Jean-André Santoni e49d505254 Code sign OSX release 2019-11-19 17:38:11 +07:00
twinaphex 79c336b6fd Update dist-cores.sh 2019-11-19 10:04:45 +01:00
Jean-André Santoni 249c73d68c Revert "Try xcode 11.1"
This reverts commit ffda27c8a7.
2019-11-19 15:21:08 +07:00
twinaphex 5d8c566dbc (cores/ffmpeg) Resync 2019-11-19 09:09:52 +01:00
Twinaphex aa2348823c Merge pull request #9749 from libretro/kivutar/removeuselessifdef
Remove useless HAVE_COCOA_METAL ifdef
2019-11-19 09:04:20 +01:00
twinaphex 10a234908f Update libretro-ffmpeg Makefile 2019-11-19 09:01:46 +01:00
twinaphex 6d5104f6d7 (Windows/ffmpeg) Standalone Makefile - Don't set it explicitly to gcc/g++ 2019-11-19 08:55:04 +01:00
twinaphex fbdc53f926 Update ffmpeg Makefile.common - see if it changes anything 2019-11-19 08:54:19 +01:00
Jean-André Santoni 8e028f4db3 Remove useless HAVE_COCOA_METAL ifdef 2019-11-19 14:50:21 +07:00
twinaphex 29ced2a72f Simplify cocoagl_gfx_ctx_get_video_size somewhat 2019-11-19 08:26:12 +01:00
twinaphex 77b05d6078 Add this for OSX 10.7 solution 2019-11-19 08:10:12 +01:00
Twinaphex b351fac466 Merge pull request #9748 from libretro/kivutar/xcode111
Try xcode 11.1
2019-11-19 07:54:11 +01:00
Jean-André Santoni ffda27c8a7 Try xcode 11.1 2019-11-19 13:42:06 +07:00
Twinaphex 72601103ba Merge pull request #9747 from libretro/kivutar/travispr
Prevent duplicate travis jobs
2019-11-19 07:32:14 +01:00
twinaphex 4736bef77b (Apple) Add HAVE_ONLINE_UPDATER 2019-11-19 07:18:16 +01:00
Jean-André Santoni 1581d23a6c Prevent deplicate travis jobs 2019-11-19 13:17:10 +07:00
Twinaphex 15b6da2a17 Merge pull request #9745 from libretro/kivutar/osxmake
Fix building with make on OSX
2019-11-19 07:12:07 +01:00
twinaphex f0784351c4 Update header include - should look in system dir 2019-11-19 06:19:09 +01:00
Twinaphex 9df2a6fd99 Merge pull request #9676 from orbea/qb3
Some minor qb changes.
2019-11-19 06:15:55 +01:00
Twinaphex 8518b4f50b Merge pull request #9673 from orbea/deprecate
qb: Remove deprecated arguments.
2019-11-19 06:15:40 +01:00
Twinaphex 53b7fb2ba2 Remove unused variables 2019-11-19 06:08:54 +01:00
Twinaphex 6a541125aa Silence two issues 2019-11-19 06:01:11 +01:00
Jean-André Santoni 947e15f34f Move WindowListener around 2019-11-19 12:00:24 +07:00
Twinaphex c7ce2c7053 Fix Xcode issue 2019-11-19 05:54:01 +01:00
Jean-André Santoni d5a5380e6d Fix building with make on OSX 2019-11-19 11:38:27 +07:00
Twinaphex 496104005b Merge pull request #9744 from realnc/fix-aspect-ratio-change
Don't omit AR changes when not reinitting video in SET_SYSTEM_AV_INFO
2019-11-19 04:11:46 +01:00
Nikos Chantziaras 33ab147514 Don't omit AR changes when not reinitting video in SET_SYSTEM_AV_INFO 2019-11-19 04:37:03 +02:00
Twinaphex c0bc8d2df2 Update CHANGES.md 2019-11-18 08:22:50 +01:00
Twinaphex d2a1d96f59 Update CHANGES.md 2019-11-18 08:21:29 +01:00
twinaphex 9d0356dd73 Add HAVE_STEAM switch 2019-11-18 08:04:29 +01:00
twinaphex a46027bed7 Remove MENU_LABEL_ONLINE_UPDATER 2019-11-18 07:51:57 +01:00
twinaphex a68e9b5014 Start passing global struct to configuration.c functions 2019-11-18 07:32:01 +01:00
twinaphex 88d4ae6790 Buildfix for Android - this header should not be done as a system
header include
2019-11-18 06:48:15 +01:00
twinaphex 48cca00d91 Revert "(retroarch.c) Cleanups"
This reverts commit db9a067e64.
2019-11-18 06:43:30 +01:00
twinaphex 9555f70440 Cleanup some RARCH_CTL_ actions 2019-11-18 06:32:23 +01:00
twinaphex db9a067e64 (retroarch.c) Cleanups 2019-11-18 06:20:47 +01:00
twinaphex 0aa9bd9c22 (retroarch.c) Cleanups - start getting rid of driver_find_ident
functions
2019-11-18 06:06:59 +01:00
twinaphex aba96fbf03 (Menu) Small cleanups 2019-11-18 04:20:40 +01:00
Twinaphex 2a72d90e8a Merge pull request #9715 from realnc/no-video-reinit
Do not reinit video driver on SET_SYSTEM_AV_INFO unless needed
2019-11-18 00:41:30 +01:00
Twinaphex 479ba58042 Update CHANGES.md 2019-11-17 23:16:44 +01:00
Twinaphex 9c0028c1d1 Merge pull request #9739 from Jamiras/cheevos_init_load_state
(cheevos) prevent loading state while achievements are still being fetched from server
2019-11-17 23:16:21 +01:00
Twinaphex 53d18cf95e Merge pull request #9713 from Rinnegatamante/vitagl
Added gl1 video driver support to Vita build
2019-11-17 23:14:29 +01:00
twinaphex 63e437d58f Rename get_rotation to retroarch_get_rotation 2019-11-17 22:58:52 +01:00
Twinaphex ddd9fbf6ae Merge pull request #9734 from Aethyrion/rotation_fixing
Rotation fixing
2019-11-17 22:53:12 +01:00
Twinaphex 68719ac8d4 Merge pull request #9741 from Jamiras/cheevos_lbl_cleanup
(cheevos) remove unused menu labels
2019-11-17 22:44:36 +01:00
twinaphex 934697b0da Buildfix for no menu 2019-11-17 22:42:15 +01:00
twinaphex cbe68cbf88 Turn the find_handle/find_ident functions static 2019-11-17 22:31:57 +01:00
Jamiras 9e547699c6 remove CHEEVOS_UNLOCKED_ACHIEVEMENTS, CHEEVOS_LOCKED_ACHIEVEMENTS, and CHEEVOS_OLD_ENABLE menu labels 2019-11-17 13:09:55 -07:00
twinaphex f9bc57bcf8 Merge list_special.c into retroarch.c 2019-11-17 21:07:56 +01:00
twinaphex 09b7202c54 Do a fall-through here 2019-11-17 21:01:46 +01:00
twinaphex 8c799f978b Merge paths.c - this is one of the last file we merge - not long after this
we can start splitting up retroarch.c into several files
2019-11-17 21:00:15 +01:00
Rémi 34125a6d14 Remove // comments 2019-11-17 20:46:51 +01:00
twinaphex c252cbe9e0 Strip out rxml and yxml if HAVE_VIDEO_LAYOUT is not defined 2019-11-17 20:43:26 +01:00
Twinaphex 8e6e30370d Merge pull request #9729 from huwpascoe/rxml-fix
Fixed xml parsing
2019-11-17 20:23:07 +01:00
Rémi 154c2d388d Fix CI compilation issues 2019-11-17 20:18:42 +01:00
Nikos Chantziaras e8c027cbc3 Do not reinit video driver on SET_SYSTEM_AV_INFO unless needed
Video reinit causes the core to freeze momentarily, freezing audio and
flashing the window. Cores like dosbox-svn need to change fps quite often
(some DOS games even change fps mid-gameplay) and the video reinit becomes
very annoying.

Change this to not reinit the video driver unless CRT SwitchRes is enabled
or a max width/height change was requested.
2019-11-17 20:29:42 +02:00
Rémi e3a8e28edc Using MAX macro. 2019-11-17 18:34:19 +01:00
Rémi 1c9d0dbf48 Refactoring (still trying to fix CI compilation issue) 2019-11-17 18:03:57 +01:00
Jamiras 939770929f hardcore mode is not dependent on having achievement data 2019-11-17 09:36:39 -07:00
Rémi 756b4636f6 Update Aspect Ratio (1:1 PAR and Custom) when rotating from menu 2019-11-17 17:22:10 +01:00
Twinaphex 80e49531b1 Merge pull request #9738 from libretro/revert-9714-master
Revert "Refactor RetroArch input polling settings"
2019-11-17 16:45:54 +01:00
Twinaphex b6aa9f2fd1 Revert "Refactor RetroArch input polling settings" 2019-11-17 16:45:40 +01:00
Rémi 09a9b7d254 CI compilation issue 2019-11-17 16:26:29 +01:00
Rémi f804e0738f Fix Integer Scaling when rotating 2019-11-17 13:52:28 +01:00
Rémi a28e57e42d Fixing Integer Scaling for Custom Viewport (when rotating) 2019-11-17 13:21:50 +01:00
Rémi 7088281b52 Fixing 1:1 PAR for 270 degree rotation 2019-11-16 23:18:56 +01:00
Rémi ba183cf7a6 Refactoring (get_rotation) 2019-11-16 23:03:15 +01:00
Rémi 9df755bdb4 Fixing 1:1 PAR aspect ratio when video rotated 2019-11-16 22:13:12 +01:00
Huw Pascoe 4eebfa237b Fixed xml parsing 2019-11-16 20:56:12 +00:00
Rémi cc99b9f949 Merge branch 'rotation_fixing' of https://github.com/Aethyrion/RetroArch into rotation_fixing 2019-11-16 19:52:52 +01:00
Rémi 6c47f02bdf Fixing OpenGL shader rotation 2019-11-16 19:52:47 +01:00
Rémi 30f36a30f2 Remove empty line 2019-11-16 19:50:35 +01:00
Rémi b6dc887d52 Fixing OpenGL shader rotation 2019-11-16 19:45:04 +01:00
Twinaphex 9b192dc3c1 Update CHANGES.md 2019-11-16 17:28:09 +01:00
Twinaphex 686a0ce199 Update CHANGES.md 2019-11-16 17:27:01 +01:00
Twinaphex 27f88abb02 Merge pull request #9733 from Jamiras/psx_exe_hash
(cheevos) use PSX.EXE if SYSTEM.CNF cannot be found
2019-11-16 17:26:35 +01:00
Jamiras 3b0cbc1e41 use PSX.EXE if SYSTEM.CNF cannot be found 2019-11-16 08:36:13 -07:00
Twinaphex 0d284c42bc Merge pull request #9714 from rz5/master
Refactor RetroArch input polling settings
2019-11-15 17:18:30 +01:00
Twinaphex 11f054e646 Merge pull request #9725 from guoyunhe/patch-1
Fix comment in freetype.c
2019-11-15 17:16:26 +01:00
Twinaphex 6ec7eddfc9 Merge pull request #9728 from jdgleaver/glui-navigation
(GLUI) Navigation improvements
2019-11-15 16:31:19 +01:00
jdgleaver 7eefec6945 (GLUI) Navigation improvements 2019-11-15 14:53:00 +00:00
Guo Yunhe 95dede9039 Fix comment in freetype.c 2019-11-15 10:18:05 +02:00
rz5 82898ea194 Cast arg to rarch_set_in_put from what it is to enum rarch_poll_type.
Might fix building under clang 6.0
2019-11-15 00:47:46 +00:00
Twinaphex 666ebb0ae1 Update CHANGES.md 2019-11-15 00:59:17 +01:00
Twinaphex 8548771025 Merge pull request #9682 from fpscan/turkish-translation
Update msg_hash_tr.h
2019-11-15 00:58:51 +01:00
Twinaphex 6adfff6995 Update CHANGES.md 2019-11-15 00:56:51 +01:00
Twinaphex 724865a8fc Update freetype.c 2019-11-15 00:53:17 +01:00
Twinaphex eab80384ab Update CHANGES.md 2019-11-15 00:52:11 +01:00
Twinaphex cbf0bc9cfc Merge pull request #9721 from guoyunhe/fix-chinese-font-linux
Correct Droid Sans Fallback font path in Linux
2019-11-15 00:51:07 +01:00
Twinaphex 474110b818 Merge pull request #9720 from Rinnegatamante/master
Some improvements to Italian translation.
2019-11-15 00:50:27 +01:00
Guo Yunhe 52b3a4fe17 Correct Droid Sans Fallback font path 2019-11-14 18:01:46 +02:00
Rinnegatamante 2f7a6fa394 Some improvements to Italian translation. 2019-11-14 13:14:46 +01:00
Rinnegatamante 2a77dc5600 Make code C89 compliant. 2019-11-13 21:44:59 +01:00
Twinaphex d84dfee044 Merge pull request #9711 from WeedyWeedSmoker/French-update
Update french language with the latest additions
2019-11-13 18:31:23 +01:00
Rinnegatamante 616759ed8c [VITA] Implement check_window. 2019-11-13 11:19:51 +01:00
Rinnegatamante 637319c938 [VITA] Implement swap_interval in vita video driver context. 2019-11-13 09:57:03 +01:00
Rinnegatamante d7572399cc [VITA] Make (for now) vita2d renderer the default one. 2019-11-13 09:05:57 +01:00
rz5 2678789bd8 Refactor RetroArch input polling settings
* Refactored the way RetroArch sets the input state/poll callbacks, hopefully it's clearer now.

* The unnamed enum of poll type behaviors in core.h was moved to retroarch.h and is now named rarch_poll_type.
It represents polling behaviors implemented specifically by RetroArch.
First element starts at 1 to match the data encoding of RETRO_ENVIRONMENT_POLL_TYPE_OVERRIDE.

* Created rarch_set_input_cbs - sets different input state/poll callbacks based on a
rarch_poll_type parameter.

* Replaced the static variable core_poll_type_override in retroarch.c with a poll_type_lock flag
inside global_t's menu struct;
RETRO_ENVIRONMENT_POLL_TYPE_OVERRIDE will now call rarch_set_input_cbs and set poll_type_lock,
which blocks the user from changing behaviors from the menu.

* To follow the RETRO_ENVIRONMENT_POLL_TYPE_OVERRIDE spec, we now set poll_type_lock and call
rarch_set_input_cbs after calling unload_game.

* core_set/unset_netplay_callbacks will now set/unset poll_type_lock, preventing the
poll type from being changed by the user;

* The MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR action will now call rarch_set_input_cbs if poll_type_lock
isn't set, which means poll type is changed on-the-fly.
2019-11-13 00:11:05 +00:00
Rinnegatamante 96845f4a7e [VITA] Removing a no more used ifndef. 2019-11-13 00:45:48 +01:00
Twinaphex baaf27c268 Merge pull request #9712 from julianaito/master
OpenBSD/powerpc: fix "undefined reference to __mftb"
2019-11-12 23:11:17 +01:00
Charlène 3038e9e1ce OpenBSD/powerpc: fix "undefined reference to __mftb" 2019-11-12 22:24:35 +01:00
Rinnegatamante a30f7dc79f [VITA/PSP] Fix logging to file not working. 2019-11-12 19:46:37 +01:00
Rinnegatamante 2b20c8d350 [GL1] Fixed core frame renderer. 2019-11-12 19:46:37 +01:00
radius 3f88a49bdc linux frontend: add proper drives 2019-11-12 19:11:51 +01:00
Rinnegatamante bed9847b48 [VITA] Hijacking wrong positioning for UI elements. 2019-11-12 19:06:18 +01:00
Rinnegatamante 66bdf711f4 [VITA] Back to GL_LUMINANCE_ALPHA usage. 2019-11-12 16:33:47 +01:00
Rinnegatamante f3ca57e6f0 [VITA] Add vita video driver context. 2019-11-12 16:33:36 +01:00
Rinnegatamante 6b7673f806 [VITA] Fixing gl1 video driver crashes. 2019-11-12 15:37:37 +01:00
twinaphex 312f143253 Update dist-cores.sh 2019-11-12 14:55:37 +01:00
twinaphex 3a552e08ff Fix dist-cores.sh 2019-11-12 14:54:21 +01:00
Rinnegatamante 1533d618e5 [VITA] Allow usage of null context with gl1. 2019-11-12 13:50:14 +01:00
Rinnegatamante 6394342b9c [VITA] Add gl1 video driver support through vitaGL. 2019-11-12 11:54:00 +01:00
Weedy Weed Smoker 9c27f0e7c3 Update french language with the latest additions 2019-11-12 12:06:25 +07:00
twinaphex a0486c3cd7 Revert "Simplify slang_process.cpp"
This reverts commit 25a417cdd7.
2019-11-12 01:34:03 +01:00
Twinaphex 4cca0c1eb7 Merge pull request #9709 from Tatsuya79/patch-1
French translation fix
2019-11-11 19:58:40 +01:00
Tatsuya79 a75491375c French translation fix 2019-11-11 19:34:36 +01:00
Twinaphex d31dcbed81 Merge pull request #9708 from jdgleaver/glui-thumb-tweaks
(GLUI) Minor thumbnail improvements
2019-11-11 19:20:35 +01:00
twinaphex 25a417cdd7 Simplify slang_process.cpp 2019-11-11 18:55:33 +01:00
jdgleaver df6d65e061 (GLUI) Minor thumbnail improvements 2019-11-11 16:30:42 +00:00
Twinaphex 95f68b0625 Update CHANGES.md 2019-11-11 15:47:53 +01:00
Twinaphex f9f7092370 Update CHANGES.md 2019-11-11 15:47:44 +01:00
Twinaphex 9e2ac1100c Merge pull request #9701 from WeedyWeedSmoker/French-translation-update
Update the french translation
2019-11-11 15:46:16 +01:00
twinaphex 8f492adac3 Fix some errors 2019-11-11 15:05:18 +01:00
twinaphex 0a4795f6d5 Rewrite dist-cores.sh - make it so that we don't exit out of the entire
script when a core fails to compile
2019-11-11 15:03:49 +01:00
Twinaphex 8a26931622 Update CHANGES.md 2019-11-11 14:20:07 +01:00
Twinaphex 52db3779c7 Merge pull request #9706 from Jamiras/cheevos_unsupported
(cheevos) display Unofficial and Unsupported achievement states
2019-11-11 14:19:36 +01:00
Jamiras 84de1ce2f2 display Unofficial and Unsupported achievement states 2019-11-10 19:48:46 -07:00
twinaphex 6443169bac Desktop Menu - hide 'Online Updater' if HAVE_ONLINE_UPDATER is not
defined
2019-11-11 02:06:33 +01:00
twinaphex 08ce33eed0 Add HAVE_ONLINE_UPDATER 2019-11-11 00:22:03 +01:00
Weedy Weed Smoker 1fc1a48bfe Ready to merge! 2019-11-11 06:21:49 +07:00
Weedy Weed Smoker e4bcfa6a2a Missed one translation! Done... 2019-11-11 06:15:31 +07:00
twinaphex cf586b7273 Hide Core Updater properly 2019-11-10 18:12:23 +01:00
twinaphex bc657778fe Add HAVE_UPDATE_CORES - by running ./configure --disable-update_cores
you can strip out the Online Core Updater
2019-11-10 15:55:39 +01:00
Weedy Weed Smoker ad5874b94d Clarify a sublabel... 2019-11-10 04:01:09 +07:00
Weedy Weed Smoker 0e6f33103a Add the new dual-thumbnail option from the US file 2019-11-10 03:54:07 +07:00
twinaphex 455982da91 Silence warning 2019-11-09 18:01:13 +01:00
twinaphex 0c83d2a7cf (Libnx) RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT - return false for libnx 2019-11-09 17:29:49 +01:00
twinaphex dbd1e70410 RETRO_ENVIRONMENT_SET_HW_SHARED_CONTEXT - turn this off for now
for Switch
2019-11-09 17:16:29 +01:00
Twinaphex c62af7dc49 Merge pull request #9700 from jdgleaver/glui-dual-thumbs
(GLUI) Add dual thumbnail support
2019-11-09 15:19:21 +01:00
Weedy Weed Smoker 946713100a Add english back to the "cutie" color themes 2019-11-09 12:28:19 +07:00
Weedy Weed Smoker a3aef0f3f5 Use the "cutie" reference instead of a translation 2019-11-09 12:26:26 +07:00
Weedy Weed Smoker f3506054a1 Add a plural for the thumbnails... 2019-11-09 07:04:25 +07:00
Weedy Weed Smoker a5f1e9f817 Add a translation for "sunbeam"... 2019-11-09 01:28:59 +07:00
Weedy Weed Smoker ff03272e07 Update the french translation
with the latest additions in the US file!
2019-11-09 01:22:32 +07:00
jdgleaver bba454207e (GLUI) Add dual thumbnail support 2019-11-08 16:45:46 +00:00
Twinaphex f2898f4404 Merge pull request #9697 from BarryJRowe/master
Added fix for ai service overlay still showing when opening the menu.
2019-11-07 23:29:41 +01:00
Barry Rowe a247ee14cd Added fix for ai service overlay still showing when opening the menu. 2019-11-06 09:52:26 -08:00
Ömercan Kömür 42a85938e7 Update msg_hash_tr.h 2019-11-05 23:37:15 +03:00
Twinaphex 4d6555d58b Update CHANGES.md 2019-11-05 17:42:23 +01:00
Twinaphex 0493ecc7a6 Merge pull request #9687 from Jamiras/cheevos_user_agent
(cheevos) pass RetroArch and core versions through User-Agent HTTP header
2019-11-05 17:42:05 +01:00
Twinaphex 44219c00aa Update CHANGES.md 2019-11-05 17:41:33 +01:00
Twinaphex 545996f52e Merge pull request #9693 from altiereslima/master
Update Portuguese Brazilian translation
2019-11-05 17:41:04 +01:00
Twinaphex 16e7fe41dc Update CHANGES.md 2019-11-05 17:40:43 +01:00
Twinaphex 4a4b76111f Merge pull request #9692 from jdgleaver/glui-scroll-fix
(GLUI) Halt scrolling when pointer is pressed/stationary
2019-11-05 17:40:16 +01:00
Twinaphex 38716b518c Merge pull request #9688 from yoshisuga/ios_tvos_update_1_8_1
iOS/tvOS: update default assets.zip to show functional UI on startup;…
2019-11-05 17:02:51 +01:00
altiereslima a28bbf5d14 Update Portuguese Brazilian translation 2019-11-05 11:26:30 -03:00
jdgleaver 6afd684ae5 (GLUI) Halt scrolling when pointer is pressed/stationary 2019-11-05 12:23:09 +00:00
Ömercan Kömür ab56aca3ef Update msg_hash_tr.h
missing text added and translated
missing texts translated
2019-11-05 04:13:34 +03:00
Yoshi Sugawara 7e6ce4e279 iOS/tvOS: update default assets.zip to show functional UI on startup; update version to 1.8.1 2019-11-03 13:40:14 -10:00
Jamiras 67e9fba9d7 generate User-Agent for retroachievement API calls 2019-11-02 21:52:30 -06:00
Ömercan Kömür d326828fd6 Update msg_hash_tr.h
Missing texts translated to Turkish language
2019-11-02 18:00:29 +03:00
Ömercan Kömür 82b31c12c1 Flux
New RGUI Theme
2019-11-02 17:33:51 +03:00
orbea 841b3d620f travis: Log configure arguments + use before_script. 2019-11-01 09:41:38 -07:00
orbea b427f44908 qb: Update configure checks to print the check before the result.
This is very helpful for debugging in case the check just exits or hangs
unexpectingly.
2019-11-01 09:02:01 -07:00
orbea 98de418b7a qb: Improve the windres check. 2019-11-01 09:01:38 -07:00
orbea 8fc4a788e1 qb: Make the pkgconfig check more simple pt. 2: 2019-11-01 08:38:52 -07:00
orbea b590d0a219 qb: Print ... earlier.
Its better if the ... is printed before the check in case of unexpected
errors where it will look better.
2019-11-01 08:37:27 -07:00
orbea 98b04b99dc qb: Remove deprecated arguments.
Please use --bindir, --mandir and --sysconfdir now.
2019-10-31 22:53:52 -07:00
MrJs 41d3dfc591 Update project.pbxproj
Bump Optimization level to -0s for Release builds
2019-10-06 10:25:34 -07:00
397 changed files with 55323 additions and 10861 deletions

No files matched your search

+24 -2
View File
@@ -1,3 +1,9 @@
# This setting is to prevent travis to launch duplicate builds on PRs
branches:
only:
- master
- /^v.*$/
# Use 'generic' to be able to override CC/CXX for clang
language: generic
@@ -52,15 +58,28 @@ matrix:
env: CXX_BUILD=1 CC=clang-6.0 CXX=clang++-6.0
- os: osx
env: CC=clang CXX=clang++
- name: OSX OpenGL Make
os: osx
osx_image: xcode11.2
script:
- ./configure --enable-opengl --disable-metal
- make
- os: osx
osx_image: xcode8
script:
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
- os: osx
osx_image: xcode10.1
osx_image: xcode11.2
script:
- brew update-reset
- brew install --force-bottle qt5
- security create-keychain -p travis build.keychain
- security default-keychain -s build.keychain
- security unlock-keychain -p travis build.keychain
- echo $OSX_CERT | base64 --decode > dev.p12
- security import dev.p12 -k build.keychain -P $OSX_CERT_PASS -T /usr/bin/codesign
- rm dev.p12
- security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k travis build.keychain
- xcodebuild -target RetroArchQt -configuration Release -project pkg/apple/RetroArch_Metal.xcodeproj
deploy:
skip_cleanup: true
@@ -98,7 +117,7 @@ before_install:
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
fi
script:
before_script:
- |
if [ -n "$CROSS_COMPILE" ]; then
ARGS="$ARGS --disable-d3d8 --disable-d3d9 --disable-d3d10 --disable-d3d11 --disable-d3d12"
@@ -131,6 +150,9 @@ script:
if [ -n "$ENABLE_GLES3" ]; then
ARGS="$ARGS --enable-opengles3"
fi
- echo "Configure arguments = $ARGS"
script:
- ./configure $ARGS
- |
if [ -n "$C89_BUILD" ]; then
+119
View File
@@ -1,5 +1,124 @@
# Future
# 1.8.2
- BUG/CRASH/GLSLANG: Fix glslang crashing error - managed to reproduce an issue which has been plaguing
users for a while, where glslang throws an assert after closing a game (and starting a new one). This would affect all video drivers that use Slang for shaders, such as D3D10/11/12/Vulkan/Metal
- CHEEVOS: Display Unofficial and Unsupported achievement states
- CHEEVOS: Pass RetroArch and core versions through User-Agent HTTP header
- CHEEVOS: Use PSX.EXE if SYSTEM.CNF cannot be found
- CHEEVOS: Prevent loading state while achievements are still being fetched from server
- CHEEVOS: Pause hardcore if core doesn't support achievements
- CHEEVOS/CRASH: Fix AddressSanitizer + CHD cause hard crash when Cheevos are enabled
- CORE UPDATER: Only download when new core is available
- CORE UPDATER: Add option to update all installed cores
- DRM/KMS: Better detection for the current video mode
- DYNAMIC RATE CONTROL: Support DRC even when using a vsync swap interval higher than 1
- EMSCRIPTEN: Fix bug in Emscripten input code
- EMSCRIPTEN: Changes to support upgraded emscripten SDK
- FFMPEG CORE: Hardware accelerated video decoding
- FFMPEG CORE: Implement send/receive encoding API, will allow for hardware accelerated AMD video encoding
- FFMPEG CORE: The video FIFO can be removed, since we have a ring buffer in its place. This removes unneeded copy operations and as a positive side improves overall decoding speed. Makes 8k60p SW and 4k60p HW decoding feasible on many systems. For now the ring buffer is 32 images deep. This limitation will be removed, once audio and video decoder have their own packet handling.
- INPUT: Fix 'Analog stick controls menu even if autoconfig disabled'
- INPUT/TURBO: Added alternate Turbo-Mode 'Single Button' - For systems supporting only a single button, the turbo-button will toggle firing that button without the need to hold it. When holding the button turbo will be suspended and resumed when the button is released. Holding the button may have a different function to just tapping it.
- IOS: Forcibly disable Threaded Video until UIWindow concurrency issues are fixed
- INPUT/ANALOG: Fix radial analog deadzone scaling
- INPUT/ANALOG: Implement proper analog button deadzone
- INPUT/MENU: Analog stick controls menu even if autoconfig disabled
- LOCALIZATION: Update Italian translation
- LOCALIZATION: Update French translation
- LOCALIZATION: Update Polish translation
- LOCALIZATION: Update Portuguese Brazilian Translation
- LOCALIZATION: Update Turkish translation
- LINUX/LOCALIZATION: Correct Droid Sans Fallback font path in Linux. This should fix Chinese/Korean font display issues on Fedora/RHEL/CentOS/openSUSE/SLE
- MENU/BUGFIX: When using a keyboard/gamepad/mouse wheel to navigate, the menu scroll position is always maintained and updated in a consistent (and expected) fashion
- MENU/BUGFIX: When resizing the window, or changing the orientation of a mobile device, the current scroll position is correctly preserved
- MENU/BUGFIX: All 'normal' pointer input is now inhibited when showing message boxes
- MENU/BUGFIX: The pointer actions 'select' and 'cancel' both now properly close a message box if it is currently being shown
- MENU/BUGFIX: Pointer 'select' and 'cancel' actions are now inhibited when an input bind dialog is active
- MENU/INPUT: Change 'User' terminology to 'Port' for input binding
- MENU/LINUX: Add proper drives to Load Content
- MENU/MATERIALUI: Halt scrolling when pointer is pressed/stationary
- MENU/MATERIALUI: Dual thumbnail view
- MENU/MATERIALUI: Fullscreen thumbnail viewer for boxart
- MENU/MATERIALUI: Scroll rapidly by press and holding the scrollbar
- MENU/RGUI: New theme 'Flux'
- MENU/OZONE: Thumbnails now have a fade-in animation
- MENU/OZONE: Fullscreen thumbnail viewer for boxart and pictures
- MENU/QT/WIMP: Fix dock titles getting cut off
- MENU/XMB: Fullscreen thumbnail viewer for boxart and pictures
- MENU/USABILITY: Selectively hide 'Disallow Non-Slave Mode Clients' if 'Allow Slave-Mode Clients' is disabled
- MENU/USABILITY: Hide 'Show desktop menu on startup' if 'Desktop menu' setting itself is disabled
- MENU/USABILITY: Reimplement Quick Menu - > Shaders -> Watch shader files for changes - can now be turned on/off through touch
- MENU/USABILITY: Refactor Quick Menu - Controls - each port now has its own submenu
- MENU/USABILITY: Quick Menu - Cheats - Delete All no longer requires five right button presses - this should fix this functionality for mobile touch users too
- MENU/USABILITY: Hide Refresh Rate options when Threaded Video is enabled - these settings do nothing with Threaded Video
- MENU/USABILITY: Hide Logging Verbosity levels behind Logging Verbosity
- MENU/USABILITY: Get rid of 'Port Number' label for Port Binds screen
- MENU/USABILITY/MOBILE: Should no longer crash when clicking on a cheat entry
- MENU/USABILITY: Shader parameters now have a dropdown list
- MENU/USABILITY: Shader passes now has a dropdown list
- MENU/USABILITY: Video - Hide Windowed Mode settings selectively
- MENU/USABILITY: Video - Hide Fullscreen Mode settings if windowed mode is not supported by context driver
- MENU/USABILITY: Selectively hide Network Command Port
- MENU/USABILITY: Selectively hide Relay Server Location
- MENU/USABILITY: User Interface -> Appearance - Selectively hide XMB Horizontal Animation setting
- MENU/USABILITY: Playlists - more selective hiding
- MENU/USABILITY: Selectively hide Rewind Settings
- MENU/USABILITY: Selectively hide Overlay Settings
- MENU/USABILITY: Selectively hide FPS Update Interval based on Display Framerate being enabled
- MENU/USABILITY: Selectively hide Onscreen Notifications BG Color Settings
- MENU/USABILITY: Settings -> Logging - Hide 'Log To File Timestamp' if 'Log To File' is disabled
- MENU/USABILITY: Video -> Scaling - Hide Custom Viewport X/Y when Integer Scale is enabled as description indicates
- MENU/USABILITY: Achievement submenu - selectively hide
- MENU/USABILITY: Settings -> Video -> Aspect ratio - selectively hide/show values based on whether you have Custom or Config selected
- MENU/USABILITY: Settings -> Video -> Selectively hide Hard Sync
- MENU/USABILITY: Settings -> Video -> Implement selective hiding for VSync and Hard Sync
- MENU/USABILITY: Selective hiding of Runahead settings based on global setting
- MENU/USABILITY: Add Input -> Haptic Feedback submenu
- MENU/USABILITY: Add Input -> Menu Controls submenu
- MENU/USABILITY: Settings -> Video -> Max Swapchain Images - Add OK action
- MENU/USABILITY: Input - Implement OK action for Bind Hold, Turbo Period and Duty Cycle
- MENU/USABILITY: Input - Hotkey Binds refactor
- MENU/USABILITY: Move 'Press Quit Twice' and 'Menu Toggle Gamepad Combo' to Input -> Hotkey Binds
- MENU/USABILITY: Video - Add sublabel for Video Output submenu
- MENU/USABILITY: If 'Favorites Tab' is disabled, don't show 'Add To Favorites' option in Quick Menu/Playlist menu
- MENU/USABILITY: If On-Demand Thumbnail Downloader is enabled, hide 'Download Thumbnails' from playlist menu screen
- MENU/USABILITY: Add Audio Driver setting to Audio -> Output
- MENU/USABILITY: Add Audio -> Resampler settings
- MENU/USABILITY: Add Audio -> Output and Audio -> Synchronization
- OPENGL: Shaders are now working properly (only in OpenGL) when rotating both from Core API rotation and from menu video rotation. The fix is clearly visible with crt-royale for example
- OPENGL: 1:1 PAR is now correct when rotating (both from Core API rotation and from menu video rotation, as you said, in the latter case you currently have to change Aspect Ratio after menu video rotation for it to work)
- OPENGL: When using Custom Aspect Ratio and rotation (both from Core API rotation and from menu video rotation), Integer Scaling is now working properly (correct multiples of internal resolution). Even when Integer Scaling is not activated, the Custom AR width / height are now correctly labeled using (1x), (2x), ... suffixes. You also have to activate Integer Scaling after menu video rotation for it to work
- OPENGL: For all other Aspect Ratio options, Integer Scaling and rotation (both from Core API rotation and from menu video rotation) are now working properly together (correct multiples of internal resolution). You also have to activate Integer Scaling after menu video rotation for it to work
- OPENBSD/POWERPC: Should build now on OpenBSD PowerPC
- PLAYLISTS: Pressing 'Start' or long touching a playlist will bring you to a Playlist submenu where you can set a default core, setup thumbnail view, delete the playlist, etc
- OSX: Forcibly disable Threaded Video until NSWindow concurrency issues are fixed
- PSP: Solving issue exiting RetroArch by HOME button
- SCANNER: Manual scanner, not dependent on database files
- SCANNER/MANUAL: Add option to scan inside archives
- SCANNER/MANUAL: Enable automatic naming of arcade content via DAT files. This is compatible with DAT files in either Logiqx XML or MAME List XML format.
- VIDEO: Do not reinit video driver on SET_SYSTEM_AV_INFO unless needed
- VIDEO: Support DRC even when using a vsync swap interval higher than 1
- VIDEO LAYOUT: Fixed XML parsing of attributes with spaces, should fix issues with several video layouts
- VITA: GL1 driver support
- VITA/VITA2D: Several improvements to Vita 2D driver - menu widgets implemented
- VITA/VITA2D: Fix clipping and reduce number of calls
- VULKAN/ANDROID: Workaround weird WSI return codes in landscape mode - Android WSI wants you to use preTransform, and if it is not used correctly, Android 10 will return VK_SUBOPTIMAL_KHR, and we would create a new swapchain every frame. This workaround just ignores this error, since it's not really an error. A more "proper" fix is to use prerotate and modify the MVP matrices,
which might help certain devices with crummy display processors
- VULKAN/ANDROID: Recreate swapchain on orientation change. ANativeWindow getWidth/Height does not detect any changes when using
Vulkan, so use the old onContentRectChanged callback to get notified when size changed. Use those values instead when figuring out how large swapchain to create
- WINDOWS/XINPUT: Get rid of 128 byte device name limit for XInput device discover - when device name was too long, it would not be picked up by the XInput driver and would instead fallback to DirectInput
- WINDOWS: ANGLE OpenGL ES 2 support
- UWP: Fix crashes on startup / prompt for folder permissions when trying to load custom.ini
- UWP: Fix - Mouse input is offset on high DPI monitors
- UWP: Fix - Keyboard input hangs sometimes
- UWP: Fix - Multi-touch support
- UWP: Fix - Enable menu touch input by default
- UWP: Fix - Get user language
- UWP: Fix - Get CPU model name
- UWP: Fix - Use GLUI instead of XMB on Windows Mobile 10
- UWP: ANGLE OpenGL ES 2 support
# (1.8.1)
- BUGFIX/MENU: Fix menu rendering with Mali GPUs after changing video dimensions
- CDROM: Adds pregap support to cdfs helper methods
+2 -2
View File
@@ -38,7 +38,7 @@ A pull request may be asked to fix the coding style before submission.
In other cases, a pull request may be followed up with a "style nit commit".
## Non-obvious things:
- Code should be both ISO C99 and ISO C++ compatible. This dual requirement is for XBox360 and MSVC in general. Think of it as a C++ compatible subset of C99.
- Code should be both C89 and ISO C++ compatible. This dual requirement is for XBox360 and MSVC in general. Think of it as a C++ compatible subset of C99.
- Warnings are not allowed (-Wall). Make sure your code is warning-free. Note that warning sensitivity differs a bit across compiler versions.
- Using deprecated APIs is discouraged.
@@ -55,4 +55,4 @@ We value discussing things in "real-time".
# Commit Access
Contributors who show a track record of making good pull requests over time will eventually get commit access to the repo.
This typically happens when the "overhead" of looking through pull requests over time becomes a burden.
This typically happens when the "overhead" of looking through pull requests over time becomes a burden.
+48 -10
View File
@@ -155,7 +155,6 @@ endif
OBJ += frontend/frontend_driver.o \
frontend/drivers/platform_null.o \
retroarch.o \
paths.o \
msg_hash.o \
intl/msg_hash_us.o \
$(LIBRETRO_COMM_DIR)/queues/task_queue.o \
@@ -164,6 +163,7 @@ OBJ += frontend/frontend_driver.o \
tasks/task_file_transfer.o \
tasks/task_image.o \
tasks/task_playlist_manager.o \
tasks/task_manual_content_scan.o \
$(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \
$(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \
$(LIBRETRO_COMM_DIR)/encodings/encoding_base64.o \
@@ -181,7 +181,6 @@ OBJ += frontend/frontend_driver.o \
$(LIBRETRO_COMM_DIR)/lists/string_list.o \
$(LIBRETRO_COMM_DIR)/string/stdstring.o \
$(LIBRETRO_COMM_DIR)/memmap/memalign.o \
list_special.o \
$(LIBRETRO_COMM_DIR)/file/nbio/nbio_stdio.o
ifneq ($(findstring Linux,$(OS)),)
@@ -260,8 +259,8 @@ OBJ += \
performance_counters.o \
verbosity.o \
midi/drivers/null_midi.o \
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o
$(LIBRETRO_COMM_DIR)/playlists/label_sanitization.o \
manual_content_scan.o
ifeq ($(HAVE_AUDIOMIXER), 1)
DEFINES += -DHAVE_AUDIOMIXER
@@ -893,6 +892,7 @@ ifeq ($(HAVE_VITA2D), 1)
$(DEPS_DIR)/libvita2d/shader/color_f_gxp.o \
$(DEPS_DIR)/libvita2d/shader/texture_v_gxp.o \
$(DEPS_DIR)/libvita2d/shader/texture_f_gxp.o \
$(DEPS_DIR)/libvita2d/shader/texture_tint_v_gxp.o \
$(DEPS_DIR)/libvita2d/shader/texture_tint_f_gxp.o
ifeq ($(HAVE_MENU_COMMON),1)
@@ -987,6 +987,12 @@ ifeq ($(HAVE_WAYLAND), 1)
endif
# XML
OBJ += \
$(LIBRETRO_COMM_DIR)/formats/xml/rxml.o \
$(LIBRETRO_COMM_DIR)/formats/logiqx_dat/logiqx_dat.o \
deps/yxml/yxml.o
#Input
ifeq ($(HAVE_DINPUT), 1)
@@ -1156,6 +1162,14 @@ ifeq ($(HAVE_PLAIN_DRM), 1)
LIBS += -ldrm
endif
ifeq ($(HAVE_VITAGL), 1)
DEFINES += -DHAVE_OPENGL1
OBJ += gfx/drivers/gl1.o \
gfx/drivers_font/gl1_raster_font.o \
gfx/drivers_context/vita_ctx.o \
menu/drivers_display/menu_display_gl1.o
endif
ifeq ($(HAVE_GL_CONTEXT), 1)
ifeq ($(HAVE_GL_MODERN), 1)
DEFINES += -DHAVE_OPENGL
@@ -1717,12 +1731,11 @@ endif
OBJ += $(LIBRETRO_COMM_DIR)/formats/bmp/rbmp_encode.o \
$(LIBRETRO_COMM_DIR)/formats/json/jsonsax.o \
$(LIBRETRO_COMM_DIR)/formats/json/jsonsax_full.o \
$(LIBRETRO_COMM_DIR)/formats/xml/rxml.o \
$(LIBRETRO_COMM_DIR)/formats/image_transfer.o
# Easter Egg
ifeq ($(HAVE_EASTEREGG),1)
DEFINES += -DHAVE_EASTEREGG
# Gong embedded core
ifeq ($(HAVE_GONG),1)
DEFINES += -DHAVE_GONG
OBJ += cores/libretro-gong/gong.o
endif
@@ -1747,6 +1760,7 @@ ifeq ($(HAVE_NETWORKING), 1)
$(LIBRETRO_COMM_DIR)/net/net_http_parse.o \
$(LIBRETRO_COMM_DIR)/net/net_socket.o \
$(LIBRETRO_COMM_DIR)/net/net_natt.o \
core_updater_list.o \
network/net_http_special.o \
tasks/task_http.o \
tasks/task_netplay_lan_scan.o \
@@ -1756,7 +1770,8 @@ ifeq ($(HAVE_NETWORKING), 1)
ifeq ($(HAVE_MENU_COMMON), 1)
OBJ += tasks/task_pl_thumbnail_download.o \
menu/menu_networking.o
tasks/task_core_updater.o \
menu/menu_networking.o
endif
ifeq ($(HAVE_SSL), 1)
@@ -1941,11 +1956,20 @@ ifneq ($(findstring Win32,$(OS)),)
LIBS += -lhid -lsetupapi
endif
ifeq ($(HAVE_ANGLE), 1)
OBJ += gfx/common/angle_common.o
DEFINES += -DHAVE_ANGLE
# TODO/FIXME - should perhaps set these libraries as separate CFLAG variables in qb system
LIBS += -lEGL
endif
# Record
ifeq ($(HAVE_FFMPEG), 1)
OBJ += record/drivers/record_ffmpeg.o \
cores/libretro-ffmpeg/ffmpeg_core.o
cores/libretro-ffmpeg/ffmpeg_core.o \
cores/libretro-ffmpeg/video_buffer.o \
$(LIBRETRO_COMM_DIR)/rthreads/tpool.o
LIBS += $(AVCODEC_LIBS) $(AVFORMAT_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(SWRESAMPLE_LIBS) $(FFMPEG_LIBS)
DEFINES += -DHAVE_FFMPEG
@@ -2037,6 +2061,20 @@ ifeq ($(HAVE_RPILED), 1)
OBJ += led/drivers/led_rpi.o
endif
ifeq ($(HAVE_MATH_NEON), 1)
DEFINES += -DHAVE_MATH_NEON
INCLUDE_DIRS += -I$(DEPS_DIR)/math-neon/source
SOURCES := $(DEPS_DIR)/math-neon/source
OBJ += $(patsubst %.c,%.o,$(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c)))
endif
ifeq ($(HAVE_VITAGL), 1)
DEFINES += -DHAVE_VITAGL -DTRANSPOSE_MATRICES
INCLUDE_DIRS += -I$(DEPS_DIR)/vitaGL/source
SOURCES := $(DEPS_DIR)/vitaGL/source $(DEPS_DIR)/vitaGL/source/utils
OBJ += $(patsubst %.c,%.o,$(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c)))
endif
##################################
### Classic Platform specifics ###
###############WIP################
+7 -8
View File
@@ -17,7 +17,6 @@ HAVE_CC_RESAMPLER = 1
HAVE_EGL = 1
HAVE_OPENGLES = 1
HAVE_RJPEG = 0
HAVE_RPNG = 1
HAVE_EMSCRIPTEN = 1
HAVE_MENU = 1
HAVE_MENU_WIDGETS = 1
@@ -30,7 +29,7 @@ HAVE_STATIC_VIDEO_FILTERS = 1
HAVE_STATIC_AUDIO_FILTERS = 1
HAVE_STB_FONT = 1
MEMORY = 536870912
MEMORY = 134217728
PRECISE_F32 = 1
@@ -38,9 +37,9 @@ OBJDIR := obj-emscripten
#if you compile with SDL2 flag add this Emscripten flag "-s USE_SDL=2" to LDFLAGS:
LIBS := -s USE_ZLIB=1
LDFLAGS := -L. --no-heap-copy -s USE_ZLIB=1 -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 \
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
LIBS := -s USE_ZLIB=1 -s USE_LIBPNG=1
LDFLAGS := -L. --no-heap-copy -s $(LIBS) -s TOTAL_MEMORY=$(MEMORY) -s NO_EXIT_RUNTIME=0 -s FULL_ES2=1 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']" \
-s ALLOW_MEMORY_GROWTH=1 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_load_state', '_cmd_take_screenshot']" \
--js-library emscripten/library_rwebaudio.js \
--js-library emscripten/library_rwebcam.js \
--js-library emscripten/library_errno_codes.js
@@ -70,16 +69,16 @@ ifeq ($(DEBUG), 1)
LDFLAGS += -O0 -g
CFLAGS += -O0 -g
else
LDFLAGS += -O2 -s WASM=1
LDFLAGS += -O3 -s WASM=1
# WARNING: some optimizations can break some cores (ex: LTO breaks tyrquake)
LDFLAGS += -s PRECISE_F32=$(PRECISE_F32)
ifeq ($(LTO), 1)
LDFLAGS += --llvm-lto 3
endif
CFLAGS += -O2
CFLAGS += -O3
endif
CFLAGS += -DHAVE_RPNG -Wall -I. -Ilibretro-common/include -std=gnu99 -s USE_ZLIB=1 \
CFLAGS += -Wall -I. -Ilibretro-common/include -std=gnu99 $(LIBS) \
-s EXPORTED_FUNCTIONS="['_main', '_malloc', '_cmd_savefiles', '_cmd_save_state', '_cmd_take_screenshot']"
RARCH_OBJ := $(addprefix $(OBJDIR)/,$(OBJ))
+6 -6
View File
@@ -439,7 +439,7 @@ else ifeq ($(platform), windows_msvc2005_x86)
CXX = cl.exe
LD = link.exe
PLATCFLAGS += -D_WIN32 -D_WIN32_WINNT=0x0410 -D__STDC_CONSTANT_MACROS -D_MBCS -DHAVE_EASTEREGG -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE
PLATCFLAGS += -D_WIN32 -D_WIN32_WINNT=0x0410 -D__STDC_CONSTANT_MACROS -D_MBCS -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib msimg32.lib
PATH := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin"):$(PATH)
@@ -491,7 +491,7 @@ else ifneq (,$(findstring windows_msvc2010,$(platform)))
LD = link.exe
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_UPDATE_ASSETS -DWIN32 -DHAVE_EASTEREGG -DHAVE_CDROM
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib msimg32.lib
PlatformSuffix = $(subst windows_msvc2010_,,$(platform))
@@ -565,7 +565,7 @@ else ifneq (,$(findstring windows_msvc2012,$(platform)))
LD = link.exe
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_UPDATE_ASSETS -DWIN32 -DHAVE_EASTEREGG -DHAVE_CDROM
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
PlatformSuffix = $(subst windows_msvc2012_,,$(platform))
@@ -643,7 +643,7 @@ else ifneq (,$(findstring windows_msvc2013,$(platform)))
LD = link.exe
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_UPDATE_ASSETS -DWIN32 -DHAVE_EASTEREGG -DHAVE_CDROM
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
PlatformSuffix = $(subst windows_msvc2013_,,$(platform))
@@ -722,7 +722,7 @@ else ifneq (,$(findstring windows_msvc2015,$(platform)))
PLATCFLAGS += -utf-8
PLATCFLAGS += -D_WIN32 -D__STDC_CONSTANT_MACROS -D_MBCS
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_UPDATE_ASSETS -DWIN32 -DHAVE_EASTEREGG -DHAVE_CDROM
PLATCFLAGS += -D__i686__ -D__MMX__ -D__SSE__ -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DHAVE_CC_RESAMPLER -DHAVE_GL_SYNC -DHAVE_GLSL -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_OPENGL -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DWIN32 -DHAVE_CDROM
LDFLAGS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib iphlpapi.lib
PlatformSuffix = $(subst windows_msvc2015_,,$(platform))
@@ -806,7 +806,7 @@ else ifneq (,$(findstring unix,$(platform)))
HAVE_GRIFFIN_CPP := 1
WANT_GLSLANG := 1
PLATCFLAGS += -DHAVE_EASTEREGG -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_FBO -DHAVE_GL_SYNC -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_MENU_WIDGETS -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_UPDATE_ASSETS -DHAVE_VULKAN -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_X11 -DHAVE_XCB -DHAVE_UDEV -DHAVE_PULSE
PLATCFLAGS += -D__MMX__ -D__SSE__ -DHAVE_OPENGL -DHAVE_OPENGL1 -DHAVE_GLSL -DHAVE_SHADERPIPELINE -DHAVE_OZONE -DHAVE_CC_RESAMPLER -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_FBO -DHAVE_GL_SYNC -DHAVE_SLANG -DHAVE_GLSLANG -DHAVE_IMAGEVIEWER -DHAVE_LANGEXTRA -DHAVE_RUNAHEAD -DHAVE_MENU_WIDGETS -DHAVE_SPIRV_CROSS -DHAVE_STB_FONT -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_VULKAN -DHAVE_XMB -DRARCH_INTERNAL -DWANT_GLSLANG -DHAVE_X11 -DHAVE_XCB -DHAVE_UDEV -DHAVE_PULSE
EXT_TARGET := $(TARGET_NAME)
EXT_INTER_TARGET := $(TARGET_NAME)
INCLUDE += -Ilibretro-common/include -Igfx/include -Ideps -Ideps/stb -Ideps/rcheevos/include -Ideps/SPIRV-Cross -Ideps/glslang -I.
+2 -1
View File
@@ -21,6 +21,7 @@ OBJ :=
DEFINES := -D__SWITCH__=1 -U__linux__ -U__linux -DGLM_FORCE_PURE=1 -DRARCH_CONSOLE -DRARCH_INTERNAL -DGLOBAL_CONFIG_DIR='"/switch"' -DHAVE_STB_VORBIS
HAVE_DR_MP3 = 1
HAVE_TRANSLATE = 1
HAVE_AUDIOMIXER = 1
HAVE_CC_RESAMPLER = 1
@@ -117,7 +118,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE -mcpu=cortex-a57+crc+fp
CFLAGS := -g -Wall -O3 -ffast-math -ffunction-sections \
$(ARCH) $(DEFINES) $(INCLUDE_DIRS) -I$(LIBNX)/include -I$(PORTLIBS)/include/ -include $(LIBNX)/include/switch.h #$(shell $(PORTLIBS)/bin/freetype-config --cflags)
CFLAGS += $(INCLUDE) -DSWITCH=1 -DHAVE_LIBNX=1 -DNXLINK=1 -DHAVE_SHADERPIPELINE -DHAVE_UPDATE_ASSETS -DHAVE_STB_FONT #-DHAVE_FREETYPE
CFLAGS += $(INCLUDE) -DSWITCH=1 -DHAVE_LIBNX=1 -DNXLINK=1 -DHAVE_SHADERPIPELINE -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES -DHAVE_STB_FONT #-DHAVE_FREETYPE
ifeq ($(strip $(HAVE_STATIC_DUMMY)),1)
CFLAGS += -DHAVE_STATIC_DUMMY=1
+4 -1
View File
@@ -18,7 +18,7 @@ ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1
DEFINES += -DHAVE_NEON -DHAVE_MENU -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB DEFINES -DHAVE_KEYMAPPER
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_CC_RESAMPLER -DHAVE_UPDATE_ASSETS
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DHAVE_CC_RESAMPLER -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_ASSETS -DHAVE_UPDATE_CORES
ifeq ($(DEBUG), 1)
DEFINES += -DHAVE_NETLOGGER
endif
@@ -26,6 +26,7 @@ ifeq ($(GRIFFIN_BUILD), 1)
else
HAVE_NEON := 1
HAVE_MATH_NEON := 1
HAVE_FILTERS_BUILTIN := 1
HAVE_LANGEXTRA := 1
HAVE_RPNG := 1
@@ -35,10 +36,12 @@ else
HAVE_ZLIB := 1
HAVE_7ZIP := 1
HAVE_VITA2D := 1
HAVE_VITAGL := 1
HAVE_NETWORKING := 1
HAVE_SOCKET_LEGACY := 1
HAVE_MENU := 1
HAVE_MENU_COMMON := 1
HAVE_MENU_WIDGETS = 1
HAVE_OVERLAY := 1
HAVE_VIDEO_LAYOUT := 0
HAVE_MATERIALUI := 1
+2
View File
@@ -74,7 +74,9 @@ ifeq ($(SALAMANDER_BUILD),1)
else
DEFINES += -DRARCH_INTERNAL
DEFINES += -DHAVE_KEYMAPPER
DEFINES += -DHAVE_ONLINE_UPDATER
DEFINES += -DHAVE_UPDATE_ASSETS
DEFINES += -DHAVE_UPDATE_CORES
DEFINES += -DHAVE_FILTERS_BUILTIN
DEFINES += -DHAVE_SLANG
DEFINES += -DHAVE_SHADERPIPELINE
+3 -3
View File
@@ -4,10 +4,10 @@
#include <psp2/kernel/sysmem.h>
#include <psp2/kernel/threadmgr.h>
#define RAM_THRESHOLD 0xA00000 // Memory left to the system for threads and other internal stuffs
#define RAM_THRESHOLD 0x1000000 // Memory left to the system for threads and other internal stuffs
static int _newlib_heap_memblock;
static unsigned _newlib_heap_size;
int _newlib_heap_memblock;
unsigned _newlib_heap_size;
char *_newlib_heap_base, *_newlib_heap_end, *_newlib_heap_cur;
static char _newlib_sbrk_mutex[32] __attribute__ ((aligned (8)));
+560 -307
View File
File diff suppressed because it is too large. Load diff
+24 -3
View File
@@ -168,9 +168,30 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console)
}
else if (console == RC_CONSOLE_PC_ENGINE)
{
/* RAM. */
CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1f0000);
address += 0x1f0000;
if (address < 0x002000)
{
/* RAM. */
CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1f0000);
address += 0x1f0000;
}
else if (address < 0x012000)
{
/* CD-ROM RAM. */
CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x100000 - 0x002000);
address += 0x100000 - 0x002000;
}
else if (address < 0x042000)
{
/* Super System Card RAM. */
CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x0d0000 - 0x012000);
address += 0x0d0000 - 0x012000;
}
else
{
/* CD-ROM battery backed RAM. */
CHEEVOS_LOG(RCHEEVOS_TAG "PCE memory address %X adjusted to %X\n", address, address + 0x1ee000 - 0x042000);
address += 0x1ee000 - 0x042000;
}
}
else if (console == RC_CONSOLE_SUPER_NINTENDO)
{
+31 -5
View File
@@ -97,7 +97,7 @@
#define DEFAULT_MOUSE_SCALE 1
#endif
#if defined(RARCH_MOBILE) || defined(HAVE_LIBNX)
#if defined(RARCH_MOBILE) || defined(HAVE_LIBNX) || defined(__WINRT__)
#define DEFAULT_POINTER_ENABLE true
#else
#define DEFAULT_POINTER_ENABLE false
@@ -132,9 +132,9 @@
/* Adjust menu padding etc. to better fit the
* screen when using landscape layouts */
#if defined(RARCH_MOBILE)
#define DEFAULT_MATERIALUI_OPTIMIZE_LANDSCAPE_LAYOUT false
#define DEFAULT_MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION_DISABLED
#else
#define DEFAULT_MATERIALUI_OPTIMIZE_LANDSCAPE_LAYOUT true
#define DEFAULT_MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION_ALWAYS
#endif
/* Reposition navigation bar to make better use
@@ -146,6 +146,22 @@
#define DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL
#define DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM
/* Enable second thumbnail when using 'list view'
* thumbnail views
* Note: Second thumbnail will only be drawn if
* display has sufficient horizontal real estate */
#if defined(RARCH_MOBILE)
#define DEFAULT_MATERIALUI_DUAL_THUMBNAIL_LIST_VIEW_ENABLE false
#else
#define DEFAULT_MATERIALUI_DUAL_THUMBNAIL_LIST_VIEW_ENABLE true
#endif
/* Draw solid colour 4:3 background when rendering
* thumbnails
* > Helps to unify menu appearance when viewing
* thumbnails of different sizes */
#define DEFAULT_MATERIALUI_THUMBNAIL_BACKGROUND_ENABLE true
#define DEFAULT_CRT_SWITCH_RESOLUTION CRT_SWITCH_NONE
#define DEFAULT_CRT_SWITCH_RESOLUTION_SUPER 2560
@@ -156,6 +172,10 @@
#define DEFAULT_PLAYLIST_ENTRY_RENAME true
#define DEFAULT_ACCESSIBILITY_ENABLE false
#define DEFAULT_ACCESSIBILITY_NARRATOR_SPEECH_SPEED 5
#define DEFAULT_DRIVER_SWITCH_ENABLE true
#define DEFAULT_USER_LANGUAGE 0
@@ -187,7 +207,13 @@
/* Fullscreen */
/* To start in Fullscreen, or not. */
#ifdef HAVE_STEAM
/* Start in fullscreen mode for Steam build */
#define DEFAULT_FULLSCREEN true
#else
#define DEFAULT_FULLSCREEN false
#endif
/* To use windowed mode or not when going fullscreen. */
#define DEFAULT_WINDOWED_FULLSCREEN true
@@ -492,9 +518,7 @@ static bool content_show_video = true;
static bool content_show_netplay = true;
#endif
static bool content_show_history = true;
#ifdef HAVE_LIBRETRODB
static bool content_show_add = true;
#endif
static bool content_show_playlists = true;
#ifdef HAVE_XMB
@@ -955,6 +979,8 @@ static const float analog_sensitivity = 1.0f;
/* Describes speed of which turbo-enabled buttons toggle. */
static const unsigned turbo_period = 6;
static const unsigned turbo_duty_cycle = 3;
static const unsigned turbo_mode = 0;
static const unsigned turbo_default_btn = RETRO_DEVICE_ID_JOYPAD_B;
/* Enable input auto-detection. Will attempt to autoconfigure
* gamepads, plug-and-play style. */
+29 -26
View File
@@ -319,6 +319,8 @@ enum midi_driver_enum
#if defined(HAVE_METAL)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_METAL;
#elif defined(HAVE_VITA2D)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D;
#elif defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_GL;
#elif defined(HAVE_OPENGL_CORE)
@@ -345,8 +347,6 @@ static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D9;
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_D3D8;
#elif defined(HAVE_VG)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VG;
#elif defined(HAVE_VITA2D)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_VITA2D;
#elif defined(PSP)
static enum video_driver_enum VIDEO_DEFAULT_DRIVER = VIDEO_PSP1;
#elif defined(PS2)
@@ -1330,6 +1330,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
struct config_bool_setting *tmp = (struct config_bool_setting*)calloc(1, (*size + 1) * sizeof(struct config_bool_setting));
unsigned count = 0;
SETTING_BOOL("accessibility_enable", &settings->bools.accessibility_enable, true, DEFAULT_ACCESSIBILITY_ENABLE, false);
SETTING_BOOL("driver_switch_enable", &settings->bools.driver_switch_enable, true, DEFAULT_DRIVER_SWITCH_ENABLE, false);
SETTING_BOOL("frame_time_counter_reset_after_fastforwarding", &settings->bools.frame_time_counter_reset_after_fastforwarding, true, false, false);
SETTING_BOOL("frame_time_counter_reset_after_load_state", &settings->bools.frame_time_counter_reset_after_load_state, true, false, false);
@@ -1522,9 +1523,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
SETTING_BOOL("content_show_netplay", &settings->bools.menu_content_show_netplay, true, content_show_netplay, false);
#endif
SETTING_BOOL("content_show_history", &settings->bools.menu_content_show_history, true, content_show_history, false);
#ifdef HAVE_LIBRETRODB
SETTING_BOOL("content_show_add", &settings->bools.menu_content_show_add, true, content_show_add, false);
#endif
SETTING_BOOL("content_show_playlists", &settings->bools.menu_content_show_playlists, true, content_show_playlists, false);
SETTING_BOOL("menu_show_load_core", &settings->bools.menu_show_load_core, true, menu_show_load_core, false);
SETTING_BOOL("menu_show_load_content", &settings->bools.menu_show_load_content, true, menu_show_load_content, false);
@@ -1556,8 +1555,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
SETTING_BOOL("menu_show_advanced_settings", &settings->bools.menu_show_advanced_settings, true, DEFAULT_SHOW_ADVANCED_SETTINGS, false);
#ifdef HAVE_MATERIALUI
SETTING_BOOL("materialui_icons_enable", &settings->bools.menu_materialui_icons_enable, true, DEFAULT_MATERIALUI_ICONS_ENABLE, false);
SETTING_BOOL("materialui_optimize_landscape_layout", &settings->bools.menu_materialui_optimize_landscape_layout, true, DEFAULT_MATERIALUI_OPTIMIZE_LANDSCAPE_LAYOUT, false);
SETTING_BOOL("materialui_auto_rotate_nav_bar", &settings->bools.menu_materialui_auto_rotate_nav_bar, true, DEFAULT_MATERIALUI_AUTO_ROTATE_NAV_BAR, false);
SETTING_BOOL("materialui_dual_thumbnail_list_view_enable", &settings->bools.menu_materialui_dual_thumbnail_list_view_enable, true, DEFAULT_MATERIALUI_DUAL_THUMBNAIL_LIST_VIEW_ENABLE, false);
SETTING_BOOL("materialui_thumbnail_background_enable", &settings->bools.menu_materialui_thumbnail_background_enable, true, DEFAULT_MATERIALUI_THUMBNAIL_BACKGROUND_ENABLE, false);
#endif
#ifdef HAVE_RGUI
SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false);
@@ -1726,6 +1726,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
if (!tmp)
return NULL;
SETTING_UINT("accessibility_narrator_speech_speed", &settings->uints.accessibility_narrator_speech_speed, true, DEFAULT_ACCESSIBILITY_NARRATOR_SPEECH_SPEED, false);
#ifdef HAVE_NETWORKING
SETTING_UINT("streaming_mode", &settings->uints.streaming_mode, true, STREAMING_MODE_TWITCH, false);
#endif
@@ -1734,6 +1735,8 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
SETTING_UINT("input_bind_hold", &settings->uints.input_bind_hold, true, input_bind_hold, false);
SETTING_UINT("input_turbo_period", &settings->uints.input_turbo_period, true, turbo_period, false);
SETTING_UINT("input_duty_cycle", &settings->uints.input_turbo_duty_cycle, true, turbo_duty_cycle, false);
SETTING_UINT("input_turbo_mode", &settings->uints.input_turbo_mode, true, turbo_mode, false);
SETTING_UINT("input_turbo_default_button", &settings->uints.input_turbo_default_button, true, turbo_default_btn, false);
SETTING_UINT("input_max_users", input_driver_get_uint(INPUT_ACTION_MAX_USERS), true, input_max_users, false);
SETTING_UINT("fps_update_interval", &settings->uints.fps_update_interval, true, DEFAULT_FPS_UPDATE_INTERVAL, false);
SETTING_UINT("input_menu_toggle_gamepad_combo", &settings->uints.input_menu_toggle_gamepad_combo, true, menu_toggle_gamepad_combo, false);
@@ -1814,6 +1817,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
SETTING_UINT("materialui_menu_transition_animation", &settings->uints.menu_materialui_transition_animation, true, DEFAULT_MATERIALUI_TRANSITION_ANIM, false);
SETTING_UINT("materialui_thumbnail_view_portrait", &settings->uints.menu_materialui_thumbnail_view_portrait, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT, false);
SETTING_UINT("materialui_thumbnail_view_landscape", &settings->uints.menu_materialui_thumbnail_view_landscape, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE, false);
SETTING_UINT("materialui_landscape_layout_optimization", &settings->uints.menu_materialui_landscape_layout_optimization, true, DEFAULT_MATERIALUI_LANDSCAPE_LAYOUT_OPTIMIZATION, false);
SETTING_UINT("menu_shader_pipeline", &settings->uints.menu_xmb_shader_pipeline, true, DEFAULT_MENU_SHADER_PIPELINE, false);
#ifdef HAVE_OZONE
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 1, false);
@@ -1950,12 +1954,13 @@ static struct config_int_setting *populate_settings_int(settings_t *settings, in
*
* Set 'default' configuration values.
**/
void config_set_defaults(void)
void config_set_defaults(void *data)
{
unsigned i, j;
#ifdef HAVE_MENU
static bool first_initialized = true;
#endif
global_t *global = (global_t*)data;
settings_t *settings = config_get_ptr();
int bool_settings_size = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
int float_settings_size = sizeof(settings->floats) / sizeof(settings->floats.placeholder);
@@ -2214,14 +2219,10 @@ void config_set_defaults(void)
rarch_ctl(RARCH_CTL_UNSET_BPS_PREF, NULL);
rarch_ctl(RARCH_CTL_UNSET_IPS_PREF, NULL);
if (global)
{
global_t *global = global_get_ptr();
if (global)
{
*global->record.output_dir = '\0';
*global->record.config_dir = '\0';
}
*global->record.output_dir = '\0';
*global->record.config_dir = '\0';
}
*settings->paths.path_core_options = '\0';
@@ -2687,7 +2688,8 @@ static bool check_menu_driver_compatibility(void)
* Loads a config file and reads all the values into memory.
*
*/
static bool config_load_file(const char *path, settings_t *settings)
static bool config_load_file(global_t *global,
const char *path, settings_t *settings)
{
unsigned i;
size_t path_size = PATH_MAX_LENGTH * sizeof(char);
@@ -3113,8 +3115,6 @@ static bool config_load_file(const char *path, settings_t *settings)
else if (path_is_directory(tmp_str))
{
global_t *global = global_get_ptr();
dir_set(RARCH_DIR_SAVEFILE, tmp_str);
if (global)
@@ -3138,8 +3138,6 @@ static bool config_load_file(const char *path, settings_t *settings)
dir_set(RARCH_DIR_SAVESTATE, g_defaults.dirs[DEFAULT_DIR_SAVESTATE]);
else if (path_is_directory(tmp_str))
{
global_t *global = global_get_ptr();
dir_set(RARCH_DIR_SAVESTATE, tmp_str);
if (global)
@@ -3382,7 +3380,8 @@ bool config_load_override(void)
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL);
if (!config_load_file(path_get(RARCH_PATH_CONFIG), config_get_ptr()))
if (!config_load_file(global_get_ptr(),
path_get(RARCH_PATH_CONFIG), config_get_ptr()))
goto error;
/* Restore the libretro_path we're using
@@ -3428,7 +3427,8 @@ bool config_unload_override(void)
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_STATE_PATH, NULL);
retroarch_override_setting_unset(RARCH_OVERRIDE_SETTING_SAVE_PATH, NULL);
if (!config_load_file(path_get(RARCH_PATH_CONFIG), config_get_ptr()))
if (!config_load_file(global_get_ptr(),
path_get(RARCH_PATH_CONFIG), config_get_ptr()))
return false;
RARCH_LOG("[Overrides] configuration overrides unloaded, original configuration restored.\n");
@@ -3575,8 +3575,9 @@ success:
* Loads a config file and reads all the values into memory.
*
*/
void config_parse_file(void)
void config_parse_file(void *data)
{
global_t *global = (global_t*)data;
if (path_is_empty(RARCH_PATH_CONFIG))
{
RARCH_LOG("[config] Loading default config.\n");
@@ -3586,7 +3587,7 @@ void config_parse_file(void)
const char *config_path = path_get(RARCH_PATH_CONFIG);
RARCH_LOG("[config] loading config from: %s.\n", config_path);
if (!config_load_file(config_path, config_get_ptr()))
if (!config_load_file(global, config_path, config_get_ptr()))
{
RARCH_ERR("[config] couldn't find config at path: \"%s\"\n",
config_path);
@@ -3600,10 +3601,11 @@ void config_parse_file(void)
* Loads a config file and reads all the values into memory.
*
*/
void config_load(void)
void config_load(void *data)
{
config_set_defaults();
config_parse_file();
global_t *global = (global_t*)data;
config_set_defaults(global);
config_parse_file(global);
}
/**
@@ -4034,7 +4036,8 @@ bool config_save_overrides(int override_type)
conf = config_file_new_alloc();
/* Load the original config file in memory */
config_load_file(path_get(RARCH_PATH_CONFIG), settings);
config_load_file(global_get_ptr(),
path_get(RARCH_PATH_CONFIG), settings);
bool_settings = populate_settings_bool(settings, &bool_settings_size);
tmp_i = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
+13 -3
View File
@@ -110,6 +110,9 @@ typedef struct settings
bool video_layout_enable;
#endif
/* Accessibility */
bool accessibility_enable;
/* Audio */
bool audio_enable;
bool audio_enable_menu;
@@ -186,8 +189,9 @@ typedef struct settings
bool menu_show_video_layout;
#endif
bool menu_materialui_icons_enable;
bool menu_materialui_optimize_landscape_layout;
bool menu_materialui_auto_rotate_nav_bar;
bool menu_materialui_dual_thumbnail_list_view_enable;
bool menu_materialui_thumbnail_background_enable;
bool menu_rgui_background_filler_thickness_enable;
bool menu_rgui_border_filler_thickness_enable;
bool menu_rgui_border_filler_enable;
@@ -460,6 +464,8 @@ typedef struct settings
unsigned input_turbo_period;
unsigned input_turbo_duty_cycle;
unsigned input_turbo_mode;
unsigned input_turbo_default_button;
unsigned input_bind_timeout;
unsigned input_bind_hold;
@@ -517,6 +523,9 @@ typedef struct settings
#endif
unsigned video_shader_delay;
/* Accessibility */
unsigned accessibility_narrator_speech_speed;
unsigned menu_timedate_style;
unsigned menu_thumbnails;
unsigned menu_left_thumbnails;
@@ -537,6 +546,7 @@ typedef struct settings
unsigned menu_materialui_transition_animation;
unsigned menu_materialui_thumbnail_view_portrait;
unsigned menu_materialui_thumbnail_view_landscape;
unsigned menu_materialui_landscape_layout_optimization;
unsigned menu_ozone_color_theme;
unsigned menu_font_color_red;
unsigned menu_font_color_green;
@@ -805,7 +815,7 @@ const char *config_get_default_record(void);
* Loads a config file and reads all the values into memory.
*
*/
void config_parse_file(void);
void config_parse_file(void *data);
/**
* config_load_override:
@@ -874,7 +884,7 @@ bool config_replace(bool config_save_on_exit, char *path);
bool config_overlay_enable_default(void);
void config_set_defaults(void);
void config_set_defaults(void *data);
settings_t *config_get_ptr(void);
+778
View File
@@ -0,0 +1,778 @@
/* Copyright (C) 2010-2019 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (core_updater_list.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <file/file_path.h>
#include <string/stdstring.h>
#include <lists/string_list.h>
#include <net/net_http.h>
#include <retro_miscellaneous.h>
#include "configuration.h"
#include "file_path_special.h"
#include "core_info.h"
#include "core_updater_list.h"
/* Holds all entries in a core updater list */
struct core_updater_list
{
size_t size;
size_t capacity;
core_updater_list_entry_t *entries;
};
/* Cached ('global') core updater list */
static core_updater_list_t *core_list_cached = NULL;
/**************************************/
/* Initialisation / De-Initialisation */
/**************************************/
/* Frees contents of specified core updater
* list entry */
static void core_updater_list_free_entry(core_updater_list_entry_t *entry)
{
if (!entry)
return;
if (entry->remote_filename)
{
free(entry->remote_filename);
entry->remote_filename = NULL;
}
if (entry->remote_core_path)
{
free(entry->remote_core_path);
entry->remote_core_path = NULL;
}
if (entry->local_core_path)
{
free(entry->local_core_path);
entry->local_core_path = NULL;
}
if (entry->local_info_path)
{
free(entry->local_info_path);
entry->local_info_path = NULL;
}
if (entry->display_name)
{
free(entry->display_name);
entry->display_name = NULL;
}
}
/* Creates a new, empty core updater list.
* Returns a handle to a new core_updater_list_t object
* on success, otherwise returns NULL. */
core_updater_list_t *core_updater_list_init(size_t max_size)
{
core_updater_list_t *core_list = NULL;
core_updater_list_entry_t *entries = NULL;
/* Sanity check */
if (max_size < 1)
return NULL;
/* Create core updater list */
core_list = (core_updater_list_t*)calloc(1, sizeof(*core_list));
if (!core_list)
return NULL;
/* Create entries array */
entries = (core_updater_list_entry_t*)calloc(max_size, sizeof(*entries));
if (!entries)
{
free(core_list);
return NULL;
}
/* Initial configuration */
core_list->size = 0;
core_list->capacity = max_size;
core_list->entries = entries;
return core_list;
}
/* Resets (removes all entries of) specified core
* updater list */
void core_updater_list_reset(core_updater_list_t *core_list)
{
size_t i;
if (!core_list)
return;
for (i = 0; i < core_list->size; i++)
{
core_updater_list_entry_t *entry = &core_list->entries[i];
if (entry)
core_updater_list_free_entry(entry);
}
core_list->size = 0;
}
/* Frees specified core updater list */
void core_updater_list_free(core_updater_list_t *core_list)
{
size_t i;
if (!core_list)
return;
for (i = 0; i < core_list->size; i++)
{
core_updater_list_entry_t *entry = &core_list->entries[i];
if (entry)
core_updater_list_free_entry(entry);
}
free(core_list->entries);
core_list->entries = NULL;
free(core_list);
}
/***************/
/* Cached List */
/***************/
/* Creates a new, empty cached core updater list
* (i.e. 'global' list).
* Returns false in the event of an error. */
bool core_updater_list_init_cached(size_t max_size)
{
/* Free any existing cached core updater list */
if (core_list_cached)
{
core_updater_list_free(core_list_cached);
core_list_cached = NULL;
}
core_list_cached = core_updater_list_init(max_size);
if (!core_list_cached)
return false;
return true;
}
/* Fetches cached core updater list */
core_updater_list_t *core_updater_list_get_cached(void)
{
if (core_list_cached)
return core_list_cached;
return NULL;
}
/* Frees cached core updater list */
void core_updater_list_free_cached(void)
{
core_updater_list_free(core_list_cached);
core_list_cached = NULL;
}
/***********/
/* Getters */
/***********/
/* Returns number of entries in core updater list */
size_t core_updater_list_size(core_updater_list_t *core_list)
{
if (!core_list)
return 0;
return core_list->size;
}
/* Returns maximum allowed number of entries in core
* updater list */
size_t core_updater_list_capacity(core_updater_list_t *core_list)
{
if (!core_list)
return 0;
return core_list->capacity;
}
/* Fetches core updater list entry corresponding
* to the specified entry index.
* Returns false if index is invalid. */
bool core_updater_list_get_index(
core_updater_list_t *core_list,
size_t idx,
const core_updater_list_entry_t **entry)
{
if (!core_list || !entry)
return false;
if (idx >= core_list->size)
return false;
if (entry)
*entry = &core_list->entries[idx];
return true;
}
/* Fetches core updater list entry corresponding
* to the specified remote core filename.
* Returns false if core is not found. */
bool core_updater_list_get_filename(
core_updater_list_t *core_list,
const char *remote_filename,
const core_updater_list_entry_t **entry)
{
size_t i;
if (!core_list || string_is_empty(remote_filename))
return false;
if (core_list->size < 1)
return false;
/* Search for specified filename */
for (i = 0; i < core_list->size; i++)
{
core_updater_list_entry_t *current_entry = &core_list->entries[i];
if (string_is_empty(current_entry->remote_filename))
continue;
if (string_is_equal(remote_filename, current_entry->remote_filename))
{
if (entry)
*entry = current_entry;
return true;
}
}
return false;
}
/* Fetches core updater list entry corresponding
* to the specified core.
* Returns false if core is not found. */
bool core_updater_list_get_core(
core_updater_list_t *core_list,
const char *local_core_path,
const core_updater_list_entry_t **entry)
{
size_t i;
char real_core_path[PATH_MAX_LENGTH];
real_core_path[0] = '\0';
if (!core_list || !entry || string_is_empty(local_core_path))
return false;
if (core_list->size < 1)
return false;
/* Resolve absolute pathname of local_core_path */
strlcpy(real_core_path, local_core_path, sizeof(real_core_path));
path_resolve_realpath(real_core_path, sizeof(real_core_path), true);
if (string_is_empty(real_core_path))
return false;
/* Search for specified core */
for (i = 0; i < core_list->size; i++)
{
core_updater_list_entry_t *current_entry = &core_list->entries[i];
if (string_is_empty(current_entry->local_core_path))
continue;
#ifdef _WIN32
/* Handle case-insensitive operating systems*/
if (string_is_equal_noncase(real_core_path, current_entry->local_core_path))
{
#else
if (string_is_equal(real_core_path, current_entry->local_core_path))
{
#endif
if (entry)
*entry = current_entry;
return true;
}
}
return false;
}
/***********/
/* Setters */
/***********/
/* Parses date string and adds contents to
* specified core updater list entry */
static bool core_updater_list_set_date(
core_updater_list_entry_t *entry, const char *date_str)
{
struct string_list *date_list = NULL;
if (!entry || string_is_empty(date_str))
goto error;
/* Split date string into component values */
date_list = string_split(date_str, "-");
if (!date_list)
goto error;
/* Date string must have 3 values:
* [year] [month] [day] */
if (date_list->size < 3)
goto error;
/* Convert date string values */
entry->date.year = string_to_unsigned(date_list->elems[0].data);
entry->date.month = string_to_unsigned(date_list->elems[1].data);
entry->date.day = string_to_unsigned(date_list->elems[2].data);
/* Clean up */
string_list_free(date_list);
return true;
error:
if (date_list)
string_list_free(date_list);
return false;
}
/* Parses crc string and adds value to
* specified core updater list entry */
static bool core_updater_list_set_crc(
core_updater_list_entry_t *entry, const char *crc_str)
{
uint32_t crc;
if (!entry || string_is_empty(crc_str))
return false;
crc = (uint32_t)string_hex_to_unsigned(crc_str);
if (crc == 0)
return false;
entry->crc = crc;
return true;
}
/* Parses core filename string and adds all
* associated paths to the specified core
* updater list entry */
static bool core_updater_list_set_paths(
core_updater_list_entry_t *entry, const char *filename_str)
{
settings_t *settings = config_get_ptr();
char *last_underscore = NULL;
char *tmp_url = NULL;
char remote_core_path[PATH_MAX_LENGTH];
char local_core_path[PATH_MAX_LENGTH];
char local_info_path[PATH_MAX_LENGTH];
char display_name[255];
bool is_archive;
remote_core_path[0] = '\0';
local_core_path[0] = '\0';
local_info_path[0] = '\0';
display_name[0] = '\0';
if (!entry || string_is_empty(filename_str) || !settings)
return false;
if (string_is_empty(settings->paths.directory_libretro) ||
string_is_empty(settings->paths.path_libretro_info) ||
string_is_empty(settings->paths.network_buildbot_url))
return false;
/* Check whether remote file is an archive */
is_archive = path_is_compressed_file(filename_str);
/* remote_filename */
if (entry->remote_filename)
{
free(entry->remote_filename);
entry->remote_filename = NULL;
}
entry->remote_filename = strdup(filename_str);
/* remote_core_path */
fill_pathname_join(
remote_core_path,
settings->paths.network_buildbot_url,
filename_str,
sizeof(remote_core_path));
/* > Apply proper URL encoding (messy...) */
tmp_url = strdup(remote_core_path);
remote_core_path[0] = '\0';
net_http_urlencode_full(
remote_core_path, tmp_url, sizeof(remote_core_path));
if (tmp_url)
free(tmp_url);
if (entry->remote_core_path)
{
free(entry->remote_core_path);
entry->remote_core_path = NULL;
}
entry->remote_core_path = strdup(remote_core_path);
/* local_core_path */
fill_pathname_join(
local_core_path,
settings->paths.directory_libretro,
filename_str,
sizeof(local_core_path));
if (is_archive)
path_remove_extension(local_core_path);
path_resolve_realpath(local_core_path, sizeof(local_core_path), true);
if (entry->local_core_path)
{
free(entry->local_core_path);
entry->local_core_path = NULL;
}
entry->local_core_path = strdup(local_core_path);
/* local_info_path */
fill_pathname_join_noext(
local_info_path,
settings->paths.path_libretro_info,
filename_str,
sizeof(local_info_path));
if (is_archive)
path_remove_extension(local_info_path);
/* > Remove any non-standard core filename
* additions (i.e. info files end with
* '_libretro' but core files may have
* a platform specific addendum,
* e.g. '_android')*/
last_underscore = (char*)strrchr(local_info_path, '_');
if (!string_is_empty(last_underscore))
{
if (string_is_not_equal_fast(last_underscore, "_libretro", 9))
*last_underscore = '\0';
}
/* > Add proper file extension */
strlcat(
local_info_path,
file_path_str(FILE_PATH_CORE_INFO_EXTENSION),
sizeof(local_info_path));
if (entry->local_info_path)
{
free(entry->local_info_path);
entry->local_info_path = NULL;
}
entry->local_info_path = strdup(local_info_path);
/* display_name
* > Note: It's a bit rubbish that we have to
* read the actual core info files here...
* Would be better to cache this globally
* (at present, we only cache info for
* *installed* cores...) */
if (path_is_valid(local_info_path))
if (!core_info_get_display_name(
local_info_path, display_name, sizeof(display_name)))
display_name[0] = '\0';
/* > If info file does not exist, just use
* core filename */
if (string_is_empty(display_name))
strlcpy(display_name, filename_str, sizeof(display_name));
if (entry->display_name)
{
free(entry->display_name);
entry->display_name = NULL;
}
entry->display_name = strdup(display_name);
return true;
}
/* Adds entry to the end of the specified core
* updater list
* NOTE: Entry string values are passed by
* reference - *do not free the entry passed
* to this function* */
static bool core_updater_list_push_entry(
core_updater_list_t *core_list, core_updater_list_entry_t *entry)
{
core_updater_list_entry_t *list_entry = NULL;
if (!core_list || !entry)
return false;
/* Ensure there is enough space for the new entry */
if (core_list->capacity <= core_list->size)
return false;
/* Get handle of new entry inside list */
list_entry = &core_list->entries[core_list->size];
if (!list_entry)
return false;
/* Ensure list entry is empty */
core_updater_list_free_entry(list_entry);
/* Assign paths */
list_entry->remote_filename = entry->remote_filename;
list_entry->remote_core_path = entry->remote_core_path;
list_entry->local_core_path = entry->local_core_path;
list_entry->local_info_path = entry->local_info_path;
list_entry->display_name = entry->display_name;
/* Copy crc */
list_entry->crc = entry->crc;
/* Copy date */
memcpy(&list_entry->date, &entry->date, sizeof(core_updater_list_date_t));
/* Increment list size */
core_list->size++;
return true;
}
/* Parses the contents of a single buildbot
* core listing and adds it to the specified
* core updater list */
static void core_updater_list_add_entry(
core_updater_list_t *core_list,
struct string_list *network_core_entry_list)
{
const char *date_str = NULL;
const char *crc_str = NULL;
const char *filename_str = NULL;
core_updater_list_entry_t entry = {0};
if (!core_list || !network_core_entry_list)
goto error;
/* > Listings must have 3 entries:
* [date] [crc] [filename] */
if (network_core_entry_list->size < 3)
goto error;
/* Get handles of the individual listing strings */
date_str = network_core_entry_list->elems[0].data;
crc_str = network_core_entry_list->elems[1].data;
filename_str = network_core_entry_list->elems[2].data;
if (string_is_empty(date_str) ||
string_is_empty(crc_str) ||
string_is_empty(filename_str))
goto error;
/* Check whether core file is already included
* in the list (this is *not* an error condition,
* it just means we can skip the current listing) */
if (core_updater_list_get_filename(core_list, filename_str, NULL))
goto error;
/* Parse individual listing strings */
if (!core_updater_list_set_date(&entry, date_str))
goto error;
if (!core_updater_list_set_crc(&entry, crc_str))
goto error;
if (!core_updater_list_set_paths(&entry, filename_str))
goto error;
/* Add entry to list */
if (!core_updater_list_push_entry(core_list, &entry))
goto error;
return;
error:
/* This is not a *fatal* error - it just
* means one of the following:
* - The current line of entry text received
* from the buildbot is broken somehow
* (could be the case that the network buffer
* wasn't large enough to cache the entire
* string, so the last line was truncated)
* - The core updater list struct is at capacity
* In either case, the current entry is discarded
* and we move on to the next one
* (network transfers are fishy business, so we
* choose to ignore this sort of error - don't
* want the whole fetch to fail because of a
* trivial glitch...) */
core_updater_list_free_entry(&entry);
}
/* Core updater list qsort helper function */
static int core_updater_list_qsort_func(
const core_updater_list_entry_t *a, const core_updater_list_entry_t *b)
{
if (!a || !b)
return 0;
if (string_is_empty(a->display_name) || string_is_empty(b->display_name))
return 0;
return strcasecmp(a->display_name, b->display_name);
}
/* Sorts core updater list into alphabetical order */
static void core_updater_list_qsort(core_updater_list_t *core_list)
{
if (!core_list)
return;
if (core_list->size < 2)
return;
qsort(
core_list->entries,
core_list->size,
sizeof(core_updater_list_entry_t),
(int (*)(const void *, const void *))
core_updater_list_qsort_func);
}
/* Reads the contents of a buildbot core list
* network request into the specified
* core_updater_list_t object.
* Returns false in the event of an error. */
bool core_updater_list_parse_network_data(
core_updater_list_t *core_list, const char *data, size_t len)
{
struct string_list *network_core_list = NULL;
struct string_list *network_core_entry_list = NULL;
char *data_buf = NULL;
size_t i;
/* Sanity check */
if (!core_list || string_is_empty(data) || (len < 1))
goto error;
/* We're populating a list 'from scratch' - remove
* any existing entries */
core_updater_list_reset(core_list);
/* Input data string is not terminated - have
* to copy it to a temporary buffer... */
data_buf = (char*)malloc((len + 1) * sizeof(char));
if (!data_buf)
goto error;
memcpy(data_buf, data, len * sizeof(char));
data_buf[len] = '\0';
/* Split network listing request into lines */
network_core_list = string_split(data_buf, "\n");
if (!network_core_list)
goto error;
if (network_core_list->size < 1)
goto error;
/* Temporary data buffer is no longer required */
free(data_buf);
/* Loop over lines */
for (i = 0; i < network_core_list->size; i++)
{
const char *line = network_core_list->elems[i].data;
if (string_is_empty(line))
continue;
/* Split line into listings info components */
network_core_entry_list = string_split(line, " ");
/* Parse listings info and add to core updater
* list */
core_updater_list_add_entry(
core_list, network_core_entry_list);
/* Clean up */
string_list_free(network_core_entry_list);
network_core_entry_list = NULL;
}
/* Sanity check */
if (core_list->size < 1)
goto error;
/* Clean up */
string_list_free(network_core_list);
/* Sort completed list */
core_updater_list_qsort(core_list);
return true;
error:
if (network_core_list)
string_list_free(network_core_list);
if (network_core_entry_list)
string_list_free(network_core_entry_list);
if (data_buf)
free(data_buf);
return false;
}
+143
View File
@@ -0,0 +1,143 @@
/* Copyright (C) 2010-2019 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (core_updater_list.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __CORE_UPDATER_LIST_H
#define __CORE_UPDATER_LIST_H
#include <retro_common_api.h>
#include <libretro.h>
#include <boolean.h>
RETRO_BEGIN_DECLS
/* Default maximum number of entries in
* a core updater list */
#define CORE_UPDATER_LIST_SIZE 9999
/* Holds all date info for a core file
* on the buildbot */
typedef struct
{
unsigned year;
unsigned month;
unsigned day;
} core_updater_list_date_t;
/* Holds all info related to a core
* file on the buildbot */
typedef struct
{
char *remote_filename;
char *remote_core_path;
char *local_core_path;
char *local_info_path;
char *display_name;
uint32_t crc;
core_updater_list_date_t date;
} core_updater_list_entry_t;
/* Prevent direct access to core_updater_list_t
* members */
typedef struct core_updater_list core_updater_list_t;
/**************************************/
/* Initialisation / De-Initialisation */
/**************************************/
/* Creates a new, empty core updater list with a
* maximum number of 'max_size' entries.
* Returns a handle to a new core_updater_list_t object
* on success, otherwise returns NULL. */
core_updater_list_t *core_updater_list_init(size_t max_size);
/* Resets (removes all entries of) specified core
* updater list */
void core_updater_list_reset(core_updater_list_t *core_list);
/* Frees specified core updater list */
void core_updater_list_free(core_updater_list_t *core_list);
/***************/
/* Cached List */
/***************/
/* Creates a new, empty cached core updater list
* (i.e. 'global' list).
* Returns false in the event of an error. */
bool core_updater_list_init_cached(size_t max_size);
/* Fetches cached core updater list */
core_updater_list_t *core_updater_list_get_cached(void);
/* Frees cached core updater list */
void core_updater_list_free_cached(void);
/***********/
/* Getters */
/***********/
/* Returns number of entries in core updater list */
size_t core_updater_list_size(core_updater_list_t *core_list);
/* Returns maximum allowed number of entries in core
* updater list */
size_t core_updater_list_capacity(core_updater_list_t *core_list);
/* Fetches core updater list entry corresponding
* to the specified entry index.
* Returns false if index is invalid. */
bool core_updater_list_get_index(
core_updater_list_t *core_list,
size_t idx,
const core_updater_list_entry_t **entry);
/* Fetches core updater list entry corresponding
* to the specified remote core filename.
* Returns false if core is not found. */
bool core_updater_list_get_filename(
core_updater_list_t *core_list,
const char *remote_filename,
const core_updater_list_entry_t **entry);
/* Fetches core updater list entry corresponding
* to the specified core.
* Returns false if core is not found. */
bool core_updater_list_get_core(
core_updater_list_t *core_list,
const char *local_core_path,
const core_updater_list_entry_t **entry);
/***********/
/* Setters */
/***********/
/* Reads the contents of a buildbot core list
* network request into the specified
* core_updater_list_t object.
* Returns false in the event of an error. */
bool core_updater_list_parse_network_data(
core_updater_list_t *core_list, const char *data, size_t len);
RETRO_END_DECLS
#endif
+1 -1
View File
@@ -360,7 +360,7 @@ size_t libretro_videoprocessor_retro_get_memory_size(unsigned id);
#endif
#ifdef HAVE_EASTEREGG
#ifdef HAVE_GONG
/* Internal gong core. */
void libretro_gong_retro_init(void);
+17 -4
View File
@@ -75,6 +75,11 @@ endif
TARGET_NAME := ffmpeg
GIT_VERSION ?= " $(shell git rev-parse --short HEAD || echo unknown)"
ifneq ($(GIT_VERSION)," unknown")
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
endif
ifneq (,$(findstring unix,$(platform)))
ARCH_X86 = 1
TARGET := $(TARGET_NAME)_libretro.so
@@ -123,7 +128,7 @@ else ifneq (,$(findstring ios,$(platform)))
TARGET := $(TARGET_NAME)_libretro_ios.dylib
fpic := -fPIC
SHARED := -dynamiclib
CFLAGS += -I. -I.. -DHAVE_FMINF -DIOS
CFLAGS += -I. -I.. -DHAVE_FMINF -DIOS -DHAVE_UNISTD_H
ifeq ($(OPENGL),1)
HAVE_OPENGL = 1
GLES = 1
@@ -140,11 +145,16 @@ ifeq ($(IOSSDK),)
IOSSDK := $(shell xcodebuild -version -sdk iphoneos Path)
endif
ifeq ($(platform),ios-arm64)
CC = cc -arch arm64 -isysroot $(IOSSDK)
CXX = c++ -arch arm64 -isysroot $(IOSSDK)
else
CC = cc -arch armv7 -isysroot $(IOSSDK)
CXX = c++ -arch armv7 -isysroot $(IOSSDK)
LD = armv7-apple-darwin11-ld
endif
ifeq ($(platform),ios9)
ifeq ($(platform),$(filter $(platform),ios9 ios-arm64))
CC += -miphoneos-version-min=8.0
CFLAGS += -miphoneos-version-min=8.0
else
@@ -177,20 +187,23 @@ else ifeq ($(platform), emscripten)
else
ARCH_X86 = 1
CC = gcc
CXX = g++
TARGET := $(TARGET_NAME)_libretro.dll
SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=link.T -Wl,--no-undefined
CFLAGS += -Iffmpeg
ifeq ($(OPENGL),1)
GL_LIB := -lopengl32
CFLAGS += -DHAVE_OPENGL
HAVE_OPENGL = 1
HAVE_GL_FFT := 1
WIN32_PLATFORM := 1
endif
LIBS += -L.
endif
ifeq ($(LIBRETRO_SWITCH), 1)
CFLAGS += -DUPSTREAM_VERSION=\"$(shell cat ../RELEASE)\"
endif
CFLAGS += -D__LIBRETRO__
include Makefile.common
+3 -1
View File
@@ -19,10 +19,12 @@ SWRESAMPLE_DIR := $(BASE_DIR)/libswresample
INCFLAGS += -I$(BASE_DIR) -I$(CORE_DIR) -I$(LIBRETRO_COMM_DIR)/include -I$(LIBRETRO_COMM_DIR)/include/compat
LIBRETRO_SOURCE += $(CORE_DIR)/ffmpeg_core.c \
$(CORE_DIR)/video_buffer.c \
$(LIBRETRO_COMM_DIR)/rthreads/tpool.c \
$(LIBRETRO_COMM_DIR)/queues/fifo_queue.c \
$(LIBRETRO_COMM_DIR)/rthreads/rthreads.c
ifeq ($(LIBRETRO_SWITCH),1)
ifeq ($(LIBRETRO_SWITCH), 1)
DEFINES += -DLIBRETRO_SWITCH=1
INTERNAL_LIBAVCODEC = 1
INTERNAL_LIBAVFORMAT = 1
+1
View File
@@ -5,6 +5,7 @@ ifeq ($(INTERNAL_ZLIB),0)
HAVE_ZLIB = 1
else
HAVE_ZLIB = 1
DEFINES += -DWANT_ZLIB
INCFLAGS += -I$(DEPS_DIR)/libz
DEPS_SOURCE += $(wildcard $(DEPS_DIR)/libz/*.c)
endif
File diff suppressed because it is too large. Load diff
+246
View File
@@ -0,0 +1,246 @@
#include <libavformat/avformat.h>
#include <rthreads/rthreads.h>
#include "video_buffer.h"
enum kbStatus
{
KB_OPEN,
KB_IN_PROGRESS,
KB_FINISHED
};
struct video_buffer
{
video_decoder_context_t *buffer;
enum kbStatus *status;
size_t size;
slock_t *lock;
scond_t *open_cond;
scond_t *finished_cond;
int64_t head;
int64_t tail;
};
video_buffer_t *video_buffer_create(size_t num, int frame_size, int width, int height)
{
video_buffer_t *b = malloc(sizeof (video_buffer_t));
if (!b)
return NULL;
b->lock = NULL;
b->open_cond = NULL;
b->finished_cond = NULL;
b->buffer = NULL;
b->size = num;
b->head = 0;
b->tail = 0;
b->status = malloc(sizeof(enum kbStatus) * num);
if (!b->status)
goto fail;
for (int i = 0; i < num; i++)
b->status[i] = KB_OPEN;
b->lock = slock_new();
b->open_cond = scond_new();
b->finished_cond = scond_new();
if (!b->lock || !b->open_cond || !b->finished_cond)
goto fail;
b->buffer = malloc(sizeof(video_decoder_context_t) * num);
if (!b->buffer)
goto fail;
for (int i = 0; i < num; i++)
{
b->buffer[i].index = i;
b->buffer[i].pts = 0;
b->buffer[i].sws = sws_alloc_context();
b->buffer[i].source = av_frame_alloc();
#if LIBAVUTIL_VERSION_MAJOR > 55
b->buffer[i].hw_source = av_frame_alloc();
#endif
b->buffer[i].target = av_frame_alloc();
b->buffer[i].frame_buf = av_malloc(frame_size);
avpicture_fill((AVPicture*)b->buffer[i].target, (const uint8_t*)b->buffer[i].frame_buf,
PIX_FMT_RGB32, width, height);
if (!b->buffer[i].sws ||
!b->buffer[i].source ||
#if LIBAVUTIL_VERSION_MAJOR > 55
!b->buffer[i].hw_source ||
#endif
!b->buffer[i].target ||
!b->buffer[i].frame_buf)
goto fail;
}
return b;
fail:
video_buffer_destroy(b);
return NULL;
}
void video_buffer_destroy(video_buffer_t *video_buffer)
{
if (!video_buffer)
return;
slock_free(video_buffer->lock);
scond_free(video_buffer->open_cond);
scond_free(video_buffer->finished_cond);
free(video_buffer->status);
if (video_buffer->buffer)
for (int i = 0; i < video_buffer->size; i++)
{
#if LIBAVUTIL_VERSION_MAJOR > 55
av_frame_free(&video_buffer->buffer[i].hw_source);
#endif
av_frame_free(&video_buffer->buffer[i].source);
av_frame_free(&video_buffer->buffer[i].target);
av_freep(&video_buffer->buffer[i].frame_buf);
sws_freeContext(video_buffer->buffer[i].sws);
}
free(video_buffer->buffer);
free(video_buffer);
}
void video_buffer_clear(video_buffer_t *video_buffer)
{
if (!video_buffer)
return;
slock_lock(video_buffer->lock);
scond_signal(video_buffer->open_cond);
scond_signal(video_buffer->finished_cond);
video_buffer->head = 0;
video_buffer->tail = 0;
for (int i = 0; i < video_buffer->size; i++)
video_buffer->status[i] = KB_OPEN;
slock_unlock(video_buffer->lock);
}
void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_context_t **context)
{
slock_lock(video_buffer->lock);
if (video_buffer->status[video_buffer->head] == KB_OPEN)
{
*context = &video_buffer->buffer[video_buffer->head];
video_buffer->status[video_buffer->head] = KB_IN_PROGRESS;
video_buffer->head++;
video_buffer->head %= video_buffer->size;
}
slock_unlock(video_buffer->lock);
}
void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context)
{
slock_lock(video_buffer->lock);
if (video_buffer->status[context->index] == KB_IN_PROGRESS)
{
video_buffer->status[context->index] = KB_OPEN;
video_buffer->head--;
video_buffer->head %= video_buffer->size;
}
slock_unlock(video_buffer->lock);
}
void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context)
{
slock_lock(video_buffer->lock);
if (video_buffer->status[context->index] == KB_FINISHED)
{
video_buffer->status[context->index] = KB_OPEN;
video_buffer->tail++;
video_buffer->tail %= (video_buffer->size);
scond_signal(video_buffer->open_cond);
}
slock_unlock(video_buffer->lock);
}
void video_buffer_get_finished_slot(video_buffer_t *video_buffer, video_decoder_context_t **context)
{
slock_lock(video_buffer->lock);
if (video_buffer->status[video_buffer->tail] == KB_FINISHED)
*context = &video_buffer->buffer[video_buffer->tail];
slock_unlock(video_buffer->lock);
}
void video_buffer_finish_slot(video_buffer_t *video_buffer, video_decoder_context_t *context)
{
slock_lock(video_buffer->lock);
if (video_buffer->status[context->index] == KB_IN_PROGRESS)
{
video_buffer->status[context->index] = KB_FINISHED;
scond_signal(video_buffer->finished_cond);
}
slock_unlock(video_buffer->lock);
}
bool video_buffer_wait_for_open_slot(video_buffer_t *video_buffer)
{
slock_lock(video_buffer->lock);
while (video_buffer->status[video_buffer->head] != KB_OPEN)
scond_wait(video_buffer->open_cond, video_buffer->lock);
slock_unlock(video_buffer->lock);
return true;
}
bool video_buffer_wait_for_finished_slot(video_buffer_t *video_buffer)
{
slock_lock(video_buffer->lock);
while (video_buffer->status[video_buffer->tail] != KB_FINISHED)
scond_wait(video_buffer->finished_cond, video_buffer->lock);
slock_unlock(video_buffer->lock);
return true;
}
bool video_buffer_has_open_slot(video_buffer_t *video_buffer)
{
bool ret = false;
slock_lock(video_buffer->lock);
if (video_buffer->status[video_buffer->head] == KB_OPEN)
ret = true;
slock_unlock(video_buffer->lock);
return ret;
}
bool video_buffer_has_finished_slot(video_buffer_t *video_buffer)
{
bool ret = false;
slock_lock(video_buffer->lock);
if (video_buffer->status[video_buffer->tail] == KB_FINISHED)
ret = true;
slock_unlock(video_buffer->lock);
return ret;
}
+196
View File
@@ -0,0 +1,196 @@
#ifndef __LIBRETRO_SDK_SWSBUFFER_H__
#define __LIBRETRO_SDK_SWSBUFFER_H__
#include <retro_common_api.h>
#include <boolean.h>
#include <stdint.h>
#ifdef HAVE_SSA
#include <ass/ass.h>
#endif
#include <libavutil/frame.h>
#include <libswscale/swscale.h>
#include <retro_miscellaneous.h>
RETRO_BEGIN_DECLS
#ifndef PIX_FMT_RGB32
#define PIX_FMT_RGB32 AV_PIX_FMT_RGB32
#endif
/**
* video_decoder_context
*
* Context object for the sws worker threads.
*
*/
struct video_decoder_context
{
int index;
int64_t pts;
struct SwsContext *sws;
AVFrame *source;
#if LIBAVUTIL_VERSION_MAJOR > 55
AVFrame *hw_source;
#endif
AVFrame *target;
#ifdef HAVE_SSA
ASS_Track *ass_track_active;
#endif
uint8_t *frame_buf;
};
typedef struct video_decoder_context video_decoder_context_t;
/**
* video_buffer
*
* The video_buffer is a ring buffer, that can be used as a
* buffer for many workers while keeping the order.
*
* It is thread safe in a sensem that it is designed to work
* with one work coordinator, that allocates work slots for
* workers threads to work on and later collect the work
* product in the same order, as the slots were allocated.
*
*/
struct video_buffer;
typedef struct video_buffer video_buffer_t;
/**
* video_buffer_create:
* @num : Size of the buffer.
* @frame_size : Size of the target frame.
* @width : Width of the target frame.
* @height : Height of the target frame.
*
* Create a video_buffer.
*
* Returns: A video buffer.
*/
video_buffer_t *video_buffer_create(size_t num, int frame_size, int width, int height);
/**
* video_buffer_destroy:
* @video_buffer : video buffer.
*
* Destory a video_buffer.
*
* Does also free the buffer allocated with video_buffer_create().
* User has to shut down any external worker threads that may have
* a reference to this video_buffer.
*
**/
void video_buffer_destroy(video_buffer_t *video_buffer);
/**
* video_buffer_clear:
* @video_buffer : video buffer.
*
* Clears a video_buffer.
*
**/
void video_buffer_clear(video_buffer_t *video_buffer);
/**
* video_buffer_get_open_slot:
* @video_buffer : video buffer.
* @contex : sws context.
*
* Returns the next open context inside the ring buffer
* and it's index. The status of the slot will be marked as
* 'in progress' until slot is marked as finished with
* video_buffer_finish_slot();
*
**/
void video_buffer_get_open_slot(video_buffer_t *video_buffer, video_decoder_context_t **context);
/**
* video_buffer_return_open_slot:
* @video_buffer : video buffer.
* @contex : sws context.
*
* Marks the given sws context that is "in progress" as "open" again.
*
**/
void video_buffer_return_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_open_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Sets the status of the given context from "finished" to "open".
* The slot is then available for producers to claim again with video_buffer_get_open_slot().
**/
void video_buffer_open_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_get_finished_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Returns a reference for the next context inside
* the ring buffer. User needs to use video_buffer_open_slot()
* to open the slot in the ringbuffer for the next
* work assignment. User is free to re-allocate or
* re-use the context.
*
*/
void video_buffer_get_finished_slot(video_buffer_t *video_buffer, video_decoder_context_t **context);
/**
* video_buffer_finish_slot:
* @video_buffer : video buffer.
* @context : sws context.
*
* Sets the status of the given context from "in progress" to "finished".
* This is normally done by a producer. User can then retrieve the finished work
* context by calling video_buffer_get_finished_slot().
*/
void video_buffer_finish_slot(video_buffer_t *video_buffer, video_decoder_context_t *context);
/**
* video_buffer_wait_for_open_slot:
* @video_buffer : video buffer.
*
* Blocks until open slot is available.
*
* Returns true if the buffer has a open slot available.
*/
bool video_buffer_wait_for_open_slot(video_buffer_t *video_buffer);
/**
* video_buffer_wait_for_finished_slot:
* @video_buffer : video buffer.
*
* Blocks until finished slot is available.
*
* Returns true if the buffers next slot is finished and a
* context available.
*/
bool video_buffer_wait_for_finished_slot(video_buffer_t *video_buffer);
/**
* bool video_buffer_has_open_slot(video_buffer_t *video_buffer)
:
* @video_buffer : video buffer.
*
* Returns true if the buffer has a open slot available.
*/
bool video_buffer_has_open_slot(video_buffer_t *video_buffer);
/**
* video_buffer_has_finished_slot:
* @video_buffer : video buffer.
*
* Returns true if the buffers next slot is finished and a
* context available.
*/
bool video_buffer_has_finished_slot(video_buffer_t *video_buffer);
RETRO_END_DECLS
#endif
+21 -4
View File
@@ -21,6 +21,7 @@
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <mutex>
#include "../../verbosity.h"
@@ -31,18 +32,33 @@ struct SlangProcess
{
public:
SlangProcess();
TBuiltInResource& GetResources() { return Resources; }
~SlangProcess() { FinalizeProcess(); }
private:
TBuiltInResource Resources;
};
// We don't use glslang from multiple threads, but to be sure.
// Initializing TLS and freeing it for glslang works around a really bizarre issue
// where the TLS key is suddenly corrupted *somehow*.
static std::mutex glslang_global_lock;
struct SlangProcessHolder
{
SlangProcessHolder()
{
glslang_global_lock.lock();
InitializeProcess();
}
~SlangProcessHolder()
{
FinalizeProcess();
glslang_global_lock.unlock();
}
};
SlangProcess::SlangProcess()
{
InitializeProcess();
char DefaultConfig[] =
"MaxLights 32\n"
"MaxClipPlanes 6\n"
@@ -337,6 +353,7 @@ SlangProcess::SlangProcess()
bool glslang::compile_spirv(const string &source, Stage stage, std::vector<uint32_t> *spirv)
{
static SlangProcess process;
SlangProcessHolder process_holder;
TProgram program;
EShLanguage language;
@@ -158,6 +158,7 @@ bool DetachProcess()
OS_FreeTLSIndex(ThreadInitializeIndex);
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
DeinitializePoolIndex();
return success;
}
@@ -38,6 +38,7 @@
namespace glslang {
bool InitializePoolIndex();
bool DeinitializePoolIndex();
} // end namespace glslang
@@ -65,6 +65,15 @@ bool InitializePoolIndex()
return true;
}
bool DeinitializePoolIndex()
{
if (PoolIndex == OS_INVALID_TLS_INDEX)
return false;
OS_FreeTLSIndex(PoolIndex);
PoolIndex = OS_INVALID_TLS_INDEX;
return true;
}
//
// Implement the functionality of the TPoolAllocator class, which
// is documented in PoolAlloc.h.
@@ -1312,6 +1312,7 @@ int __fastcall ShFinalize()
glslang::HlslScanContext::deleteKeywordMap();
#endif
DetachProcess();
return 1;
}
+2 -1
View File
@@ -8,10 +8,11 @@ extern SceGxmVertexProgram *_vita2d_colorVertexProgram;
extern SceGxmFragmentProgram *_vita2d_colorFragmentProgram;
extern SceGxmVertexProgram *_vita2d_textureVertexProgram;
extern SceGxmFragmentProgram *_vita2d_textureFragmentProgram;
extern SceGxmVertexProgram *_vita2d_textureTintVertexProgram;
extern SceGxmFragmentProgram *_vita2d_textureTintFragmentProgram;
extern const SceGxmProgramParameter *_vita2d_colorWvpParam;
extern const SceGxmProgramParameter *_vita2d_textureWvpParam;
extern const SceGxmProgramParameter *_vita2d_textureTintColorParam;
extern const SceGxmProgramParameter *_vita2d_textureTintWvpParam;
#endif
+15 -1
View File
@@ -31,6 +31,18 @@ typedef struct vita2d_texture_vertex {
float v;
} vita2d_texture_vertex;
typedef struct vita2d_texture_tint_vertex {
float x;
float y;
float z;
float u;
float v;
float r;
float g;
float b;
float a;
} vita2d_texture_tint_vertex;
typedef struct vita2d_texture {
SceGxmTexture gxm_tex;
SceUID data_UID;
@@ -77,6 +89,7 @@ int vita2d_get_clipping_enabled();
void vita2d_set_clip_rectangle(int x_min, int y_min, int x_max, int y_max);
void vita2d_get_clip_rectangle(int *x_min, int *y_min, int *x_max, int *y_max);
void vita2d_set_blend_mode_add(int enable);
void vita2d_set_viewport(int x, int y, int width, int height);
void *vita2d_pool_malloc(unsigned int size);
void *vita2d_pool_memalign(unsigned int size, unsigned int alignment);
@@ -120,13 +133,14 @@ void vita2d_draw_texture_part_scale_rotate(const vita2d_texture *texture, float
void vita2d_draw_texture_tint(const vita2d_texture *texture, float x, float y, unsigned int color);
void vita2d_draw_texture_tint_rotate(const vita2d_texture *texture, float x, float y, float rad, unsigned int color);
void vita2d_draw_texture_tint_rotate_hotspot(const vita2d_texture *texture, float x, float y, float rad, float center_x, float center_y, unsigned int color);
void vita2d_draw_texture_tint_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, unsigned int color);
void vita2d_draw_texture_tint_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, const float *color);
void vita2d_draw_texture_tint_part(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, unsigned int color);
void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, unsigned int color);
void vita2d_draw_texture_tint_scale_rotate_hotspot(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y, unsigned int color);
void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, unsigned int color);
void vita2d_draw_texture_part_tint_scale_rotate(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, float rad, unsigned int color);
void vita2d_draw_array_textured(const vita2d_texture *texture, SceGxmPrimitiveType mode, const vita2d_texture_vertex *vertices, size_t count, unsigned int color);
void vita2d_draw_array_textured_mat(const vita2d_texture *texture, const vita2d_texture_tint_vertex *vertices, size_t count, float *mat);
/** ADVANCED **/
void vita2d_texture_set_wvp(float x, float y, float width, float height);
+20 -22
View File
@@ -1,24 +1,22 @@
/* Generated by bin2c, do not edit manually */
/* Contents of file texture_tint_f.gxp */
const long int texture_tint_f_gxp_size = 288;
// Imported from file 'shader_f.gxp'
const unsigned char texture_tint_f_gxp[288] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x04, 0x00, 0x00, 0x1F, 0x01, 0x00, 0x00, 0xEA, 0xFC, 0xA0, 0xCB,
0x79, 0x0C, 0xE6, 0xA5, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00,
0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x00, 0xF8,
0x02, 0x80, 0x99, 0xAF, 0xBC, 0x0D, 0xC0, 0x40, 0x3C, 0x00, 0x04, 0xCF, 0x84, 0x47, 0xA4, 0x08,
0x00, 0xBC, 0x19, 0x20, 0x7E, 0x0D, 0x81, 0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0xE4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x54, 0x69, 0x6E, 0x74, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x00, 0x74, 0x65, 0x78, 0x00, 0x00
0x47,0x58,0x50,0x00,0x01,0x05,0x10,0x03,0x20,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x05,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xc4,0x00,0x00,0x00,0x70,0x00,0x00,0x00,
0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x00,0x00,
0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x74,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0xc0,0x3c,0x03,0x00,
0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x01,0x00,0x01,0x00,0x04,0x00,0x00,0x00,
0x00,0xa9,0xd0,0x0e,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x44,0xfa,0x00,0x00,0x00,0x00,
0x40,0x09,0x00,0xf8,0x02,0x80,0x99,0xaf,0xbc,0x0d,0xc0,0x40,0x06,0x82,0xb9,0xaf,
0xbc,0x0d,0x80,0x40,0x7c,0x0f,0x04,0x00,0x86,0x47,0xa4,0x10,0x30,0x00,0x00,0x00,
0x02,0x04,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0x65,0x78,0x00
};
const unsigned int texture_tint_f_gxp_size = 288;
+28
View File
@@ -0,0 +1,28 @@
// Imported from file 'shader_v.gxp'
const unsigned char texture_tint_v_gxp[384] = {
0x47,0x58,0x50,0x00,0x01,0x05,0x10,0x03,0x7f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70,0x00,0x00,0x00,
0x0c,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x0b,0x00,0x00,0x00,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x74,0x00,0x00,0x00,0x70,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0xb0,0x00,0x00,0x00,0xc0,0x3c,0x03,0x00,
0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa4,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x94,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8c,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x0f,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0a,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x07,0x44,0xfa,0x01,0x0e,0x01,0x01,0x02,0x00,0x10,0xfa,
0x80,0x00,0x08,0x83,0x21,0x25,0x80,0x38,0x01,0x01,0x01,0x01,0x00,0x00,0x14,0xfa,
0x02,0x80,0x81,0xaf,0x9c,0x0d,0xc0,0x40,0x0e,0x86,0xb9,0xff,0xbc,0x0d,0xc0,0x40,
0x04,0x11,0x49,0xcf,0x80,0x8f,0xb1,0x18,0x02,0x11,0x45,0xcf,0x80,0x8f,0xb1,0x18,
0x00,0x11,0x01,0xc0,0x81,0x81,0xb1,0x18,0x01,0xd1,0x42,0xc0,0x81,0x81,0xb1,0x18,
0x00,0x00,0x20,0xa0,0x00,0x50,0x27,0xfb,0x0e,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
0x40,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3a,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
0x2b,0x00,0x00,0x00,0x01,0xe4,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x61,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x61,0x54,0x65,0x78,0x63,0x6f,
0x6f,0x72,0x64,0x00,0x61,0x43,0x6f,0x6c,0x6f,0x72,0x00,0x77,0x76,0x70,0x00,0x00
};
const unsigned int texture_tint_v_gxp_size = 384;
+78 -5
View File
@@ -39,6 +39,7 @@ extern const SceGxmProgram color_v_gxp;
extern const SceGxmProgram color_f_gxp;
extern const SceGxmProgram texture_v_gxp;
extern const SceGxmProgram texture_f_gxp;
extern const SceGxmProgram texture_tint_v_gxp;
extern const SceGxmProgram texture_tint_f_gxp;
/* Static variables */
@@ -51,6 +52,7 @@ static const SceGxmProgram *const colorVertexProgramGxp = &color_v_gxp;
static const SceGxmProgram *const colorFragmentProgramGxp = &color_f_gxp;
static const SceGxmProgram *const textureVertexProgramGxp = &texture_v_gxp;
static const SceGxmProgram *const textureFragmentProgramGxp = &texture_f_gxp;
static const SceGxmProgram *const textureTintVertexProgramGxp = &texture_tint_v_gxp;
static const SceGxmProgram *const textureTintFragmentProgramGxp = &texture_tint_f_gxp;
static int vita2d_initialized = 0;
@@ -95,6 +97,7 @@ static SceGxmShaderPatcherId colorVertexProgramId;
static SceGxmShaderPatcherId colorFragmentProgramId;
static SceGxmShaderPatcherId textureVertexProgramId;
static SceGxmShaderPatcherId textureFragmentProgramId;
static SceGxmShaderPatcherId textureTintVertexProgramId;
static SceGxmShaderPatcherId textureTintFragmentProgramId;
static SceUID patcherBufferUid;
@@ -113,11 +116,12 @@ SceGxmVertexProgram *_vita2d_colorVertexProgram = NULL;
SceGxmFragmentProgram *_vita2d_colorFragmentProgram = NULL;
SceGxmVertexProgram *_vita2d_textureVertexProgram = NULL;
SceGxmFragmentProgram *_vita2d_textureFragmentProgram = NULL;
SceGxmVertexProgram *_vita2d_textureTintVertexProgram = NULL;
SceGxmFragmentProgram *_vita2d_textureTintFragmentProgram = NULL;
const SceGxmProgramParameter *_vita2d_clearClearColorParam = NULL;
const SceGxmProgramParameter *_vita2d_colorWvpParam = NULL;
const SceGxmProgramParameter *_vita2d_textureWvpParam = NULL;
const SceGxmProgramParameter *_vita2d_textureTintColorParam = NULL;
const SceGxmProgramParameter *_vita2d_textureTintWvpParam = NULL;
typedef struct vita2d_fragment_programs {
SceGxmFragmentProgram *color;
@@ -208,7 +212,7 @@ static void _vita2d_make_fragment_programs(vita2d_fragment_programs *out,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
msaa,
blend_info,
textureVertexProgramGxp,
textureTintVertexProgramGxp,
&out->textureTint);
VITA2D_DEBUG("texture_tint sceGxmShaderPatcherCreateFragmentProgram(): 0x%08X\n", err);
@@ -442,6 +446,8 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
VITA2D_DEBUG("texture_v sceGxmProgramCheck(): 0x%08X\n", err);
err = sceGxmProgramCheck(textureFragmentProgramGxp);
VITA2D_DEBUG("texture_f sceGxmProgramCheck(): 0x%08X\n", err);
err = sceGxmProgramCheck(textureTintVertexProgramGxp);
VITA2D_DEBUG("texture_v sceGxmProgramCheck(): 0x%08X\n", err);
err = sceGxmProgramCheck(textureTintFragmentProgramGxp);
VITA2D_DEBUG("texture_tint_f sceGxmProgramCheck(): 0x%08X\n", err);
@@ -464,6 +470,9 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
err = sceGxmShaderPatcherRegisterProgram(shaderPatcher, textureFragmentProgramGxp, &textureFragmentProgramId);
VITA2D_DEBUG("texture_f sceGxmShaderPatcherRegisterProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherRegisterProgram(shaderPatcher, textureTintVertexProgramGxp, &textureTintVertexProgramId);
VITA2D_DEBUG("texture_v sceGxmShaderPatcherRegisterProgram(): 0x%08X\n", err);
err = sceGxmShaderPatcherRegisterProgram(shaderPatcher, textureTintFragmentProgramGxp, &textureTintFragmentProgramId);
VITA2D_DEBUG("texture_tint_f sceGxmShaderPatcherRegisterProgram(): 0x%08X\n", err);
@@ -630,6 +639,52 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err);
const SceGxmProgramParameter *paramTextureTintPositionAttribute = sceGxmProgramFindParameterByName(textureTintVertexProgramGxp, "aPosition");
VITA2D_DEBUG("aPosition sceGxmProgramFindParameterByName(): %p\n", paramTextureTintPositionAttribute);
const SceGxmProgramParameter *paramTextureTintTexcoordAttribute = sceGxmProgramFindParameterByName(textureTintVertexProgramGxp, "aTexcoord");
VITA2D_DEBUG("aTexcoord sceGxmProgramFindParameterByName(): %p\n", paramTextureTintTexcoordAttribute);
const SceGxmProgramParameter *paramTextureTintColorAttribute = sceGxmProgramFindParameterByName(textureTintVertexProgramGxp, "aColor");
VITA2D_DEBUG("aColor sceGxmProgramFindParameterByName(): %p\n", paramTextureTintColorAttribute);
// create texture vertex format
SceGxmVertexAttribute textureTintVertexAttributes[3];
SceGxmVertexStream textureTintVertexStreams[1];
/* x,y,z: 3 float 32 bits */
textureTintVertexAttributes[0].streamIndex = 0;
textureTintVertexAttributes[0].offset = 0;
textureTintVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
textureTintVertexAttributes[0].componentCount = 3; // (x, y, z)
textureTintVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTintPositionAttribute);
/* u,v: 2 floats 32 bits */
textureTintVertexAttributes[1].streamIndex = 0;
textureTintVertexAttributes[1].offset = 12; // (x, y, z) * 4 = 12 bytes
textureTintVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
textureTintVertexAttributes[1].componentCount = 2; // (u, v)
textureTintVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTintTexcoordAttribute);
/* r,g,b,a: 4 floats 32 bits */
textureTintVertexAttributes[2].streamIndex = 0;
textureTintVertexAttributes[2].offset = 20; // (u, v) * 4 = 8 bytes
textureTintVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
textureTintVertexAttributes[2].componentCount = 4; // (r, g, b, a)
textureTintVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTintColorAttribute);
// 16 bit (short) indices
textureTintVertexStreams[0].stride = sizeof(vita2d_texture_tint_vertex);
textureTintVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
// create texture shaders
err = sceGxmShaderPatcherCreateVertexProgram(
shaderPatcher,
textureTintVertexProgramId,
textureTintVertexAttributes,
3,
textureTintVertexStreams,
1,
&_vita2d_textureTintVertexProgram);
VITA2D_DEBUG("texture sceGxmShaderPatcherCreateVertexProgram(): 0x%08X\n", err);
// Create variations of the fragment program based on blending mode
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_normal, &blend_info, msaa);
_vita2d_make_fragment_programs(&_vita2d_fragmentPrograms.blend_mode_add, &blend_info_add, msaa);
@@ -647,8 +702,8 @@ static int vita2d_init_internal(unsigned int temp_pool_size, SceGxmMultisampleMo
_vita2d_textureWvpParam = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
VITA2D_DEBUG("texture wvp sceGxmProgramFindParameterByName(): %p\n", _vita2d_textureWvpParam);
_vita2d_textureTintColorParam = sceGxmProgramFindParameterByName(textureTintFragmentProgramGxp, "uTintColor");
VITA2D_DEBUG("texture wvp sceGxmProgramFindParameterByName(): %p\n", _vita2d_textureWvpParam);
_vita2d_textureTintWvpParam = sceGxmProgramFindParameterByName(textureTintVertexProgramGxp, "wvp");
VITA2D_DEBUG("texture tint wvp sceGxmProgramFindParameterByName(): %p\n", _vita2d_textureTintWvpParam);
// Allocate memory for the memory pool
pool_size = temp_pool_size;
@@ -743,7 +798,8 @@ int vita2d_fini()
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, colorVertexProgramId);
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, textureFragmentProgramId);
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, textureTintFragmentProgramId);
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, textureVertexProgramId);
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, textureTintVertexProgramId);
sceGxmShaderPatcherUnregisterProgram(shaderPatcher, textureVertexProgramId);
sceGxmShaderPatcherDestroy(shaderPatcher);
fragment_usse_free(patcherFragmentUsseUid);
@@ -877,12 +933,16 @@ int vita2d_get_clipping_enabled()
void vita2d_set_clip_rectangle(int x_min, int y_min, int x_max, int y_max)
{
vita2d_set_viewport(0,0,DISPLAY_WIDTH,DISPLAY_HEIGHT);
clipping_enabled = 1;
clip_rect_x_min = x_min;
clip_rect_y_min = y_min;
clip_rect_x_max = x_max;
clip_rect_y_max = y_max;
// we can only draw during a scene, but we can cache the values since they're not going to have any visible effect till the scene starts anyways
if(drawing) {
sceGxmSetFrontDepthWriteEnable(_vita2d_context,
SCE_GXM_DEPTH_WRITE_DISABLED);
// clear the stencil buffer to 0
sceGxmSetFrontStencilFunc(
_vita2d_context,
@@ -903,6 +963,8 @@ void vita2d_set_clip_rectangle(int x_min, int y_min, int x_max, int y_max)
0xFF,
0xFF);
vita2d_draw_rectangle(x_min, y_min, x_max - x_min, y_max - y_min, 0);
sceGxmSetFrontDepthWriteEnable(_vita2d_context,
SCE_GXM_DEPTH_WRITE_ENABLED);
if(clipping_enabled) {
// set the stencil function to only accept pixels where the stencil is 1
sceGxmSetFrontStencilFunc(
@@ -1035,4 +1097,15 @@ void vita2d_set_blend_mode_add(int enable)
_vita2d_colorFragmentProgram = in->color;
_vita2d_textureFragmentProgram = in->texture;
_vita2d_textureTintFragmentProgram = in->textureTint;
}
void vita2d_set_viewport(int x, int y, int width, int height){
static float vh = DISPLAY_HEIGHT;
float sw = width / 2.;
float sh = height / 2.;
float x_scale = sw;
float x_port = x + sw;
float y_scale = -(sh);
float y_port = vh - y - sh;
sceGxmSetViewport(_vita2d_context, x_port, x_scale, y_port, y_scale, -0.5f, 0.5f);
}
+127 -27
View File
@@ -271,7 +271,7 @@ static inline void set_texture_program()
static inline void set_texture_tint_program()
{
sceGxmSetVertexProgram(_vita2d_context, _vita2d_textureVertexProgram);
sceGxmSetVertexProgram(_vita2d_context, _vita2d_textureTintVertexProgram);
sceGxmSetFragmentProgram(_vita2d_context, _vita2d_textureTintFragmentProgram);
}
@@ -282,21 +282,11 @@ static inline void set_texture_wvp_uniform()
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix);
}
static inline void set_texture_tint_color_uniform(unsigned int color)
static inline void set_texture_tint_wvp_uniform()
{
void *texture_tint_color_buffer;
sceGxmReserveFragmentDefaultUniformBuffer(_vita2d_context, &texture_tint_color_buffer);
float *tint_color = vita2d_pool_memalign(
4 * sizeof(float), // RGBA
sizeof(float));
tint_color[0] = ((color >> 8*0) & 0xFF)/255.0f;
tint_color[1] = ((color >> 8*1) & 0xFF)/255.0f;
tint_color[2] = ((color >> 8*2) & 0xFF)/255.0f;
tint_color[3] = ((color >> 8*3) & 0xFF)/255.0f;
sceGxmSetUniformDataF(texture_tint_color_buffer, _vita2d_textureTintColorParam, 0, 4, tint_color);
void *vertex_wvp_buffer;
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer);
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureTintWvpParam, 0, 16, _vita2d_ortho_matrix);
}
static inline void draw_texture_generic(const vita2d_texture *texture, float x, float y)
@@ -350,7 +340,6 @@ void vita2d_draw_texture_tint(const vita2d_texture *texture, float x, float y, u
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_generic(texture, x, y);
}
@@ -430,7 +419,6 @@ void vita2d_draw_texture_tint_rotate_hotspot(const vita2d_texture *texture, floa
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_rotate_hotspot_generic(texture, x, y, rad, center_x, center_y);
}
@@ -474,6 +462,54 @@ static inline void draw_texture_scale_generic(const vita2d_texture *texture, flo
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
}
static inline void draw_texture_tint_scale_generic(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, const float *color)
{
vita2d_texture_tint_vertex *vertices = (vita2d_texture_tint_vertex *)vita2d_pool_memalign(
4 * sizeof(vita2d_texture_tint_vertex), // 4 vertices
sizeof(vita2d_texture_tint_vertex));
const float w = x_scale * vita2d_texture_get_width(texture);
const float h = y_scale * vita2d_texture_get_height(texture);
vertices[0].x = x;
vertices[0].y = y;
vertices[0].z = +0.5f;
vertices[0].u = 0.0f;
vertices[0].v = 0.0f;
vertices[1].x = x + w;
vertices[1].y = y;
vertices[1].z = +0.5f;
vertices[1].u = 1.0f;
vertices[1].v = 0.0f;
vertices[2].x = x;
vertices[2].y = y + h;
vertices[2].z = +0.5f;
vertices[2].u = 0.0f;
vertices[2].v = 1.0f;
vertices[3].x = x + w;
vertices[3].y = y + h;
vertices[3].z = +0.5f;
vertices[3].u = 1.0f;
vertices[3].v = 1.0f;
for(int n = 0; n < 4; n++){
int k = (n + 2) % 4 ;
vertices[n].r = color[4*k+0];
vertices[n].g = color[4*k+1];
vertices[n].b = color[4*k+2];
vertices[n].a = color[4*k+3];
}
// Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
}
void vita2d_draw_texture_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale)
{
set_texture_program();
@@ -481,12 +517,11 @@ void vita2d_draw_texture_scale(const vita2d_texture *texture, float x, float y,
draw_texture_scale_generic(texture, x, y, x_scale, y_scale);
}
void vita2d_draw_texture_tint_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, unsigned int color)
void vita2d_draw_texture_tint_scale(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, const float *color)
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_scale_generic(texture, x, y, x_scale, y_scale);
set_texture_tint_wvp_uniform();
draw_texture_tint_scale_generic(texture, x, y, x_scale, y_scale, color);
}
@@ -546,7 +581,6 @@ void vita2d_draw_texture_tint_part(const vita2d_texture *texture, float x, float
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_part_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h);
}
@@ -598,6 +632,61 @@ static inline void draw_texture_part_scale_generic(const vita2d_texture *texture
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
}
static inline void draw_texture_tint_part_scale_generic(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale, unsigned int color)
{
vita2d_texture_tint_vertex *vertices = (vita2d_texture_tint_vertex *)vita2d_pool_memalign(
4 * sizeof(vita2d_texture_tint_vertex), // 4 vertices
sizeof(vita2d_texture_tint_vertex));
const float w = vita2d_texture_get_width(texture);
const float h = vita2d_texture_get_height(texture);
const float u0 = tex_x/w;
const float v0 = tex_y/h;
const float u1 = (tex_x+tex_w)/w;
const float v1 = (tex_y+tex_h)/h;
tex_w *= x_scale;
tex_h *= y_scale;
vertices[0].x = x;
vertices[0].y = y;
vertices[0].z = +0.5f;
vertices[0].u = u0;
vertices[0].v = v0;
vertices[1].x = x + tex_w;
vertices[1].y = y;
vertices[1].z = +0.5f;
vertices[1].u = u1;
vertices[1].v = v0;
vertices[2].x = x;
vertices[2].y = y + tex_h;
vertices[2].z = +0.5f;
vertices[2].u = u0;
vertices[2].v = v1;
vertices[3].x = x + tex_w;
vertices[3].y = y + tex_h;
vertices[3].z = +0.5f;
vertices[3].u = u1;
vertices[3].v = v1;
for(int n = 0; n < 4; n++){
vertices[n].r = ((color >> 8*0) & 0xFF)/255.0f;
vertices[n].g = ((color >> 8*1) & 0xFF)/255.0f;
vertices[n].b = ((color >> 8*2) & 0xFF)/255.0f;
vertices[n].a = ((color >> 8*3) & 0xFF)/255.0f;
}
// Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), 4);
}
void vita2d_draw_texture_part_scale(const vita2d_texture *texture, float x, float y, float tex_x, float tex_y, float tex_w, float tex_h, float x_scale, float y_scale)
{
set_texture_program();
@@ -609,8 +698,7 @@ void vita2d_draw_texture_tint_part_scale(const vita2d_texture *texture, float x,
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_part_scale_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale);
draw_texture_tint_part_scale_generic(texture, x, y, tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, color);
}
static inline void draw_texture_scale_rotate_hotspot_generic(const vita2d_texture *texture, float x, float y, float x_scale, float y_scale, float rad, float center_x, float center_y)
@@ -684,7 +772,6 @@ void vita2d_draw_texture_tint_scale_rotate_hotspot(const vita2d_texture *texture
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_scale_rotate_hotspot_generic(texture, x, y, x_scale, y_scale,
rad, center_x, center_y);
}
@@ -769,7 +856,6 @@ void vita2d_draw_texture_part_tint_scale_rotate(const vita2d_texture *texture, f
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
draw_texture_part_scale_rotate_generic(texture, x, y,
tex_x, tex_y, tex_w, tex_h, x_scale, y_scale, rad);
}
@@ -778,7 +864,6 @@ void vita2d_draw_array_textured(const vita2d_texture *texture, SceGxmPrimitiveTy
{
set_texture_tint_program();
set_texture_wvp_uniform();
set_texture_tint_color_uniform(color);
sceGxmSetBackPolygonMode(_vita2d_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
@@ -788,3 +873,18 @@ void vita2d_draw_array_textured(const vita2d_texture *texture, SceGxmPrimitiveTy
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, mode, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), count);
}
void vita2d_draw_array_textured_mat(const vita2d_texture *texture, const vita2d_texture_tint_vertex *vertices, size_t count, float *mat)
{
set_texture_tint_program();
void *vertex_wvp_buffer;
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer);
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, mat);
// Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, vita2d_get_linear_indices(), count);
}
+17
View File
@@ -0,0 +1,17 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
+26
View File
@@ -0,0 +1,26 @@
*.o
*.a
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
+29
View File
@@ -0,0 +1,29 @@
TARGET := libmathneon
SOURCES := source
LIBS = -lc -lm -lSceGxm_stub -lSceDisplay_stub
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
CGFILES := $(foreach dir,$(SHADERS), $(wildcard $(dir)/*.cg))
HEADERS := $(CGFILES:.cg=.h)
OBJS := $(CFILES:.c=.o)
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
AR = $(PREFIX)-gcc-ar
CFLAGS = -g -Wl,-q -O2 -ffast-math -mtune=cortex-a9 -mfpu=neon -flto -ftree-vectorize
ASFLAGS = $(CFLAGS)
all: $(TARGET).a
$(TARGET).a: $(OBJS)
$(AR) -rc $@ $^
clean:
@rm -rf $(TARGET).a $(TARGET).elf $(OBJS)
install: $(TARGET).a
@mkdir -p $(VITASDK)/$(PREFIX)/lib/
cp $(TARGET).a $(VITASDK)/$(PREFIX)/lib/
@mkdir -p $(VITASDK)/$(PREFIX)/include/
cp source/math_neon.h $(VITASDK)/$(PREFIX)/include/
+169
View File
@@ -0,0 +1,169 @@
Library: MATH-NEON
By: Lachlan Tychsen-Smith
Licence: MIT (expat)
=======================================================================================
This project implements the cmath functions and some optimised matrix functions
with the aim of increasing the floating point performance of ARM Cortex A-8
based platforms. As well as implementing the functions in ARM NEON assembly,
they sacrifice error checking and some accuracy to achieve better performance.
Function Errors:
=======================================================================================
The measurement and characterisations of the inaccuracies present within these
functions is really a field within itself. For the benchmark i provide the
maximum absolute, maximum relative and root mean squared error compared to the
cmath implementations over the specified range. However these values can be
misleading, especially for functions which quickly go to infinity. So its always a
good idea to test it within your actual program. In general, this library will not
be as accurate as cmath, however for many functions it is close enough to be
negilible.
Notes:
=======================================================================================
- The *_c functions are c implementations of the *_neon code.
- Like cmath, The errors present in the functions are very dependent on the
range which your operating in. So you should test them first.
- Look in the "math_neon.h" file for discriptions of the functions. In some
function files there are also notes on the specific implementation.
- The *_neon functions make certain assumptions about the location of arguments
that is incompatible with inlining.
Contact:
=======================================================================================
Name: Lachlan Tychsen-Smith
Email: [email protected]
PSVITA performances test results:
RUNFAST: Enabled
------------------------------------------------------------------------------------------------------
MATRIX FUNCTION TESTS
------------------------------------------------------------------------------------------------------
matmul2_c =
|-7.16, 9.42|
|17.86, -10.70|
matmul2_neon =
|-7.16, 9.42|
|17.86, -10.70|
matmul2: c=183985 neon=87480 rate=2.10
matvec2_c = |-7.16, 17.86|
matvec2_neon = |-7.16, 17.86|
matvec2: c=98178 neon=66040 rate=1.49
matmul3_c =
|11.14, -0.78, -3.98|
|16.56, 17.96, 23.58|
|8.73, -0.18, 1.57|
matmul3_neon =
|11.14, -0.78, -3.98|
|16.56, 17.96, 23.58|
|8.73, -0.18, 1.57|
matmul3: c=551838 neon=340292 rate=1.62
matvec3_c = |11.14, 16.56, 8.73|
matvec3_neon = |11.14, 16.56, 8.73|
matvec3: c=98178 neon=66040 rate=1.49
matmul4_c =
|17.91, -23.96, 1.86, 16.53|
|4.10, -18.16, 4.17, 29.06|
|6.92, -1.60, 3.12, 27.81|
|-15.13, -7.46, -17.91, 22.49|
matmul4_neon =
|17.91, -23.96, 1.86, 16.53|
|4.10, -18.16, 4.17, 29.06|
|6.92, -1.60, 3.12, 27.81|
|-15.13, -7.46, -17.91, 22.49|
matmul4: c=1316131 neon=315444 rate=4.17
matvec4_c = |17.91, 4.10, 6.92, -15.126419|
matvec4_neon = |17.91, 4.10, 6.92, -15.126419|
matvec4: c=98178 neon=66040 rate=1.49
dot2_c = 5.804099
dot2_neon = 5.804099
dot2: c=291526 neon=307025 rate=0.95
normalize2_c = [0.97, 0.24]
normalize2_neon = [0.97, 0.24]
normalize2: c=1058588 neon=965696 rate=1.10
dot3_c = -0.817487
dot3_neon = -0.817487
dot3: c=322094 neon=444834 rate=0.72
normalize3_c = [0.50, 0.12, -0.86]
normalize3_neon = [0.50, 0.12, -0.86]
normalize3: c=1257201 neon=1134375 rate=1.11
cross3_c = [-13.16, -17.29, -10.19]
cross3_neon = [-13.16, -17.29, -10.19]
cross3: c=705298 neon=766477 rate=0.92
dot4_c = -7.880241
dot4_neon = -7.880241
dot4: c=414431 neon=506460 rate=0.82
normalize4_c = [0.45, 0.11, -0.77, -0.44]
normalize4_neon = [0.45, 0.11, -0.77, -0.44]
normalize4: c=1410727 neon=1102802 rate=1.28
------------------------------------------------------------------------------------------------------
CMATH FUNCTION TESTS
------------------------------------------------------------------------------------------------------
Function Range Number ABS Max Error REL Max Error RMS Error Time Rate
------------------------------------------------------------------------------------------------------
sinf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 647042739 x1.00
sinf_c [-3.14, 3.14] 500000 7.75e-07 1.00e+02% 4.09e-07 646276691 x1.00
sinf_neon [-3.14, 3.14] 500000 1.00e+00 1.00e+02% 7.07e-01 645546381 x1.00
cosf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 644742077 x1.00
cosf_c [-3.14, 3.14] 500000 7.75e-07 6.74e-01% 4.15e-07 643957358 x1.00
cosf_neon [-3.14, 3.14] 500000 1.00e+00 1.00e+02% 7.06e-01 643211256 x1.00
tanf [-0.79, 0.79] 500000 0.00e+00 0.00e+00% 0.00e+00 642444112 x1.00
tanf_c [-0.79, 0.79] 500000 2.98e-06 7.94e-04% 1.31e-06 641628507 x1.00
tanf_neon [-0.79, 0.79] 500000 1.00e+00 1.00e+02% nan 640740514 x1.00
asinf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 639560380 x1.00
asinf_c [-1.00, 1.00] 500000 5.54e-05 1.06e-02% nan 638453383 x1.00
asinf_neon [-1.00, 1.00] 500000 1.57e+00 1.00e+02% 6.84e-01 637349653 x1.00
acosf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 636078992 x1.00
acosf_c [-1.00, 1.00] 500000 5.56e-05 6.46e-03% nan 634934201 x1.00
acosf_neon [-1.00, 1.00] 500000 1.57e+00 1.02e+05% 6.84e-01 633793585 x1.00
atanf [-1.00, 1.00] 500000 0.00e+00 0.00e+00% 0.00e+00 632835241 x1.00
atanf_c [-1.00, 1.00] 500000 1.67e-04 2.12e-02% 7.40e-05 632142823 x1.00
atanf_neon [-1.00, 1.00] 500000 7.85e-01 0.00e+00% nan 631387330 x1.00
sinhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 630142014 x1.00
sinhf_c [-3.14, 3.14] 500000 1.91e-06 1.52e-01% 1.85e-07 628992714 x1.00
sinhf_neon [-3.14, 3.14] 500000 1.15e+01 1.00e+02% 4.55e+00 627998454 x1.00
coshf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 626869866 x1.00
coshf_c [-3.14, 3.14] 500000 9.54e-07 2.38e-05% 1.64e-07 625829657 x1.00
coshf_neon [-3.14, 3.14] 500000 1.06e+01 9.14e+01% 3.92e+00 624873969 x1.00
tanhf [-3.14, 3.14] 500000 0.00e+00 0.00e+00% 0.00e+00 623689093 x1.00
tanhf_c [-3.14, 3.14] 500000 1.20e-05 2.48e-01% 5.48e-06 622547097 x1.00
tanhf_neon [-3.14, 3.14] 500000 9.96e-01 1.00e+02% 8.26e-01 621506812 x1.00
expf [0.00, 10.00] 500000 0.00e+00 0.00e+00% 0.00e+00 620497304 x1.00
expf_c [0.00, 10.00] 500000 9.77e-03 6.15e-05% 1.64e-03 619569554 x1.00
expf_neon [0.00, 10.00] 500000 2.20e+04 1.00e+02% 4.92e+03 618761400 x1.00
logf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 617882765 x1.00
logf_c [1.00, 1000.00] 500000 6.20e-06 1.62e-02% 9.83e-07 617087810 x1.00
logf_neon [1.00, 1000.00] 500000 9.49e+01 inf% 9.39e+01 616388420 x1.00
log10f [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 615405364 x1.00
log10f_c [1.00, 1000.00] 500000 2.86e-06 6.68e-03% 4.79e-07 614442585 x1.00
log10f_neon [1.00, 1000.00] 500000 4.12e+01 inf% 4.07e+01 613671782 x1.00
floorf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 611113689 x1.00
floorf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 608159325 x1.00
floorf_neon [1.00, 1000.00] 5000000 2.00e+00 2.00e+02% 1.42e-02 604769008 x1.01
ceilf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 601342443 x1.00
ceilf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 598387998 x1.00
ceilf_neon [1.00, 1000.00] 5000000 2.00e+00 1.00e+02% 1.02e+00 594959710 x1.01
fabsf [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 592068236 x1.00
fabsf_c [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 589808748 x1.00
fabsf_neon [1.00, 1000.00] 5000000 0.00e+00 0.00e+00% 0.00e+00 587712180 x1.01
sqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 586496654 x1.00
sqrtf_c [1.00, 1000.00] 500000 2.33e-04 1.06e-03% 8.69e-05 585470866 x1.00
sqrtf_neon [1.00, 1000.00] 500000 0.00e+00 0.00e+00% nan 584594551 x1.00
invsqrtf [1.00, 1000.00] 500000 0.00e+00 0.00e+00% 0.00e+00 583492213 x1.00
invsqrtf_c [1.00, 1000.00] 500000 4.35e-06 4.78e-04% 2.00e-07 582448164 x1.00
invsqrtf_neon [1.00, 1000.00] 500000 0.00e+00 0.00e+00% nan 581642365 x1.00
atan2f [0.10, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 83594269 x1.00
atan2f_c [0.10, 10.00] 10000 1.73e-04 2.23e-02% 0.00e+00 85383651 x0.98
atan2f_neon [0.10, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 87387055 x0.96
powf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 93430489 x1.00
powf_c [1.00, 10.00] 10000 1.08e+05 4.37e-03% 0.00e+00 96726976 x0.97
powf_neon [1.00, 10.00] 10000 9.97e+09 1.00e+02% 0.00e+00 100185753 x0.93
fmodf [1.00, 10.00] 10000 0.00e+00 0.00e+00% 0.00e+00 101653673 x1.00
fmodf_c [1.00, 10.00] 10000 9.90e+00 8.06e-02% 0.00e+00 103177551 x0.99
fmodf_neon [1.00, 10.00] 10000 9.99e+00 1.00e+02% 0.00e+00 104771240 x0.97
+67
View File
@@ -0,0 +1,67 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
/*
Test func : acosf(x)
Test Range: -1.0 < x < 1.0
Peak Error: ~0.005%
RMS Error: ~0.001%
*/
const float __acosf_pi_2 = M_PI_2;
float acosf_c(float x)
{
return __acosf_pi_2 - asinf_c(x);
}
float acosf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asinf_neon_hfp(x);
asm volatile (
"vdup.f32 d1, %0 \n\t" //d1 = {pi/2, pi/2};
"vsub.f32 d0, d1, d0 \n\t" //d0 = d1 - d0;
::"r"(__acosf_pi_2):
);
#endif
}
float acosf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
acosf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return acosf_c(x);
#endif
}
+183
View File
@@ -0,0 +1,183 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
/*
Test func : asinf(x)
Test Range: -1.0 < x < 1.0
Peak Error: ~0.005%
RMS Error: ~0.001%
*/
const float __asinf_lut[4] = {
0.105312459675071, //p7
0.169303418571894, //p3
0.051599985887214, //p5
0.999954835104825 //p1
};
const float __asinf_pi_2 = M_PI_2;
float asinf_c(float x)
{
float a, b, c, d, r, ax;
int m;
union {
float f;
int i;
} xx;
ax = fabs(x);
d = 0.5;
d = d - ax*0.5;
//fast invsqrt approx
xx.f = d;
xx.i = 0x5F3759DF - (xx.i >> 1); //VRSQRTE
c = d * xx.f;
b = (3.0f - c * xx.f) * 0.5; //VRSQRTS
xx.f = xx.f * b;
c = d * xx.f;
b = (3.0f - c * xx.f) * 0.5;
xx.f = xx.f * b;
//fast inverse approx
d = xx.f;
m = 0x3F800000 - (xx.i & 0x7F800000);
xx.i = xx.i + m;
xx.f = 1.41176471f - 0.47058824f * xx.f;
xx.i = xx.i + m;
b = 2.0 - xx.f * d;
xx.f = xx.f * b;
b = 2.0 - xx.f * d;
xx.f = xx.f * b;
//if |x|>0.5 -> x = sqrt((1-x)/2)
xx.f = xx.f - ax;
a = (ax > 0.5f);
d = __asinf_pi_2 * a;
c = 1.0f - 3.0f * a;
ax = ax + xx.f * a;
//polynomial evaluation
xx.f = ax * ax;
a = (__asinf_lut[0] * ax) * xx.f + (__asinf_lut[2] * ax);
b = (__asinf_lut[1] * ax) * xx.f + (__asinf_lut[3] * ax);
xx.f = xx.f * xx.f;
r = b + a * xx.f;
r = d + c * r;
a = r + r;
b = (x < 0.0f);
r = r - a * b;
return r;
}
float asinf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x};
"vdup.f32 d4, %1 \n\t" //d4 = {pi/2, pi/2};
"vmov.f32 d6, d0 \n\t" //d6 = d0;
"vabs.f32 d0, d0 \n\t" //d0 = fabs(d0) ;
"vmov.f32 d5, #0.5 \n\t" //d5 = 0.5;
"vmls.f32 d5, d0, d5 \n\t" //d5 = d5 - d0*d5;
//fast invsqrt approx
"vmov.f32 d1, d5 \n\t" //d1 = d5
"vrsqrte.f32 d5, d5 \n\t" //d5 = ~ 1.0 / sqrt(d5)
"vmul.f32 d2, d5, d1 \n\t" //d2 = d5 * d1
"vrsqrts.f32 d3, d2, d5 \n\t" //d3 = (3 - d5 * d2) / 2
"vmul.f32 d5, d5, d3 \n\t" //d5 = d5 * d3
"vmul.f32 d2, d5, d1 \n\t" //d2 = d5 * d1
"vrsqrts.f32 d3, d2, d5 \n\t" //d3 = (3 - d5 * d3) / 2
"vmul.f32 d5, d5, d3 \n\t" //d5 = d5 * d3
//fast reciporical approximation
"vrecpe.f32 d1, d5 \n\t" //d1 = ~ 1 / d5;
"vrecps.f32 d2, d1, d5 \n\t" //d2 = 2.0 - d1 * d5;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d5 \n\t" //d2 = 2.0 - d1 * d5;
"vmul.f32 d5, d1, d2 \n\t" //d5 = d1 * d2;
//if |x| > 0.5 -> ax = sqrt((1-ax)/2), r = pi/2
"vsub.f32 d5, d0, d5 \n\t" //d5 = d0 - d5;
"vmov.f32 d2, #0.5 \n\t" //d2 = 0.5;
"vcgt.f32 d3, d0, d2 \n\t" //d3 = (d0 > d2);
"vmov.f32 d1, #3.0 \n\t" //d5 = 3.0;
"vshr.u32 d3, #31 \n\t" //d3 = d3 >> 31;
"vmov.f32 d16, #1.0 \n\t" //d16 = 1.0;
"vcvt.f32.u32 d3, d3 \n\t" //d3 = (float) d3;
"vmls.f32 d0, d5, d3[0] \n\t" //d0 = d0 - d5 * d3[0];
"vmul.f32 d7, d4, d3[0] \n\t" //d7 = d5 * d4;
"vmls.f32 d16, d1, d3[0] \n\t" //d16 = d16 - d1 * d3;
//polynomial:
"vmul.f32 d2, d0, d0 \n\t" //d2 = d0*d0 = {ax^2, ax^2}
"vld1.32 {d4, d5}, [%0] \n\t" //d4 = {p7, p3}, d5 = {p5, p1}
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q2, d0[0] \n\t" //q0 = q2 * d0[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2[0] = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d1[0] = {..., p1x + p3x^3 + p5x^5 + p7x^7}
"vmla.f32 d7, d1, d16 \n\t" //d7 = d7 + d1*d16
"vadd.f32 d2, d7, d7 \n\t" //d2 = d7 + d7
"vclt.f32 d3, d6, #0 \n\t" //d3 = (d6 < 0)
"vshr.u32 d3, #31 \n\t" //d3 = d3 >> 31;
"vcvt.f32.u32 d3, d3 \n\t" //d3 = (float) d3
"vmls.f32 d7, d2, d3[0] \n\t" //d7 = d7 - d2 * d3[0];
"vmov.f32 s0, s15 \n\t" //s0 = s3
:: "r"(__asinf_lut), "r"(__asinf_pi_2)
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
);
#endif
}
float asinf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
asinf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return asinf_c(x);
#endif
}
+170
View File
@@ -0,0 +1,170 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __atan2f_lut[4] = {
-0.0443265554792128, //p7
-0.3258083974640975, //p3
+0.1555786518463281, //p5
+0.9997878412794807 //p1
};
const float __atan2f_pi_2 = M_PI_2;
float atan2f_c(float y, float x)
{
float a, b, c, r, xx;
int m;
union {
float f;
int i;
} xinv;
//fast inverse approximation (2x newton)
xx = fabs(x);
xinv.f = xx;
m = 0x3F800000 - (xinv.i & 0x7F800000);
xinv.i = xinv.i + m;
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
xinv.i = xinv.i + m;
b = 2.0 - xinv.f * xx;
xinv.f = xinv.f * b;
b = 2.0 - xinv.f * xx;
xinv.f = xinv.f * b;
c = fabs(y * xinv.f);
//fast inverse approximation (2x newton)
xinv.f = c;
m = 0x3F800000 - (xinv.i & 0x7F800000);
xinv.i = xinv.i + m;
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
xinv.i = xinv.i + m;
b = 2.0 - xinv.f * c;
xinv.f = xinv.f * b;
b = 2.0 - xinv.f * c;
xinv.f = xinv.f * b;
//if |x| > 1.0 -> ax = -1/ax, r = pi/2
xinv.f = xinv.f + c;
a = (c > 1.0f);
c = c - a * xinv.f;
r = a * __atan2f_pi_2;
//polynomial evaluation
xx = c * c;
a = (__atan2f_lut[0] * c) * xx + (__atan2f_lut[2] * c);
b = (__atan2f_lut[1] * c) * xx + (__atan2f_lut[3] * c);
xx = xx * xx;
r = r + a * xx;
r = r + b;
//determine quadrant and test for small x.
b = M_PI;
b = b - 2.0f * r;
r = r + (x < 0.0f) * b;
b = (fabs(x) < 0.000001f);
c = !b;
r = c * r;
r = r + __atan2f_pi_2 * b;
b = r + r;
r = r - (y < 0.0f) * b;
return r;
}
float atan2f_neon_hfp(float y, float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d17, d0[1] \n\t" //d17 = {x, x};
"vdup.f32 d16, d0[0] \n\t" //d16 = {y, y};
//1.0 / x
"vrecpe.f32 d18, d17 \n\t" //d16 = ~ 1 / d1;
"vrecps.f32 d19, d18, d17 \n\t" //d17 = 2.0 - d16 * d1;
"vmul.f32 d18, d18, d19 \n\t" //d16 = d16 * d17;
"vrecps.f32 d19, d18, d17 \n\t" //d17 = 2.0 - d16 * d1;
"vmul.f32 d18, d18, d19 \n\t" //d16 = d16 * d17;
//y * (1.0 /x)
"vmul.f32 d0, d16, d18 \n\t" //d0 = d16 * d18;
"vdup.f32 d4, %1 \n\t" //d4 = {pi/2, pi/2};
"vmov.f32 d6, d0 \n\t" //d6 = d0;
"vabs.f32 d0, d0 \n\t" //d0 = fabs(d0) ;
//fast reciporical approximation
"vrecpe.f32 d1, d0 \n\t" //d1 = ~ 1 / d0;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
//if |x| > 1.0 -> ax = 1/ax, r = pi/2
"vadd.f32 d1, d1, d0 \n\t" //d1 = d1 + d0;
"vmov.f32 d2, #1.0 \n\t" //d2 = 1.0;
"vcgt.f32 d3, d0, d2 \n\t" //d3 = (d0 > d2);
"vcvt.f32.u32 d3, d3 \n\t" //d3 = (float) d3;
"vmls.f32 d0, d1, d3 \n\t" //d0 = d0 - d1 * d3;
"vmul.f32 d7, d3, d4 \n\t" //d7 = d3 * d4;
//polynomial:
"vmul.f32 d2, d0, d0 \n\t" //d2 = d0*d0 = {ax^2, ax^2}
"vld1.32 {d4, d5}, [%0] \n\t" //d4 = {p7, p3}, d5 = {p5, p1}
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q2, d0[0] \n\t" //q0 = q2 * d0[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2[0] = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d1[0] = {..., p1x + p3x^3 + p5x^5 + p7x^7}
"vadd.f32 d1, d1, d7 \n\t" //d1 = d1 + d7
"vadd.f32 d2, d1, d1 \n\t" //d2 = d1 + d1
"vclt.f32 d3, d6, #0 \n\t" //d3 = (d6 < 0)
"vcvt.f32.u32 d3, d3 \n\t" //d3 = (float) d3
"vmls.f32 d1, d3, d2 \n\t" //d1 = d1 - d2 * d3;
"vmov.f32 s0, s3 \n\t" //s0 = s3
:: "r"(__atan2f_lut), "r"(__atan2f_pi_2)
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
);
#endif
}
float atan2f_neon_sfp(float x, float y)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
asm volatile ("vmov.f32 s1, r1 \n\t");
atan2f_neon_hfp(x, y);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return atan2f_c(y, x);
#endif
};
+149
View File
@@ -0,0 +1,149 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __atanf_lut[4] = {
-0.0443265554792128, //p7
-0.3258083974640975, //p3
+0.1555786518463281, //p5
+0.9997878412794807 //p1
};
const float __atanf_pi_2 = M_PI_2;
float atanf_c(float x)
{
float a, b, r, xx;
int m;
union {
float f;
int i;
} xinv, ax;
ax.f = fabs(x);
//fast inverse approximation (2x newton)
xinv.f = ax.f;
m = 0x3F800000 - (xinv.i & 0x7F800000);
xinv.i = xinv.i + m;
xinv.f = 1.41176471f - 0.47058824f * xinv.f;
xinv.i = xinv.i + m;
b = 2.0 - xinv.f * ax.f;
xinv.f = xinv.f * b;
b = 2.0 - xinv.f * ax.f;
xinv.f = xinv.f * b;
//if |x| > 1.0 -> ax = -1/ax, r = pi/2
xinv.f = xinv.f + ax.f;
a = (ax.f > 1.0f);
ax.f = ax.f - a * xinv.f;
r = a * __atanf_pi_2;
//polynomial evaluation
xx = ax.f * ax.f;
a = (__atanf_lut[0] * ax.f) * xx + (__atanf_lut[2] * ax.f);
b = (__atanf_lut[1] * ax.f) * xx + (__atanf_lut[3] * ax.f);
xx = xx * xx;
b = b + a * xx;
r = r + b;
//if x < 0 -> r = -r
a = 2 * r;
b = (x < 0.0f);
r = r - a * b;
return r;
}
float atanf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x};
"vdup.f32 d4, %1 \n\t" //d4 = {pi/2, pi/2};
"vmov.f32 d6, d0 \n\t" //d6 = d0;
"vabs.f32 d0, d0 \n\t" //d0 = fabs(d0) ;
//fast reciporical approximation
"vrecpe.f32 d1, d0 \n\t" //d1 = ~ 1 / d0;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
//if |x| > 1.0 -> ax = -1/ax, r = pi/2
"vadd.f32 d1, d1, d0 \n\t" //d1 = d1 + d0;
"vmov.f32 d2, #1.0 \n\t" //d2 = 1.0;
"vcgt.f32 d3, d0, d2 \n\t" //d3 = (d0 > d2);
"vshr.u32 d3, #31 \n\t" //d3 = (d0 > d2);
"vcvt.f32.u32 d3, d3 \n\t" //d5 = (float) d3;
"vmls.f32 d0, d1, d3[0] \n\t" //d0 = d0 - d1 * d3[0];
"vmul.f32 d7, d4, d3[0] \n\t" //d7 = d5 * d4;
//polynomial:
"vmul.f32 d2, d0, d0 \n\t" //d2 = d0*d0 = {ax^2, ax^2}
"vld1.32 {d4, d5}, [%0] \n\t" //d4 = {p7, p3}, d5 = {p5, p1}
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q2, d0[0] \n\t" //q0 = q2 * d0[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2[0] = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d1[0] = {..., p1x + p3x^3 + p5x^5 + p7x^7}
"vadd.f32 d1, d1, d7 \n\t" //d1 = d1 + d7
"vadd.f32 d2, d1, d1 \n\t" //d2 = d1 + d1
"vclt.f32 d3, d6, #0 \n\t" //d3 = (d6 < 0)
"vshr.u32 d3, #31 \n\t" //d3 = (d0 > d2);
"vcvt.f32.u32 d3, d3 \n\t" //d3 = (float) d3
"vmls.f32 d1, d3, d2 \n\t" //d1 = d1 - d2 * d3;
"vmov.f32 s0, s3 \n\t" //s0 = s3
:: "r"(__atanf_lut), "r"(__atanf_pi_2)
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
);
#endif
}
float atanf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
atanf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return atanf_c(x);
#endif
};
+71
View File
@@ -0,0 +1,71 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Assumes the floating point value |x| < 2147483648
*/
#include "math.h"
#include "math_neon.h"
float ceilf_c(float x)
{
int n;
float r;
n = (int) x;
r = (float) n;
r = r + (x > r);
return r;
}
float ceilf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vcvt.s32.f32 d1, d0 \n\t" //d1 = (int) d0;
"vcvt.f32.s32 d1, d1 \n\t" //d1 = (float) d1;
"vcgt.f32 d0, d0, d1 \n\t" //d0 = (d0 > d1);
"vshr.u32 d0, #31 \n\t" //d0 = d0 >> 31;
"vcvt.f32.u32 d0, d0 \n\t" //d0 = (float) d0;
"vadd.f32 d0, d1, d0 \n\t" //d0 = d1 + d0;
::: "d0", "d1"
);
#endif
}
float ceilf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
ceilf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return ceilf_c(x);
#endif
};
+50
View File
@@ -0,0 +1,50 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math_neon.h"
float cosf_c(float x)
{
return sinf_c(x + M_PI_2);
}
float cosf_neon_hfp(float x)
{
#ifdef __MATH_NEON
float xx = x + M_PI_2;
return sinf_neon_hfp(xx);
#endif
}
float cosf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
cosf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return cosf_c(x);
#endif
};
+120
View File
@@ -0,0 +1,120 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __coshf_rng[2] = {
1.442695041f,
0.693147180f
};
const float __coshf_lut[16] = {
0.00019578093328483123, //p7
0.00019578093328483123, //p7
0.0014122663401803872, //p6
0.0014122663401803872, //p6
0.008336936973260111, //p5
0.008336936973260111, //p5
0.04165989275009526, //p4
0.04165989275009526, //p4
0.16666570253074878, //p3
0.16666570253074878, //p3
0.5000006143673624, //p2
0.5000006143673624, //p2
1.000000059694879, //p1
1.000000059694879, //p1
0.9999999916728642, //p0
0.9999999916728642 //p0
};
float coshf_c(float x)
{
float a, b, xx;
xx = -x;
a = expf_c(x);
b = expf_c(xx);
a = a * 0.5f;
a = a + 0.5f * b;
return a;
}
float coshf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"fnegs s1, s1 \n\t" //s1 = -s1
//Range Reduction:
"vld1.32 d2, [%0] \n\t" //d2 = {invrange, range}
"vld1.32 {d16, d17}, [%1]! \n\t"
"vmul.f32 d6, d0, d2[0] \n\t" //d6 = d0 * d2[0]
"vcvt.s32.f32 d6, d6 \n\t" //d6 = (int) d6
"vld1.32 {d18}, [%1]! \n\t"
"vcvt.f32.s32 d1, d6 \n\t" //d1 = (float) d6
"vld1.32 {d19}, [%1]! \n\t"
"vmls.f32 d0, d1, d2[1] \n\t" //d0 = d0 - d1 * d2[1]
"vld1.32 {d20}, [%1]! \n\t"
//polynomial:
"vmla.f32 d17, d16, d0 \n\t" //d17 = d17 + d16 * d0;
"vld1.32 {d21}, [%1]! \n\t"
"vmla.f32 d18, d17, d0 \n\t" //d18 = d18 + d17 * d0;
"vld1.32 {d22}, [%1]! \n\t"
"vmla.f32 d19, d18, d0 \n\t" //d19 = d19 + d18 * d0;
"vld1.32 {d23}, [%1]! \n\t"
"vmla.f32 d20, d19, d0 \n\t" //d20 = d20 + d19 * d0;
"vmla.f32 d21, d20, d0 \n\t" //d21 = d21 + d20 * d0;
"vmla.f32 d22, d21, d0 \n\t" //d22 = d22 + d21 * d0;
"vmla.f32 d23, d22, d0 \n\t" //d23 = d23 + d22 * d0;
//multiply by 2 ^ m
"vshl.i32 d6, d6, #23 \n\t" //d6 = d6 << 23
"vadd.i32 d0, d23, d6 \n\t" //d0 = d22 + d6
"vdup.f32 d2, d0[1] \n\t" //d2 = s1
"vmov.f32 d1, #0.5 \n\t" //d1 = 0.5
"vadd.f32 d0, d0, d2 \n\t" //d0 = d0 + d2
"vmul.f32 d0, d1 \n\t" //d0 = d0 * d1
:: "r"(__coshf_rng), "r"(__coshf_lut)
: "d0", "d1", "q1", "q2", "d6"
);
#endif
}
float coshf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
coshf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return coshf_c(x);
#endif
};
+135
View File
@@ -0,0 +1,135 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Based on:
e ^ x = (1+m) * (2^n)
x = log(1+m) + n * log(2)
n = (int) (x * 1.0 / log(2))
(1+m) = e ^ (x - n * log(2))
(1+m) = Poly(x - n * log(2))
where Poly(x) is the Minimax approximation of e ^ x over the
range [-Log(2), Log(2)]
Test func : expf(x)
Test Range: 0 < x < 50
Peak Error: ~0.00024%
RMS Error: ~0.00007%
*/
#include "math.h"
#include "math_neon.h"
const float __expf_rng[2] = {
1.442695041f,
0.693147180f
};
const float __expf_lut[8] = {
0.9999999916728642, //p0
0.04165989275009526, //p4
0.5000006143673624, //p2
0.0014122663401803872, //p6
1.000000059694879, //p1
0.008336936973260111, //p5
0.16666570253074878, //p3
0.00019578093328483123 //p7
};
float expf_c(float x)
{
float a, b, c, d, xx;
int m;
union {
float f;
int i;
} r;
//Range Reduction:
m = (int) (x * __expf_rng[0]);
x = x - ((float) m) * __expf_rng[1];
//Taylor Polynomial (Estrins)
a = (__expf_lut[4] * x) + (__expf_lut[0]);
b = (__expf_lut[6] * x) + (__expf_lut[2]);
c = (__expf_lut[5] * x) + (__expf_lut[1]);
d = (__expf_lut[7] * x) + (__expf_lut[3]);
xx = x * x;
a = a + b * xx;
c = c + d * xx;
xx = xx* xx;
r.f = a + c * xx;
//multiply by 2 ^ m
m = m << 23;
r.i = r.i + m;
return r.f;
}
float expf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
//Range Reduction:
"vld1.32 d2, [%0] \n\t" //d2 = {invrange, range}
"vmul.f32 d6, d0, d2[0] \n\t" //d6 = d0 * d2[0]
"vcvt.s32.f32 d6, d6 \n\t" //d6 = (int) d6
"vcvt.f32.s32 d1, d6 \n\t" //d1 = (float) d6
"vmls.f32 d0, d1, d2[1] \n\t" //d0 = d0 - d1 * d2[1]
//polynomial:
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0*d0 = {x^2, x^2}
"vld1.32 {d2, d3, d4, d5}, [%1] \n\t" //q1 = {p0, p4, p2, p6}, q2 = {p1, p5, p3, p7} ;
"vmla.f32 q1, q2, d0[0] \n\t" //q1 = q1 + q2 * d0[0]
"vmla.f32 d2, d3, d1[0] \n\t" //d2 = d2 + d3 * d1[0]
"vmul.f32 d1, d1, d1 \n\t" //d1 = d1 * d1 = {x^4, x^4}
"vmla.f32 d2, d1, d2[1] \n\t" //d2 = d2 + d1 * d2[1]
//multiply by 2 ^ m
"vshl.i32 d6, d6, #23 \n\t" //d6 = d6 << 23
"vadd.i32 d0, d2, d6 \n\t" //d0 = d2 + d6
:: "r"(__expf_rng), "r"(__expf_lut)
: "d0", "d1", "q1", "q2", "d6"
);
#endif
}
float expf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
expf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return expf_c(x);
#endif
};
+58
View File
@@ -0,0 +1,58 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math_neon.h"
float fabsf_c(float x)
{
union {
int i;
float f;
} xx;
xx.f = x;
xx.i = xx.i & 0x7FFFFFFF;
return xx.f;
}
float fabsf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"fabss s0, s0 \n\t" //s0 = fabs(s0)
);
#endif
}
float fabsf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"bic r0, r0, #0x80000000 \n\t" //r0 = r0 & ~(1 << 31)
);
#else
return fabsf_c(x);
#endif
}
+66
View File
@@ -0,0 +1,66 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Assumes the floating point value |x| < 2147483648
*/
#include "math.h"
#include "math_neon.h"
float floorf_c(float x)
{
int n;
float r;
n = (int) x;
r = (float) n;
r = r - (r > x);
return r;
}
float floorf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vcvt.s32.f32 d1, d0 \n\t" //d1 = (int) d0;
"vcvt.f32.s32 d1, d1 \n\t" //d1 = (float) d1;
"vcgt.f32 d0, d1, d0 \n\t" //d0 = (d1 > d0);
"vshr.u32 d0, #31 \n\t" //d0 = d0 >> 31;
"vcvt.f32.u32 d0, d0 \n\t" //d0 = (float) d0;
"vsub.f32 d0, d1, d0 \n\t" //d0 = d1 - d0;
::: "d0", "d1"
);
#endif
}
float floorf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
floorf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return floorf_c(x);
#endif
};
+100
View File
@@ -0,0 +1,100 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Assumes the floating point value |x / y| < 2,147,483,648
*/
#include "math_neon.h"
float fmodf_c(float x, float y)
{
int n;
union {
float f;
int i;
} yinv;
float a;
//fast reciporical approximation (4x Newton)
yinv.f = y;
n = 0x3F800000 - (yinv.i & 0x7F800000);
yinv.i = yinv.i + n;
yinv.f = 1.41176471f - 0.47058824f * yinv.f;
yinv.i = yinv.i + n;
a = 2.0 - yinv.f * y;
yinv.f = yinv.f * a;
a = 2.0 - yinv.f * y;
yinv.f = yinv.f * a;
a = 2.0 - yinv.f * y;
yinv.f = yinv.f * a;
a = 2.0 - yinv.f * y;
yinv.f = yinv.f * a;
n = (int)(x * yinv.f);
x = x - ((float)n) * y;
return x;
}
float fmodf_neon_hfp(float x, float y)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d1, d0[1] \n\t" //d1[0] = y
"vdup.f32 d0, d0[0] \n\t" //d1[0] = y
//fast reciporical approximation
"vrecpe.f32 d2, d1 \n\t" //d2 = ~1.0 / d1
"vrecps.f32 d3, d2, d1 \n\t" //d3 = 2.0 - d2 * d1;
"vmul.f32 d2, d2, d3 \n\t" //d2 = d2 * d3;
"vrecps.f32 d3, d2, d1 \n\t" //d3 = 2.0 - d2 * d1;
"vmul.f32 d2, d2, d3 \n\t" //d2 = d2 * d3;
"vrecps.f32 d3, d2, d1 \n\t" //d3 = 2.0 - d2 * d1;
"vmul.f32 d2, d2, d3 \n\t" //d2 = d2 * d3;
"vrecps.f32 d3, d2, d1 \n\t" //d3 = 2.0 - d2 * d1;
"vmul.f32 d2, d2, d3 \n\t" //d2 = d2 * d3;
"vmul.f32 d2, d2, d0 \n\t" //d2 = d2 * d0;
"vcvt.s32.f32 d2, d2 \n\t" //d2 = (int) d2;
"vcvt.f32.s32 d2, d2 \n\t" //d2 = (float) d2;
"vmls.f32 d0, d1, d2 \n\t" //d0 = d0 - d1 * d2;
::: "d0", "d1", "d2", "d3"
);
#endif
}
float fmodf_neon_sfp(float x, float y)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
asm volatile ("vmov.f32 s1, r1 \n\t");
fmodf_neon_hfp(x, y);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return fmodf_c(x,y);
#endif
};
+79
View File
@@ -0,0 +1,79 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
float invsqrtf_c(float x)
{
float b, c;
union {
float f;
int i;
} a;
//fast invsqrt approx
a.f = x;
a.i = 0x5F3759DF - (a.i >> 1); //VRSQRTE
c = x * a.f;
b = (3.0f - c * a.f) * 0.5; //VRSQRTS
a.f = a.f * b;
c = x * a.f;
b = (3.0f - c * a.f) * 0.5;
a.f = a.f * b;
return a.f;
}
float invsqrtf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4
::: "d0", "d1", "d2", "d3"
);
#endif
}
float invsqrtf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
invsqrtf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return invsqrtf_c(x);
#endif
};
+67
View File
@@ -0,0 +1,67 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
float ldexpf_c(float m, int e)
{
union {
float f;
int i;
} r;
r.f = m;
r.i += (e << 23);
return r.f;
}
float ldexpf_neon_hfp(float m, int e)
{
#ifdef __MATH_NEON
float r;
asm volatile (
"lsl r0, r0, #23 \n\t" //r0 = r0 << 23
"vdup.i32 d1, r0 \n\t" //d1 = {r0, r0}
"vadd.i32 d0, d0, d1 \n\t" //d0 = d0 + d1
::: "d0", "d1"
);
#endif
}
float ldexpf_neon_sfp(float m, int e)
{
#ifdef __MATH_NEON
float r;
asm volatile (
"lsl r1, r1, #23 \n\t" //r1 = r1 << 23
"vdup.f32 d0, r0 \n\t" //d0 = {r0, r0}
"vdup.i32 d1, r1 \n\t" //d1 = {r1, r1}
"vadd.i32 d0, d0, d1 \n\t" //d0 = d0 + d1
"vmov.f32 r0, s0 \n\t" //r0 = s0
::: "d0", "d1"
);
#else
return ldexpf_c(m,e);
#endif
}
+135
View File
@@ -0,0 +1,135 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Based on:
log10(x) = log10((1+m) * (2^n))
log(x) = n * log10(2) + log10(1 + m)
log(1+m) = Poly(1+m)
where Poly(x) is the Minimax approximation of log10(x) over the
range [1, 2]
Test func : log10f(x)
Test Range: 1 < x < 10000
Peak Error: ~0.000040%
RMS Error: ~0.000008%
*/
#include "math.h"
#include "math_neon.h"
const float __log10f_rng = 0.3010299957f;
const float __log10f_lut[8] = {
-0.99697286229624, //p0
-1.07301643912502, //p4
-2.46980061535534, //p2
-0.07176870463131, //p6
2.247870219989470, //p1
0.366547581117400, //p5
1.991005185100089, //p3
0.006135635201050, //p7
};
float log10f_c(float x)
{
float a, b, c, d, xx;
int m;
union {
float f;
int i;
} r;
//extract exponent
r.f = x;
m = (r.i >> 23);
m = m - 127;
r.i = r.i - (m << 23);
//Taylor Polynomial (Estrins)
xx = r.f * r.f;
a = (__log10f_lut[4] * r.f) + (__log10f_lut[0]);
b = (__log10f_lut[6] * r.f) + (__log10f_lut[2]);
c = (__log10f_lut[5] * r.f) + (__log10f_lut[1]);
d = (__log10f_lut[7] * r.f) + (__log10f_lut[3]);
a = a + b * xx;
c = c + d * xx;
xx = xx * xx;
r.f = a + c * xx;
//add exponent
r.f = r.f + ((float) m) * __log10f_rng;
return r.f;
}
float log10f_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x,x};
//extract exponent
"vmov.i32 d2, #127 \n\t" //d2 = 127;
"vshr.u32 d6, d0, #23 \n\t" //d6 = d0 >> 23;
"vsub.i32 d6, d6, d2 \n\t" //d6 = d6 - d2;
"vshl.u32 d1, d6, #23 \n\t" //d1 = d6 << 23;
"vsub.i32 d0, d0, d1 \n\t" //d0 = d0 + d1;
//polynomial:
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0*d0 = {x^2, x^2}
"vld1.32 {d2, d3, d4, d5}, [%1] \n\t" //q1 = {p0, p4, p2, p6}, q2 = {p1, p5, p3, p7} ;
"vmla.f32 q1, q2, d0[0] \n\t" //q1 = q1 + q2 * d0[0]
"vmla.f32 d2, d3, d1[0] \n\t" //d2 = d2 + d3 * d1[0]
"vmul.f32 d1, d1, d1 \n\t" //d1 = d1 * d1 = {x^4, x^4}
"vmla.f32 d2, d1, d2[1] \n\t" //d2 = d2 + d1 * d2[1]
//add exponent
"vdup.32 d7, %0 \n\t" //d7 = {rng, rng}
"vcvt.f32.s32 d6, d6 \n\t" //d6 = (float) d6
"vmla.f32 d2, d6, d7 \n\t" //d2 = d2 + d6 * d7
"vmov.f32 s0, s4 \n\t" //s0 = s4
:: "r"(__log10f_rng), "r"(__log10f_lut)
: "d0", "d1", "q1", "q2", "d6", "d7"
);
#endif
}
float log10f_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
log10f_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return log10f_c(x);
#endif
};
+135
View File
@@ -0,0 +1,135 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Based on:
log(x) = log((1+m) * (2^n))
log(x) = n * log(2) + log(1 + m)
log(1+m) = Poly(1+m)
where Poly(x) is the Minimax approximation of log(x) over the
range [1, 2]
Test func : logf(x)
Test Range: 1 < x < 10000
Peak Error: ~0.000601%
RMS Error: ~0.000005%
*/
#include "math.h"
#include "math_neon.h"
const float __logf_rng = 0.693147180f;
const float __logf_lut[8] = {
-2.295614848256274, //p0
-2.470711633419806, //p4
-5.686926051100417, //p2
-0.165253547131978, //p6
+5.175912446351073, //p1
+0.844006986174912, //p5
+4.584458825456749, //p3
+0.014127821926000 //p7
};
float logf_c(float x)
{
float a, b, c, d, xx;
int m;
union {
float f;
int i;
} r;
//extract exponent
r.f = x;
m = (r.i >> 23);
m = m - 127;
r.i = r.i - (m << 23);
//Taylor Polynomial (Estrins)
xx = r.f * r.f;
a = (__logf_lut[4] * r.f) + (__logf_lut[0]);
b = (__logf_lut[6] * r.f) + (__logf_lut[2]);
c = (__logf_lut[5] * r.f) + (__logf_lut[1]);
d = (__logf_lut[7] * r.f) + (__logf_lut[3]);
a = a + b * xx;
c = c + d * xx;
xx = xx * xx;
r.f = a + c * xx;
//add exponent
r.f = r.f + ((float) m) * __logf_rng;
return r.f;
}
float logf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x,x};
//extract exponent
"vmov.i32 d2, #127 \n\t" //d2 = 127;
"vshr.u32 d6, d0, #23 \n\t" //d6 = d0 >> 23;
"vsub.i32 d6, d6, d2 \n\t" //d6 = d6 - d2;
"vshl.u32 d1, d6, #23 \n\t" //d1 = d6 << 23;
"vsub.i32 d0, d0, d1 \n\t" //d0 = d0 + d1;
//polynomial:
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0*d0 = {x^2, x^2}
"vld1.32 {d2, d3, d4, d5}, [%1] \n\t" //q1 = {p0, p4, p2, p6}, q2 = {p1, p5, p3, p7} ;
"vmla.f32 q1, q2, d0[0] \n\t" //q1 = q1 + q2 * d0[0]
"vmla.f32 d2, d3, d1[0] \n\t" //d2 = d2 + d3 * d1[0]
"vmul.f32 d1, d1, d1 \n\t" //d1 = d1 * d1 = {x^4, x^4}
"vmla.f32 d2, d1, d2[1] \n\t" //d2 = d2 + d1 * d2[1]
//add exponent
"vdup.32 d7, %0 \n\t" //d7 = {rng, rng}
"vcvt.f32.s32 d6, d6 \n\t" //d6 = (float) d6
"vmla.f32 d2, d6, d7 \n\t" //d2 = d2 + d6 * d7
"vmov.f32 s0, s4 \n\t" //s0 = s4
:: "r"(__logf_rng), "r"(__logf_lut)
: "d0", "d1", "q1", "q2", "d6", "d7"
);
#endif
}
float logf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
logf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return logf_c(x);
#endif
};
+95
View File
@@ -0,0 +1,95 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Matrices are specified in column major format:
| a c |
| b d |
therefore m[2] = c
*/
#include "math_neon.h"
//matrix matrix multipication. d = m0 * m1;
void
matmul2_c(float m0[4], float m1[4], float d[4])
{
d[0] = m0[0]*m1[0] + m0[2]*m1[1];
d[1] = m0[1]*m1[0] + m0[3]*m1[1];
d[2] = m0[0]*m1[2] + m0[2]*m1[3];
d[3] = m0[1]*m1[2] + m0[3]*m1[3];
}
void
matmul2_neon(float m0[4], float m1[4], float d[4])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d0, d1}, [%0] \n\t" //Q1 = m0
"vld1.32 {d2, d3}, [%1] \n\t" //Q2 = m1
"vmul.f32 d4, d0, d2[0] \n\t" //D4 = D0*D2[0]
"vmul.f32 d5, d0, d3[0] \n\t" //D5 = D0*D3[0]
"vmla.f32 d4, d1, d2[1] \n\t" //D4 += D1*D2[1]
"vmla.f32 d5, d1, d3[1] \n\t" //D5 += D1*D3[1]
"vst1.32 {d4, d5}, [%2] \n\t" //Q4 = m+12
:: "r"(m0), "r"(m1), "r"(d)
: "q0", "q1", "q2", "memory"
);
#else
matmul2_c(m0, m1, d);
#endif
}
//matrix vector multiplication. d = m * v
void
matvec2_c(float m[4], float v[2], float d[2])
{
d[0] = m[0]*v[0] + m[2]*v[1];
d[1] = m[1]*v[0] + m[3]*v[1];
}
void
matvec2_neon(float m[4], float v[2], float d[2])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 d0, [%1] \n\t" //d0 = v
"vld1.32 {d1, d2}, [%0] \n\t" //Q1 = m
"vmul.f32 d3, d1, d0[0] \n\t" //Q5 = Q1*d0[0]
"vmla.f32 d3, d2, d0[1] \n\t" //Q5 += Q1*d0[1]
"vst1.32 d3, [%2] \n\t" //Q4 = m+12
:: "r"(m), "r"(v), "r"(d)
: "d0", "d1", "d2","d3", "memory"
);
#else
matvec2_c(m, v, d);
#endif
}
+131
View File
@@ -0,0 +1,131 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Matrices are specified in row major format:
| x0 x2 |
| x1 x3 |
therefore m[2] = x2
*/
#include "math_neon.h"
//matrix matrix multipication. d = m0 * m1;
void
matmul3_c(float m0[9], float m1[9], float d[9])
{
d[0] = m0[0]*m1[0] + m0[3]*m1[1] + m0[6]*m1[2];
d[1] = m0[1]*m1[0] + m0[4]*m1[1] + m0[7]*m1[2];
d[2] = m0[2]*m1[0] + m0[5]*m1[1] + m0[8]*m1[2];
d[3] = m0[0]*m1[3] + m0[3]*m1[4] + m0[6]*m1[5];
d[4] = m0[1]*m1[3] + m0[4]*m1[4] + m0[7]*m1[5];
d[5] = m0[2]*m1[3] + m0[5]*m1[4] + m0[8]*m1[5];
d[6] = m0[0]*m1[6] + m0[3]*m1[7] + m0[6]*m1[8];
d[7] = m0[1]*m1[6] + m0[4]*m1[7] + m0[7]*m1[8];
d[8] = m0[2]*m1[6] + m0[5]*m1[7] + m0[8]*m1[8];
}
void
matmul3_neon(float m0[9], float m1[9], float d[9])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d0, d1}, [%1]! \n\t" //q0 = m1
"vld1.32 {d2, d3}, [%1]! \n\t" //q1 = m1+4
"flds s8, [%1] \n\t" //q2 = m1+8
"vld1.32 {d6, d7}, [%0] \n\t" //q3[0] = m0
"add %0, %0, #12 \n\t" //q3[0] = m0
"vld1.32 {d8, d9}, [%0] \n\t" //q4[0] = m0+12
"add %0, %0, #12 \n\t" //q3[0] = m0
"vld1.32 {d10}, [%0] \n\t" //q5[0] = m0+24
"add %0, %0, #8 \n\t" //q3[0] = m0
"flds s22, [%0] \n\t" //q2 = m1+8
"vmul.f32 q6, q3, d0[0] \n\t" //q12 = q3 * d0[0]
"vmul.f32 q7, q3, d1[1] \n\t" //q13 = q3 * d2[0]
"vmul.f32 q8, q3, d3[0] \n\t" //q14 = q3 * d4[0]
"vmla.f32 q6, q4, d0[1] \n\t" //q12 = q9 * d0[1]
"vmla.f32 q7, q4, d2[0] \n\t" //q13 = q9 * d2[1]
"vmla.f32 q8, q4, d3[1] \n\t" //q14 = q9 * d4[1]
"vmla.f32 q6, q5, d1[0] \n\t" //q12 = q10 * d0[0]
"vmla.f32 q7, q5, d2[1] \n\t" //q13 = q10 * d2[0]
"vmla.f32 q8, q5, d4[0] \n\t" //q14 = q10 * d4[0]
"vmov.f32 q0, q8 \n\t" //q14 = q10 * d4[0]
"vst1.32 {d12, d13}, [%2] \n\t" //d = q12
"add %2, %2, #12 \n\t" //q3[0] = m0
"vst1.32 {d14, d15}, [%2] \n\t" //d+4 = q13
"add %2, %2, #12 \n\t" //q3[0] = m0
"vst1.32 {d0}, [%2] \n\t" //d+8 = q14
"add %2, %2, #8 \n\t" //q3[0] = m0
"fsts s2, [%2] \n\t" //d = q12
: "+r"(m0), "+r"(m1), "+r"(d):
: "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", "memory"
);
#else
matmul3_c(m0, m1, d);
#endif
};
//matrix vector multiplication. d = m * v
void
matvec3_c(float m[9], float v[3], float d[3])
{
d[0] = m[0]*v[0] + m[3]*v[1] + m[6]*v[2];
d[1] = m[1]*v[0] + m[4]*v[1] + m[7]*v[2];
d[2] = m[2]*v[0] + m[5]*v[1] + m[8]*v[2];
}
void
matvec3_neon(float m[9], float v[3], float d[3])
{
#ifdef __MATH_NEON
int tmp;
asm volatile (
"mov %3, #12 \n\t" //r3 = 12
"vld1.32 {d0, d1}, [%1] \n\t" //Q0 = v
"vld1.32 {d2, d3}, [%0], %3 \n\t" //Q1 = m
"vld1.32 {d4, d5}, [%0], %3 \n\t" //Q2 = m+12
"vld1.32 {d6, d7}, [%0], %3 \n\t" //Q3 = m+24
"vmul.f32 q9, q1, d0[0] \n\t" //Q9 = Q1*Q0[0]
"vmla.f32 q9, q2, d0[1] \n\t" //Q9 += Q2*Q0[1]
"vmla.f32 q9, q3, d1[0] \n\t" //Q9 += Q3*Q0[2]
"vmov.f32 q0, q9 \n\t" //Q0 = q9
"vst1.32 d0, [%2]! \n\t" //r2 = D24
"fsts s2, [%2] \n\t" //r2 = D25[0]
: "+r"(m), "+r"(v), "+r"(d), "+r"(tmp):
: "q0", "q9", "q10","q11", "q12", "q13", "memory"
);
#else
matvec3_c(m, v, d);
#endif
}
+144
View File
@@ -0,0 +1,144 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Matrices are specified in row major format:
| x0 x2 |
| x1 x3 |
therefore m[2] = x2
*/
#include "math_neon.h"
//matrix matrix multipication. d = m0 * m1;
void
matmul4_c(float m0[16], float m1[16], float d[16])
{
d[0] = m0[0]*m1[0] + m0[4]*m1[1] + m0[8]*m1[2] + m0[12]*m1[3];
d[1] = m0[1]*m1[0] + m0[5]*m1[1] + m0[9]*m1[2] + m0[13]*m1[3];
d[2] = m0[2]*m1[0] + m0[6]*m1[1] + m0[10]*m1[2] + m0[14]*m1[3];
d[3] = m0[3]*m1[0] + m0[7]*m1[1] + m0[11]*m1[2] + m0[15]*m1[3];
d[4] = m0[0]*m1[4] + m0[4]*m1[5] + m0[8]*m1[6] + m0[12]*m1[7];
d[5] = m0[1]*m1[4] + m0[5]*m1[5] + m0[9]*m1[6] + m0[13]*m1[7];
d[6] = m0[2]*m1[4] + m0[6]*m1[5] + m0[10]*m1[6] + m0[14]*m1[7];
d[7] = m0[3]*m1[4] + m0[7]*m1[5] + m0[11]*m1[6] + m0[15]*m1[7];
d[8] = m0[0]*m1[8] + m0[4]*m1[9] + m0[8]*m1[10] + m0[12]*m1[11];
d[9] = m0[1]*m1[8] + m0[5]*m1[9] + m0[9]*m1[10] + m0[13]*m1[11];
d[10] = m0[2]*m1[8] + m0[6]*m1[9] + m0[10]*m1[10] + m0[14]*m1[11];
d[11] = m0[3]*m1[8] + m0[7]*m1[9] + m0[11]*m1[10] + m0[15]*m1[11];
d[12] = m0[0]*m1[12] + m0[4]*m1[13] + m0[8]*m1[14] + m0[12]*m1[15];
d[13] = m0[1]*m1[12] + m0[5]*m1[13] + m0[9]*m1[14] + m0[13]*m1[15];
d[14] = m0[2]*m1[12] + m0[6]*m1[13] + m0[10]*m1[14] + m0[14]*m1[15];
d[15] = m0[3]*m1[12] + m0[7]*m1[13] + m0[11]*m1[14] + m0[15]*m1[15];
}
void
matmul4_neon(float m0[16], float m1[16], float d[16])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d0, d1}, [%1]! \n\t" //q0 = m1
"vld1.32 {d2, d3}, [%1]! \n\t" //q1 = m1+4
"vld1.32 {d4, d5}, [%1]! \n\t" //q2 = m1+8
"vld1.32 {d6, d7}, [%1] \n\t" //q3 = m1+12
"vld1.32 {d16, d17}, [%0]! \n\t" //q8 = m0
"vld1.32 {d18, d19}, [%0]! \n\t" //q9 = m0+4
"vld1.32 {d20, d21}, [%0]! \n\t" //q10 = m0+8
"vld1.32 {d22, d23}, [%0] \n\t" //q11 = m0+12
"vmul.f32 q12, q8, d0[0] \n\t" //q12 = q8 * d0[0]
"vmul.f32 q13, q8, d2[0] \n\t" //q13 = q8 * d2[0]
"vmul.f32 q14, q8, d4[0] \n\t" //q14 = q8 * d4[0]
"vmul.f32 q15, q8, d6[0] \n\t" //q15 = q8 * d6[0]
"vmla.f32 q12, q9, d0[1] \n\t" //q12 = q9 * d0[1]
"vmla.f32 q13, q9, d2[1] \n\t" //q13 = q9 * d2[1]
"vmla.f32 q14, q9, d4[1] \n\t" //q14 = q9 * d4[1]
"vmla.f32 q15, q9, d6[1] \n\t" //q15 = q9 * d6[1]
"vmla.f32 q12, q10, d1[0] \n\t" //q12 = q10 * d0[0]
"vmla.f32 q13, q10, d3[0] \n\t" //q13 = q10 * d2[0]
"vmla.f32 q14, q10, d5[0] \n\t" //q14 = q10 * d4[0]
"vmla.f32 q15, q10, d7[0] \n\t" //q15 = q10 * d6[0]
"vmla.f32 q12, q11, d1[1] \n\t" //q12 = q11 * d0[1]
"vmla.f32 q13, q11, d3[1] \n\t" //q13 = q11 * d2[1]
"vmla.f32 q14, q11, d5[1] \n\t" //q14 = q11 * d4[1]
"vmla.f32 q15, q11, d7[1] \n\t" //q15 = q11 * d6[1]
"vst1.32 {d24, d25}, [%2]! \n\t" //d = q12
"vst1.32 {d26, d27}, [%2]! \n\t" //d+4 = q13
"vst1.32 {d28, d29}, [%2]! \n\t" //d+8 = q14
"vst1.32 {d30, d31}, [%2] \n\t" //d+12 = q15
: "+r"(m0), "+r"(m1), "+r"(d) :
: "q0", "q1", "q2", "q3", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
"memory"
);
#else
matmul4_c(m0, m1, d);
#endif
}
//matrix vector multiplication. d = m * v
void
matvec4_c(float m[16], float v[4], float d[4])
{
d[0] = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3];
d[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3];
d[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3];
d[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3];
}
void
matvec4_neon(float m[16], float v[4], float d[4])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d0, d1}, [%1] \n\t" //Q0 = v
"vld1.32 {d18, d19}, [%0]! \n\t" //Q1 = m
"vld1.32 {d20, d21}, [%0]! \n\t" //Q2 = m+4
"vld1.32 {d22, d23}, [%0]! \n\t" //Q3 = m+8
"vld1.32 {d24, d25}, [%0]! \n\t" //Q4 = m+12
"vmul.f32 q13, q9, d0[0] \n\t" //Q5 = Q1*Q0[0]
"vmla.f32 q13, q10, d0[1] \n\t" //Q5 += Q1*Q0[1]
"vmla.f32 q13, q11, d1[0] \n\t" //Q5 += Q2*Q0[2]
"vmla.f32 q13, q12, d1[1] \n\t" //Q5 += Q3*Q0[3]
"vst1.32 {d26, d27}, [%2] \n\t" //Q4 = m+12
:
: "r"(m), "r"(v), "r"(d)
: "q0", "q9", "q10","q11", "q12", "q13", "memory"
);
#else
matvec4_c(m, v, d);
#endif
}
+71
View File
@@ -0,0 +1,71 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Assumes the floating point value |x| < 2,147,483,648
*/
#include "math_neon.h"
float modf_c(float x, int *i)
{
int n;
n = (int)x;
*i = n;
x = x - (float)n;
return x;
}
float modf_neon_hfp(float x, int *i)
{
#ifdef __MATH_NEON
asm volatile (
"vcvt.s32.f32 d1, d0 \n\t" //d1 = (int) d0;
"vcvt.f32.s32 d2, d1 \n\t" //d2 = (float) d1;
"vsub.f32 d0, d0, d2 \n\t" //d0 = d0 - d2;
"vstr.i32 s2, [r0] \n\t" //[r0] = d1[0]
::: "d0", "d1", "d2"
);
#endif
}
float modf_neon_sfp(float x, int *i)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, r0 \n\t" //d0 = {x, x}
"vcvt.s32.f32 d1, d0 \n\t" //d1 = (int) d0;
"vcvt.f32.s32 d2, d1 \n\t" //d2 = (float) d1;
"vsub.f32 d0, d0, d2 \n\t" //d0 = d0 - d2;
"vstr.i32 s2, [r1] \n\t" //[r0] = d1[0]
"vmov.f32 r0, s0 \n\t" //r0 = d0[0];
::: "d0", "d1", "d2"
);
#else
return modf_c(x, i);
#endif
}
+435
View File
@@ -0,0 +1,435 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef __MATH_NEON_H__
#define __MATH_NEON_H__
#if !defined(__i386__) && defined(__arm__)
//if defined neon ASM routines are used, otherwise all calls to *_neon
//functions are rerouted to their equivalent *_c function.
#define __MATH_NEON
//Default Floating Point value ABI: 0=softfp, 1=hardfp. Only effects *_neon routines.
//You can access the hardfp versions directly via the *_hard suffix.
//You can access the softfp versions directly via the *_soft suffix.
#define __MATH_FPABI 0
#endif
#ifdef GCC
#define ALIGN(A) __attribute__ ((aligned (A))
#else
#define ALIGN(A)
#endif
#ifndef _MATH_H
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#define M_PI_4 0.78539816339744830962 /* pi/4 */
#define M_E 2.7182818284590452354 /* e */
#define M_LOG2E 1.4426950408889634074 /* log_2 e */
#define M_LOG10E 0.43429448190325182765 /* log_10 e */
#define M_LN2 0.69314718055994530942 /* log_e 2 */
#define M_LN10 2.30258509299404568402 /* log_e 10 */
#define M_1_PI 0.31830988618379067154 /* 1/pi */
#define M_2_PI 0.63661977236758134308 /* 2/pi */
#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
#endif
#if __MATH_FPABI == 1
#define sinf_neon sinf_neon_hfp
#define cosf_neon cosf_neon_hfp
#define sincosf_neon sincosf_neon_hfp
#define tanf_neon tanf_neon_hfp
#define atanf_neon atanf_neon_hfp
#define atan2f_neon atan2f_neon_hfp
#define asinf_neon asinf_neon_hfp
#define acosf_neon acosf_neon_hfp
#define sinhf_neon sinhf_neon_hfp
#define coshf_neon coshf_neon_hfp
#define tanhf_neon tanhf_neon_hfp
#define expf_neon expf_neon_hfp
#define logf_neon logf_neon_hfp
#define log10f_neon log10f_neon_hfp
#define powf_neon powf_neon_hfp
#define floorf_neon floorf_neon_hfp
#define ceilf_neon ceilf_neon_hfp
#define fabsf_neon fabsf_neon_hfp
#define ldexpf_neon ldexpf_neon_hfp
#define frexpf_neon frexpf_neon_hfp
#define fmodf_neon fmodf_neon_hfp
#define modf_neon modf_neon_hfp
#define sqrtf_neon sqrtf_neon_hfp
#define invsqrtf_neon invsqrtf_neon_hfp
#else
#define sinf_neon sinf_neon_sfp
#define cosf_neon cosf_neon_sfp
#define sincosf_neon sincosf_neon_sfp
#define tanf_neon tanf_neon_sfp
#define atanf_neon atanf_neon_sfp
#define atan2f_neon atan2f_neon_sfp
#define asinf_neon asinf_neon_sfp
#define acosf_neon acosf_neon_sfp
#define sinhf_neon sinhf_neon_sfp
#define coshf_neon coshf_neon_sfp
#define tanhf_neon tanhf_neon_sfp
#define expf_neon expf_neon_sfp
#define logf_neon logf_neon_sfp
#define log10f_neon log10f_neon_sfp
#define powf_neon powf_neon_sfp
#define floorf_neon floorf_neon_sfp
#define ceilf_neon ceilf_neon_sfp
#define fabsf_neon fabsf_neon_sfp
#define ldexpf_neon ldexpf_neon_sfp
#define frexpf_neon frexpf_neon_sfp
#define fmodf_neon fmodf_neon_sfp
#define modf_neon modf_neon_sfp
#define sqrtf_neon sqrtf_neon_sfp
#define invsqrtf_neon invsqrtf_neon_sfp
#define dot2_neon dot2_neon_sfp
#define dot3_neon dot3_neon_sfp
#define dot4_neon dot4_neon_sfp
#endif
/*
function: enable_runfast
this function enables the floating point runfast mode on the
ARM Cortex A8.
*/
void enable_runfast();
float dot2_c(float v0[2], float v1[2]);
float dot2_neon(float v0[2], float v1[2]);
float dot3_c(float v0[3], float v1[3]);
float dot3_neon(float v0[3], float v1[3]);
float dot4_c(float v0[4], float v1[4]);
float dot4_neon(float v0[4], float v1[4]);
void cross3_c(float v0[3], float v1[3], float d[3]);
void cross3_neon(float v0[3], float v1[3], float d[3]);
void normalize2_c(float v[2], float d[2]);
void normalize2_neon(float v[2], float d[2]);
void normalize3_c(float v[3], float d[3]);
void normalize3_neon(float v[3], float d[3]);
void normalize4_c(float v[4], float d[4]);
void normalize4_neon(float v[4], float d[4]);
/*
function: matmul2
arguments: m0 2x2 matrix, m1 2x2 matrix
return: d 2x2 matrix
expression: d = m0 * m1
*/
void matmul2_c(float m0[4], float m1[4], float d[4]);
void matmul2_neon(float m0[4], float m1[4], float d[4]);
/*
function: matmul3
arguments: m0 3x3 matrix, m1 3x3 matrix
return: d 3x3 matrix
expression: d = m0 * m1
*/
void matmul3_c(float m0[9], float m1[9], float d[9]);
void matmul3_neon(float m0[9], float m1[9], float d[9]);
/*
function: matmul4
arguments: m0 4x4 matrix, m1 4x4 matrix
return: d 4x4 matrix
expression: d = m0 * m1
*/
void matmul4_c(float m0[16], float m1[16], float d[16]);
void matmul4_neon(float m0[16], float m1[16], float d[16]);
/*
function: matvec2
arguments: m 2x2 matrix, v 2 element vector
return: d 2x2 matrix
expression: d = m * v
*/
void matvec2_c(float m[4], float v[2], float d[2]);
void matvec2_neon(float m[4], float v[2], float d[2]);
/*
function: matvec3
arguments: m 3x3 matrix, v 3 element vector
return: d 3x3 matrix
expression: d = m * v
*/
void matvec3_c(float m[9], float v[3], float d[3]);
void matvec3_neon(float m[9], float v[3], float d[3]);
/*
function: matvec4
arguments: m 4x4 matrix, v 4 element vector
return: d 4x4 matrix
expression: d = m * v
*/
void matvec4_c(float m[16], float v[4], float d[4]);
void matvec4_neon(float m[16], float v[4], float d[4]);
/*
function: sinf
arguments: x radians
return: the sine function evaluated at x radians.
expression: r = sin(x)
*/
float sinf_c(float x);
float sinf_neon_hfp(float x);
float sinf_neon_sfp(float x);
/*
function: cosf
arguments: x radians
return: the cosine function evaluated at x radians.
expression: r = cos(x)
notes: computed using cos(x) = sin(x + pi/2)
*/
float cosf_c(float x);
float cosf_neon_hfp(float x);
float cosf_neon_sfp(float x);
/*
function: sincosf
arguments: x radians, r[2] result array.
return: both the sine and the cosine evaluated at x radians.
expression: r = {sin(x), cos(x)}
notes: faster than evaluating seperately.
*/
void sincosf_c(float x, float r[2]);
void sincosf_neon_hfp(float x, float r[2]);
void sincosf_neon_sfp(float x, float r[2]);
/*
function: sinfv
return: the sine function evaluated at x[i] radians
expression: r[i] = sin(x[i])
notes: faster than evaluating individually.
r and x can be the same memory location.
*/
void sinfv_c(float *x, int n, float *r);
void sinfv_neon(float *x, int n, float *r);
/*
function: tanf
return: the tangent evaluated at x radians.
expression: r = tan(x)
notes: computed using tan(x) = sin(x) / cos(x)
*/
float tanf_c(float x);
float tanf_neon_hfp(float x);
float tanf_neon_sfp(float x);
/*
function: atanf
return: the arctangent evaluated at x.
expression: r = atan(x)
*/
float atanf_c(float x);
float atanf_neon_hfp(float x);
float atanf_neon_sfp(float x);
/*
function: atanf
return: the arctangent evaluated at x.
expression: r = atan(x)
*/
float atan2f_c(float y, float x);
float atan2f_neon_hfp(float y, float x);
float atan2f_neon_sfp(float y, float x);
/*
function: asinf
return: the arcsine evaluated at x.
expression: r = asin(x)
*/
float asinf_c(float x);
float asinf_neon_hfp(float x);
float asinf_neon_sfp(float x);
/*
function: acosf
return: the arcsine evaluated at x.
expression: r = asin(x)
*/
float acosf_c(float x);
float acosf_neon_hfp(float x);
float acosf_neon_sfp(float x);
/*
function: sinhf
return: the arcsine evaluated at x.
expression: r = asin(x)
*/
float sinhf_c(float x);
float sinhf_neon_hfp(float x);
float sinhf_neon_sfp(float x);
/*
function: coshf
return: the arcsine evaluated at x.
expression: r = asin(x)
*/
float coshf_c(float x);
float coshf_neon_hfp(float x);
float coshf_neon_sfp(float x);
/*
function: tanhf
return: the arcsine evaluated at x.
expression: r = asin(x)
*/
float tanhf_c(float x);
float tanhf_neon_hfp(float x);
float tanhf_neon_sfp(float x);
/*
function: expf
return: the natural exponential evaluated at x.
expression: r = e ** x
*/
float expf_c(float x);
float expf_neon_hfp(float x);
float expf_neon_sfp(float x);
/*
function: logf
return: the value of the natural logarithm of x.
expression: r = ln(x)
notes: assumes x > 0
*/
float logf_c(float x);
float logf_neon_hfp(float x);
float logf_neon_sfp(float x);
/*
function: log10f
return: the value of the power 10 logarithm of x.
expression: r = log10(x)
notes: assumes x > 0
*/
float log10f_c(float x);
float log10f_neon_hfp(float x);
float log10f_neon_sfp(float x);
/*
function: powf
return: x raised to the power of n, x ** n.
expression: r = x ** y
notes: computed using e ** (y * ln(x))
*/
float powf_c(float x, float n);
float powf_neon_sfp(float x, float n);
float powf_neon_hfp(float x, float n);
/*
function: floorf
return: x rounded down (towards negative infinity) to its nearest
integer value.
notes: assumes |x| < 2 ** 31
*/
float floorf_c(float x);
float floorf_neon_sfp(float x);
float floorf_neon_hfp(float x);
/*
function: ceilf
return: x rounded up (towards positive infinity) to its nearest
integer value.
notes: assumes |x| < 2 ** 31
*/
float ceilf_c(float x);
float ceilf_neon_hfp(float x);
float ceilf_neon_sfp(float x);
/*
function: fabsf
return: absolute vvalue of x
notes: assumes |x| < 2 ** 31
*/
float fabsf_c(float x);
float fabsf_neon_hfp(float x);
float fabsf_neon_sfp(float x);
/*
function: ldexpf
return: the value of m multiplied by 2 to the power of e.
expression: r = m * (2 ** e)
*/
float ldexpf_c(float m, int e);
float ldexpf_neon_hfp(float m, int e);
float ldexpf_neon_sfp(float m, int e);
/*
function: frexpf
return: the exponent and mantissa of x
*/
float frexpf_c(float x, int *e);
float frexpf_neon_hfp(float x, int *e);
float frexpf_neon_sfp(float x, int *e);
/*
function: fmodf
return: the remainder of x divided by y, x % y
expression: r = x - floor(x / y) * y;
notes: assumes that |x / y| < 2 ** 31
*/
float fmodf_c(float x, float y);
float fmodf_neon_hfp(float x, float y);
float fmodf_neon_sfp(float x, float y);
/*
function: modf
return: breaks x into the integer (i) and fractional part (return)
notes: assumes that |x| < 2 ** 31
*/
float modf_c(float x, int *i);
float modf_neon_hfp(float x, int *i);
float modf_neon_sfp(float x, int *i);
/*
function: sqrtf
return: (x^0.5)
notes:
*/
float sqrtf_c(float x);
float sqrtf_neon_hfp(float x);
float sqrtf_neon_sfp(float x);
/*
function: invsqrtf
return: 1.0f / (x^0.5)
notes:
*/
float invsqrtf_c(float x);
float invsqrtf_neon_hfp(float x);
float invsqrtf_neon_sfp(float x);
#endif
+182
View File
@@ -0,0 +1,182 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Based on x ^ n = exp(n * log(x))
Test func : powf(x, n)
Test Range: (1,1) < (x, n) < (10, 10)
Peak Error: ~0.0010%
RMS Error: ~0.0002%
*/
#include "math.h"
#include "math_neon.h"
const float __powf_rng[2] = {
1.442695041f,
0.693147180f
};
const float __powf_lut[16] = {
-2.295614848256274, //p0 log
-2.470711633419806, //p4
-5.686926051100417, //p2
-0.165253547131978, //p6
+5.175912446351073, //p1
+0.844006986174912, //p5
+4.584458825456749, //p3
+0.014127821926000, //p7
0.9999999916728642, //p0 exp
0.04165989275009526, //p4
0.5000006143673624, //p2
0.0014122663401803872, //p6
1.000000059694879, //p1
0.008336936973260111, //p5
0.16666570253074878, //p3
0.00019578093328483123 //p7
};
float powf_c(float x, float n)
{
float a, b, c, d, xx;
int m;
union {
float f;
int i;
} r;
//extract exponent
r.f = x;
m = (r.i >> 23);
m = m - 127;
r.i = r.i - (m << 23);
//Taylor Polynomial (Estrins)
xx = r.f * r.f;
a = (__powf_lut[4] * r.f) + (__powf_lut[0]);
b = (__powf_lut[6] * r.f) + (__powf_lut[2]);
c = (__powf_lut[5] * r.f) + (__powf_lut[1]);
d = (__powf_lut[7] * r.f) + (__powf_lut[3]);
a = a + b * xx;
c = c + d * xx;
xx = xx * xx;
r.f = a + c * xx;
//add exponent
r.f = r.f + ((float) m) * __powf_rng[1];
r.f = r.f * n;
//Range Reduction:
m = (int) (r.f * __powf_rng[0]);
r.f = r.f - ((float) m) * __powf_rng[1];
//Taylor Polynomial (Estrins)
a = (__powf_lut[12] * r.f) + (__powf_lut[8]);
b = (__powf_lut[14] * r.f) + (__powf_lut[10]);
c = (__powf_lut[13] * r.f) + (__powf_lut[9]);
d = (__powf_lut[15] * r.f) + (__powf_lut[11]);
xx = r.f * r.f;
a = a + b * xx;
c = c + d * xx;
xx = xx* xx;
r.f = a + c * xx;
//multiply by 2 ^ m
m = m << 23;
r.i = r.i + m;
return r.f;
}
float powf_neon_hfp(float x, float n)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d16, d0[1] \n\t" //d16 = {y,y};
"vdup.f32 d0, d0[0] \n\t" //d0 = {x,x};
//extract exponent
"vmov.i32 d2, #127 \n\t" //d2 = 127;
"vshr.u32 d6, d0, #23 \n\t" //d6 = d0 >> 23;
"vsub.i32 d6, d6, d2 \n\t" //d6 = d6 - d2;
"vshl.u32 d1, d6, #23 \n\t" //d1 = d6 << 23;
"vsub.i32 d0, d0, d1 \n\t" //d0 = d0 + d1;
//polynomial:
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0*d0 = {x^2, x^2}
"vld1.32 {d2, d3, d4, d5}, [%1]! \n\t" //q1 = {p0, p4, p2, p6}, q2 = {p1, p5, p3, p7} ;
"vmla.f32 q1, q2, d0[0] \n\t" //q1 = q1 + q2 * d0[0]
"vmla.f32 d2, d3, d1[0] \n\t" //d2 = d2 + d3 * d1[0]
"vmul.f32 d1, d1, d1 \n\t" //d1 = d1 * d1 = {x^4, x^4}
"vmla.f32 d2, d1, d2[1] \n\t" //d2 = d2 + d1 * d2[1]
//add exponent
"vld1.32 d7, [%0] \n\t" //d7 = {invrange, range}
"vcvt.f32.s32 d6, d6 \n\t" //d6 = (float) d6
"vmla.f32 d2, d6, d7[1] \n\t" //d2 = d2 + d6 * d7[1]
"vdup.f32 d0, d2[0] \n\t" //d0 = d2[0]
"vmul.f32 d0, d0, d16 \n\t" //d0 = d0 * d16
//Range Reduction:
"vmul.f32 d6, d0, d7[0] \n\t" //d6 = d0 * d7[0]
"vcvt.u32.f32 d6, d6 \n\t" //d6 = (int) d6
"vcvt.f32.u32 d1, d6 \n\t" //d1 = (float) d6
"vmls.f32 d0, d1, d7[1] \n\t" //d0 = d0 - d1 * d7[1]
//polynomial:
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0*d0 = {x^2, x^2}
"vld1.32 {d2, d3, d4, d5}, [%1] \n\t" //q1 = {p0, p4, p2, p6}, q2 = {p1, p5, p3, p7} ;
"vmla.f32 q1, q2, d0[0] \n\t" //q1 = q1 + q2 * d0[0]
"vmla.f32 d2, d3, d1[0] \n\t" //d2 = d2 + d3 * d1[0]
"vmul.f32 d1, d1, d1 \n\t" //d1 = d1 * d1 = {x^4, x^4}
"vmla.f32 d2, d1, d2[1] \n\t" //d2 = d2 + d1 * d2[1]
//multiply by 2 ^ m
"vshl.i32 d6, d6, #23 \n\t" //d6 = d6 << 23
"vadd.i32 d0, d2, d6 \n\t" //d0 = d2 + d6
:: "r"(__powf_rng), "r"(__powf_lut)
: "d0", "d1", "d2","d3", "d4", "d5", "d6", "d7"
);
#endif
}
float powf_neon_sfp(float x, float n)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
asm volatile ("vmov.f32 s1, r1 \n\t");
powf_neon_hfp(x, n);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return powf_c(x, n);
#endif
};
+42
View File
@@ -0,0 +1,42 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
void
enable_runfast()
{
#ifdef __arm__
static const unsigned int x = 0x04086060;
static const unsigned int y = 0x03000000;
int r;
asm volatile (
"fmrx %0, fpscr \n\t" //r0 = FPSCR
"and %0, %0, %1 \n\t" //r0 = r0 & 0x04086060
"orr %0, %0, %2 \n\t" //r0 = r0 | 0x03000000
"fmxr fpscr, %0 \n\t" //FPSCR = r0
: "=r"(r)
: "r"(x), "r"(y)
);
#endif
}
+163
View File
@@ -0,0 +1,163 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __sincosf_rng[2] = {
2.0 / M_PI,
M_PI / 2.0
};
const float __sincosf_lut[8] = {
-0.00018365f, //p7
-0.00018365f, //p7
+0.00830636f, //p5
+0.00830636f, //p5
-0.16664831f, //p3
-0.16664831f, //p3
+0.99999661f, //p1
+0.99999661f, //p1
};
void sincosf_c( float x, float r[2])
{
union {
float f;
int i;
} ax, bx;
float y;
float a, b, c, d, xx, yy;
int m, n, o, p;
y = x + __sincosf_rng[1];
ax.f = fabsf(x);
bx.f = fabsf(y);
//Range Reduction:
m = (int) (ax.f * __sincosf_rng[0]);
o = (int) (bx.f * __sincosf_rng[0]);
ax.f = ax.f - (((float)m) * __sincosf_rng[1]);
bx.f = bx.f - (((float)o) * __sincosf_rng[1]);
//Test Quadrant
n = m & 1;
p = o & 1;
ax.f = ax.f - n * __sincosf_rng[1];
bx.f = bx.f - p * __sincosf_rng[1];
m = m >> 1;
o = o >> 1;
n = n ^ m;
p = p ^ o;
m = (x < 0.0);
o = (y < 0.0);
n = n ^ m;
p = p ^ o;
n = n << 31;
p = p << 31;
ax.i = ax.i ^ n;
bx.i = bx.i ^ p;
//Taylor Polynomial
xx = ax.f * ax.f;
yy = bx.f * bx.f;
r[0] = __sincosf_lut[0];
r[1] = __sincosf_lut[1];
r[0] = r[0] * xx + __sincosf_lut[2];
r[1] = r[1] * yy + __sincosf_lut[3];
r[0] = r[0] * xx + __sincosf_lut[4];
r[1] = r[1] * yy + __sincosf_lut[5];
r[0] = r[0] * xx + __sincosf_lut[6];
r[1] = r[1] * yy + __sincosf_lut[7];
r[0] = r[0] * ax.f;
r[1] = r[1] * bx.f;
}
void sincosf_neon_hfp(float x, float r[2])
{
//HACK: Assumes for softfp that r1 = x, and for hardfp that s0 = x.
#ifdef __MATH_NEON
asm volatile (
//{x, y} = {x, x + pi/2}
"vdup.f32 d1, d0[0] \n\t" //d1 = {x, x}
"vld1.32 d3, [%1] \n\t" //d3 = {invrange, range}
"vadd.f32 d0, d1, d3 \n\t" //d0 = d1 + d3
"vmov.f32 s0, s2 \n\t" //d0[0] = d1[0]
"vabs.f32 d1, d0 \n\t" //d1 = {abs(x), abs(y)}
//Range Reduction:
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
//Checking Quadrant:
//ax = ax - (k&1) * M_PI_2
"vmov.i32 d4, #1 \n\t" //d4 = 1
"vand.i32 d4, d4, d2 \n\t" //d4 = d4 & d2
"vcvt.f32.u32 d5, d4 \n\t" //d5 = (float) d4
"vmls.f32 d1, d5, d3[1] \n\t" //d1 = d1 - d5 * d3[1]
//ax = ax ^ ((k & 1) ^ (k >> 1) ^ (x < 0) << 31)
"vshr.u32 d3, d2, #1 \n\t" //d3 = d2 >> 1
"veor.i32 d4, d4, d3 \n\t" //d4 = d4 ^ d3
"vclt.f32 d3, d0, #0 \n\t" //d3 = (d0 < 0.0)
"veor.i32 d4, d4, d3 \n\t" //d4 = d4 ^ d3
"vshl.i32 d4, d4, #31 \n\t" //d4 = d4 << 31
"veor.i32 d0, d1, d4 \n\t" //d0 = d1 ^ d4
//polynomial:
"vldm %2!, {d2, d3} \n\t" //d2 = {p7, p7}, d3 = {p5, p5}, r3 += 4;
"vmul.f32 d1, d0, d0 \n\t" //d1 = d0 * d0 = {x^2, y^2}
"vldm %2!, {d4} \n\t" //d4 = {p3, p3}, r3 += 2;
"vmla.f32 d3, d2, d1 \n\t" //d3 = d3 + d2 * d1;
"vldm %2!, {d5} \n\t" //d5 = {p1, p1}, r3 += 2;
"vmla.f32 d4, d3, d1 \n\t" //d4 = d4 + d3 * d1;
"vmla.f32 d5, d4, d1 \n\t" //d5 = d5 + d4 * d1;
"vmul.f32 d5, d5, d0 \n\t" //d5 = d5 * d0;
"vstm.f32 %0, {d5} \n\t" //r[0] = d5[0], r[1]=d5[1];
: "+r"(r)
: "r"(__sincosf_rng), "r"(__sincosf_lut)
: "d0", "d1", "d2", "d3", "d4", "d5"
);
#else
sincosf_c(x, r);
#endif
}
void sincosf_neon_sfp(float x, float r[2])
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
sincosf_neon_hfp(x, r);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
sincosf_c(x, r);
#endif
};
+128
View File
@@ -0,0 +1,128 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <math.h>
#include "math_neon.h"
static const float __sinf_rng[2] = {
2.0 / M_PI,
M_PI / 2.0
} ALIGN(16);
static const float __sinf_lut[4] = {
-0.00018365f, //p7
-0.16664831f, //p3
+0.00830636f, //p5
+0.99999661f, //p1
} ALIGN(16);
float sinf_c(float x)
{
union {
float f;
int i;
} ax;
float r, a, b, xx;
int m, n;
ax.f = fabsf(x);
//Range Reduction:
m = (int) (ax.f * __sinf_rng[0]);
ax.f = ax.f - (((float)m) * __sinf_rng[1]);
//Test Quadrant
n = m & 1;
ax.f = ax.f - n * __sinf_rng[1];
m = m >> 1;
n = n ^ m;
m = (x < 0.0);
n = n ^ m;
n = n << 31;
ax.i = ax.i ^ n;
//Taylor Polynomial (Estrins)
xx = ax.f * ax.f;
a = (__sinf_lut[0] * ax.f) * xx + (__sinf_lut[2] * ax.f);
b = (__sinf_lut[1] * ax.f) * xx + (__sinf_lut[3] * ax.f);
xx = xx * xx;
r = b + a * xx;
return r;
}
float sinf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 d3, [%0] \n\t" //d3 = {invrange, range}
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vmov.i32 d5, #1 \n\t" //d5 = 1
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vshr.u32 d7, d2, #1 \n\t" //d7 = d2 >> 1
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
"vand.i32 d5, d2, d5 \n\t" //d5 = d2 & d5
"vclt.f32 d18, d0, #0 \n\t" //d18 = (d0 < 0.0)
"vcvt.f32.u32 d6, d5 \n\t" //d6 = (float) d5
"vmls.f32 d1, d6, d3[1] \n\t" //d1 = d1 - d6 * d3[1]
"veor.i32 d5, d5, d7 \n\t" //d5 = d5 ^ d7
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d16, d17}, [%1] \n\t" //q8 = {p7, p3, p5, p1}
"veor.i32 d5, d5, d18 \n\t" //d5 = d5 ^ d18
"vshl.i32 d5, d5, #31 \n\t" //d5 = d5 << 31
"veor.i32 d1, d1, d5 \n\t" //d1 = d1 ^ d5
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q8, d1[0] \n\t" //q0 = q8 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {...., p1x + p3x^3 + p5x^5 + p7x^7}
"vmov.f32 s0, s3 \n\t" //s0 = s3
:
: "r"(__sinf_rng), "r"(__sinf_lut)
: "q0", "q1", "q2", "q3", "q8", "q9"
);
#endif
}
float sinf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
sinf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return sinf_c(x);
#endif
};
+110
View File
@@ -0,0 +1,110 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __sinfv_rng[2] = {
2.0 / M_PI,
M_PI / 2.0,
};
const float __sinfv_lut[4] = {
-0.00018365f, //p7
-0.16664831f, //p3
+0.00830636f, //p5
+0.99999661f, //p1
};
void sinfv_c(float *x, int n, float *r)
{
union {
float f;
int i;
} ax, bx;
float aa, ab, ba, bb, axx, bxx;
int am, bm, an, bn;
if (n & 0x1) {
*r++ = sinf_c(*x++);
n--;
}
float rng0 = __sinfv_rng[0];
float rng1 = __sinfv_rng[1];
while(n > 0){
float x0 = *x++;
float x1 = *x++;
ax.f = fabsf(x0);
bx.f = fabsf(x1);
//Range Reduction:
am = (int) (ax.f * rng0);
bm = (int) (bx.f * rng0);
ax.f = ax.f - (((float)am) * rng1);
bx.f = bx.f - (((float)bm) * rng1);
//Test Quadrant
an = am & 1;
bn = bm & 1;
ax.f = ax.f - an * rng1;
bx.f = bx.f - bn * rng1;
am = (am & 2) >> 1;
bm = (bm & 2) >> 1;
ax.i = ax.i ^ ((an ^ am ^ (x0 < 0)) << 31);
bx.i = bx.i ^ ((bn ^ bm ^ (x1 < 0)) << 31);
//Taylor Polynomial (Estrins)
axx = ax.f * ax.f;
bxx = bx.f * bx.f;
aa = (__sinfv_lut[0] * ax.f) * axx + (__sinfv_lut[2] * ax.f);
ba = (__sinfv_lut[0] * bx.f) * bxx + (__sinfv_lut[2] * bx.f);
ab = (__sinfv_lut[1] * ax.f) * axx + (__sinfv_lut[3] * ax.f);
bb = (__sinfv_lut[1] * bx.f) * bxx + (__sinfv_lut[3] * bx.f);
axx = axx * axx;
bxx = bxx * bxx;
*r++ = ab + aa * axx;
*r++ = bb + ba * bxx;
n -= 2;
}
}
void sinfv_neon(float *x, int n, float *r)
{
#ifdef __MATH_NEON
asm volatile (""
:
:"r"(x), "r"(n)
);
#else
sinfv_c(x, n, r);
#endif
}
+120
View File
@@ -0,0 +1,120 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __sinhf_rng[2] = {
1.442695041f,
0.693147180f
};
const float __sinhf_lut[16] = {
0.00019578093328483123, //p7
0.00019578093328483123, //p7
0.0014122663401803872, //p6
0.0014122663401803872, //p6
0.008336936973260111, //p5
0.008336936973260111, //p5
0.04165989275009526, //p4
0.04165989275009526, //p4
0.16666570253074878, //p3
0.16666570253074878, //p3
0.5000006143673624, //p2
0.5000006143673624, //p2
1.000000059694879, //p1
1.000000059694879, //p1
0.9999999916728642, //p0
0.9999999916728642 //p0
};
float sinhf_c(float x)
{
float a, b, xx;
xx = -x;
a = expf_c(x);
b = expf_c(xx);
a = a - b;
a = a * 0.5f;
return a;
}
float sinhf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"fnegs s1, s1 \n\t" //s1 = -s1
//Range Reduction:
"vld1.32 d2, [%0] \n\t" //d2 = {invrange, range}
"vld1.32 {d16, d17}, [%1]! \n\t"
"vmul.f32 d6, d0, d2[0] \n\t" //d6 = d0 * d2[0]
"vcvt.s32.f32 d6, d6 \n\t" //d6 = (int) d6
"vld1.32 {d18}, [%1]! \n\t"
"vcvt.f32.s32 d1, d6 \n\t" //d1 = (float) d6
"vld1.32 {d19}, [%1]! \n\t"
"vmls.f32 d0, d1, d2[1] \n\t" //d0 = d0 - d1 * d2[1]
"vld1.32 {d20}, [%1]! \n\t"
//polynomial:
"vmla.f32 d17, d16, d0 \n\t" //d17 = d17 + d16 * d0;
"vld1.32 {d21}, [%1]! \n\t"
"vmla.f32 d18, d17, d0 \n\t" //d18 = d18 + d17 * d0;
"vld1.32 {d22}, [%1]! \n\t"
"vmla.f32 d19, d18, d0 \n\t" //d19 = d19 + d18 * d0;
"vld1.32 {d23}, [%1]! \n\t"
"vmla.f32 d20, d19, d0 \n\t" //d20 = d20 + d19 * d0;
"vmla.f32 d21, d20, d0 \n\t" //d21 = d21 + d20 * d0;
"vmla.f32 d22, d21, d0 \n\t" //d22 = d22 + d21 * d0;
"vmla.f32 d23, d22, d0 \n\t" //d23 = d23 + d22 * d0;
//multiply by 2 ^ m
"vshl.i32 d6, d6, #23 \n\t" //d6 = d6 << 23
"vadd.i32 d0, d23, d6 \n\t" //d0 = d22 + d6
"vdup.f32 d2, d0[1] \n\t" //d2 = s1
"vmov.f32 d1, #0.5 \n\t" //d1 = 0.5
"vsub.f32 d0, d0, d2 \n\t" //d0 = d0 - d2
"vmul.f32 d0, d1 \n\t" //d0 = d0 * d1
:: "r"(__sinhf_rng), "r"(__sinhf_lut)
: "d0", "d1", "q1", "q2", "d6"
);
#endif
}
float sinhf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
sinhf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return sinhf_c(x);
#endif
};
+105
View File
@@ -0,0 +1,105 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Test func : sqrtf(x)
Test Range: 0 < x < 1,000,000,000
Peak Error: ~0.0010%
RMS Error: ~0.0005%
*/
#include "math.h"
#include "math_neon.h"
float sqrtf_c(float x)
{
float b, c;
int m;
union {
float f;
int i;
} a;
//fast invsqrt approx
a.f = x;
a.i = 0x5F3759DF - (a.i >> 1); //VRSQRTE
c = x * a.f;
b = (3.0f - c * a.f) * 0.5; //VRSQRTS
a.f = a.f * b;
c = x * a.f;
b = (3.0f - c * a.f) * 0.5;
a.f = a.f * b;
//fast inverse approx
x = a.f;
m = 0x3F800000 - (a.i & 0x7F800000);
a.i = a.i + m;
a.f = 1.41176471f - 0.47058824f * a.f;
a.i = a.i + m;
b = 2.0 - a.f * x;
a.f = a.f * b;
b = 2.0 - a.f * x;
a.f = a.f * b;
return a.f;
}
float sqrtf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
//fast invsqrt approx
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
//fast reciporical approximation
"vrecpe.f32 d1, d0 \n\t" //d1 = ~ 1 / d0;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d0, d1, d2 \n\t" //d0 = d1 * d2;
::: "d0", "d1", "d2", "d3"
);
#endif
}
float sqrtf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
sqrtf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return sqrtf_c(x);
#endif
};
+147
View File
@@ -0,0 +1,147 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Test func : sqrtf(x)
Test Range: 0 < x < 1,000,000,000
Peak Error: ~0.0010%
RMS Error: ~0.0005%
*/
#include "math.h"
#include "math_neon.h"
void sqrtfv_c(float *x, int n, float *r)
{
float x0, x1;
float b0, b1, c0, c1;
int m0, m1;
union {
float f;
int i;
} a0, a1;
if (n & 0x1){
*r++ = sqrtf_c(*x++);
n--;
}
while(n > 0){
x0 = *x++;
x1 = *x++;
//fast invsqrt approx
a0.f = x0;
a1.f = x1;
a0.i = 0x5F3759DF - (a0.i >> 1); //VRSQRTE
a1.i = 0x5F3759DF - (a1.i >> 1); //VRSQRTE
c0 = x0 * a0.f;
c1 = x1 * a1.f;
b0 = (3.0f - c0 * a0.f) * 0.5; //VRSQRTS
b1 = (3.0f - c1 * a1.f) * 0.5; //VRSQRTS
a0.f = a0.f * b0;
a1.f = a1.f * b1;
c0 = x0 * a0.f;
c1 = x1 * a1.f;
b0 = (3.0f - c0 * a0.f) * 0.5; //VRSQRTS
b1 = (3.0f - c1 * a1.f) * 0.5; //VRSQRTS
a0.f = a0.f * b0;
a1.f = a1.f * b1;
//fast inverse approx
c0 = a0.f;
c0 = a1.f;
m0 = 0x3F800000 - (a0.i & 0x7F800000);
m1 = 0x3F800000 - (a1.i & 0x7F800000);
a0.i = a0.i + m0;
a1.i = a1.i + m1;
a0.f = 1.41176471f - 0.47058824f * a0.f;
a1.f = 1.41176471f - 0.47058824f * a1.f;
a0.i = a0.i + m0;
a1.i = a1.i + m1;
b0 = 2.0 - a0.f * c0;
b1 = 2.0 - a1.f * c1;
a0.f = a0.f * b0;
a1.f = a1.f * b1;
b0 = 2.0 - a0.f * c0;
b1 = 2.0 - a1.f * c1;
a0.f = a0.f * b0;
a1.f = a1.f * b1;
*r++ = a0.f;
*r++ = a1.f;
n -= 2;
}
}
void sqrtfv_neon(float *x, int n, float *r)
{
#if 0
asm volatile (
"tst r1, #1 \n\t" //r1 & 1
"beq 1f \n\t" //
"vld1.32 d0[0], [r0]! \n\t" //s0 = *x++
"mov ip, lr \n\t" //ip = lr
//"bl sqrtf_neon_hfp \n\t" //sqrtf_neon
"mov lr, ip \n\t" //lr = ip
"vst1.32 d0[0], [r2]! \n\t" //*r++ = r0
"subs r1, r1, #1 \n\t" //r1 = r1 - 1;
"bxeq lr \n\t" //
"1: \n\t" //
"vld1.32 d0, [r0]! \n\t" //d0 = (*x[0], *x[1]), x+=2;
//fast invsqrt approx
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d3 = d0 * d2
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4
"vmul.f32 d2, d0, d1 \n\t" //d3 = d0 * d2
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4
//fast reciporical approximation
"vrecpe.f32 d1, d0 \n\t" //d1 = ~ 1 / d0;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d0, d1, d2 \n\t" //d0 = d1 * d2;
"vst1.64 d0, [r2]! \n\t" //*r++ = d0;
"subs r1, r1, #2 \n\t" //n = n - 2; update flags
"bgt 1b \n\t" //
::: "d0", "d1", "d2", "d3"
);
#else
sqrtfv_c(x, n, r);
#endif
}
+156
View File
@@ -0,0 +1,156 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
const float __tanf_rng[2] = {
2.0 / M_PI,
M_PI / 2.0
};
const float __tanf_lut[4] = {
-0.00018365f, //p7
-0.16664831f, //p3
+0.00830636f, //p5
+0.99999661f, //p1
};
float tanf_c(float x){
union {
float f;
int i;
} ax, c;
float r, a, b, xx, cc, cx;
int m;
ax.f = fabsf(x);
//Range Reduction:
m = (int) (ax.f * __tanf_rng[0]);
ax.f = ax.f - (((float)m) * __tanf_rng[1]);
//Test Quadrant
ax.f = ax.f - (m & 1) * __tanf_rng[1];
ax.i = ax.i ^ ((*(int*)&x) & 0x80000000);
//Taylor Polynomial (Estrins)
xx = ax.f * ax.f;
a = (__tanf_lut[0] * ax.f) * xx + (__tanf_lut[2] * ax.f);
b = (__tanf_lut[1] * ax.f) * xx + (__tanf_lut[3] * ax.f);
xx = xx * xx;
r = b + a * xx;
//cosine
c.f = 1.0 - r * r;
//fast invsqrt approximation (2x newton iterations)
cc = c.f;
c.i = 0x5F3759DF - (c.i >> 1); //VRSQRTE
cx = cc * c.f;
a = (3.0f - cx * c.f) / 2; //VRSQRTS
c.f = c.f * a;
cx = cc * c.f;
a = (3.0f - cx * c.f) / 2;
c.f = c.f * a;
r = r * c.f;
return r;
}
float tanf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile (
"vdup.f32 d0, d0[0] \n\t" //d0 = {x, x}
"vabs.f32 d1, d0 \n\t" //d1 = {ax, ax}
//Range Reduction:
"vld1.32 d3, [%0] \n\t" //d3 = {invrange, range}
"vmul.f32 d2, d1, d3[0] \n\t" //d2 = d1 * d3[0]
"vcvt.u32.f32 d2, d2 \n\t" //d2 = (int) d2
"vcvt.f32.u32 d4, d2 \n\t" //d4 = (float) d2
"vmls.f32 d1, d4, d3[1] \n\t" //d1 = d1 - d4 * d3[1]
//Checking Quadrant:
//ax = ax - (k&1) * M_PI_2
"vmov.i32 d4, #1 \n\t" //d4 = 1
"vand.i32 d2, d2, d4 \n\t" //d2 = d2 & d4
"vcvt.f32.u32 d2, d2 \n\t" //d2 = (float) d2
"vmls.f32 d1, d2, d3[1] \n\t" //d1 = d1 - d2 * d3[1]
//ax = ax ^ ( x.i & 0x800000000)
"vmov.i32 d4, #0x80000000 \n\t" //d4 = 0x80000000
"vand.i32 d0, d0, d4 \n\t" //d0 = d0 & d4
"veor.i32 d1, d1, d0 \n\t" //d1 = d1 ^ d0
//polynomial:
"vmul.f32 d2, d1, d1 \n\t" //d2 = d1*d1 = {x^2, x^2}
"vld1.32 {d4, d5}, [%1] \n\t" //d4 = {p7, p3}, d5 = {p5, p1}
"vmul.f32 d3, d2, d2 \n\t" //d3 = d2*d2 = {x^4, x^4}
"vmul.f32 q0, q2, d1[0] \n\t" //q0 = q2 * d1[0] = {p7x, p3x, p5x, p1x}
"vmla.f32 d1, d0, d2[0] \n\t" //d1 = d1 + d0*d2 = {p5x + p7x^3, p1x + p3x^3}
"vmla.f32 d1, d3, d1[0] \n\t" //d1 = d1 + d3*d0 = {..., p1x + p3x^3 + p5x^5 + p7x^7}
//cosine
"vmov.f32 s1, #1.0 \n\t" //d0[1] = 1.0
"vmls.f32 d0, d1, d1 \n\t" //d0 = {..., 1.0 - sx*sx}
//invsqrt approx
"vmov.f32 d2, d0 \n\t" //d2 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d3, d0, d2 \n\t" //d3 = d0 * d2
"vrsqrts.f32 d4, d3, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d4 \n\t" //d0 = d0 * d4
"vmul.f32 d3, d0, d2 \n\t" //d3 = d0 * d2
"vrsqrts.f32 d4, d3, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d4 \n\t" //d0 = d0 * d4
"vmul.f32 d0, d0, d1 \n\t" //d0 = d0 * d1
"vmov.f32 s0, s1 \n\t" //s0 = s1
:: "r"(__tanf_rng), "r"(__tanf_lut)
: "d0", "d1", "d2", "d3", "d4", "d5"
);
#endif
}
float tanf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vdup.f32 d0, r0 \n\t");
tanf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return tanf_c(x);
#endif
};
+95
View File
@@ -0,0 +1,95 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math.h"
#include "math_neon.h"
/*
TanH = (e^x - e^-x) / (e^x + e^-x)
TanH = (e^x - e^-x)(e^x) / (e^x + e^-x)(e^x)
TanH = (e^2x - 1) / (e^2x + 1)
*/
float tanhf_c(float x)
{
float a, b, c;
int m;
union{
float f;
int i;
} xx;
x = 2.0f * x;
a = expf_c(x);
c = a + 1.0f;
//reciporical approx.
xx.f = c;
m = 0x3F800000 - (xx.i & 0x7F800000);
xx.i = xx.i + m;
xx.f = 1.41176471f - 0.47058824f * xx.f;
xx.i = xx.i + m;
b = 2.0 - xx.f * c;
xx.f = xx.f * b;
b = 2.0 - xx.f * c;
xx.f = xx.f * b;
c = a - 1.0;
xx.f *= c;
return xx.f;
}
float tanhf_neon_hfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vadd.f32 d0, d0, d0 \n\t");
expf_neon_hfp(x);
asm volatile (
"vmov.f32 d2, #1.0 \n\t"
"vsub.f32 d3, d0, d2 \n\t"
"vadd.f32 d0, d0, d2 \n\t"
"vrecpe.f32 d1, d0 \n\t" //d1 = ~ 1 / d0;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d1, d1, d2 \n\t" //d1 = d1 * d2;
"vrecps.f32 d2, d1, d0 \n\t" //d2 = 2.0 - d1 * d0;
"vmul.f32 d0, d1, d2 \n\t" //d0 = d1 * d2;
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3;
::: "d0", "d1", "d2", "d3"
);
#endif
}
float tanhf_neon_sfp(float x)
{
#ifdef __MATH_NEON
asm volatile ("vmov.f32 s0, r0 \n\t");
tanhf_neon_hfp(x);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return tanhf_c(x);
#endif
};
+118
View File
@@ -0,0 +1,118 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math_neon.h"
//vec2 scalar product
float
dot2_c(float v0[2], float v1[2])
{
float r;
r = v0[0]*v1[0];
r += v0[1]*v1[1];
return r;
}
void
normalize2_c(float v[2], float d[2])
{
float b, c, x;
union {
float f;
int i;
} a;
x = v[0]*v[0];
x += v[1]*v[1];
//fast invsqrt approx
a.f = x;
a.i = 0x5F3759DF - (a.i >> 1); //VRSQRTE
c = x * a.f;
b = (3.0f - c * a.f) * 0.5; //VRSQRTS
a.f = a.f * b;
c = x * a.f;
b = (3.0f - c * a.f) * 0.5;
a.f = a.f * b;
d[0] = v[0]*a.f;
d[1] = v[1]*a.f;
}
float
dot2_neon_hfp(float v0[2], float v1[2])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d2}, [%0] \n\t" //d2={x0,y0}
"vld1.32 {d4}, [%1] \n\t" //d4={x1,y1}
"vmul.f32 d0, d2, d4 \n\t" //d0 = d2*d4
"vpadd.f32 d0, d0, d0 \n\t" //d0 = d[0] + d[1]
:: "r"(v0), "r"(v1)
:
);
#endif
}
float
dot2_neon_sfp(float v0[2], float v1[2])
{
#ifdef __MATH_NEON
dot2_neon_hfp(v0, v1);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return dot2_c(v0, v1);
#endif
};
void
normalize2_neon(float v[2], float d[2])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 d4, [%0] \n\t" //d4 = {x0,y0}
"vmul.f32 d0, d4, d4 \n\t" //d0 = d2*d2
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d4, d4, d0[0] \n\t" //d4 = d4*d0[0]
"vst1.32 d4, [%1] \n\t" //
:: "r"(v), "r"(d)
: "d0", "d1", "d2", "d3", "d4", "memory"
);
#else
normalize2_c(v, d);
#endif
}
+172
View File
@@ -0,0 +1,172 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math_neon.h"
//vec4 scalar product
float
dot3_c(float v0[3], float v1[3])
{
float r;
r = v0[0]*v1[0];
r += v0[1]*v1[1];
r += v0[2]*v1[2];
return r;
}
void
cross3_c(float v0[3], float v1[3], float d[3])
{
d[0] = v0[1]*v1[2] - v0[2]*v1[1];
d[1] = v0[2]*v1[0] - v0[0]*v1[2];
d[2] = v0[0]*v1[1] - v0[1]*v1[0];
}
void
normalize3_c(float v[3], float d[3])
{
float b, c, x;
union {
float f;
int i;
} a;
x = v[0]*v[0];
x += v[1]*v[1];
x += v[2]*v[2];
//fast invsqrt approx
a.f = x;
a.i = 0x5F3759DF - (a.i >> 1); //VRSQRTE
c = x * a.f;
b = (3.0f - c * a.f) * 0.5; //VRSQRTS
a.f = a.f * b;
c = x * a.f;
b = (3.0f - c * a.f) * 0.5;
a.f = a.f * b;
d[0] = v[0]*a.f;
d[1] = v[1]*a.f;
d[2] = v[2]*a.f;
}
float
dot3_neon_hfp(float v0[3], float v1[3])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d2}, [%0] \n\t" //d2={x0,y0}
"flds s6, [%0, #8] \n\t" //d3[0]={z0}
"vld1.32 {d4}, [%1] \n\t" //d4={x1,y1}
"flds s10, [%1, #8] \n\t" //d5[0]={z1}
"vmul.f32 d0, d2, d4 \n\t" //d0= d2*d4
"vpadd.f32 d0, d0, d0 \n\t" //d0 = d[0] + d[1]
"vmla.f32 d0, d3, d5 \n\t" //d0 = d0 + d3*d5
:: "r"(v0), "r"(v1)
: "d0","d1","d2","d3","d4","d5"
);
#endif
}
float
dot3_neon_sfp(float v0[3], float v1[3])
{
#ifdef __MATH_NEON
dot3_neon_hfp(v0, v1);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return dot3_c(v0, v1);
#endif
};
void cross3_neon(float v0[3], float v1[3], float d[3])
{
#ifdef __MATH_NEON
asm volatile (
"flds s3, [%0] \n\t" //d1[1]={x0}
"add %0, %0, #4 \n\t" //
"vld1.32 {d0}, [%0] \n\t" //d0={y0,z0}
"vmov.f32 s2, s1 \n\t" //d1[0]={z0}
"flds s5, [%1] \n\t" //d2[1]={x1}
"add %1, %1, #4 \n\t" //
"vld1.32 {d3}, [%1] \n\t" //d3={y1,z1}
"vmov.f32 s4, s7 \n\t" //d2[0]=d3[1]
"vmul.f32 d4, d0, d2 \n\t" //d4=d0*d2
"vmls.f32 d4, d1, d3 \n\t" //d4-=d1*d3
"vmul.f32 d5, d3, d1[1] \n\t" //d5=d3*d1[1]
"vmls.f32 d5, d0, d2[1] \n\t" //d5-=d0*d2[1]
"vst1.32 d4, [%2] \n\t" //
"add %2, %2, #8 \n\t" //
"fsts s10, [%2] \n\t" //
: "+r"(v0), "+r"(v1), "+r"(d):
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
);
#else
cross3_c(v0,v1,d);
#endif
}
void
normalize3_neon(float v[3], float d[3])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d4}, [%0] \n\t" //d4={x0,y0}
"flds s10, [%0, #8] \n\t" //d5[0]={z0}
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
"vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
"vst1.32 {d4}, [%1] \n\t" //
"fsts s10, [%1, #8] \n\t" //
:: "r"(v), "r"(d)
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
);
#else
normalize3_c(v, d);
#endif
}
+126
View File
@@ -0,0 +1,126 @@
/*
The MIT License (MIT)
Copyright (c) 2015 Lachlan Tychsen-Smith (lachlan.ts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "math_neon.h"
#ifdef __MATH_NEON
#include "arm_neon.h"
#endif
//vec4 scalar product
float dot4_c(float v0[4], float v1[4])
{
float r;
r = v0[0]*v1[0];
r += v0[1]*v1[1];
r += v0[2]*v1[2];
r += v0[3]*v1[3];
return r;
}
void normalize4_c(float v[4], float d[4])
{
float b, c, x;
union {
float f;
int i;
} a;
x = v[0]*v[0];
x += v[1]*v[1];
x += v[2]*v[2];
x += v[3]*v[3];
//fast invsqrt approx
a.f = x;
a.i = 0x5F3759DF - (a.i >> 1); //VRSQRTE
c = x * a.f;
b = (3.0f - c * a.f) * 0.5; //VRSQRTS
a.f = a.f * b;
c = x * a.f;
b = (3.0f - c * a.f) * 0.5;
a.f = a.f * b;
d[0] = v[0]*a.f;
d[1] = v[1]*a.f;
d[2] = v[2]*a.f;
d[3] = v[3]*a.f;
}
void normalize4_neon(float v[4], float d[4])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d4, d5}, [%0] \n\t" //d2={x0,y0}, d3={z0, w0}
"vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4
"vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
"vmov.f32 d1, d0 \n\t" //d1 = d0
"vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0)
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3
"vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1
"vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2
"vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4
"vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4
"vst1.32 {d4, d5}, [%1] \n\t" //d2={x0,y0}, d3={z0, w0}
:: "r"(v), "r"(d)
: "d0", "d1", "d2", "d3", "d4", "d5", "memory"
);
#else
normalize4_c(v, d);
#endif
}
float dot4_neon_hfp(float v0[4], float v1[4])
{
#ifdef __MATH_NEON
asm volatile (
"vld1.32 {d2, d3}, [%0] \n\t" //d2={x0,y0}, d3={z0, w0}
"vld1.32 {d4, d5}, [%1] \n\t" //d4={x1,y1}, d5={z1, w1}
"vmul.f32 d0, d2, d4 \n\t" //d0= d2*d4
"vmla.f32 d0, d3, d5 \n\t" //d0 = d0 + d3*d5
"vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1]
:: "r"(v0), "r"(v1) :
);
#endif
}
float dot4_neon_sfp(float v0[4], float v1[4])
{
#ifdef __MATH_NEON
dot4_neon_hfp(v0, v1);
asm volatile ("vmov.f32 r0, s0 \n\t");
#else
return dot4_c(v0, v1);
#endif
};
+43 -16
View File
@@ -53,7 +53,13 @@ enum {
RC_MISSING_CANCEL = -14,
RC_MISSING_SUBMIT = -15,
RC_MISSING_VALUE = -16,
RC_INVALID_LBOARD_FIELD = -17
RC_INVALID_LBOARD_FIELD = -17,
RC_MISSING_DISPLAY_STRING = -18,
RC_OUT_OF_MEMORY = -19,
RC_INVALID_VALUE_FLAG = -20,
RC_MISSING_VALUE_MEASURED = -21,
RC_MULTIPLE_MEASURED = -22,
RC_INVALID_MEASURED_TARGET = -23
};
```
@@ -190,16 +196,14 @@ struct rc_condition_t {
/* Number of hits so far. */
unsigned current_hits;
/**
* Set if the condition needs to processed as part of the "check if paused"
* pass
*/
char pause;
/* The type of the condition. */
char type;
/* The comparison operator to use. */
char oper; /* operator is a reserved word in C++. */
/* Set if the condition needs to processed as part of the "check if paused" pass. */
char pause;
/* Whether or not the condition evaluated as true on the last check. */
char is_true;
};
```
@@ -212,7 +216,10 @@ enum {
RC_CONDITION_RESET_IF,
RC_CONDITION_ADD_SOURCE,
RC_CONDITION_SUB_SOURCE,
RC_CONDITION_ADD_HITS
RC_CONDITION_ADD_HITS,
RC_CONDITION_AND_NEXT,
RC_CONDITION_MEASURED,
RC_CONDITION_ADD_ADDRESS
};
```
@@ -225,7 +232,8 @@ enum {
RC_CONDITION_LE,
RC_CONDITION_GT,
RC_CONDITION_GE,
RC_CONDITION_NE
RC_CONDITION_NE,
RC_CONDITION_NONE
};
```
@@ -279,10 +287,10 @@ rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L,
`buffer` is the caller-allocated buffer, which must have enough space for the trigger. `memaddr` describes the trigger, and must be the same one used to compute the trigger's size with `rc_trigger_size`. `L` must be a valid Lua state, and `funcs_ndx` must be an index to the current Lua stack which contains a table which is a map of names to functions. This map is used to look for operands which are Lua functions.
Once the trigger is created, `rc_test_trigger` can be called to test whether the trigger fires or not.
Once the trigger is created, `rc_evaluate_trigger` can be called to test whether the trigger fires or not.
```c
int rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
int rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
```
`trigger` is the trigger to test. `peek` is a callback used to read bytes from the emulated memory. `ud` is an user-provided opaque value that is passed to `peek`. `L` is the Lua state in which context the Lua functions are looked for and called, if necessary.
@@ -297,6 +305,18 @@ where `address` is the starting address to read from, `num_bytes` the number of
> Addresses passed to `peek` do *not* map 1:1 to the emulated memory. (**TODO**: document the mapping from `peek` addresses to emulated memory for each supported system.)
The return value of `rc_evaluate_trigger` is one of the following:
```c
enum {
RC_TRIGGER_STATE_INACTIVE, /* achievement is not being processed */
RC_TRIGGER_STATE_WAITING, /* achievement cannot trigger until it has been false for at least one frame */
RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */
RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */
RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */
RC_TRIGGER_STATE_TRIGGERED /* achievement has triggered */
};
```
Finally, `rc_reset_trigger` can be used to reset the internal state of a trigger.
```c
@@ -348,6 +368,12 @@ A value is a collection of expressions. It's used to give the value for a leader
typedef struct {
/* The list of expression to evaluate. */
rc_expression_t* expressions;
/* The list of conditions to evaluate. */
rc_condset_t* conditions;
/* The memory references required by the value. */
rc_memref_value_t* memrefs;
}
rc_value_t;
```
@@ -369,7 +395,7 @@ rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int
To compute the value, use `rc_evaluate_value`:
```c
unsigned rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L);
int rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L);
```
`value` is the value to compute the value of, and `peek`, `ud`, and `L`, are as in [`rc_test_trigger`](#rc_test_trigger).
@@ -404,7 +430,7 @@ rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, in
A leaderboard can be evaluated with the `rc_evaluate_lboard` function:
```c
int rc_evaluate_lboard(rc_lboard_t* lboard, unsigned* value, rc_peek_t peek, void* peek_ud, lua_State* L);
int rc_evaluate_lboard(rc_lboard_t* lboard, int* value, rc_peek_t peek, void* peek_ud, lua_State* L);
```
The function returns an action that must be performed by the caller, and `value` contains the value to be used for that action when the function returns. The action can be one of:
@@ -451,7 +477,8 @@ enum {
RC_FORMAT_CENTISECS,
RC_FORMAT_SCORE,
RC_FORMAT_VALUE,
RC_FORMAT_OTHER,
RC_FORMAT_MINUTES,
RC_FORMAT_SECONDS_AS_MINUTES
};
```
@@ -460,10 +487,10 @@ enum {
`rc_format_value` can be used to format the given value into the provided buffer:
```c
void rc_format_value(char* buffer, int size, unsigned value, int format);
int rc_format_value(char* buffer, int size, int value, int format);
```
`buffer` receives `value` formatted according to `format`. No more than `size` characters will be written to `buffer`. 32 characters are enough to hold any valid value with any format.
`buffer` receives `value` formatted according to `format`. No more than `size` characters will be written to `buffer`. 32 characters are enough to hold any valid value with any format. The returned value is the number of characters written.
# **rurl**
+52 -13
View File
@@ -31,7 +31,11 @@ enum {
RC_MISSING_VALUE = -16,
RC_INVALID_LBOARD_FIELD = -17,
RC_MISSING_DISPLAY_STRING = -18,
RC_OUT_OF_MEMORY = -19
RC_OUT_OF_MEMORY = -19,
RC_INVALID_VALUE_FLAG = -20,
RC_MISSING_VALUE_MEASURED = -21,
RC_MULTIPLE_MEASURED = -22,
RC_INVALID_MEASURED_TARGET = -23
};
/*****************************************************************************\
@@ -112,6 +116,8 @@ typedef struct {
char size;
/* True if the value is in BCD. */
char is_bcd;
/* True if the reference will be used in indirection */
char is_indirect;
} rc_memref_t;
typedef struct rc_memref_value_t rc_memref_value_t;
@@ -176,7 +182,9 @@ enum {
RC_CONDITION_ADD_SOURCE,
RC_CONDITION_SUB_SOURCE,
RC_CONDITION_ADD_HITS,
RC_CONDITION_AND_NEXT
RC_CONDITION_AND_NEXT,
RC_CONDITION_MEASURED,
RC_CONDITION_ADD_ADDRESS
};
/* operators */
@@ -186,7 +194,8 @@ enum {
RC_CONDITION_LE,
RC_CONDITION_GT,
RC_CONDITION_GE,
RC_CONDITION_NE
RC_CONDITION_NE,
RC_CONDITION_NONE
};
typedef struct rc_condition_t rc_condition_t;
@@ -204,16 +213,17 @@ struct rc_condition_t {
/* The next condition in the chain. */
rc_condition_t* next;
/**
* Set if the condition needs to processed as part of the "check if paused"
* pass
*/
char pause;
/* The type of the condition. */
char type;
/* The comparison operator to use. */
char oper; /* operator is a reserved word in C++. */
/* Set if the condition needs to processed as part of the "check if paused" pass. */
char pause;
/* Whether or not the condition evaluated true on the last check */
char is_true;
};
/*****************************************************************************\
@@ -231,12 +241,24 @@ struct rc_condset_t {
/* True if any condition in the set is a pause condition. */
char has_pause;
/* True if the set is currently paused. */
char is_paused;
};
/*****************************************************************************\
| Trigger |
\*****************************************************************************/
enum {
RC_TRIGGER_STATE_INACTIVE, /* achievement is not being processed */
RC_TRIGGER_STATE_WAITING, /* achievement cannot trigger until it has been false for at least one frame */
RC_TRIGGER_STATE_ACTIVE, /* achievement is active and may trigger */
RC_TRIGGER_STATE_PAUSED, /* achievement is currently paused and will not trigger */
RC_TRIGGER_STATE_RESET, /* achievement hit counts were reset */
RC_TRIGGER_STATE_TRIGGERED /* achievement has triggered */
};
typedef struct {
/* The main condition set. */
rc_condset_t* requirement;
@@ -246,11 +268,24 @@ typedef struct {
/* The memory references required by the trigger. */
rc_memref_value_t* memrefs;
/* The current state of the MEASURED condition. */
unsigned measured_value;
/* The target state of the MEASURED condition */
unsigned measured_target;
/* The current state of the trigger */
char state;
/* True if at least one condition has a non-zero hit count */
char has_hits;
}
rc_trigger_t;
int rc_trigger_size(const char* memaddr);
rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
int rc_evaluate_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
int rc_test_trigger(rc_trigger_t* trigger, rc_peek_t peek, void* ud, lua_State* L);
void rc_reset_trigger(rc_trigger_t* self);
@@ -287,6 +322,9 @@ typedef struct {
/* The list of expression to evaluate. */
rc_expression_t* expressions;
/* The list of conditions to evaluate. */
rc_condset_t* conditions;
/* The memory references required by the value. */
rc_memref_value_t* memrefs;
}
@@ -294,7 +332,7 @@ rc_value_t;
int rc_value_size(const char* memaddr);
rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
unsigned rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L);
int rc_evaluate_value(rc_value_t* value, rc_peek_t peek, void* ud, lua_State* L);
/*****************************************************************************\
| Leaderboards |
@@ -324,7 +362,7 @@ rc_lboard_t;
int rc_lboard_size(const char* memaddr);
rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx);
int rc_evaluate_lboard(rc_lboard_t* lboard, unsigned* value, rc_peek_t peek, void* peek_ud, lua_State* L);
int rc_evaluate_lboard(rc_lboard_t* lboard, int* value, rc_peek_t peek, void* peek_ud, lua_State* L);
void rc_reset_lboard(rc_lboard_t* lboard);
/*****************************************************************************\
@@ -338,11 +376,12 @@ enum {
RC_FORMAT_CENTISECS,
RC_FORMAT_SCORE,
RC_FORMAT_VALUE,
RC_FORMAT_OTHER
RC_FORMAT_MINUTES,
RC_FORMAT_SECONDS_AS_MINUTES
};
int rc_parse_format(const char* format_str);
int rc_format_value(char* buffer, int size, unsigned value, int format);
int rc_format_value(char* buffer, int size, int value, int format);
/*****************************************************************************\
| Rich Presence |
+1 -1
View File
@@ -9,7 +9,7 @@ extern "C" {
int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned cheevo_id, int hardcore);
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, unsigned value, unsigned char hash[16]);
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, unsigned char hash[16]);
int rc_url_get_gameid(char* buffer, size_t size, unsigned char hash[16]);
+1
View File
@@ -44,6 +44,7 @@ void rc_init_parse_state(rc_parse_state_t* parse, void* buffer, lua_State* L, in
parse->scratch.memref_size = sizeof(parse->scratch.memref_buffer) / sizeof(parse->scratch.memref_buffer[0]);
parse->scratch.memref_count = 0;
parse->first_memref = 0;
parse->measured_target = 0;
}
void rc_destroy_parse_state(rc_parse_state_t* parse)
+19 -6
View File
@@ -2,7 +2,7 @@
#include <stdlib.h>
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse) {
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse, int is_indirect) {
rc_condition_t* self;
const char* aux;
int ret2;
@@ -19,6 +19,8 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
case 'b': case 'B': self->type = RC_CONDITION_SUB_SOURCE; break;
case 'c': case 'C': self->type = RC_CONDITION_ADD_HITS; break;
case 'n': case 'N': self->type = RC_CONDITION_AND_NEXT; break;
case 'm': case 'M': self->type = RC_CONDITION_MEASURED; break;
case 'i': case 'I': self->type = RC_CONDITION_ADD_ADDRESS; break;
default: parse->offset = RC_INVALID_CONDITION_TYPE; return 0;
}
@@ -28,7 +30,7 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
self->type = RC_CONDITION_STANDARD;
}
ret2 = rc_parse_operand(&self->operand1, &aux, 1, parse);
ret2 = rc_parse_operand(&self->operand1, &aux, 1, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
@@ -71,9 +73,19 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
}
break;
case '_':
case ')':
case '\0':
self->oper = RC_CONDITION_NONE;
self->operand2.type = RC_OPERAND_CONST;
self->operand2.value.num = 1;
self->required_hits = 0;
*memaddr = aux - 1;
return self;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 1, parse);
ret2 = rc_parse_operand(&self->operand2, &aux, 1, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
@@ -110,9 +122,9 @@ rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse
return self;
}
int rc_test_condition(rc_condition_t* self, unsigned add_buffer, rc_peek_t peek, void* ud, lua_State* L) {
unsigned value1 = rc_evaluate_operand(&self->operand1, peek, ud, L) + add_buffer;
unsigned value2 = rc_evaluate_operand(&self->operand2, peek, ud, L);
int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state) {
unsigned value1 = rc_evaluate_operand(&self->operand1, eval_state) + eval_state->add_value;
unsigned value2 = rc_evaluate_operand(&self->operand2, eval_state);
switch (self->oper) {
case RC_CONDITION_EQ: return value1 == value2;
@@ -121,6 +133,7 @@ int rc_test_condition(rc_condition_t* self, unsigned add_buffer, rc_peek_t peek,
case RC_CONDITION_LE: return value1 <= value2;
case RC_CONDITION_GT: return value1 > value2;
case RC_CONDITION_GE: return value1 >= value2;
case RC_CONDITION_NONE: return 1;
default: return 1;
}
}
+101 -23
View File
@@ -14,6 +14,7 @@ static void rc_update_condition_pause(rc_condition_t* condition, int* in_pause)
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_ADD_HITS:
case RC_CONDITION_AND_NEXT:
case RC_CONDITION_ADD_ADDRESS:
condition->pause = *in_pause;
break;
@@ -27,9 +28,10 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
rc_condset_t* self;
rc_condition_t** next;
int in_pause;
int in_add_address;
self = RC_ALLOC(rc_condset_t, parse);
self->has_pause = 0;
self->has_pause = self->is_paused = 0;
next = &self->conditions;
if (**memaddr == 'S' || **memaddr == 's' || !**memaddr) {
@@ -38,14 +40,54 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
return self;
}
in_add_address = 0;
for (;;) {
*next = rc_parse_condition(memaddr, parse);
*next = rc_parse_condition(memaddr, parse, in_add_address);
if (parse->offset < 0) {
return 0;
}
if ((*next)->oper == RC_CONDITION_NONE) {
switch ((*next)->type) {
case RC_CONDITION_ADD_ADDRESS:
case RC_CONDITION_ADD_HITS:
case RC_CONDITION_ADD_SOURCE:
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_AND_NEXT:
break;
default:
parse->offset = RC_INVALID_OPERATOR;
return 0;
}
}
self->has_pause |= (*next)->type == RC_CONDITION_PAUSE_IF;
in_add_address = (*next)->type == RC_CONDITION_ADD_ADDRESS;
if ((*next)->type == RC_CONDITION_MEASURED) {
unsigned measured_target = 0;
if ((*next)->required_hits == 0) {
if ((*next)->operand2.type != RC_OPERAND_CONST) {
parse->offset = RC_INVALID_MEASURED_TARGET;
return 0;
}
measured_target = (*next)->operand2.value.num;
}
else {
measured_target = (*next)->required_hits;
}
if (parse->measured_target && measured_target != parse->measured_target) {
parse->offset = RC_MULTIPLE_MEASURED;
return 0;
}
parse->measured_target = measured_target;
}
next = &(*next)->next;
if (**memaddr != '_') {
@@ -66,14 +108,13 @@ rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse) {
return self;
}
static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, int* reset, rc_peek_t peek, void* ud, lua_State* L) {
static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, rc_eval_state_t* eval_state) {
rc_condition_t* condition;
int set_valid, cond_valid, prev_cond;
unsigned add_buffer, add_hits;
set_valid = 1;
prev_cond = 1;
add_buffer = add_hits = 0;
eval_state->add_value = eval_state->add_hits = eval_state->add_address = 0;
for (condition = self->conditions; condition != 0; condition = condition->next) {
if (condition->pause != processing_pause) {
@@ -82,39 +123,60 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, in
switch (condition->type) {
case RC_CONDITION_ADD_SOURCE:
add_buffer += rc_evaluate_operand(&condition->operand1, peek, ud, L);
eval_state->add_value += rc_evaluate_operand(&condition->operand1, eval_state);
eval_state->add_address = 0;
continue;
case RC_CONDITION_SUB_SOURCE:
add_buffer -= rc_evaluate_operand(&condition->operand1, peek, ud, L);
eval_state->add_value -= rc_evaluate_operand(&condition->operand1, eval_state);
eval_state->add_address = 0;
continue;
case RC_CONDITION_ADD_HITS:
if (rc_test_condition(condition, add_buffer, peek, ud, L)) {
/* always evaluate the condition to ensure everything is updated correctly */
cond_valid = rc_test_condition(condition, eval_state);
/* merge AndNext value and reset it for the next condition */
cond_valid &= prev_cond;
prev_cond = 1;
/* if the condition is true, tally it */
if (cond_valid) {
if (condition->required_hits == 0 || condition->current_hits < condition->required_hits) {
condition->current_hits++;
}
condition->is_true = (condition->required_hits == 0 || condition->current_hits >= condition->required_hits);
}
else {
condition->is_true = 0;
}
add_buffer = 0;
add_hits += condition->current_hits;
eval_state->add_value = 0;
eval_state->add_address = 0;
eval_state->add_hits += condition->current_hits;
continue;
case RC_CONDITION_AND_NEXT:
prev_cond &= rc_test_condition(condition, add_buffer, peek, ud, L);
add_buffer = 0;
prev_cond &= rc_test_condition(condition, eval_state);
eval_state->add_value = 0;
eval_state->add_address = 0;
continue;
case RC_CONDITION_ADD_ADDRESS:
eval_state->add_address = rc_evaluate_operand(&condition->operand1, eval_state);
continue;
}
/* always evaluate the condition to ensure delta values get tracked correctly */
cond_valid = rc_test_condition(condition, add_buffer, peek, ud, L);
/* always evaluate the condition to ensure everything is updated correctly */
cond_valid = rc_test_condition(condition, eval_state);
/* merge AndNext value and reset it for the next condition */
cond_valid &= prev_cond;
prev_cond = 1;
/* if the condition has a target hit count that has already been met, it's automatically true, even if not currently true. */
if (condition->required_hits != 0 && (condition->current_hits + add_hits) >= condition->required_hits) {
if (condition->required_hits != 0 && (condition->current_hits + eval_state->add_hits) >= condition->required_hits) {
cond_valid = 1;
}
else if (cond_valid) {
@@ -123,14 +185,28 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, in
if (condition->required_hits == 0) {
/* not a hit-based requirement: ignore any additional logic! */
}
else if ((condition->current_hits + add_hits) < condition->required_hits) {
else if ((condition->current_hits + eval_state->add_hits) < condition->required_hits) {
/* HitCount target has not yet been met, condition is not yet valid */
cond_valid = 0;
}
}
condition->is_true = cond_valid;
eval_state->has_hits |= (condition->current_hits || eval_state->add_hits);
/* capture measured state */
if (condition->type == RC_CONDITION_MEASURED) {
unsigned int measured_value;
if (condition->required_hits > 0)
measured_value = condition->current_hits + eval_state->add_hits;
else
measured_value = rc_evaluate_operand(&condition->operand1, eval_state) + eval_state->add_value;
if (measured_value > eval_state->measured_value)
eval_state->measured_value = measured_value;
}
/* reset AddHits and AddSource/SubSource values */
add_buffer = add_hits = 0;
eval_state->add_value = eval_state->add_hits = eval_state->add_address = 0;
switch (condition->type) {
case RC_CONDITION_PAUSE_IF:
@@ -155,7 +231,7 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, in
case RC_CONDITION_RESET_IF:
if (cond_valid) {
*reset = 1; /* let caller know to reset all hit counts */
eval_state->was_reset = 1; /* let caller know to reset all hit counts */
set_valid = 0; /* cannot be valid if we've hit a reset condition */
}
@@ -170,18 +246,20 @@ static int rc_test_condset_internal(rc_condset_t* self, int processing_pause, in
return set_valid;
}
int rc_test_condset(rc_condset_t* self, int* reset, rc_peek_t peek, void* ud, lua_State* L) {
int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state) {
if (self->conditions == 0) {
/* important: empty group must evaluate true */
return 1;
}
if (self->has_pause && rc_test_condset_internal(self, 1, reset, peek, ud, L)) {
/* one or more Pause conditions exists, if any of them are true, stop processing this group */
return 0;
if (self->has_pause) {
if ((self->is_paused = rc_test_condset_internal(self, 1, eval_state))) {
/* one or more Pause conditions exists, if any of them are true, stop processing this group */
return 0;
}
}
return rc_test_condset_internal(self, 0, reset, peek, ud, L);
return rc_test_condset_internal(self, 0, eval_state);
}
void rc_reset_condset(rc_condset_t* self) {
+4 -4
View File
@@ -8,7 +8,7 @@ rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* par
next = &self->terms;
for (;;) {
*next = rc_parse_term(memaddr, parse);
*next = rc_parse_term(memaddr, 0, parse);
if (parse->offset < 0) {
return 0;
@@ -27,14 +27,14 @@ rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* par
return self;
}
unsigned rc_evaluate_expression(rc_expression_t* self, rc_peek_t peek, void* ud, lua_State* L) {
int rc_evaluate_expression(rc_expression_t* self, rc_eval_state_t* eval_state) {
rc_term_t* term;
unsigned value;
int value;
value = 0;
for (term = self->terms; term != 0; term = term->next) {
value += rc_evaluate_term(term, peek, ud, L);
value += rc_evaluate_term(term, eval_state);
}
return value;
+67 -24
View File
@@ -29,6 +29,9 @@ int rc_parse_format(const char* format_str) {
if (!strcmp(format_str, "CORE")) {
return RC_FORMAT_SCORE;
}
if (!strcmp(format_str, "ECS_AS_MINS")) {
return RC_FORMAT_SECONDS_AS_MINUTES;
}
break;
@@ -36,6 +39,9 @@ int rc_parse_format(const char* format_str) {
if (!strcmp(format_str, "ILLISECS")) {
return RC_FORMAT_CENTISECS;
}
if (!strcmp(format_str, "INUTES")) {
return RC_FORMAT_MINUTES;
}
break;
@@ -55,7 +61,7 @@ int rc_parse_format(const char* format_str) {
case 'O':
if (!strcmp(format_str, "THER")) {
return RC_FORMAT_OTHER;
return RC_FORMAT_SCORE;
}
break;
@@ -64,45 +70,82 @@ int rc_parse_format(const char* format_str) {
return RC_FORMAT_VALUE;
}
int rc_format_value(char* buffer, int size, unsigned value, int format) {
unsigned a, b, c;
static int rc_format_value_minutes(char* buffer, int size, unsigned minutes) {
unsigned hours;
hours = minutes / 60;
minutes -= hours * 60;
return snprintf(buffer, size, "%uh%02u", hours, minutes);
}
static int rc_format_value_seconds(char* buffer, int size, unsigned seconds) {
unsigned hours, minutes;
/* apply modulus math to split the seconds into hours/minutes/seconds */
minutes = seconds / 60;
seconds -= minutes * 60;
if (minutes < 60) {
return snprintf(buffer, size, "%u:%02u", minutes, seconds);
}
hours = minutes / 60;
minutes -= hours * 60;
return snprintf(buffer, size, "%uh%02u:%02u", hours, minutes, seconds);
}
static int rc_format_value_centiseconds(char* buffer, int size, unsigned centiseconds) {
unsigned seconds;
int chars, chars2;
/* modulus off the centiseconds */
seconds = centiseconds / 100;
centiseconds -= seconds * 100;
chars = rc_format_value_seconds(buffer, size, seconds);
if (chars > 0) {
chars2 = snprintf(buffer + chars, size - chars, ".%02u", centiseconds);
if (chars2 > 0) {
chars += chars2;
} else {
chars = chars2;
}
}
return chars;
}
int rc_format_value(char* buffer, int size, int value, int format) {
int chars;
switch (format) {
case RC_FORMAT_FRAMES:
a = value * 10 / 6; /* centisecs */
b = a / 100; /* seconds */
a -= b * 100;
c = b / 60; /* minutes */
b -= c * 60;
chars = snprintf(buffer, size, "%02u:%02u.%02u", c, b, a);
/* 60 frames per second = 100 centiseconds / 60 frames; multiply frames by 100 / 60 */
chars = rc_format_value_centiseconds(buffer, size, value * 10 / 6);
break;
case RC_FORMAT_SECONDS:
a = value / 60; /* minutes */
value -= a * 60;
chars = snprintf(buffer, size, "%02u:%02u", a, value);
chars = rc_format_value_seconds(buffer, size, value);
break;
case RC_FORMAT_CENTISECS:
a = value / 100; /* seconds */
value -= a * 100;
b = a / 60; /* minutes */
a -= b * 60;
chars = snprintf(buffer, size, "%02u:%02u.%02u", b, a, value);
chars = rc_format_value_centiseconds(buffer, size, value);
break;
case RC_FORMAT_SECONDS_AS_MINUTES:
chars = rc_format_value_minutes(buffer, size, value / 60);
break;
case RC_FORMAT_MINUTES:
chars = rc_format_value_minutes(buffer, size, value);
break;
case RC_FORMAT_SCORE:
chars = snprintf(buffer, size, "%06u Points", value);
chars = snprintf(buffer, size, "%06d", value);
break;
case RC_FORMAT_VALUE:
chars = snprintf(buffer, size, "%01u", value);
break;
case RC_FORMAT_OTHER:
default:
chars = snprintf(buffer, size, "%06u", value);
case RC_FORMAT_VALUE:
chars = snprintf(buffer, size, "%d", value);
break;
}
+29 -13
View File
@@ -1,8 +1,7 @@
#ifndef INTERNAL_H
#define INTERNAL_H
#include <stddef.h>
#include <rcheevos.h>
#include "rcheevos.h"
#define RC_ALLOW_ALIGN(T) struct __align_ ## T { char ch; T t; };
RC_ALLOW_ALIGN(rc_condition_t)
@@ -21,8 +20,6 @@ RC_ALLOW_ALIGN(rc_trigger_t)
RC_ALLOW_ALIGN(rc_value_t)
RC_ALLOW_ALIGN(char)
#define RC_TAG2(x,y) x ## y
#define RC_TAG(x,y) RC_TAG2(x,y)
#define RC_ALIGNOF(T) (sizeof(struct __align_ ## T) - sizeof(T))
#define RC_ALLOC(t, p) ((t*)rc_alloc((p)->buffer, &(p)->offset, sizeof(t), RC_ALIGNOF(t), &(p)->scratch))
@@ -52,6 +49,21 @@ typedef struct {
}
rc_scratch_t;
typedef struct {
unsigned add_value; /* AddSource/SubSource */
unsigned add_hits; /* AddHits */
unsigned add_address; /* AddAddress */
rc_peek_t peek;
void* peek_userdata;
lua_State* L;
unsigned measured_value; /* Measured */
char was_reset; /* ResetIf triggered */
char has_hits; /* one of more hit counts is non-zero */
}
rc_eval_state_t;
typedef struct {
int offset;
@@ -62,6 +74,8 @@ typedef struct {
rc_scratch_t scratch;
rc_memref_value_t** first_memref;
unsigned measured_target;
}
rc_parse_state_t;
@@ -72,26 +86,28 @@ void rc_destroy_parse_state(rc_parse_state_t* parse);
void* rc_alloc(void* pointer, int* offset, int size, int alignment, rc_scratch_t* scratch);
char* rc_alloc_str(rc_parse_state_t* parse, const char* text, int length);
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd);
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect);
void rc_update_memref_values(rc_memref_value_t* memref, rc_peek_t peek, void* ud);
void rc_update_memref_value(rc_memref_value_t* memref, rc_peek_t peek, void* ud);
rc_memref_value_t* rc_get_indirect_memref(rc_memref_value_t* memref, rc_eval_state_t* eval_state);
void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse);
rc_condset_t* rc_parse_condset(const char** memaddr, rc_parse_state_t* parse);
int rc_test_condset(rc_condset_t* self, int* reset, rc_peek_t peek, void* ud, lua_State* L);
int rc_test_condset(rc_condset_t* self, rc_eval_state_t* eval_state);
void rc_reset_condset(rc_condset_t* self);
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse);
int rc_test_condition(rc_condition_t* self, unsigned add_buffer, rc_peek_t peek, void* ud, lua_State* L);
rc_condition_t* rc_parse_condition(const char** memaddr, rc_parse_state_t* parse, int is_indirect);
int rc_test_condition(rc_condition_t* self, rc_eval_state_t* eval_state);
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, rc_parse_state_t* parse);
unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_State* L);
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, int is_indirect, rc_parse_state_t* parse);
unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state);
rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse);
unsigned rc_evaluate_term(rc_term_t* self, rc_peek_t peek, void* ud, lua_State* L);
rc_term_t* rc_parse_term(const char** memaddr, int is_indirect, rc_parse_state_t* parse);
int rc_evaluate_term(rc_term_t* self, rc_eval_state_t* eval_state);
rc_expression_t* rc_parse_expression(const char** memaddr, rc_parse_state_t* parse);
unsigned rc_evaluate_expression(rc_expression_t* self, rc_peek_t peek, void* ud, lua_State* L);
int rc_evaluate_expression(rc_expression_t* self, rc_eval_state_t* eval_state);
void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse);
+5 -2
View File
@@ -162,7 +162,7 @@ rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, in
return parse.offset >= 0 ? self : 0;
}
int rc_evaluate_lboard(rc_lboard_t* self, unsigned* value, rc_peek_t peek, void* peek_ud, lua_State* L) {
int rc_evaluate_lboard(rc_lboard_t* self, int* value, rc_peek_t peek, void* peek_ud, lua_State* L) {
int start_ok, cancel_ok, submit_ok;
int action = -1;
@@ -217,8 +217,11 @@ int rc_evaluate_lboard(rc_lboard_t* self, unsigned* value, rc_peek_t peek, void*
/* Calculate the value */
switch (action) {
case RC_LBOARD_ACTIVE: /* fall through */
case RC_LBOARD_STARTED:
if (self->value.conditions)
rc_reset_condset(self->value.conditions);
/* fall through */
case RC_LBOARD_ACTIVE:
*value = rc_evaluate_value(self->progress != 0 ? self->progress : &self->value, peek, peek_ud, L);
break;
+143 -66
View File
@@ -3,75 +3,101 @@
#include <stdlib.h> /* malloc/realloc */
#include <string.h> /* memcpy */
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd) {
rc_memref_value_t** next_memref_value;
rc_memref_value_t* memref_value;
#define MEMREF_PLACEHOLDER_ADDRESS 0xFFFFFFFF
static rc_memref_value_t* rc_alloc_memref_value_sizing_mode(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
rc_memref_t* memref;
int i;
if (!parse->first_memref) {
/* sizing mode - have to track unique address/size/bcd combinations */
for (i = 0; i < parse->scratch.memref_count; ++i) {
memref = &parse->scratch.memref[i];
if (memref->address == address && memref->size == size && memref->is_bcd == is_bcd) {
return &parse->scratch.obj.memref_value;
}
}
/* resize unique tracking buffer if necessary */
if (parse->scratch.memref_count == parse->scratch.memref_size) {
if (parse->scratch.memref == parse->scratch.memref_buffer) {
parse->scratch.memref_size += 16;
memref = (rc_memref_t*)malloc(parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
memcpy(memref, parse->scratch.memref_buffer, parse->scratch.memref_count * sizeof(parse->scratch.memref_buffer[0]));
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
else {
parse->scratch.memref_size += 32;
memref = (rc_memref_t*)realloc(parse->scratch.memref, parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
}
/* add new unique tracking entry */
if (parse->scratch.memref) {
memref = &parse->scratch.memref[parse->scratch.memref_count++];
memref->address = address;
memref->size = size;
memref->is_bcd = is_bcd;
}
/* allocate memory but don't actually populate, as it might overwrite the self object referencing the rc_memref_value_t */
/* indirect address always creates two new entries; don't bother tracking them */
if (is_indirect) {
RC_ALLOC(rc_memref_value_t, parse);
return RC_ALLOC(rc_memref_value_t, parse);
}
/* construction mode - find or create the appropriate rc_memref_value_t */
next_memref_value = parse->first_memref;
while (*next_memref_value) {
memref_value = *next_memref_value;
if (memref_value->memref.address == address && memref_value->memref.size == size && memref_value->memref.is_bcd == is_bcd) {
return memref_value;
}
next_memref_value = &memref_value->next;
}
memref = NULL;
/* have to track unique address/size/bcd combinations - use scratch.memref for sizing mode */
for (i = 0; i < parse->scratch.memref_count; ++i) {
memref = &parse->scratch.memref[i];
if (memref->address == address && memref->size == size && memref->is_bcd == is_bcd) {
return &parse->scratch.obj.memref_value;
}
}
/* no match found - resize unique tracking buffer if necessary */
if (parse->scratch.memref_count == parse->scratch.memref_size) {
if (parse->scratch.memref == parse->scratch.memref_buffer) {
parse->scratch.memref_size += 16;
memref = (rc_memref_t*)malloc(parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
memcpy(memref, parse->scratch.memref_buffer, parse->scratch.memref_count * sizeof(parse->scratch.memref_buffer[0]));
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
else {
parse->scratch.memref_size += 32;
memref = (rc_memref_t*)realloc(parse->scratch.memref, parse->scratch.memref_size * sizeof(parse->scratch.memref_buffer[0]));
if (memref) {
parse->scratch.memref = memref;
}
else {
parse->offset = RC_OUT_OF_MEMORY;
return 0;
}
}
}
/* add new unique tracking entry */
if (parse->scratch.memref) {
memref = &parse->scratch.memref[parse->scratch.memref_count++];
memref->address = address;
memref->size = size;
memref->is_bcd = is_bcd;
memref->is_indirect = is_indirect;
}
/* allocate memory but don't actually populate, as it might overwrite the self object referencing the rc_memref_value_t */
return RC_ALLOC(rc_memref_value_t, parse);
}
static rc_memref_value_t* rc_alloc_memref_value_constuct_mode(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
rc_memref_value_t** next_memref_value;
rc_memref_value_t* memref_value;
rc_memref_value_t* indirect_memref_value;
if (!is_indirect) {
/* attempt to find an existing rc_memref_value_t */
next_memref_value = parse->first_memref;
while (*next_memref_value) {
memref_value = *next_memref_value;
if (!memref_value->memref.is_indirect && memref_value->memref.address == address &&
memref_value->memref.size == size && memref_value->memref.is_bcd == is_bcd) {
return memref_value;
}
next_memref_value = &memref_value->next;
}
}
else {
/* indirect address always creates two new entries - one for the original address, and one for
the indirect dereference - just skip ahead to the end of the list */
next_memref_value = parse->first_memref;
while (*next_memref_value) {
next_memref_value = &(*next_memref_value)->next;
}
}
/* no match found, create a new entry */
memref_value = RC_ALLOC(rc_memref_value_t, parse);
memref_value->memref.address = address;
memref_value->memref.size = size;
memref_value->memref.is_bcd = is_bcd;
memref_value->memref.is_indirect = is_indirect;
memref_value->value = 0;
memref_value->previous = 0;
memref_value->prior = 0;
@@ -79,9 +105,31 @@ rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned addre
*next_memref_value = memref_value;
/* also create the indirect deference entry for indirect references */
if (is_indirect) {
indirect_memref_value = RC_ALLOC(rc_memref_value_t, parse);
indirect_memref_value->memref.address = MEMREF_PLACEHOLDER_ADDRESS;
indirect_memref_value->memref.size = size;
indirect_memref_value->memref.is_bcd = is_bcd;
indirect_memref_value->memref.is_indirect = 1;
indirect_memref_value->value = 0;
indirect_memref_value->previous = 0;
indirect_memref_value->prior = 0;
indirect_memref_value->next = 0;
memref_value->next = indirect_memref_value;
}
return memref_value;
}
rc_memref_value_t* rc_alloc_memref_value(rc_parse_state_t* parse, unsigned address, char size, char is_bcd, char is_indirect) {
if (!parse->first_memref)
return rc_alloc_memref_value_sizing_mode(parse, address, size, is_bcd, is_indirect);
return rc_alloc_memref_value_constuct_mode(parse, address, size, is_bcd, is_indirect);
}
static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud) {
unsigned value;
@@ -149,6 +197,7 @@ static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud)
break;
case RC_MEMSIZE_24_BITS:
/* peek 4 bytes - don't expect the caller to understand 24-bit numbers */
value = peek(self->address, 4, ud);
if (self->is_bcd) {
@@ -158,6 +207,8 @@ static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud)
+ ((value >> 8) & 0x0f) * 100
+ ((value >> 4) & 0x0f) * 10
+ ((value >> 0) & 0x0f) * 1;
} else {
value &= 0x00FFFFFF;
}
break;
@@ -186,19 +237,45 @@ static unsigned rc_memref_get_value(rc_memref_t* self, rc_peek_t peek, void* ud)
return value;
}
void rc_update_memref_value(rc_memref_value_t* memref, rc_peek_t peek, void* ud) {
memref->previous = memref->value;
memref->value = rc_memref_get_value(&memref->memref, peek, ud);
if (memref->value != memref->previous)
memref->prior = memref->previous;
}
void rc_update_memref_values(rc_memref_value_t* memref, rc_peek_t peek, void* ud) {
while (memref) {
memref->previous = memref->value;
memref->value = rc_memref_get_value(&memref->memref, peek, ud);
if (memref->value != memref->previous)
memref->prior = memref->previous;
if (memref->memref.address != MEMREF_PLACEHOLDER_ADDRESS)
rc_update_memref_value(memref, peek, ud);
memref = memref->next;
}
}
void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_value_t** memrefs)
{
void rc_init_parse_state_memrefs(rc_parse_state_t* parse, rc_memref_value_t** memrefs) {
parse->first_memref = memrefs;
*memrefs = 0;
}
rc_memref_value_t* rc_get_indirect_memref(rc_memref_value_t* memref, rc_eval_state_t* eval_state) {
unsigned new_address;
if (eval_state->add_address == 0)
return memref;
if (!memref->memref.is_indirect)
return memref;
new_address = memref->memref.address + eval_state->add_address;
/* an extra rc_memref_value_t is allocated for offset calculations */
memref = memref->next;
/* if the adjusted address has changed, update the record */
if (memref->memref.address != new_address) {
memref->memref.address = new_address;
rc_update_memref_value(memref, eval_state->peek, eval_state->peek_userdata);
}
return memref;
}
+34 -28
View File
@@ -66,7 +66,7 @@ static int rc_parse_operand_lua(rc_operand_t* self, const char** memaddr, rc_par
return RC_OK;
}
static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse, int is_indirect) {
const char* aux = *memaddr;
char* end;
unsigned long address;
@@ -135,7 +135,7 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
address = 0xffffffffU;
}
self->value.memref = rc_alloc_memref_value(parse, (unsigned)address, size, is_bcd);
self->value.memref = rc_alloc_memref_value(parse, address, size, is_bcd, is_indirect);
if (parse->offset < 0)
return parse->offset;
@@ -143,7 +143,7 @@ static int rc_parse_operand_memory(rc_operand_t* self, const char** memaddr, rc_
return RC_OK;
}
static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
const char* aux = *memaddr;
char* end;
int ret;
@@ -151,6 +151,11 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, rc
switch (*aux) {
case 'h': case 'H':
if (aux[2] == 'x' || aux[2] == 'X') {
/* H0x1234 is a typo - either H1234 or 0xH1234 was probably meant */
return RC_INVALID_CONST_OPERAND;
}
value = strtoul(++aux, &end, 16);
if (end == aux) {
@@ -171,7 +176,7 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, rc
if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux, parse);
ret = rc_parse_operand_memory(self, &aux, parse, is_indirect);
if (ret < 0) {
return ret;
@@ -214,11 +219,12 @@ static int rc_parse_operand_trigger(rc_operand_t* self, const char** memaddr, rc
return RC_OK;
}
static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, rc_parse_state_t* parse) {
static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
const char* aux = *memaddr;
char* end;
int ret;
unsigned long value;
long svalue;
switch (*aux) {
case 'h': case 'H':
@@ -239,18 +245,18 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, rc_pa
break;
case 'v': case 'V':
value = strtoul(++aux, &end, 10);
svalue = strtol(++aux, &end, 10);
if (end == aux) {
return RC_INVALID_CONST_OPERAND;
}
if (value > 0xffffffffU) {
value = 0xffffffffU;
if (svalue > 0xffffffffU) {
svalue = 0xffffffffU;
}
self->type = RC_OPERAND_CONST;
self->value.num = (unsigned)value;
self->value.num = (unsigned)svalue;
aux = end;
break;
@@ -259,7 +265,7 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, rc_pa
if (aux[1] == 'x' || aux[1] == 'X') {
/* fall through */
default:
ret = rc_parse_operand_memory(self, &aux, parse);
ret = rc_parse_operand_memory(self, &aux, parse, is_indirect);
if (ret < 0) {
return ret;
@@ -303,12 +309,12 @@ static int rc_parse_operand_term(rc_operand_t* self, const char** memaddr, rc_pa
return RC_OK;
}
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, rc_parse_state_t* parse) {
int rc_parse_operand(rc_operand_t* self, const char** memaddr, int is_trigger, int is_indirect, rc_parse_state_t* parse) {
if (is_trigger) {
return rc_parse_operand_trigger(self, memaddr, parse);
return rc_parse_operand_trigger(self, memaddr, is_indirect, parse);
}
else {
return rc_parse_operand_term(self, memaddr, parse);
return rc_parse_operand_term(self, memaddr, is_indirect, parse);
}
}
@@ -333,7 +339,7 @@ static int rc_luapeek(lua_State* L) {
#endif /* RC_DISABLE_LUA */
unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_State* L) {
unsigned rc_evaluate_operand(rc_operand_t* self, rc_eval_state_t* eval_state) {
#ifndef RC_DISABLE_LUA
rc_luapeek_t luapeek;
#endif /* RC_DISABLE_LUA */
@@ -352,25 +358,25 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_S
case RC_OPERAND_LUA:
#ifndef RC_DISABLE_LUA
if (L != 0) {
lua_rawgeti(L, LUA_REGISTRYINDEX, self->value.luafunc);
lua_pushcfunction(L, rc_luapeek);
if (eval_state->L != 0) {
lua_rawgeti(eval_state->L, LUA_REGISTRYINDEX, self->value.luafunc);
lua_pushcfunction(eval_state->L, rc_luapeek);
luapeek.peek = peek;
luapeek.ud = ud;
luapeek.peek = eval_state->peek;
luapeek.ud = eval_state->peek_userdata;
lua_pushlightuserdata(L, &luapeek);
lua_pushlightuserdata(eval_state->L, &luapeek);
if (lua_pcall(L, 2, 1, 0) == LUA_OK) {
if (lua_isboolean(L, -1)) {
value = lua_toboolean(L, -1);
if (lua_pcall(eval_state->L, 2, 1, 0) == LUA_OK) {
if (lua_isboolean(eval_state->L, -1)) {
value = lua_toboolean(eval_state->L, -1);
}
else {
value = (unsigned)lua_tonumber(L, -1);
value = (unsigned)lua_tonumber(eval_state->L, -1);
}
}
lua_pop(L, 1);
lua_pop(eval_state->L, 1);
}
#endif /* RC_DISABLE_LUA */
@@ -378,15 +384,15 @@ unsigned rc_evaluate_operand(rc_operand_t* self, rc_peek_t peek, void* ud, lua_S
break;
case RC_OPERAND_ADDRESS:
value = self->value.memref->value;
value = rc_get_indirect_memref(self->value.memref, eval_state)->value;
break;
case RC_OPERAND_DELTA:
value = self->value.memref->previous;
value = rc_get_indirect_memref(self->value.memref, eval_state)->previous;
break;
case RC_OPERAND_PRIOR:
value = self->value.memref->prior;
value = rc_get_indirect_memref(self->value.memref, eval_state)->prior;
break;
}
+20 -3
View File
@@ -51,8 +51,10 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
const char* in;
char* out;
if (endline - line < 1)
if (endline - line < 1) {
parse->offset = RC_MISSING_DISPLAY_STRING;
return 0;
}
{
self = RC_ALLOC(rc_richpresence_display_t, parse);
@@ -103,6 +105,11 @@ static rc_richpresence_display_t* rc_parse_richpresence_display_internal(const c
while (ptr < endline && *ptr != '(')
++ptr;
if (ptr == endline) {
parse->offset = RC_MISSING_VALUE;
return 0;
}
if (ptr > line) {
if (!parse->buffer) {
/* just calculating size, can't confirm lookup exists */
@@ -179,6 +186,7 @@ static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup
const char* line;
const char* endline;
const char* defaultlabel = 0;
char* endptr = 0;
unsigned key;
int chars;
@@ -208,9 +216,14 @@ static const char* rc_parse_richpresence_lookup(rc_richpresence_lookup_t* lookup
}
if (number[0] == '0' && number[1] == 'x')
key = (unsigned)strtoul(&number[2], 0, 16);
key = strtoul(&number[2], &endptr, 16);
else
key = (unsigned)strtoul(&number[0], 0, 10);
key = strtoul(&number[0], &endptr, 10);
if (*endptr && !isspace(*endptr)) {
parse->offset = RC_INVALID_CONST_OPERAND;
return nextline;
}
item = RC_ALLOC(rc_richpresence_lookup_item_t, parse);
item->value = key;
@@ -263,6 +276,8 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script,
nextlookup = &lookup->next;
nextline = rc_parse_richpresence_lookup(lookup, nextline, parse);
if (parse->offset < 0)
return;
} else if (strncmp(line, "Format:", 7) == 0) {
line += 7;
@@ -316,6 +331,8 @@ void rc_parse_richpresence_internal(rc_richpresence_t* self, const char* script,
if (ptr < endline) {
*nextdisplay = rc_parse_richpresence_display_internal(ptr + 1, endline, parse, self);
if (parse->offset < 0)
return;
trigger = &((*nextdisplay)->trigger);
rc_parse_trigger_internal(trigger, &line, parse);
trigger->memrefs = 0;
+11 -7
View File
@@ -1,6 +1,6 @@
#include "internal.h"
rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse) {
rc_term_t* rc_parse_term(const char** memaddr, int is_indirect, rc_parse_state_t* parse) {
rc_term_t* self;
const char* aux;
char size;
@@ -10,7 +10,7 @@ rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse) {
self = RC_ALLOC(rc_term_t, parse);
self->invert = 0;
ret2 = rc_parse_operand(&self->operand1, &aux, 0, parse);
ret2 = rc_parse_operand(&self->operand1, &aux, 0, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
@@ -25,7 +25,7 @@ rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse) {
self->invert = 1;
}
ret2 = rc_parse_operand(&self->operand2, &aux, 0, parse);
ret2 = rc_parse_operand(&self->operand2, &aux, 0, is_indirect, parse);
if (ret2 < 0) {
parse->offset = ret2;
@@ -88,12 +88,16 @@ rc_term_t* rc_parse_term(const char** memaddr, rc_parse_state_t* parse) {
return self;
}
unsigned rc_evaluate_term(rc_term_t* self, rc_peek_t peek, void* ud, lua_State* L) {
unsigned value = rc_evaluate_operand(&self->operand1, peek, ud, L);
int rc_evaluate_term(rc_term_t* self, rc_eval_state_t* eval_state) {
/* Operands are usually memory references and are always retrieved as unsigned. The floating
* point operand is signed, and will automatically make the result signed. Otherwise, multiply
* by the secondary operand (which is usually 1) and cast to signed.
*/
unsigned value = rc_evaluate_operand(&self->operand1, eval_state);
if (self->operand2.type != RC_OPERAND_FP) {
return value * (rc_evaluate_operand(&self->operand2, peek, ud, L) ^ self->invert);
return (int)(value * (rc_evaluate_operand(&self->operand2, eval_state) ^ self->invert));
}
return (unsigned)((double)value * self->operand2.value.dbl);
return (int)((double)value * self->operand2.value.dbl);
}
+106 -30
View File
@@ -1,6 +1,7 @@
#include "internal.h"
#include <stddef.h>
#include <memory.h>
void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_parse_state_t* parse) {
rc_condset_t** next;
@@ -35,6 +36,11 @@ void rc_parse_trigger_internal(rc_trigger_t* self, const char** memaddr, rc_pars
*next = 0;
*memaddr = aux;
self->measured_value = 0;
self->measured_target = parse->measured_target;
self->state = RC_TRIGGER_STATE_WAITING;
self->has_hits = 0;
}
int rc_trigger_size(const char* memaddr) {
@@ -63,36 +69,7 @@ rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L,
return parse.offset >= 0 ? self : 0;
}
int rc_test_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State* L) {
int ret, reset;
rc_condset_t* condset;
rc_update_memref_values(self->memrefs, peek, ud);
reset = 0;
ret = self->requirement != 0 ? rc_test_condset(self->requirement, &reset, peek, ud, L) : 1;
condset = self->alternative;
if (condset) {
int sub = 0;
do {
sub |= rc_test_condset(condset, &reset, peek, ud, L);
condset = condset->next;
}
while (condset != 0);
ret &= sub && !reset;
}
if (reset) {
rc_reset_trigger(self);
}
return ret;
}
void rc_reset_trigger(rc_trigger_t* self) {
static void rc_reset_trigger_hitcounts(rc_trigger_t* self) {
rc_condset_t* condset;
if (self->requirement != 0) {
@@ -106,3 +83,102 @@ void rc_reset_trigger(rc_trigger_t* self) {
condset = condset->next;
}
}
int rc_evaluate_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State* L) {
rc_eval_state_t eval_state;
rc_condset_t* condset;
int ret;
char is_paused;
/* previously triggered, do nothing - return INACTIVE so caller doesn't report a repeated trigger */
if (self->state == RC_TRIGGER_STATE_TRIGGERED)
return RC_TRIGGER_STATE_INACTIVE;
rc_update_memref_values(self->memrefs, peek, ud);
/* not yet active, only update the memrefs - so deltas are corrent when it becomes active */
if (self->state == RC_TRIGGER_STATE_INACTIVE)
return RC_TRIGGER_STATE_INACTIVE;
/* process the trigger */
memset(&eval_state, 0, sizeof(eval_state));
eval_state.peek = peek;
eval_state.peek_userdata = ud;
eval_state.L = L;
ret = self->requirement != 0 ? rc_test_condset(self->requirement, &eval_state) : 1;
condset = self->alternative;
if (condset) {
int sub = 0;
do {
sub |= rc_test_condset(condset, &eval_state);
condset = condset->next;
}
while (condset != 0);
ret &= sub;
}
self->measured_value = eval_state.measured_value;
/* if the state is WAITING and the trigger is ready to fire, ignore it and reset the hit counts */
/* otherwise, if the state is WAITING, proceed to activating the trigger */
if (self->state == RC_TRIGGER_STATE_WAITING && ret) {
rc_reset_trigger(self);
self->has_hits = 0;
return RC_TRIGGER_STATE_WAITING;
}
if (eval_state.was_reset) {
/* if any ResetIf condition was true, reset the hit counts */
rc_reset_trigger_hitcounts(self);
/* if there were hit counts to clear, return RESET, but don't change the state */
if (self->has_hits) {
self->has_hits = 0;
return RC_TRIGGER_STATE_RESET;
}
/* any hits that were tallied were just reset */
eval_state.has_hits = 0;
}
else if (ret) {
/* trigger was triggered */
self->state = RC_TRIGGER_STATE_TRIGGERED;
return RC_TRIGGER_STATE_TRIGGERED;
}
/* did not trigger this frame - update the information we'll need for next time */
self->has_hits = eval_state.has_hits;
/* check to see if the trigger is paused */
is_paused = (self->requirement != NULL) ? self->requirement->is_paused : 0;
if (!is_paused) {
/* if the core is not paused, all alts must be paused to count as a paused trigger */
is_paused = (self->alternative != NULL);
for (condset = self->alternative; condset != NULL; condset = condset->next) {
if (!condset->is_paused) {
is_paused = 0;
break;
}
}
}
self->state = is_paused ? RC_TRIGGER_STATE_PAUSED : RC_TRIGGER_STATE_ACTIVE;
return self->state;
}
int rc_test_trigger(rc_trigger_t* self, rc_peek_t peek, void* ud, lua_State* L) {
/* for backwards compatibilty, rc_test_trigger always assumes the achievement is active */
self->state = RC_TRIGGER_STATE_ACTIVE;
return (rc_evaluate_trigger(self, peek, ud, L) == RC_TRIGGER_STATE_TRIGGERED);
}
void rc_reset_trigger(rc_trigger_t* self) {
rc_reset_trigger_hitcounts(self);
self->state = RC_TRIGGER_STATE_WAITING;
}
+101 -6
View File
@@ -1,8 +1,88 @@
#include "internal.h"
#include <memory.h>
static void rc_parse_cond_value(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) {
rc_condition_t** next;
int has_measured;
int in_add_address;
has_measured = 0;
in_add_address = 0;
self->expressions = 0;
/* this largely duplicates rc_parse_condset, but we cannot call it directly, as we need to check the
* type of each condition as we go */
self->conditions = RC_ALLOC(rc_condset_t, parse);
self->conditions->next = 0;
self->conditions->has_pause = 0;
next = &self->conditions->conditions;
for (;;) {
*next = rc_parse_condition(memaddr, parse, in_add_address);
if (parse->offset < 0) {
return;
}
in_add_address = (*next)->type == RC_CONDITION_ADD_ADDRESS;
switch ((*next)->type) {
case RC_CONDITION_ADD_HITS:
case RC_CONDITION_ADD_SOURCE:
case RC_CONDITION_SUB_SOURCE:
case RC_CONDITION_AND_NEXT:
case RC_CONDITION_ADD_ADDRESS:
/* combining flags are allowed */
break;
case RC_CONDITION_RESET_IF:
/* ResetIf is allowed (primarily for rich presense - leaderboard will typically cancel instead of resetting) */
break;
case RC_CONDITION_MEASURED:
if (has_measured) {
parse->offset = RC_MULTIPLE_MEASURED;
return;
}
has_measured = 1;
if ((*next)->required_hits == 0 && (*next)->oper != RC_CONDITION_NONE)
(*next)->required_hits = (unsigned)-1;
break;
default:
/* non-combinding flags and PauseIf are not allowed */
parse->offset = RC_INVALID_VALUE_FLAG;
return;
}
(*next)->pause = 0;
next = &(*next)->next;
if (**memaddr != '_') {
break;
}
(*memaddr)++;
}
*next = 0;
if (!has_measured) {
parse->offset = RC_MISSING_VALUE_MEASURED;
}
}
void rc_parse_value_internal(rc_value_t* self, const char** memaddr, rc_parse_state_t* parse) {
rc_expression_t** next;
/* if it starts with a condition flag (M: A: B: C:), parse the conditions */
if ((*memaddr)[1] == ':') {
rc_parse_cond_value(self, memaddr, parse);
return;
}
self->conditions = 0;
next = &self->expressions;
for (;;) {
@@ -50,17 +130,15 @@ rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int
return parse.offset >= 0 ? self : 0;
}
unsigned rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State* L) {
static int rc_evaluate_expr_value(rc_value_t* self, rc_eval_state_t* eval_state) {
rc_expression_t* exp;
unsigned value, max;
rc_update_memref_values(self->memrefs, peek, ud);
int value, max;
exp = self->expressions;
max = rc_evaluate_expression(exp, peek, ud, L);
max = rc_evaluate_expression(exp, eval_state);
for (exp = exp->next; exp != 0; exp = exp->next) {
value = rc_evaluate_expression(exp, peek, ud, L);
value = rc_evaluate_expression(exp, eval_state);
if (value > max) {
max = value;
@@ -69,3 +147,20 @@ unsigned rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State
return max;
}
int rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State* L) {
rc_eval_state_t eval_state;
memset(&eval_state, 0, sizeof(eval_state));
eval_state.peek = peek;
eval_state.peek_userdata = ud;
eval_state.L = L;
rc_update_memref_values(self->memrefs, peek, ud);
if (self->expressions) {
return rc_evaluate_expr_value(self, &eval_state);
}
rc_test_condset(self->conditions, &eval_state);
return (int)eval_state.measured_value;
}
+2 -2
View File
@@ -69,7 +69,7 @@ int rc_url_award_cheevo(char* buffer, size_t size, const char* user_name, const
return (size_t)written >= size ? -1 : 0;
}
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, unsigned value, unsigned char hash[16]) {
int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const char* login_token, unsigned lboard_id, int value, unsigned char hash[16]) {
char urle_user_name[64];
char urle_login_token[64];
int written;
@@ -85,7 +85,7 @@ int rc_url_submit_lboard(char* buffer, size_t size, const char* user_name, const
written = snprintf(
buffer,
size,
"http://retroachievements.org/dorequest.php?r=submitlbentry&u=%s&t=%s&i=%u&s=%u&v=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
"http://retroachievements.org/dorequest.php?r=submitlbentry&u=%s&t=%s&i=%u&s=%d&v=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
urle_user_name,
urle_login_token,
lboard_id,
+99
View File
@@ -0,0 +1,99 @@
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: Always
...
+17
View File
@@ -0,0 +1,17 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
+57
View File
@@ -0,0 +1,57 @@
*.vpk
*.elf
*.velf
*.bin
*.sfo
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Vita build stuffs
*.a
*.o
+165
View File
@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser 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
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
+69
View File
@@ -0,0 +1,69 @@
TARGET := libvitaGL
SOURCES := source source/utils
SHADERS := shaders
LIBS = -lc -lm -lSceGxm_stub -lSceDisplay_stub
ifeq ($(HAVE_SBRK),1)
SOURCES += source/hacks
endif
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
CGFILES := $(foreach dir,$(SHADERS), $(wildcard $(dir)/*.cg))
HEADERS := $(CGFILES:.cg=.h)
OBJS := $(CFILES:.c=.o)
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
AR = $(PREFIX)-gcc-ar
CFLAGS = -g -Wl,-q -O2 -ffast-math -mtune=cortex-a9 -mfpu=neon -flto -ftree-vectorize -DTRANSPOSE_MATRICES
ASFLAGS = $(CFLAGS)
all: $(TARGET).a
$(TARGET).a: $(OBJS)
$(AR) -rc $@ $^
%_f.h:
psp2cgc -profile sce_fp_psp2 $(@:_f.h=_f.cg) -Wperf -fastprecision -O3 -o $(@:_f.h=_f.gxp)
bin2c $(@:_f.h=_f.gxp) source/shaders/$(notdir $(@)) $(notdir $(@:_f.h=_f))
@rm -rf $(@:_f.h=_f.gxp)
%_v.h:
psp2cgc -profile sce_vp_psp2 $(@:_v.h=_v.cg) -Wperf -fastprecision -O3 -o $(@:_v.h=_v.gxp)
bin2c $(@:_v.h=_v.gxp) source/shaders/$(notdir $(@:_v.h=_v.h)) $(notdir $(@:_v.h=_v))
@rm -rf $(@:_v.h=_v.gxp)
shaders: $(HEADERS)
clean:
@rm -rf $(TARGET).a $(TARGET).elf $(OBJS)
@make -C samples/sample1 clean
@make -C samples/sample2 clean
@make -C samples/sample3 clean
@make -C samples/sample4 clean
@make -C samples/sample5 clean
@make -C samples/sample6 clean
@make -C samples/sample7 clean
install: $(TARGET).a
@mkdir -p $(VITASDK)/$(PREFIX)/lib/
cp $(TARGET).a $(VITASDK)/$(PREFIX)/lib/
@mkdir -p $(VITASDK)/$(PREFIX)/include/
cp source/vitaGL.h $(VITASDK)/$(PREFIX)/include/
samples: $(TARGET).a
@make -C samples/sample1
cp "samples/sample1/vitaGL-Sample001.vpk" .
@make -C samples/sample2
cp "samples/sample2/vitaGL-Sample002.vpk" .
@make -C samples/sample3
cp "samples/sample3/vitaGL-Sample003.vpk" .
@make -C samples/sample4
cp "samples/sample4/vitaGL-Sample004.vpk" .
@make -C samples/sample5
cp "samples/sample5/vitaGL-Sample005.vpk" .
@make -C samples/sample6
cp "samples/sample6/vitaGL-Sample006.vpk" .
@make -C samples/sample7
cp "samples/sample7/vitaGL-Sample007.vpk" .
+37
View File
@@ -0,0 +1,37 @@
# vitaGL
vitaGL is a wrapper between openGL and sceGxm. It allows to use a subset of openGL functions with fully hardware acceleration by translating the code to sceGxm equivalent.
# Samples
You can find samples in the *samples* folder in this repository.
# Help and Troubleshooting
If you plan to use vitaGL for one of your projects, you can find an official channel to get help with it on Vita Nuova discord server: https://discord.gg/PyCaBx9
# Projects actually using vitaGL
Here you can find a list of projects using vitaGL:
Direct OpenGL Usage:<br>
[vitaQuake](https://vitadb.rinnegatamante.it/#/info/10) - Port of Quake I and mission packs<br>
[vitaQuakeII](https://vitadb.rinnegatamante.it/#/info/278) -Port of Quake II and mission packs<br>
[vitaQuakeIII](https://vitadb.rinnegatamante.it/#/info/375) - Port of ioquake3 (Quake III: Arena, Quake III: Team Arena, OpenArena)<br>
[vitaRTCW](https://vitadb.rinnegatamante.it/#/info/459) - Port of iortcw (Return to Castle Wolfenstein)<br>
[vitaHexenII](https://vitadb.rinnegatamante.it/#/info/196) - Port of Hexen II<br>
[vitaXash3D](https://vitadb.rinnegatamante.it/#/info/365) - Port of Xash3D (Half Life, Counter Strike 1.6)<br>
[Fade to Black](https://vitadb.rinnegatamante.it/#/info/367) - Port of Fade to Black<br>
[vitaVoyager](https://vitadb.rinnegatamante.it/#/info/367) - Port of lilium-voyager (Star Trek Voyager: Elite Force)<br>
Libraries:<br>
[sdl12_gl](https://github.com/Rinnegatamante/SDL-Vita/tree/sdl12_gl/src) - SDL 1.2 Vita port adapted to work with vitaGL as renderer<br>
[imgui_vita](https://github.com/Rinnegatamante/imgui-vita) - Port of dear imGui <br>
sdl12_gl Apps:<br>
[SuperMarioWar](https://vitadb.rinnegatamante.it/#/info/422) - Port of Super Mario War<br>
[ZeldaOLB](https://vitadb.rinnegatamante.it/#/info/265) - Port of Zelda: Oni Link Begins<br>
[ZeldaROTH](https://vitadb.rinnegatamante.it/#/info/109) - Port of Zelda: Return of the Hylian<br>
[Zelda3T](https://vitadb.rinnegatamante.it/#/info/334) - Port of Zelda: Time to Triumph<br>
[ZeldaNSQ](https://vitadb.rinnegatamante.it/#/info/350) - Port of Zelda: Navi's Quest<br>
[vitaWolfen](https://vitadb.rinnegatamante.it/#/info/31) - Port of Wolf4SDL<br>
[meritous](https://vitadb.rinnegatamante.it/#/info/411) - Port of meritous<br>
+6
View File
@@ -0,0 +1,6 @@
@echo off
cd source
for /f %%f in ('dir *.c *.h /b/s') do (
echo.%%f | findstr /C:"\\shaders\\">nul || (clang-format -i %%f)
)
cd ..
+40
View File
@@ -0,0 +1,40 @@
SAMPLE_NUM := 001
TARGET := vitaGL-Sample$(SAMPLE_NUM)
SOURCES := .
INCLUDES := include
LIBS = -lvitaGL -lSceLibKernel_stub -lScePvf_stub -lmathneon \
-lSceAppMgr_stub -lSceAppUtil_stub -lScePgf_stub \
-ljpeg -lfreetype -lc -lSceCommonDialog_stub -lpng16 -lm -lz \
-lSceGxm_stub -lSceDisplay_stub -lSceSysmodule_stub \
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
CPPFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.cpp))
BINFILES := $(foreach dir,$(DATA), $(wildcard $(dir)/*.bin))
OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
CFLAGS = -g -Wl,-q -O2 -ftree-vectorize
CXXFLAGS = $(CFLAGS) -fno-exceptions -std=gnu++11 -fpermissive
ASFLAGS = $(CFLAGS)
all: $(TARGET).vpk
$(TARGET).vpk: eboot.bin
vita-mksfoex -s TITLE_ID=VITAGL$(SAMPLE_NUM) "$(TARGET)" param.sfo
vita-pack-vpk -s param.sfo -b eboot.bin -a texture.bmp=texture.bmp $@
eboot.bin: $(TARGET).velf
vita-make-fself -s $< eboot.bin
%.velf: %.elf
vita-elf-create $< $@
$(TARGET).elf: $(OBJS)
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
clean:
@rm -rf *.velf *.elf *.vpk $(OBJS) param.sfo eboot.bin
+67
View File
@@ -0,0 +1,67 @@
// Drawing a fullscreen image on screen with glBegin/glEnd
#include <vitaGL.h>
#include <vita2d.h>
#include <stdlib.h>
GLenum texture_format = GL_RGB;
GLuint texture = 0;
int main(){
// Initializing graphics device
vglInit(0x800000);
// Loading BMP image to use as texture
SceUID fd = sceIoOpen("app0:texture.bmp", SCE_O_RDONLY, 0777);
uint16_t w, h;
sceIoLseek(fd, 0x12, SCE_SEEK_SET);
sceIoRead(fd, &w, sizeof(uint16_t));
sceIoLseek(fd, 0x16, SCE_SEEK_SET);
sceIoRead(fd, &h, sizeof(uint16_t));
sceIoLseek(fd, 0x26, SCE_SEEK_SET);
uint8_t *buffer = (uint8_t*)malloc(w * h * 3);
sceIoRead(fd, buffer, w * h * 3);
sceIoClose(fd);
glClearColor(0.50, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 960, 544, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Initializing openGL texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, texture_format, w, h, 0, texture_format, GL_UNSIGNED_BYTE, buffer);
glEnable(GL_TEXTURE_2D);
for (;;){
vglStartRendering();
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
// Note: BMP images are vertically flipped
glTexCoord2i(0, 1);
glVertex3f(0, 0, 0);
glTexCoord2i(1, 1);
glVertex3f(960, 0, 0);
glTexCoord2i(1, 0);
glVertex3f(960, 544, 0);
glTexCoord2i(0, 0);
glVertex3f(0, 544, 0);
glEnd();
vglStopRendering();
glLoadIdentity();
}
vglEnd();
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+42
View File
@@ -0,0 +1,42 @@
SAMPLE_NUM := 002
TARGET := vitaGL-Sample$(SAMPLE_NUM)
SOURCES := .
INCLUDES := include
LIBS = -lvitaGL -lc -lSceCommonDialog_stub -lm -lSceGxm_stub -lSceDisplay_stub -lmathneon
CFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.c))
CPPFILES := $(foreach dir,$(SOURCES), $(wildcard $(dir)/*.cpp))
BINFILES := $(foreach dir,$(DATA), $(wildcard $(dir)/*.bin))
OBJS := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
PREFIX = arm-vita-eabi
CC = $(PREFIX)-gcc
CXX = $(PREFIX)-g++
CFLAGS = -g -Wl,-q -O2 -ftree-vectorize
CXXFLAGS = $(CFLAGS) -fno-exceptions -std=gnu++11 -fpermissive
ASFLAGS = $(CFLAGS)
all: $(TARGET).vpk
debug: CFLAGS += -DDEBUG_BUILD
debug: all
$(TARGET).vpk: eboot.bin
vita-mksfoex -s TITLE_ID=VITAGL$(SAMPLE_NUM) "$(TARGET)" param.sfo
vita-pack-vpk -s param.sfo -b eboot.bin $@
eboot.bin: $(TARGET).velf
vita-make-fself -s $< eboot.bin
%.velf: %.elf
cp $< $<.unstripped.elf
vita-elf-create $< $@
$(TARGET).elf: $(OBJS)
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
clean:
@rm -rf *.velf *.elf *.vpk $(OBJS) param.sfo eboot.bin
Loaded 100 of 397 files, more files were not shown because too many files have changed in this diff. Show more