Compare commits

...
493 Commits
Author SHA1 Message Date
twinaphex 51581e1578 Include string.h instead 2017-03-09 01:50:27 +01:00
Jean-André Santoni 1148c6156e Fix wrong wraparound code 2017-03-08 21:32:43 +01:00
Twinaphex 256433a00b Bump up to 1.5.0 2017-03-07 18:37:57 +01:00
twinaphex 2559aec92d Bump version 2017-03-07 18:35:06 +01:00
twinaphex 9e2ae4aca4 Use 1.5.0 2017-03-07 18:33:35 +01:00
Brad Parker c12cc8e5be netplay: change lobby reannounce period to 600 frames 2017-03-07 12:29:51 -05:00
twinaphex 03d58e9e62 Update 2017-03-07 15:00:20 +01:00
twinaphex 17739435de Cleanups 2017-03-07 12:59:58 +01:00
twinaphex 4118d0bbd2 Cleanups 2017-03-07 12:49:52 +01:00
twinaphex f4ac760178 Cleanups 2017-03-07 12:37:11 +01:00
twinaphex cb1c8df547 Simplify gl_glsl_set_coords 2017-03-07 12:35:29 +01:00
Jean-André Santoni 7db6e58273 Don't run OSK code if the OSK is not displayed 2017-03-07 11:57:30 +01:00
Brad Parker bb362f307d netplay: don't advertise over LAN or try to open a port with UPnP if we're using a MITM server 2017-03-06 21:39:03 -05:00
bparker06 ced1dc10c1 Merge pull request #4732 from GregorR/netplay-server-spectator-fix-2-electric-boogaloo
Yet another server-is-spectator bug. Don't ever ignore stalls if we're a client
2017-03-06 21:25:18 -05:00
Brad Parker 4f02450bf9 forgot extra storage for NULL byte 2017-03-06 21:10:27 -05:00
Gregor Richards 2f21a3e370 Yet another server-is-spectator bug. Don't ever ignore stalls if we're a
client
2017-03-06 20:13:26 -05:00
Jean-André Santoni ff575a3460 PCE-CD magic number detection 2017-03-07 01:16:58 +01:00
Brad Parker d9c78c75f0 fix setting of netplay has_password in lobby announcement 2017-03-06 16:01:45 -05:00
Twinaphex 4b796ae740 Silence warnings 2017-03-06 12:12:00 +01:00
Jean-André Santoni c7722143b9 Update CHANGES.md 2017-03-06 09:50:24 +01:00
Brad Parker 6a68a01eb9 msvc2005 buildfix 2017-03-05 22:02:55 -05:00
Brad Parker 310c486f6a update changelog 2017-03-05 20:48:14 -05:00
Jean-André Santoni e7be847784 Avoid pushing netplay rooms on wrong tabs 2017-03-05 22:42:33 +01:00
Jean-André Santoni 4318000f8f (XMB) Change icon sets on the fly 2017-03-05 22:31:30 +01:00
twinaphex cf82bdbebd Get rid of more implicit memsets 2017-03-05 22:24:35 +01:00
twinaphex 85e5a01576 Get rid of some implicit memsets 2017-03-05 22:21:55 +01:00
Twinaphex 7d9edc0874 Update iOS solutions 2017-03-05 22:07:19 +01:00
Brad Parker 12a208f75e merge reannounce bugfix from radius 2017-03-05 15:49:07 -05:00
Twinaphex ec14874363 Update to version 1.4.2 2017-03-05 20:52:24 +01:00
twinaphex c5717ecd84 Start bumping up to version 1.4.2 2017-03-05 20:51:15 +01:00
Twinaphex c343a88c10 Silence unused variable warnings 2017-03-05 20:30:14 +01:00
Brad Parker 9a7d38de77 MSVC buildfix: add UTF8 BOM to korean translation 2017-03-05 14:28:33 -05:00
Brad Parker 1a251de6be update changelog 2017-03-05 14:22:50 -05:00
Brad Parker c6b1a4bb48 join MITM server when host starts game, if the announcement requested MITM 2017-03-05 14:19:39 -05:00
Brad Parker 2df1ed9157 fix inconsistent dll linkage warning in msvc 2017-03-05 14:19:39 -05:00
Brad Parker bd6ca986d8 msvc buildfix 2017-03-05 14:19:38 -05:00
Brad Parker bf553fe65c netplay: connect to MITM server instead of host IP if one is specified in lobby listing 2017-03-05 14:19:38 -05:00
Brad Parker 8a01dda5d6 send force MITM setting with lobby announcement 2017-03-05 14:19:38 -05:00
Brad Parker f2c4eb5047 add sublabel for MITM 2017-03-05 14:19:38 -05:00
Brad Parker 1f42889936 add settings -> network entry to force using a MITM server for netplay 2017-03-05 14:19:37 -05:00
Brad Parker 1fc7a50f3e fix non-ascii URL encoding 2017-03-05 14:19:37 -05:00
Brad Parker 7aca744635 URL encode non-ascii characters 2017-03-05 14:19:37 -05:00
Brad Parker c7c0e1351a send CRC as hex string 2017-03-05 14:19:37 -05:00
Brad Parker 4f2cdf3a84 populate system info before reading it 2017-03-05 14:19:36 -05:00
Brad Parker 79899e6b71 silence linux warning 2017-03-05 14:19:36 -05:00
Brad Parker ad6733b519 add full urlencoder and encode lobby announcement POST data 2017-03-05 14:19:36 -05:00
Brad Parker 9c19f16539 remove debug stuff 2017-03-05 14:19:36 -05:00
Brad Parker 0d81b2005f parse new lobby room listing with JSON 2017-03-05 14:19:35 -05:00
Brad Parker 21fe0c8499 bake in johnanthonyowens/jsonsax as jsonsax_full 2017-03-05 14:19:35 -05:00
Brad Parker fb3393eb3a add user agent to http requests 2017-03-05 14:19:35 -05:00
Brad Parker 101475c2f6 fix POST handling 2017-03-05 14:19:34 -05:00
Brad Parker c31823aa94 add HTTP POST support 2017-03-05 14:19:34 -05:00
twinaphex c99d83f15c Update 2017-03-05 20:14:01 +01:00
twinaphex 71b0666ec5 Silence another Coverity warning 2017-03-05 20:06:36 +01:00
twinaphex 0123d33780 Silence CXX_BUILD warnings 2017-03-05 19:28:34 +01:00
twinaphex 3a5eb48c4a C89_BUILD fixes 2017-03-05 19:25:11 +01:00
twinaphex df1313bc37 Change signature for word_wrap 2017-03-05 19:15:04 +01:00
twinaphex bb15b14388 word_wrap - Dont' call strlen once every loop iteration 2017-03-05 19:09:31 +01:00
twinaphex c70b8c42c5 Cleanups to word_wrap 2017-03-05 19:02:32 +01:00
twinaphex 63973a52e0 Simplify word_wrap 2017-03-05 19:01:44 +01:00
Twinaphex a5c57fe882 Prevent unused variable warning 2017-03-05 18:57:15 +01:00
twinaphex 79bde3f9b1 remove unused value 2017-03-05 18:52:36 +01:00
twinaphex 0b7ef78122 Simplify core_info_database_supports_content_path 2017-03-05 18:47:02 +01:00
twinaphex 279b2e1123 Update CHANGES.md 2017-03-05 18:04:29 +01:00
twinaphex e122c91519 Update CHANGES.md 2017-03-05 18:03:51 +01:00
Jean-André Santoni e758406d52 Undo save/load state shouldn't be an advanced setting 2017-03-05 17:54:37 +01:00
Jean-André Santoni e587264b3d (OSK) Ascii symbol page 2017-03-05 11:54:08 +01:00
Jean-André Santoni 69694a2fab Merge pull request #4727 from losernator/master
Add Korean translation
2017-03-05 11:30:31 +01:00
Jean-André Santoni c808fa54c7 Merge pull request #4729 from libretro/touch-improvements
Touch improvements
2017-03-05 11:23:59 +01:00
Jean-André Santoni 130e3a77d8 (GLUI) Fix the menu entry being selected while we try to scroll 2017-03-05 09:49:22 +01:00
Jean-André Santoni 199d7b63a1 (Menu) Attempt to fix scroll speed issue 2017-03-05 00:15:21 +01:00
Jean-André Santoni bb0d4dae07 (Menu) iOS touch fixes 2017-03-04 22:16:55 +01:00
losernator d019855439 Update msg_hash_ko.c 2017-03-05 02:10:53 +09:00
losernator b8020c0c21 add support for Korean 2017-03-05 01:43:13 +09:00
losernator baa666022f add support for Korean 2017-03-05 01:42:14 +09:00
losernator aed6fa83bd add support for Korean 2017-03-05 01:39:14 +09:00
losernator 5f2e6c4320 add support for Korean 2017-03-05 01:36:08 +09:00
losernator b5a01bc42e add support for Korean language 2017-03-05 01:32:16 +09:00
losernator 36c2d457fc add support for Korean language 2017-03-05 01:31:18 +09:00
Jean-André Santoni 013bf29fff (Menu) A long press will reset a setting to its default value 2017-03-04 15:35:05 +01:00
Jean-André Santoni 002928c399 (Menu) Separate callbacks for pointer_up and pointer_down 2017-03-04 15:11:29 +01:00
Andrés ec395048b6 Update CHANGES.md 2017-03-01 23:07:14 -05:00
twinaphex 85b099b8cf Update 2017-03-01 22:09:38 +01:00
Twinaphex a2def14969 Merge pull request #4715 from gingerbeardman/master
Additional icons and banners for 3DS
2017-03-01 13:12:19 +01:00
twinaphex 4109ffdb6b Update of libretro-common 2017-03-01 05:03:23 +01:00
Brad Parker 96650e14ea break early if server frame count is ahead of NOINPUT 2017-02-28 21:46:57 -05:00
Jean-André Santoni dbd359ad6a Merge pull request #4712 from leiradel/master
Fix resampler->process overriding memory because we don't know exactl…
2017-02-28 19:49:45 +01:00
Jean-André Santoni 18e1a817b3 Merge pull request #4713 from fr500/master
mantain LAN rooms in the list after moving left/right
2017-02-28 19:48:57 +01:00
Matt Sephton 34e3490ce9 Updated assets.7z 2017-02-28 16:32:52 +00:00
Matt Sephton 693652b2a9 Created icons and banners for cores that have recently been compiled for 3DS
See:
https://gbatemp.net/threads/unofficial-3ds-retroarch-builds-compatibilit
y-thread.462252/page-2#post-7138543

Art files available as .afdesign or .svg or similar
2017-02-28 16:32:43 +00:00
Brad Parker fea8a0f780 Don't stall for spectator data when we're not in spectator mode, thanks @GregorR 2017-02-28 11:31:59 -05:00
Andrés f39de90837 Merge pull request #4671 from dankcushions/patch-3
One option moved to advanced settings.
2017-02-28 11:14:53 -05:00
radius eba92bd3ca mantain LAN rooms in the list after moving left/right 2017-02-28 11:10:17 -05:00
Andre Leiradella 2481d25f0f Fix resampler->process overriding memory because we don't know exactly how much memory it needss 2017-02-28 14:48:20 +00:00
twinaphex 57e0e30600 Update core_info.c 2017-02-28 11:16:05 +01:00
twinaphex 6396f0391a Cleanups 2017-02-28 10:56:02 +01:00
twinaphex 3cecdcdd7d Cleanups 2017-02-28 10:55:39 +01:00
twinaphex 824a619b90 Initialize db manually 2017-02-28 10:53:20 +01:00
twinaphex ef1323bbfd Prevent explicit NULL dereference 2017-02-28 10:47:24 +01:00
twinaphex 56eb09406b Add TODO/FIXME 2017-02-28 10:28:49 +01:00
twinaphex c17dbe6ddb Using calloc seems to get us past the crashes 2017-02-28 10:27:34 +01:00
twinaphex 2fa9d47b61 Cleanups 2017-02-28 10:22:06 +01:00
twinaphex aff63e6c3f Cleanups 2017-02-28 10:16:36 +01:00
twinaphex 8195c601d5 Cleanups 2017-02-28 10:14:00 +01:00
twinaphex 05b760d0f8 Fix C89_BUILD/CXX_BUILD 2017-02-28 09:52:33 +01:00
twinaphex 5bf5388759 Cleanups 2017-02-28 09:44:44 +01:00
Twinaphex 59f5c596d6 Merge pull request #4707 from fr500/master
LAN scanning into rooms
2017-02-28 05:47:49 +01:00
radius 0c456c2235 comment this out for now 2017-02-27 23:47:04 -05:00
twinaphex 2be88a44ed (XMB) Fix 2017-02-28 04:50:07 +01:00
bparker06 b30b9599a2 Merge pull request #4708 from GregorR/netplay-empty-info
Support empty INFO packet for undifferentiated servers.
2017-02-27 22:24:02 -05:00
Gregor Richards 8fb1f6a647 Support empty INFO packet for undifferentiated servers. 2017-02-27 22:06:20 -05:00
radius 35d78bb010 better label 2017-02-27 22:04:59 -05:00
radius ba4804ed7c differentiate lan and internet rooms 2017-02-27 21:58:39 -05:00
radius 650655abbe doesn't seem to crash anymore 2017-02-27 21:44:11 -05:00
radius e50ea80dfa integrate the rest of the lan scan parameters 2017-02-27 21:24:34 -05:00
Twinaphex 92bbeab6f6 Merge pull request #4704 from gingerbeardman/icons
Corrected height of fceumm icon to 48px
2017-02-28 02:44:57 +01:00
radius 5ca55aa533 publish IP address correctly 2017-02-27 20:22:56 -05:00
Twinaphex c9add8c68e Merge pull request #4706 from fr500/master
Adds lan games to the ROOM list
2017-02-28 01:04:59 +01:00
radius b719f30b8e add lan games 2017-02-27 19:00:43 -05:00
radius 2bdd938338 after the first scan it will no longer scan because of this line 2017-02-27 18:10:35 -05:00
Jean-André Santoni fc3547b8e4 Don't allow input on the user language setting 2017-02-28 00:03:19 +01:00
Jean-André Santoni 64a11ca0f4 (XMB) Allow hidding the netplay tab 2017-02-27 23:32:24 +01:00
Jean-André Santoni 834087d1ad (XMB) Use a tab styled icon for the netplay tab 2017-02-27 22:48:27 +01:00
Jean-André Santoni 46c153a0fe (XMB) Move netplay to the left of Add Tab 2017-02-27 22:36:45 +01:00
Matt Sephton a26e229445 Corrected height of fceumm icon to 48px
It had previously been stretched from 41px
2017-02-27 20:39:21 +00:00
Jean-André Santoni 15001a87d3 (XMB) Use a texture slice for dialogs 2017-02-27 20:34:17 +01:00
twinaphex 58c08c0c02 Cleanups 2017-02-27 09:33:20 +01:00
twinaphex 10bf8d4a8a Backport enlarge char buffers 2017-02-27 09:28:38 +01:00
Twinaphex 308aa4678f Update bundle identifiers 2017-02-27 03:52:11 +01:00
Jean-André Santoni 4b84449f59 Fix iOS9 static project 2017-02-27 03:50:08 +01:00
Twinaphex a6420ae966 Update ios10 target 2017-02-27 02:00:57 +01:00
Twinaphex 951ca852f5 Add ios .a targets 2017-02-27 02:00:57 +01:00
Jean-André Santoni c0ac7095fa Update pkg/apple/RetroArch_iOS9-Info.plist 2017-02-27 01:50:54 +01:00
Twinaphex ae92a0ceff Add to Info.plist 2017-02-27 01:42:29 +01:00
Twinaphex ddae075733 Silence more warnings 2017-02-27 01:28:01 +01:00
Twinaphex 9ebd8736e0 Update iOS 10 static 2017-02-27 01:05:10 +01:00
twinaphex 7974fb5c6e Add HAVE_APPLE_STORE to iOS 10 2017-02-26 23:00:03 +01:00
twinaphex 803dd83e67 Put IOS ifdef around this 2017-02-26 22:24:07 +01:00
Twinaphex 43c32aad3d Silence more warnings 2017-02-26 22:16:03 +01:00
Twinaphex fdbdcfee65 Merge pull request #4691 from GregorR/netplay-slave-mode
Netplay slave mode
2017-02-26 21:49:21 +01:00
Twinaphex 216e7bcdaf Silence more warnings on iOS 2017-02-26 21:46:19 +01:00
twinaphex 89715b7195 Fix CXX_BUILD 2017-02-26 10:39:15 +01:00
Twinaphex b7b3b2cb5f Try to prevent truckload of warnings on iOS 2017-02-26 10:33:03 +01:00
twinaphex 8f01bcfb8d Update of command.c 2017-02-26 09:35:35 +01:00
twinaphex af971ea9be Try setting path when defaults menu_config is set 2017-02-26 09:35:00 +01:00
twinaphex c2036e4aed (iOS) App Store versions cannot reference non-public selectors 2017-02-26 07:05:14 +01:00
twinaphex 19bf048b68 Add log message 2017-02-26 06:44:35 +01:00
twinaphex c653e6d886 Buildfix 2017-02-26 06:14:33 +01:00
twinaphex e523280cb0 Add fallback message that informs us when config saving is not working 2017-02-26 06:07:58 +01:00
twinaphex 24b9237669 Prevent null pointer dereferences 2017-02-26 04:38:24 +01:00
twinaphex e48bd0b2b5 Update config.def.h 2017-02-26 04:00:15 +01:00
Twinaphex aa2e7dc794 Silence warning 2017-02-26 03:53:05 +01:00
Twinaphex a55df42978 Update static project 2017-02-26 03:52:28 +01:00
twinaphex 1e96a600d7 Update iOS10 static solution 2017-02-25 23:23:43 +01:00
twinaphex 2b1fbca318 Add to the define 2017-02-25 02:49:18 +01:00
twinaphex 671771d3cd Update RetroArch iOS 10 solution 2017-02-25 02:47:32 +01:00
twinaphex ca2716eef7 Add DONT_WANT_ARM_OPTIMIZATIONS 2017-02-25 02:27:47 +01:00
Twinaphex 2dfb9b9638 Revert "Attempt to not use this codepath for arm64"
This reverts commit a16ba84502.
2017-02-25 02:15:26 +01:00
Twinaphex 9062f62375 Merge pull request #4695 from zeromus/master
fix win32 console logging to be better than ever and no longer slay msys windows (fixes #4673)
2017-02-25 02:10:33 +01:00
zeromus e89706d251 fix win32 console logging to be better than ever and no longer slay msys windows (fixes #4673) 2017-02-24 18:42:19 -06:00
twinaphex a16ba84502 Attempt to not use this codepath for arm64 2017-02-25 00:28:23 +01:00
Twinaphex ed51eaf449 Update iOS 10 target for both arm64 and armv7s 2017-02-25 00:21:27 +01:00
Twinaphex 3c0afd730b Update xcode proj 2017-02-25 00:13:40 +01:00
Twinaphex 5eab3e3d96 Merge pull request #4692 from daviderickson/master
Detect non-standard joystick buttons
2017-02-24 19:31:44 +01:00
David Erickson da8662bb4a Detect non-standard joystick buttons
The Xbox One S controller when connected via Bluetooth
is exposing its select button with the Linux KEY_BACK
code, which is outside of the normal input code
scan range for joysticks.  This patch adds additional
scanning to pick up such extra buttons, and adds
them as buttons after the normal ranges to preserve
compatibility with existing key mappings.
2017-02-24 01:09:15 -08:00
twinaphex 3ae52e2095 Prevent potential crashes when pressing left/right on playlists 2017-02-24 06:58:22 +01:00
twinaphex 26474ee99e Update 2017-02-24 06:52:45 +01:00
twinaphex af02707298 Update core_manager.c 2017-02-24 06:41:18 +01:00
twinaphex cc75e002cd Add managers/core_manager.c 2017-02-24 06:29:13 +01:00
twinaphex d6ecfd42b5 Take out logging 2017-02-24 06:26:50 +01:00
twinaphex 59b86027e9 Simplify menu_displaylist_parse_cores 2017-02-24 06:26:20 +01:00
twinaphex fd5836d4e7 Prevent crash 2017-02-24 04:53:54 +01:00
Gregor Richards 07cfd90dc6 Actually USE the new slave options in config. 2017-02-23 21:49:22 -05:00
Gregor Richards a3e3b3e790 Adding settings to allow/require connections in slave mode. 2017-02-23 21:33:44 -05:00
twinaphex db02a0c52a Move this back 2017-02-24 02:21:18 +01:00
twinaphex b36683ba09 Enable companion UI start on boot if HAVE_DYNAMIC = false 2017-02-24 02:19:15 +01:00
Jean-André Santoni e6bdc9363c Buildfix for RetroArch_iOS10_static 2017-02-24 01:42:37 +01:00
Twinaphex 7a510000bb Need to change bundle identifier for RetroArchiOS 10 2017-02-24 01:11:02 +01:00
Gregor Richards 3ff9a43b7d Spectator and slave mode are rewind-free
This commit makes spectator mode and slave mode in netplay always stay
ahead of the input, thereby avoiding rewinds, which is sort of the
point. This also changes catch-up detection to be a bit less eager, so
that they hopefully don't flap between stalling for server input and
catching up with that input.
2017-02-23 19:05:43 -05:00
Twinaphex d462e91659 Merge pull request #4690 from libretro/msr_temp
Avoid 'unused scalar variable' warning
2017-02-23 21:50:28 +01:00
twinaphex b5b87d7735 Avoid 'unused scalar variable' warning 2017-02-23 21:49:51 +01:00
Twinaphex 6146daf5e8 Merge pull request #4689 from libretro/coverity_scan
Coverity scan
2017-02-23 21:35:33 +01:00
twinaphex b8e68030d0 (menu_cbs_ok.c) Cleanups 2017-02-23 21:35:06 +01:00
twinaphex dcd4d6b422 Cleanups 2017-02-23 21:32:38 +01:00
Twinaphex d969229f6a Merge pull request #4688 from libretro/msr_temp
Make sure to save the config file after bundle_decompressed
2017-02-23 15:18:08 +01:00
twinaphex 1f9059f2b5 Make sure to save the config file after bundle_decompressed 2017-02-23 15:16:51 +01:00
twinaphex f9ca3c9d87 stb_vorbis.h - get rid of this 2017-02-23 14:29:47 +01:00
twinaphex 8cbb4e13ee Prevent crashes 2017-02-23 14:27:43 +01:00
twinaphex 2074d25441 Make STB_VORBIS optional 2017-02-23 05:56:31 +01:00
twinaphex aaef2bb820 Add audio_mixer.h header file 2017-02-23 05:32:03 +01:00
twinaphex 8de102e607 Make stb_vorbis C89-compatible 2017-02-23 05:23:34 +01:00
Gregor Richards e495671563 In spectator mode, we should never be ahead of our peer. 2017-02-22 23:19:22 -05:00
Gregor Richards 3e0bc5acdc Don't flush so eagerly... 2017-02-22 23:19:02 -05:00
twinaphex 22223fa6c4 Fix CXX_BUILD for audio_mixer 2017-02-23 04:41:43 +01:00
Twinaphex 1dcf57c046 Buildfixes for stb_vorbis.h 2017-02-23 04:28:36 +01:00
twinaphex cec74a9460 Add audio_mixer.c for console/Apple builds 2017-02-23 04:26:27 +01:00
twinaphex c5b7a69801 Cleanups 2017-02-23 04:03:53 +01:00
twinaphex 4e0c24acbe Some cleanups for audio mixer 2017-02-23 04:00:40 +01:00
Twinaphex c8dfdaa5ff Merge pull request #4687 from leiradel/feature/mixer
Feature/mixer
2017-02-23 03:39:19 +01:00
Gregor Richards d1ab288d73 Fix update_unread_ptr to handle the case of only slaves connected 2017-02-22 21:10:02 -05:00
Gregor Richards e70ee045bf Initial implementation of Netplay master/slave mode. 2017-02-22 20:34:17 -05:00
Andre Leiradella 342d399a2a Don't dispose the sound on behalf of the user 2017-02-23 00:15:07 +00:00
Andre Leiradella 13ef64769d Properly dispose the sound 2017-02-23 00:10:16 +00:00
Andre Leiradella 1499a7ec64 Added the audio mixer to the Makefile 2017-02-23 00:00:16 +00:00
Andre Leiradella 7e029a5981 Added an audio mixer 2017-02-22 23:54:28 +00:00
Jean-André Santoni 8a6e102a82 Increase UPNP compatibility 2017-02-22 23:02:17 +01:00
twinaphex bd9e2e5fc7 Revert "Cleanups - menu_cbs_left.c"
This reverts commit 378a69aba9.
2017-02-22 18:45:07 +01:00
twinaphex dba6c537f2 Revert "Cleanups"
This reverts commit e9f1b25e55.
2017-02-22 18:44:59 +01:00
twinaphex e9f1b25e55 Cleanups 2017-02-22 07:23:40 +01:00
twinaphex 378a69aba9 Cleanups - menu_cbs_left.c 2017-02-22 07:21:51 +01:00
twinaphex 80fff292d8 action_right_mainmenu - cleanups 2017-02-22 07:14:41 +01:00
twinaphex c72311a708 Cleanups for left/right callbacks 2017-02-22 06:01:02 +01:00
Brad Parker d61d55e3ea update nuklear 2017-02-21 23:53:29 -05:00
twinaphex ea56249661 (net_natt.c) Free net_addrinfo before going out of scope 2017-02-22 05:24:28 +01:00
bparker06 8eb32fa824 Merge pull request #4684 from GregorR/natt-uninitialized
Fixed a bug failing to check initialization in non-UPnP-supporting setups
2017-02-21 22:09:11 -05:00
BuildTools ac9aa4783a Fixed a bug failing to check initialization in non-UPnP-supporting
setups
2017-02-21 22:02:20 -05:00
twinaphex 4403734d97 (audio_mix.c) Cleanups 2017-02-22 02:04:28 +01:00
twinaphex 5e6a79c4ac Try to fix Coverity warnings 2017-02-22 01:57:16 +01:00
Twinaphex 636ab5c12c Enable 'Requires Fullscreen' 2017-02-22 00:26:13 +01:00
Twinaphex 44f08a4739 (iOS) Use libretro_ios.a 2017-02-22 00:20:45 +01:00
twinaphex f7f333477c Add iOS 10 static solution 2017-02-22 00:01:13 +01:00
Twinaphex 188141a628 Merge pull request #4683 from GregorR/ranetplayer-info-packet
Make ranetplayer save the INFO packet as a sort of format header
2017-02-21 23:55:26 +01:00
Twinaphex d2a5f53f8d Merge pull request #4682 from GregorR/natt-else-clause
Fix missing memory free when IPv6 is unsupported
2017-02-21 23:55:16 +01:00
Gregor Richards 4746bbc972 Make ranetplayer save the INFO packet as a sort of format header 2017-02-21 17:46:29 -05:00
Gregor Richards 22500914e1 Fix missing memory free when IPv6 is unsupported 2017-02-21 17:42:09 -05:00
Brad Parker 4e1b4d051d win32: copy selected file path from browser into core/content buffer 2017-02-21 15:29:16 -05:00
twinaphex 238e234106 Prevent another Coverity warning 2017-02-21 21:20:33 +01:00
twinaphex 457b54149d Prevent another Coverity warning 2017-02-21 21:17:17 +01:00
twinaphex dc4464471e Use string_is_empty 2017-02-21 21:14:58 +01:00
twinaphex 60f0b42b1c Get rid of another FORWARD_NULL 2017-02-21 21:14:33 +01:00
twinaphex 5eec1c1f39 Get rid of forward NULL 2017-02-21 21:13:46 +01:00
twinaphex f7bbafa93d Get rid of double break 2017-02-21 21:08:01 +01:00
Twinaphex d06273e38a Merge pull request #4680 from libretro/msr_temp
patch_content - cleanup
2017-02-21 20:38:52 +01:00
twinaphex ef5b26350d patch_content - cleanup 2017-02-21 20:38:02 +01:00
twinaphex 7c83071b01 Prevent 'explicit NULL dereferenced' 2017-02-21 20:30:52 +01:00
twinaphex 8b4893965f task_image.c - FIx another REVERSE_INULL coverity warning 2017-02-21 20:29:29 +01:00
twinaphex 4645e7709b Fix another REVERSE_INULL coverity warning 2017-02-21 20:28:49 +01:00
twinaphex 2ed15fbfbc (task_image.c) Fix REVERSE_INULL coverity warning 2017-02-21 20:28:10 +01:00
twinaphex 9540e91e4c (msg_hash_de.c) Fix missing break 2017-02-21 20:26:38 +01:00
twinaphex 31bf313a4f (libretro-common) Fix resource leak 2017-02-21 20:25:25 +01:00
twinaphex 21ddee6690 Don't define M_PI if we are using MSVC and USE_MATH_DEFINES is
already defined
2017-02-21 20:14:19 +01:00
twinaphex c6e150ae2a Fix CXX_BUILD 2017-02-21 20:07:13 +01:00
twinaphex f8576ca88c Fix C89_BUILD again 2017-02-21 19:56:43 +01:00
Jean-André Santoni 1cccfa09fb (Menu) Fix core option ON/OFF buttons 2017-02-21 19:54:55 +01:00
twinaphex 63eafbcac2 Silence another signed/unsigned warning 2017-02-21 19:36:43 +01:00
twinaphex e3ddb75a2a signed/unsigned warning fix 2017-02-21 19:35:22 +01:00
twinaphex 1068e67032 Add pragma disable warning for MSVC 2010 2017-02-21 19:34:04 +01:00
twinaphex 40536fde63 Get rid of retroarch_fail() inside of load_dynamic 2017-02-21 19:20:50 +01:00
twinaphex 227b862cba Cleanups to task_load_content 2017-02-21 19:09:43 +01:00
twinaphex 85053cb210 Make it unneeded to have to grab settings pointer from
firmware_update_status
2017-02-21 19:06:08 +01:00
twinaphex c215fef8dd Updates 2017-02-21 18:58:03 +01:00
twinaphex f553f3f6bd Cut down on HAVE_MENU ifdefs 2017-02-21 18:55:11 +01:00
twinaphex d789013789 Cut down on some duplicate code 2017-02-21 18:51:47 +01:00
twinaphex 0789fff6df Rename load content tasks 2017-02-21 18:36:47 +01:00
Jean-André Santoni 460e28f7e5 (Lakka) Add a way to hide most settings with SD_FLAG_LAKKA_ADVANCED 2017-02-21 18:26:39 +01:00
twinaphex 873a07030f (Win32) Buildfix 2017-02-21 17:33:51 +01:00
Jean-André Santoni d0c640af7f (Lakka) Simplified quick menu with HAVE_LAKKA 2017-02-21 17:31:56 +01:00
Twinaphex 2d239779a5 (OSX) Buildfix 2017-02-21 17:30:18 +01:00
twinaphex d3e8e66b9f Create task_push_load_content_with_current_core_from_companion_ui 2017-02-21 17:29:30 +01:00
twinaphex 03948eafd3 Create task_push_start_builtin_core 2017-02-21 17:22:04 +01:00
twinaphex 9087bc82a0 Add TODO/FIXME note 2017-02-21 17:02:37 +01:00
twinaphex 8206a751f0 Create task_push_load_content_from_cli 2017-02-21 16:59:48 +01:00
twinaphex 1ec7b79ad6 Rename another task 2017-02-21 16:53:02 +01:00
twinaphex d0e49a2d8f Rename some tasks 2017-02-21 16:50:39 +01:00
twinaphex d7fda3016e Update 2017-02-21 16:33:22 +01:00
twinaphex d74f1a56f3 Create load_content_with_new_core_from_companion_ui 2017-02-21 16:30:47 +01:00
twinaphex 4bbf2ab535 Cleanups 2017-02-21 16:11:54 +01:00
Jean-André Santoni b648f459c4 (Lakka) Move Menu Settings out of UI Settings if HAVE_LAKKA. Avoid deep settings. 2017-02-21 15:30:45 +01:00
Jean-André Santoni 8d188ff013 (Lakka) Fix display of Download Content with HAVE_LAKKA 2017-02-21 15:11:25 +01:00
Jean-André Santoni af54ca3547 (Lakka) Hide Download Core 2017-02-21 15:08:40 +01:00
twinaphex 36f5504375 Cleanup 2017-02-21 06:37:42 +01:00
twinaphex fc8063b334 Update CHANGES.md 2017-02-21 06:04:48 +01:00
Twinaphex eebc239348 Merge pull request #4678 from hizzlekizzle/master
(Vulkan) add bokeh menu shader for vulkan
2017-02-21 06:02:22 +01:00
hunterk a1124b8ded (Vulkan) add bokeh menu shader for vulkan 2017-02-20 22:59:05 -06:00
Twinaphex c6d255ef63 Merge pull request #4677 from GregorR/netplay-nat-traversal-task-3
Properly conditionalize NAT traversal task on HAVE_NETWORKING
2017-02-21 05:50:03 +01:00
twinaphex 81949ae2fe (task_content.c) Cleanups 2017-02-21 05:31:34 +01:00
Gregor Richards 631586b0b7 Properly conditionalize NAT traversal task on HAVE_NETWORKING 2017-02-20 23:27:50 -05:00
twinaphex a7592c2db7 Create task_load_content_callback function 2017-02-21 05:17:07 +01:00
twinaphex 0e24e2a9ef Cleanup 2017-02-21 05:07:53 +01:00
twinaphex 14297ef0d9 Cleanups 2017-02-21 04:50:26 +01:00
twinaphex b6fcc0dfac Cleanups 2017-02-21 04:47:01 +01:00
twinaphex 0a3cc7da52 Cleanups 2017-02-21 04:43:08 +01:00
twinaphex 409a7769c6 Cleanup task_push_content_load_default 2017-02-21 04:40:57 +01:00
twinaphex 1582a47bb9 Create task_push_content_load_new_content_with_new_core_from_menu 2017-02-21 04:31:03 +01:00
twinaphex f80064e0a3 Cleanup task_push_content_load_default 2017-02-21 04:18:51 +01:00
twinaphex 90b9cf2d46 Cleanups 2017-02-21 04:11:46 +01:00
twinaphex 0b5118423d Create task_push_content_load_nothing_with_new_core_from_menu 2017-02-21 04:07:40 +01:00
twinaphex e075ade748 Cleanups 2017-02-21 03:55:42 +01:00
twinaphex cca72126f2 Create task_push_content_load_nothing_with_current_core_from_menu 2017-02-21 03:54:34 +01:00
twinaphex 96210188b0 Create task_push_content_load_content_from_playlist_from_menu 2017-02-21 03:44:36 +01:00
twinaphex ba16bee5d1 Create task_push_content_load_nothing_with_dummy_core 2017-02-21 03:32:52 +01:00
Twinaphex 91ed01dbcc Merge pull request #4676 from GregorR/netplay-nat-traversal-task-2
Fix race condition in NAT traversal task.
2017-02-21 02:18:43 +01:00
Gregor Richards 972b41f803 Fix race condition in NAT traversal task. 2017-02-20 20:16:53 -05:00
Twinaphex ef5b8046f0 Merge pull request #4675 from GregorR/netplay-nat-traversal-task
Moving NAT traversal into a task to avoid blocking the UI.
2017-02-21 01:44:28 +01:00
Gregor Richards 5f723d1bda Moving NAT traversal into a task to avoid blocking the UI. 2017-02-20 19:08:31 -05:00
twinaphex 28e8b6090c Add to CHANGES.md 2017-02-20 23:57:11 +01:00
Jean-André Santoni b700a4e77b (CoreText) Fix loading fonts from a path 2017-02-20 23:11:40 +01:00
twinaphex b42fdf3bdc Add to CHANGES.md 2017-02-20 21:54:17 +01:00
twinaphex 4fb3315091 Change to 6 * 2 2017-02-20 21:52:49 +01:00
twinaphex 0d873b6da1 (Vulkan) Add fancy snow for Vulkan 2017-02-20 21:51:58 +01:00
twinaphex 962149ef63 (Vulkan) Add pipeline_snow 2017-02-20 21:25:40 +01:00
Twinaphex 9964f8e717 Merge pull request #4674 from Themaister/master
Vulkan: Simple snow pipeline works.
2017-02-20 20:56:46 +01:00
Hans-Kristian Arntzen 2d88530c98 Vulkan: Simple snow pipeline works.
Some other fixes too.
2017-02-20 20:53:59 +01:00
hunterk 43569c254c more French translation work 2017-02-20 10:48:58 -06:00
Twinaphex 24b28e59c8 Merge pull request #4672 from rootfather/intl-de
intl: Translate the new Netplay settings to German
2017-02-20 15:07:34 +01:00
rootfather 093916abfe intl: Translate the new Netplay settings to German
This adds translations for the new Netplay settings (Spectator Mode)
to the German GUI translation.
2017-02-20 10:58:48 +01:00
twinaphex bb542332dc scaler_ctx_gen_reset - get rid of memsets 2017-02-20 06:48:32 +01:00
twinaphex 712724e0ff (archive_file.c) Get rid of memsets 2017-02-20 02:12:39 +01:00
twinaphex af8f0eb9b2 (file_list.c) file_list_add - get rid of memset 2017-02-20 02:01:17 +01:00
twinaphex aaaba64f81 Get rid of memsets in materialui.c 2017-02-20 01:59:08 +01:00
twinaphex 90d6466d56 (configuration.c) Get rid of another memset 2017-02-20 01:53:53 +01:00
twinaphex b15698e6d2 string_list - get rid of memset 2017-02-20 01:50:35 +01:00
dankcushions 67a311a76b game_specific_options defaults to true and would need some specific test cases for them to be turned off 2017-02-19 22:35:30 +00:00
Twinaphex b59e015b8b Merge pull request #4670 from dankcushions/patch-2
Default game_specific_options to true.
2017-02-19 21:34:37 +01:00
dankcushions f05da5c0e1 Default game_specific_options to true.
This is the core-option overrides functionality. If the user hasn't created any override files, they won't be used. Seems to me like there's no harm in defaulting this to on.
2017-02-19 18:54:35 +00:00
twinaphex 7ee65bfe5d (libretro-db) Get rid of some memsets 2017-02-19 19:44:45 +01:00
twinaphex 3cfaf47637 Avoid 'variable may be used uninitialized in this function' warnings 2017-02-19 18:59:02 +01:00
Andrés 342be9a594 Merge pull request #4669 from fr500/master
fix no playlists + no content edge case
2017-02-19 11:58:30 -05:00
radius f33b6bc226 fix no playlists + no content edge case 2017-02-19 11:58:09 -05:00
aliaspider 0d945a81d7 stb_unicode: use the same unicode handling code as the freetype
renderer, which supports codepoints > 0xFFFF.
2017-02-19 14:40:05 +01:00
twinaphex 75188800b1 Use C comments 2017-02-19 04:37:40 +01:00
Twinaphex e51cfce8e3 Merge pull request #4666 from diablodiab/android-mouse-support
Android input driver mouse support fixes
2017-02-19 03:01:44 +01:00
Diablodiab 2cbd1898e8 Android input driver mouse support fixes:
- Fix bug with cursor moving down to the right
- Remove handling of "copy" and "thread" input states simplifying the driver
2017-02-19 02:57:28 +01:00
bparker06 0231585d06 Merge pull request #4665 from fr500/master
fix #4663
2017-02-18 20:41:58 -05:00
radius e980577531 fix #4663 2017-02-18 20:10:37 -05:00
twinaphex d1aff197b9 Cleanup netplay_lan_scan_callback 2017-02-18 22:12:41 +01:00
twinaphex 5576115389 Make natt_open_port a static function 2017-02-18 22:03:02 +01:00
twinaphex e6ee2527e5 Add filestream_get_size/filestream_set_size 2017-02-18 02:21:33 +01:00
twinaphex e9524f1b95 Add filestream_get_ext 2017-02-18 02:16:40 +01:00
Twinaphex acb20e2d28 Merge pull request #4658 from mcrisostomo/master
New translation file
2017-02-18 00:27:56 +01:00
Twinaphex cd3a58224f Merge pull request #4659 from aliaspider/master
(WiiU) use the TV resolution instead of the gamepad resolution for
2017-02-18 00:27:36 +01:00
mcrisostomo cb1aab93db New file
Added new file containing the portuguese translation of RetroArch texts
2017-02-17 11:12:42 -03:00
mcrisostomo 85478b8fc8 Reversing previous commit 2017-02-17 11:11:29 -03:00
aliaspider 461d6ed3e0 (WiiU) use the TV resolution instead of the gamepad resolution for
viewport settings. fixes #4655
2017-02-17 15:06:48 +01:00
mcrisostomo 5a74bbb0b3 New translation file
Added new file containing the portuguese translation of RetroArch texts
2017-02-17 11:01:20 -03:00
twinaphex 7a5ed7cc65 Add filestream_flush and use filestream interface for tasks/task_save.c 2017-02-17 03:03:18 +01:00
twinaphex 4964892e59 (movie.c) Simplify code 2017-02-17 02:53:40 +01:00
twinaphex ba4d57ba70 (movie.c) Cleanups 2017-02-17 02:37:12 +01:00
Twinaphex 7030c64bde Merge pull request #4656 from GregorR/ranetplayer
Adding ranetplayer netplay regression testing tool
2017-02-17 02:07:33 +01:00
Gregor Richards 0955667f0d Adding ranetplayer netplay regression testing tool 2017-02-16 19:59:40 -05:00
Twinaphex 5974acc3c7 Merge pull request #4653 from diablodiab/android-mouse-support
Android input driver - add middle mouse button and lightgun support
2017-02-17 01:21:55 +01:00
Twinaphex 139d2d65d7 Merge pull request #4654 from GregorR/netplay-start-as-spectator
Re-adding the option to start in spectator mode
2017-02-17 01:21:45 +01:00
Gregor Richards 816d7786ac Re-adding the option to start in spectator mode
This used to be a configuration option because spectator mode and "net"
mode were incompatible. When the ability to switch between player and
spectator was added, the configuration option was removed, since it was
no longer a mode toggle. This re-adds it, mainly so that I can use it to
implement regression tests.
2017-02-16 19:17:06 -05:00
Diablodiab 47d5242dd7 Add middle mouse button support to Android input driver
Add lightgun support to Android input driver
2017-02-16 21:52:52 +01:00
Andrés 8114ce70d2 Merge pull request #4650 from fr500/master
Better console behavior
2017-02-15 23:59:51 -05:00
radius 742e45c6eb attach to console if present, spawn our own otherwise 2017-02-15 22:25:17 -05:00
radius 4db257c104 allow console to work again 2017-02-15 21:09:27 -05:00
Brad Parker abc7da4c87 miniupnpc: fix include dir for linux, fix setsockopt warning on windows 2017-02-15 20:23:12 -05:00
twinaphex 5d8c191df7 Cleanup 2017-02-16 01:30:50 +01:00
twinaphex 91f2cd0b95 Fix this up 2017-02-16 01:10:45 +01:00
neville 4b63ef3123 (OSX PPC) MiniUPNPC support 2017-02-16 01:09:39 +01:00
Twinaphex c6502e9f2d Can't set this to 'yes' by default - certain platforms wouldn't
have this library
2017-02-16 01:06:06 +01:00
twinaphex da5966d474 Bake this in for default targets 2017-02-16 01:00:43 +01:00
twinaphex b3d71320bc Add miniupnpc to Android 2017-02-16 00:59:32 +01:00
Twinaphex 18f614ef8a Add MiniUPNPC to iOS build 2017-02-16 00:57:18 +01:00
Twinaphex 5f78d0594c Enable MiniUPNPC for OSX 2017-02-16 00:50:47 +01:00
Twinaphex 417cf09967 Merge branch 'master' of https://github.com/libretro/RetroArch 2017-02-16 00:45:36 +01:00
Twinaphex a51b751814 Merge pull request #4648 from leiradel/master
Fix for when net_http_get returns NET_HTTP_GET_OK but a NULL body
2017-02-16 00:38:36 +01:00
Twinaphex 37b2ebfcaa Merge pull request #4649 from fr500/master
Check if this string is null before trying to copy it
2017-02-16 00:36:27 +01:00
radius 14c1d48c66 update changelog 2017-02-15 18:26:18 -05:00
radius f00dd6f7c4 update changelog & copyright 2017-02-15 18:25:21 -05:00
radius 3a6c7b96fd prevent null check 2017-02-15 18:15:42 -05:00
Andre Leiradella 1b2685949a Fix for when net_http_get returns NET_HTTP_GET_OK but a NULL body 2017-02-15 21:30:47 +00:00
Twinaphex 37baccab99 Merge pull request #4647 from GregorR/netplay-reset
Support for reset in netplay
2017-02-15 21:40:42 +01:00
twinaphex db4b757843 Add missing file 2017-02-15 21:06:16 +01:00
twinaphex cd1b95220a Add miniupnpc dependency which can be optionally compiled in 2017-02-15 21:03:57 +01:00
Gregor Richards 4c1abfaa71 Support for reset in netplay
This patch transfers core_reset across netplay. Resets effectively
worked before thanks to check_frames, but this makes resets work even
without check_frames, and in particular should allow resets to force
sync in savestateless cores, bringing them one step closer to actually
being usable by non-experts.
2017-02-15 14:40:37 -05:00
Twinaphex d0b29f3d8e Merge pull request #4646 from dankcushions/patch-1
Change to advanced settings: auto_remaps_enable & auto_overrides_enable
2017-02-15 18:59:43 +01:00
dankcushions 6309b21252 Change to advanced settings: auto_remaps_enable & auto_overrides_enable
There seems to be no reason to show these options as they default to true and there's no reason to disable them unless you were debugging something (and even then...)

Maybe even remove the option entirely?
2017-02-15 15:15:09 +00:00
twinaphex 8da9acd1fe Rename variable 2017-02-15 12:03:25 +01:00
Twinaphex f84b6e9020 Merge pull request #4645 from fr500/master
Fix #4644
2017-02-15 11:49:45 +01:00
Twinaphex 604b49f7d3 Merge pull request #4640 from diablodiab/android-mouse-support
Add external mouse support and touch screen mouse emulation to Android input driver
2017-02-15 11:48:53 +01:00
radius 71b397902a better variable name 2017-02-15 01:42:44 -05:00
radius a67935404d fix logging to file 2017-02-15 01:40:04 -05:00
Diablodiab 4f039cac22 This adds external mouse support to the Android input driver. It also adds support for using the touch screen as mouse in cores with mouse support (eg. ScummVM).
It has been tested with the ScummVM core on:
- NVIDIA Shield TV running Android Nougat 7.0
- NVIDIA Shield Tablet running Android Nougat 7.0
- NVIDIA Shield Tablet running Android Lollipop 5.1
- Huawei Honor 7 running Android Marshmallow 6.0
- HTC Desire 500 running Android Jelly Bean 4.1

It's been tested using the touch screen, a USB mouse/keyboard combo, and a bluetooth mouse.

The Android version running on the device limits the functionality and user experience of the external mouse support.
Android Nougat and/or an NVIDIA SHIELD device with NVIDIA extensions provides the best user experience:

Android API < 14:
- Only left mouse button supported
- The Android mouse cursor will be visible along with the in game mouse cursor
- When the Android mouse cursor hits the edge of the screen it will not be possible to move the in-game mouse cursor further in that direction

Android API < 24 and no NVIDIA extensions available:
- Both left and right mouse buttons supported
- The Android mouse cursor will be visible along with the in game mouse cursor
- When the Android mouse cursor hits the edge of the screen it will not be possible to move the in-game mouse cursor further in that direction

Android API > 23 and/or NVIDIA extensions available (SHIELD devices):
- Both left and right mouse buttons supported
- The Android mouse cursor will be hidden
- The mouse is not limited by the (hidden) Android mouse cursor hitting the edge of the screen

Description of how the the touchscreen mouse support works:
- You can move the in-game mouse cursor using the touch screen. The in-game mouse cursor will move relative to your movements on the touch screen, it will not be centered on where you press the screen.
- One quick tap on the touch screen results in the left mouse button being clicked
- Two taps on the screen and keeping the second tap pressed down results in a left mouse being held down until you release
- Two fingers on the touch screen results in the right mouse button being clicked

The touch screen mouse functionality is active at the same time as overlay support. This might cause some confusion when using cores that are designed for mouse support but where you have also enabled overlay controls. At the top of android_input.c there's a define that can be used to turn off this functionality if it causes more problems than it solves.
2017-02-14 22:34:46 +01:00
Brad Parker d8e38bedf0 fix heap corruption in core info extension list 2017-02-14 13:50:42 -05:00
Twinaphex a624e617ed Merge pull request #4639 from bparker06/9slice
add 9-slice texture draw function and selectable texture filter type
2017-02-14 17:16:38 +01:00
Brad Parker 75a96b10bb add 9-slice texture draw function and selectable texture filter type 2017-02-14 11:04:21 -05:00
Twinaphex e05a8a7460 Add HAVE_SEGA 2017-02-14 10:30:28 +01:00
Brad Parker 8aa8d6ff6b MSVC2005: add winmm.lib to linker, needed by rthreads changes in f4c187e 2017-02-14 02:39:26 +00:00
Brad Parker 6d821132f5 msvc buildfix 2017-02-14 02:37:25 +00:00
Andrés a8f2f94bf6 Merge pull request #4637 from pedrib/patch-1
Fix dualshock 3 detection bug
2017-02-13 19:50:29 -05:00
Pedro Ribeiro 6659c6af3a Fix dualshock 3 detection bug 2017-02-13 21:52:53 +00:00
Brad Parker 91ebcc0680 revert 6e969d0, but need to investigate if the original change to string_is_equal is valid 2017-02-13 15:37:34 -05:00
Brad Parker 6e969d0bc6 should be !string_is_equal 2017-02-13 15:12:04 -05:00
twinaphex 0143b537a8 Avoid warnings 2017-02-13 20:24:27 +01:00
twinaphex 07881d9f4f Buildfix 2017-02-13 19:11:32 +01:00
Twinaphex b52bdeb038 Merge pull request #4634 from hizzlekizzle/master
More French fixes
2017-02-13 19:01:29 +01:00
hizzlekizzle 04904c5c9e whoops, double-quotes typoed in. 2017-02-13 11:48:43 -06:00
hizzlekizzle 854fd3f1f9 More French fixes
Courtesy of forum user Tromzy, once again. Much appreciated!
2017-02-13 11:33:11 -06:00
Twinaphex ab7ac777d7 Merge pull request #4628 from rootfather/intl-de
Finish the rewrite of the German translation
2017-02-13 17:52:11 +01:00
Twinaphex 31c65140c4 Merge pull request #4631 from hizzlekizzle/master
French remap save and load had the same word (charger)
2017-02-13 17:52:01 +01:00
Twinaphex 4241e4fedb Merge pull request #4632 from Themaister/master
Vulkan: Find supported composite alpha in swapchain.
2017-02-13 17:51:41 +01:00
Hans-Kristian Arntzen 6395907887 Vulkan: Find supported composite alpha in swapchain. 2017-02-13 16:30:02 +01:00
hizzlekizzle 31a62a63f6 Remap save and load had the same word (charger)
Thanks to forum user Tromzy for the heads-up!
2017-02-13 09:22:15 -06:00
rootfather b5c87b68f8 Claim copyright for msg_hash_de.c 2017-02-13 15:12:03 +01:00
rootfather c8f3c15cf5 Finish the rewrite of the German translation 2017-02-13 13:27:40 +01:00
Twinaphex d7ff3c809f Merge pull request #4627 from fr500/master
fix #4625
2017-02-13 12:48:06 +01:00
radius 28deb34742 fix #4625 2017-02-13 01:24:48 -05:00
Twinaphex 66c3599019 Merge pull request #4622 from rootfather/intl-de
Add some more strings to German translation
2017-02-12 23:44:31 +01:00
rootfather 672add6cab Add some more strings to German translation 2017-02-12 22:32:24 +01:00
Twinaphex e9cbde3188 Merge pull request #4621 from vanfanel/master
DISPMANX: Disable triple buffering for now, for stability reasons.
2017-02-12 19:36:01 +01:00
vanfanel 0b75671c21 DISPMANX: Disable triple buffering for now, for stability reasons. 2017-02-12 19:27:59 +01:00
Andrés 89244d0e58 Merge pull request #4620 from leiradel/master
Only compile support for leaderboards if CHEEVOS_ENABLE_LBOARDS is de…
2017-02-12 12:02:50 -05:00
Andre Leiradella 4fc758799f Only compile support for leaderboards if CHEEVOS_ENABLE_LBOARDS is defined 2017-02-12 16:18:32 +00:00
Twinaphex 55de1ff8c6 Merge pull request #4619 from diablodiab/android-ui-parameters
Add two new UI specific extras to Android version
2017-02-12 14:59:02 +01:00
Diablodiab 77e479a8bc Adds two new parameters that can be passed to the Android version of Retroarch at launch:
QUITFOCUS
If enabled this will cause Retroarch to quit completely when it loses focus (eg. when the home button is pressed). This is useful when you are using an alternative launcher such as Kodi because it will make the home button function as an alternative quit key, return to the alternative launcher, and then allow for a different game to start instead of returning to the current session.

HIDEMOUSE
Normally it is not possible to hide the mouse cursor if you have attached an external mouse to your Android unit. This makes it difficult to implement mouse support in the Android version of Retroarch because you will end up having two mouse cursors on the screen. NVIDIA has implemented extensions on the SHIELD that allows for hiding the mouse cursor. If this parameter is provided when starting Retroarch it will check for these extensions and if available it will hide the mouse cursor.

(I am almost done with adding mouse support to the Android input driver and will be submitting a suggestion for this very soon)
2017-02-12 13:26:18 +01:00
Twinaphex 66ff3db2e2 Merge pull request #4618 from rootfather/intl-de
Add more strings to the German translation
2017-02-12 11:34:13 +01:00
rootfather af7c346e23 Fix typo in the German translation 2017-02-11 23:10:29 +01:00
rootfather e0cbce96c5 Add more strings to the German translation 2017-02-11 22:15:25 +01:00
Twinaphex 640dca71cf Merge pull request #4617 from fr500/master
Changelog
2017-02-11 21:03:43 +01:00
radius 8783d92f23 update changelog 2017-02-11 14:45:11 -05:00
radius 0f1943259e add changelog 2017-02-11 14:43:28 -05:00
Twinaphex 7a79ee68d9 Merge pull request #4612 from fr500/master
Fix #3807
2017-02-11 16:37:59 +01:00
radius 9e09b28f50 Merge branch 'master' of github.com:fr500/RetroArch 2017-02-11 00:01:41 -05:00
radius 5ea570c978 add zip and 7z always to the list of supported extensions 2017-02-10 23:58:58 -05:00
radius 0c5fe1dd79 add zip and 7z always to the list of supported extensions 2017-02-10 23:58:40 -05:00
Twinaphex 25a29a4e0a Merge pull request #4609 from rootfather/intl-de
Add some more strings to German translation
2017-02-10 22:26:02 +01:00
rootfather b2f4359234 Add some more strings to German translation 2017-02-10 20:08:55 +01:00
Brad Parker 8e6df5fe85 MSVC buildfix 2017-02-09 23:54:35 -05:00
Andrés 754b7326f3 Merge pull request #4607 from fr500/master
fix crashes when trying to connect with contentless cores
2017-02-09 21:23:57 -05:00
radius cd17927990 fix contentless netplay! thanks Gregor 2017-02-09 21:22:52 -05:00
radius a33778cb87 fix crashes when trying to connect with contentless cores 2017-02-09 21:10:40 -05:00
aliaspider d1b93741d7 Merge pull request #4605 from xhp-creations/master
WiiU Fix Keyboard Input
2017-02-09 20:11:47 +01:00
xhp-creations b04bf809e3 WiiU Fix Keyboard Input
WiiU Fix Keyboard Input
2017-02-09 14:08:27 -05:00
aliaspider f0e45e970c Merge pull request #4602 from xhp-creations/master
WiiU Initial Keyboard Support
2017-02-09 18:52:06 +01:00
xhp-creations 4915f452f5 WiiU Initial Keyboard Support
WiiU Initial Keyboard Support
2017-02-09 12:34:12 -05:00
Twinaphex a0379f0598 Merge pull request #4600 from rootfather/intl-de
Rewrite German translation (Part 2.9)
2017-02-09 14:02:13 +01:00
rootfather 1c2e97b0c1 Rewrite German translation (Part 2.9) 2017-02-09 12:21:30 +01:00
Twinaphex bd40dd3ec2 Merge pull request #4597 from nadenislamarre/batocera-sdl2-blink
sdl2 renderer: remove the random flashing black borders
2017-02-08 22:57:57 +01:00
Nicolas Adenis-Lamarre 9993435cf9 sdl2 renderer: remove the random flashing black borders
on the batocera linux distribution (https://github.com/nadenislamarre/batocera.linux),
retroarch gives some flashing black borders sometimes when running a game.
It looks like sometimes the rendering is done without clearing the screen causing
this flashing effect.

Signed-off-by: Nicolas Adenis-Lamarre <[email protected]>
2017-02-08 22:31:26 +01:00
Twinaphex 8d2bafb279 Merge pull request #4596 from leiradel/master
Fixed crash in cheevos_get_description
2017-02-08 21:43:53 +01:00
Andre Leiradella 3785fc4524 Fixed crash in cheevos_get_description 2017-02-08 19:45:01 +00:00
Twinaphex bd8ecd9dfd Merge pull request #4595 from libretro/revert-4592-fix/robloach/battery-clock-scale
Revert "Allow normal Battery/Clock icon sizes [WIP]"
2017-02-08 20:02:33 +01:00
Twinaphex 962cf6b076 Revert "Allow normal Battery/Clock icon sizes [WIP]" 2017-02-08 20:02:26 +01:00
Twinaphex 890f28ae71 Merge pull request #4592 from RobLoach/fix/robloach/battery-clock-scale
Allow normal Battery/Clock icon sizes [WIP]
2017-02-08 19:57:08 +01:00
Twinaphex 90aa5ef8a5 Merge pull request #4585 from micochops/master
Updated a few more menu sublabels
2017-02-08 09:08:55 +01:00
Brad Parker 373535f329 DOS: improve color accuracy and scaling, thanks to aliaspider 2017-02-08 00:17:12 -05:00
Twinaphex 35f8ed82a0 Merge pull request #4584 from rootfather/intl-de
Rewrite German translation (part 2.1/fixes)
2017-02-08 05:15:54 +01:00
Mico Chopitea 0617262cd2 removed ifdef 2017-02-08 11:06:14 +08:00
Rob Loach 1ef482d6df Apply icon scaling to the battery and clock icons 2017-02-07 21:48:18 -05:00
Mico Chopitea 452c3529a8 Updated a few more menu sublabels 2017-02-07 23:11:08 +08:00
rootfather c3701783b1 Rewrite German translation (part 2.1/fixes)
Improve consistency and fix some errors.
Intermediate release in preparation of part 3.
2017-02-07 12:32:28 +01:00
Twinaphex a2141e61f7 Merge pull request #4582 from micochops/master
Updated menu sublabels and others
2017-02-07 08:03:15 +01:00
Mico Chopitea 46797c982b Updated menu sublabels and others 2017-02-07 14:39:17 +08:00
Twinaphex 98003ecf5d Merge pull request #4581 from fr500/master
Autoconf fallback for android
2017-02-07 06:20:46 +01:00
radius ee6d76e932 fix message 2017-02-07 00:12:30 -05:00
radius c9015aa9ba attempt autoconf fallback for android 2017-02-07 00:12:30 -05:00
Twinaphex ddeaf2c893 Merge pull request #4576 from rootfather/intl-de
Rewrite German translation (part 2)
2017-02-07 03:52:16 +01:00
Andrés 8005970842 Merge pull request #4579 from GregorR/netplay-private
Make announcing netplay on the public lobby optional
2017-02-06 13:48:02 -05:00
Gregor Richards aa77d688ec Make announcing netplay on the public lobby optional. 2017-02-06 13:45:58 -05:00
rootfather e98fac2046 Rewrite German translation (part 2) 2017-02-06 11:45:27 +01:00
twinaphex 593d1ff7b5 Update Chinese 2017-02-06 05:56:33 +01:00
twinaphex 959b1c4b13 Revert "Update Chinese"
This reverts commit c7297d41b2.
2017-02-06 05:56:01 +01:00
twinaphex c7297d41b2 Update Chinese 2017-02-06 05:55:25 +01:00
Twinaphex 9158573fda Merge pull request #4570 from rootfather/intl-de
Rewrite German translation (part 1)
2017-02-06 05:54:08 +01:00
Twinaphex cea6945963 Merge pull request #4571 from leiradel/master
Added preliminary support for Retro Achievements leaderboards
2017-02-06 05:53:33 +01:00
twinaphex 52d46dcaf4 Fix another relative include 2017-02-06 05:51:51 +01:00
twinaphex 6e5b7c3a7b Fix relative includes 2017-02-06 05:51:28 +01:00
Brad Parker 0bdcdac2da DOS: scale menu frame to fit screen 2017-02-05 15:23:38 -05:00
Brad Parker 83619b25e6 DOS: add keyboard driver to support non-joypad keys 2017-02-05 13:55:21 -05:00
Andre Leiradella bfcb8227f5 Fix typpo; parse constant values in leaderboards 2017-02-05 17:00:07 +00:00
Andre Leiradella b5153ced9d Make leaderboard term multipliers signed; mark leaderboards explicitly in log messages 2017-02-05 16:39:14 +00:00
Andre Leiradella 6b9ba1e2b1 Added preliminary support for Retro Achievements leaderboards 2017-02-05 16:23:13 +00:00
rootfather c866a3f1a8 Remove leftover pragma 2017-02-05 16:49:09 +01:00
rootfather a56a825dfb Rewrite German translation (part 1) 2017-02-05 16:12:06 +01:00
Alcaro fa341f03a0 Thing 2017-02-05 14:13:30 +01:00
twinaphex 0383d20465 Revert "Revert "Merge lakka patch for DRM""
This reverts commit 4e0ed3d3d6.
2017-02-05 11:06:51 +01:00
twinaphex 4e0ed3d3d6 Revert "Merge lakka patch for DRM"
This reverts commit 207ebe5e59.
2017-02-05 11:05:55 +01:00
twinaphex e6102fed35 Revert "Don't make AUDIO_DEVICE an 'advanced' option"
This reverts commit c1e08c1138.
2017-02-05 11:05:05 +01:00
twinaphex c1e08c1138 Don't make AUDIO_DEVICE an 'advanced' option 2017-02-05 06:59:23 +01:00
twinaphex e95f797307 Try to stay under max. 80-char width limit 2017-02-05 06:01:22 +01:00
twinaphex e99ba9a06a Cleanups 2017-02-05 05:47:15 +01:00
twinaphex df962d5898 Silence warnings 2017-02-05 05:45:08 +01:00
Alcaro 7d30b475ba Merge pull request #4392 from zeromus/master
rthreads work from desmume
2017-02-05 02:12:31 +01:00
zeromus 0ef09a0ed4 win32 scond_wait_timeout: refine 0 timeout logic 2017-02-04 16:24:14 -06:00
Brad Parker 38bfed4a93 revert retroarch.cfg overwrite 2017-02-04 14:01:57 -05:00
twinaphex b3cd6f13a5 Fix ./configure --disable-rgui 2017-02-04 09:22:17 +01:00
twinaphex e3a1b1859d Fix ./configure --disable-rgui 2017-02-04 09:20:41 +01:00
twinaphex a06380e9ca Fix ./configure --enable-python 2017-02-04 09:01:02 +01:00
zeromus 233c13228e attempt win32 scond_wait_timeout 2017-02-03 21:52:52 -06:00
Twinaphex f1b63bddbe Merge pull request #4559 from leiradel/master
Moved cheevos files to their own folder in preparation for the change…
2017-02-03 19:14:30 +01:00
Andre Leiradella 0c8ee93e3e Moved cheevos files to their own folder in preparation for the changes to support leaderboards 2017-02-03 10:03:57 +00:00
Twinaphex 49cb7789f7 Merge pull request #4557 from RobLoach/sublabel-information
Update sublabel for Information
2017-02-03 08:18:25 +01:00
Rob Loach 92eac10560 Update sublabel for Information 2017-02-02 20:21:24 -05:00
Twinaphex 74d29c4b40 Merge pull request #4556 from RobLoach/sublabel-network
Update the sublabel for Network
2017-02-03 02:19:20 +01:00
Rob Loach 30f8505647 Update Network sublabel 2017-02-02 20:14:00 -05:00
Twinaphex ba98ecd081 Merge pull request #4554 from JuanVCS/master
Workaround for manual netplay content loading
2017-02-02 23:24:40 +01:00
Juan 2c721a478c Workaround for manual netplay content loading 2017-02-02 16:32:01 -03:00
zeromus 168de31fb9 make scond_signal slightly more pthreads compliant (and other tidying). re: PR #4392 2017-01-21 22:44:31 -06:00
zeromus 3e8e02c953 change the main lock mutex to a critical section, and update copyrights year 2017-01-21 17:10:09 -06:00
zeromus 10157c5831 apply feedback re: PR #4392 2017-01-21 16:49:10 -06:00
zeromus f4c187e980 - port slock and scond fixes from desmume
- make sthread_isself return false for null test thread
full disclosure: this work was done months ago. I can't be 100% sure I've merged it correctly with recent rthreads.c changes
2017-01-09 16:46:35 -06:00
315 changed files with 46330 additions and 6518 deletions

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
# 1.5.0 (future)
- MOBILE: Single-tap for menu entry selection
- MOBILE: Long-tap a setting to reset to default
- ANDROID: Autoconf fallback
- ANDROID: Mouse support / Emulated mouse support
- AUTOCONF: Fix partial matches for pad name
- CHEEVOS: Fix crashes in the cheevos description menu
- CHEEVOS: WIP leaderboards support
- COMMON: Threading fixes
- COMMON: 9-slice texture drawing support
- CORETEXT/APPLE: Ability to load menu display font drivers and loading of custom font.
- DOS: Add keyboard driver
- DOS: Improve color accuracy and scaling
- GUI: Various settings are now only visible when advanced settings is enabled
- GUI: Allow changing icon theme on the fly
- GUI: Add a symbol page in the OSK
- GUI: Better dialogs for XMB
- LOCALIZATION: Add/update Korean translation
- LOCALIZATION: Rewrite German translation
- LOCALIZATION: Update several English sublabels
- LOCALIZATION: Update several Japanese labels
- NET: Allow manual netplay content loading
- NET: Announcing network games to the public lobby is optional now
- NET: Bake in miniupnpc
- NET: Fix netplay join for contentless cores
- NET: Lan games show next to lobbies with (lan) and connect via the private IP address
- NET: Use new lobby system with MITM support
- NET: Fix netplay rooms being pushed on the wrong tab
- NUKLEAR: Update to current version
- SCANNER: Always add 7z & zip to supported extensions
- VULKAN: Find supported composite alpha in swapchain
- VULKAN: Add snow/bokeh shader pipeline effects - at parity with GL now
- WIIU: Keyboard support
- WINDOWS: Logging to file no longer spawns an empty window
- WINDOWS: Fix loading of core/content via file menu
# 1.4.1
+1 -1
View File
@@ -28,7 +28,7 @@ ifneq ($(findstring DOS,$(OS)),)
endif
ifneq ($(findstring Win32,$(OS)),)
LDFLAGS += -static-libgcc
LDFLAGS += -static-libgcc -lwinmm
endif
include Makefile.common
+32 -7
View File
@@ -186,6 +186,7 @@ OBJ += frontend/frontend.o \
file_path_str.o \
$(LIBRETRO_COMM_DIR)/hash/rhash.o \
audio/audio_driver.o \
audio/audio_mixer.o \
input/input_driver.o \
gfx/video_coord_array.o \
gfx/video_driver.o \
@@ -198,6 +199,7 @@ OBJ += frontend/frontend.o \
dynamic.o \
cores/dynamic_dummy.o \
$(LIBRETRO_COMM_DIR)/queues/message_queue.o \
managers/core_manager.o \
managers/state_manager.o \
gfx/drivers_font_renderer/bitmapfont.o \
tasks/task_autodetect.o \
@@ -264,6 +266,7 @@ OBJ += intl/msg_hash_de.o \
intl/msg_hash_fr.o \
intl/msg_hash_it.o \
intl/msg_hash_ja.o \
intl/msg_hash_ko.o \
intl/msg_hash_nl.o \
intl/msg_hash_pl.o \
intl/msg_hash_pt.o \
@@ -451,9 +454,9 @@ ifeq ($(HAVE_NEON),1)
endif
OBJ += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float.o \
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.o \
$(LIBRETRO_COMM_DIR)/audio/audio_mix.o \
$(LIBRETRO_COMM_DIR)/formats/wav/rwav.o
$(LIBRETRO_COMM_DIR)/audio/conversion/float_to_s16.o \
$(LIBRETRO_COMM_DIR)/audio/audio_mix.o \
$(LIBRETRO_COMM_DIR)/formats/wav/rwav.o
ifeq ($(HAVE_NEON),1)
OBJ += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float_neon.o \
@@ -1114,6 +1117,7 @@ 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/image_transfer.o
ifdef HAVE_COMPRESSION
@@ -1165,6 +1169,7 @@ ifeq ($(HAVE_NETWORKING), 1)
network/net_http_special.o \
tasks/task_http.o \
tasks/task_netplay_lan_scan.o \
tasks/task_netplay_nat_traversal.o \
tasks/task_wifi.o \
tasks/task_netplay_find_content.o
@@ -1190,14 +1195,15 @@ ifeq ($(HAVE_NETWORKING), 1)
network/netplay/netplay_io.o \
network/netplay/netplay_sync.o \
network/netplay/netplay_discovery.o \
network/netplay/netplay_buf.o
network/netplay/netplay_buf.o \
network/netplay/netplay_room_parse.o
# Retro Achievements (also depends on threads)
ifeq ($(HAVE_CHEEVOS), 1)
ifeq ($(HAVE_THREADS), 1)
DEFINES += -DHAVE_CHEEVOS
OBJ += cheevos.o \
OBJ += cheevos/cheevos.o \
$(LIBRETRO_COMM_DIR)/utils/md5.o
endif
endif
@@ -1208,7 +1214,26 @@ ifeq ($(HAVE_NETWORKING), 1)
endif
ifeq ($(HAVE_MINIUPNPC), 1)
LIBS += -lminiupnpc
ifeq ($(HAVE_BUILTINMINIUPNPC), 1)
DEFINES += -DHAVE_BUILTINMINIUPNPC -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR
DEFINES += -I$(DEPS_DIR)
OBJ += \
$(DEPS_DIR)/miniupnpc/igd_desc_parse.o \
$(DEPS_DIR)/miniupnpc/upnpreplyparse.o \
$(DEPS_DIR)/miniupnpc/upnpcommands.o \
$(DEPS_DIR)/miniupnpc/upnperrors.o \
$(DEPS_DIR)/miniupnpc/connecthostport.o \
$(DEPS_DIR)/miniupnpc/portlistingparse.o \
$(DEPS_DIR)/miniupnpc/receivedata.o \
$(DEPS_DIR)/miniupnpc/upnpdev.o \
$(DEPS_DIR)/miniupnpc/minissdpc.o \
$(DEPS_DIR)/miniupnpc/miniwget.o \
$(DEPS_DIR)/miniupnpc/miniupnpc.o \
$(DEPS_DIR)/miniupnpc/minixml.o \
$(DEPS_DIR)/miniupnpc/minisoap.o
else
LIBS += -lminiupnpc
endif
endif
endif
@@ -1273,7 +1298,7 @@ endif
ifneq ($(findstring DOS,$(OS)),)
OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o \
input/drivers/dos_input.o input/drivers_joypad/dos_joypad.o \
frontend/drivers/platform_dos.o
frontend/drivers/platform_dos.o input/drivers_keyboard/keyboard_event_dos.o
ifeq ($(HAVE_MENU_COMMON), 1)
OBJ += menu/drivers_display/menu_display_vga.o
+10 -9
View File
@@ -31,6 +31,7 @@
#endif
#include "audio_driver.h"
#include "audio_mixer.h"
#include "audio_thread_wrapper.h"
#include "../record/record_driver.h"
#include "../frontend/frontend_driver.h"
@@ -165,7 +166,7 @@ static void compute_audio_buffer_statistics(void)
unsigned low_water_count = 0;
unsigned high_water_count = 0;
unsigned samples = MIN(
audio_driver_free_samples_count,
(unsigned)audio_driver_free_samples_count,
AUDIO_BUFFER_FREE_SAMPLES_COUNT);
if (samples < 3)
@@ -174,7 +175,7 @@ static void compute_audio_buffer_statistics(void)
for (i = 1; i < samples; i++)
accum += audio_driver_free_samples_buf[i];
avg = accum / (samples - 1);
avg = (unsigned)accum / (samples - 1);
for (i = 1; i < samples; i++)
{
@@ -186,8 +187,8 @@ static void compute_audio_buffer_statistics(void)
avg_filled = 1.0f - (float)avg / audio_driver_buffer_size;
deviation = (float)stddev / audio_driver_buffer_size;
low_water_size = audio_driver_buffer_size * 3 / 4;
high_water_size = audio_driver_buffer_size / 4;
low_water_size = (unsigned)(audio_driver_buffer_size * 3 / 4);
high_water_size = (unsigned)(audio_driver_buffer_size / 4);
for (i = 1; i < samples; i++)
{
@@ -554,7 +555,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
dsp_data.output_frames = 0;
dsp_data.input = audio_driver_input_data;
dsp_data.input_frames = samples >> 1;
dsp_data.input_frames = (unsigned)(samples >> 1);
performance_counter_init(audio_dsp, "audio_dsp");
performance_counter_start_plus(is_perfcnt_enable, audio_dsp);
@@ -575,9 +576,9 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
/* Readjust the audio input rate. */
unsigned write_idx = audio_driver_free_samples_count++ &
(AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1);
int half_size = audio_driver_buffer_size / 2;
int half_size = (int)(audio_driver_buffer_size / 2);
int avail =
current_audio->write_avail(audio_driver_context_audio_data);
(int)current_audio->write_avail(audio_driver_context_audio_data);
int delta_mid = avail - half_size;
double direction = (double)delta_mid / half_size;
double adjust = 1.0 + settings->audio.rate_control_delta * direction;
@@ -610,7 +611,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples)
performance_counter_stop_plus(is_perfcnt_enable, resampler_proc);
output_data = audio_driver_output_samples_buf;
output_frames = src_data.output_frames;
output_frames = (unsigned)src_data.output_frames;
if (!audio_driver_use_float)
{
@@ -816,7 +817,7 @@ bool audio_driver_find_driver(void)
driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);
i = drv.len;
i = (int)drv.len;
if (i >= 0)
current_audio = (const audio_driver_t*)audio_driver_find_handle(i);
+595
View File
@@ -0,0 +1,595 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2017 - Andre Leiradella
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "audio_mixer.h"
#include "audio_driver.h"
#include <audio/audio_resampler.h>
#include <streams/file_stream.h>
#include <formats/rwav.h>
#include <memalign.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef HAVE_STB_VORBIS
#define STB_VORBIS_NO_PUSHDATA_API
#define STB_VORBIS_NO_STDIO
#define STB_VORBIS_NO_CRT
#include "../deps/stb/stb_vorbis.h"
#endif
#define AUDIO_MIXER_MAX_VOICES 8
#define AUDIO_MIXER_TEMP_OGG_BUFFER 8192
#define AUDIO_MIXER_TYPE_NONE 0
#define AUDIO_MIXER_TYPE_WAV 1
#define AUDIO_MIXER_TYPE_OGG 2
struct audio_mixer_sound_t
{
unsigned type;
union
{
struct
{
/* wav */
unsigned frames;
const float* pcm;
} wav;
#ifdef HAVE_STB_VORBIS
struct
{
/* ogg */
unsigned size;
const void* data;
} ogg;
#endif
} types;
};
struct audio_mixer_voice_t
{
unsigned type;
bool repeat;
float volume;
audio_mixer_sound_t* sound;
audio_mixer_stop_cb_t stop_cb;
union
{
struct
{
/* wav */
unsigned position;
} wav;
#ifdef HAVE_STB_VORBIS
struct
{
/* ogg */
unsigned position;
unsigned samples;
stb_vorbis* stream;
float* buffer;
unsigned buf_samples;
void* resampler_data;
float ratio;
const retro_resampler_t* resampler;
} ogg;
#endif
} types;
};
static audio_mixer_voice_t s_voices[AUDIO_MIXER_MAX_VOICES];
static unsigned s_rate = 0;
static bool wav2float(const rwav_t* wav, float** pcm, size_t* samples_out)
{
size_t i;
float sample = 0.0f;
const uint8_t* u8 = NULL;
const int16_t* s16 = NULL;
float* f = NULL;
/* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes */
*samples_out = wav->numsamples * 2;
f = (float*)memalign_alloc(16,
((*samples_out + 15) & ~15) * sizeof(float));
if (!f)
return false;
*pcm = f;
if (wav->numchannels == 1)
{
if (wav->bitspersample == 8)
{
u8 = (const uint8_t*)wav->samples;
for (i = wav->numsamples; i != 0; i--)
{
sample = (float)*u8++ / 255.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
*f++ = sample;
}
}
else
{
s16 = (const int16_t*)wav->samples;
for (i = wav->numsamples; i != 0; i--)
{
sample = (float)((int)*s16++ + 32768) / 65535.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
*f++ = sample;
}
}
}
else if (wav->numchannels == 2)
{
if (wav->bitspersample == 8)
{
u8 = (const uint8_t*)wav->samples;
for (i = wav->numsamples; i != 0; i--)
{
sample = (float)*u8++ / 255.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
sample = (float)*u8++ / 255.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
}
}
else
{
s16 = (const int16_t*)wav->samples;
for (i = wav->numsamples; i != 0; i--)
{
sample = (float)((int)*s16++ + 32768) / 65535.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
sample = (float)((int)*s16++ + 32768) / 65535.0f;
sample = sample * 2.0f - 1.0f;
*f++ = sample;
}
}
}
return true;
}
static bool one_shot_resample(const float* in, size_t samples_in,
unsigned rate, float** out, size_t* samples_out)
{
struct resampler_data info;
void* data = NULL;
const retro_resampler_t* resampler = NULL;
float ratio = (double)s_rate / (double)rate;
if (!retro_resampler_realloc(&data, &resampler, NULL, ratio))
return false;
/*
* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We
* add four more samples in the formula below just as safeguard, because
* resampler->process sometimes reports more output samples than the
* formula below calculates. Ideally, audio resamplers should have a
* function to return the number of samples they will output given a
* count of input samples.
*/
*samples_out = samples_in * ratio + 4;
*out = (float*)memalign_alloc(16,
((*samples_out + 15) & ~15) * sizeof(float));
if (*out == NULL)
return false;
info.data_in = in;
info.data_out = *out;
info.input_frames = samples_in / 2;
info.output_frames = 0;
info.ratio = ratio;
resampler->process(data, &info);
resampler->free(data);
return true;
}
void audio_mixer_init(unsigned rate)
{
unsigned i;
s_rate = rate;
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
}
void audio_mixer_done(void)
{
unsigned i;
for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++)
s_voices[i].type = AUDIO_MIXER_TYPE_NONE;
}
audio_mixer_sound_t* audio_mixer_load_wav(const char* path)
{
/* WAV data */
rwav_t wav;
/* Raw WAV bytes */
void* buffer = NULL;
ssize_t size = 0;
/* WAV samples converted to float */
float* pcm = NULL;
float* resampled = NULL;
size_t samples = 0;
/* Result */
audio_mixer_sound_t* sound = NULL;
if (filestream_read_file(path, &buffer, &size) == 0)
return NULL;
if (rwav_load(&wav, buffer, size) != RWAV_ITERATE_DONE)
{
free(buffer);
return NULL;
}
free(buffer);
if (!wav2float(&wav, &pcm, &samples))
return NULL;
if (wav.samplerate != s_rate)
{
if (!one_shot_resample(pcm, samples,
wav.samplerate, &resampled, &samples))
return NULL;
memalign_free((void*)pcm);
pcm = resampled;
}
sound = (audio_mixer_sound_t*)malloc(sizeof(audio_mixer_sound_t));
if (!sound)
{
memalign_free((void*)pcm);
return NULL;
}
sound->type = AUDIO_MIXER_TYPE_WAV;
sound->types.wav.frames = (unsigned)(samples / 2);
sound->types.wav.pcm = pcm;
rwav_free(&wav);
return sound;
}
audio_mixer_sound_t* audio_mixer_load_ogg(const char* path)
{
#ifdef HAVE_STB_VORBIS
ssize_t size;
void* buffer = NULL;
audio_mixer_sound_t* sound = NULL;
if (filestream_read_file(path, &buffer, &size) == 0)
return NULL;
sound = (audio_mixer_sound_t*)malloc(sizeof(audio_mixer_sound_t));
if (!sound)
{
free(buffer);
return NULL;
}
sound->type = AUDIO_MIXER_TYPE_OGG;
sound->types.ogg.size = size;
sound->types.ogg.data = buffer;
return sound;
#else
return NULL;
#endif
}
void audio_mixer_destroy(audio_mixer_sound_t* sound)
{
switch (sound->type)
{
case AUDIO_MIXER_TYPE_WAV:
memalign_free((void*)sound->types.wav.pcm);
break;
case AUDIO_MIXER_TYPE_OGG:
#ifdef HAVE_STB_VORBIS
memalign_free((void*)sound->types.ogg.data);
#endif
break;
}
free(sound);
}
static bool audio_mixer_play_wav(audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice, bool repeat, float volume,
audio_mixer_stop_cb_t stop_cb)
{
voice->type = AUDIO_MIXER_TYPE_WAV;
voice->repeat = repeat;
voice->volume = volume;
voice->sound = sound;
voice->stop_cb = stop_cb;
voice->types.wav.position = 0;
return true;
}
#ifdef HAVE_STB_VORBIS
static bool audio_mixer_play_ogg(
audio_mixer_sound_t* sound,
audio_mixer_voice_t* voice,
bool repeat, float volume,
audio_mixer_stop_cb_t stop_cb)
{
stb_vorbis_info info;
int res = 0;
float ratio = 0.0f;
unsigned samples = 0;
voice->repeat = repeat;
voice->volume = volume;
voice->sound = sound;
voice->stop_cb = stop_cb;
voice->types.ogg.stream = stb_vorbis_open_memory(
(const unsigned char*)sound->types.ogg.data,
sound->types.ogg.size, &res, NULL);
if (!voice->types.ogg.stream)
return false;
info = stb_vorbis_get_info(voice->types.ogg.stream);
/* Only stereo supported for now */
if (info.channels != 2)
{
stb_vorbis_close(voice->types.ogg.stream);
return false;
}
if (info.sample_rate != s_rate)
{
voice->types.ogg.ratio = ratio = (double)s_rate / (double)info.sample_rate;
if (!retro_resampler_realloc(&voice->types.ogg.resampler_data,
&voice->types.ogg.resampler, NULL, ratio))
{
stb_vorbis_close(voice->types.ogg.stream);
return false;
}
}
samples =
voice->types.ogg.buf_samples = (unsigned)(AUDIO_MIXER_TEMP_OGG_BUFFER * ratio);
voice->types.ogg.buffer = (float*)memalign_alloc(16,
((samples + 15) & ~15) * sizeof(float));
if (!voice->types.ogg.buffer)
{
voice->types.ogg.resampler->free(voice->types.ogg.resampler_data);
stb_vorbis_close(voice->types.ogg.stream);
return false;
}
voice->type = AUDIO_MIXER_TYPE_OGG;
voice->types.ogg.position = voice->types.ogg.samples = 0;
return true;
}
#endif
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat,
float volume, audio_mixer_stop_cb_t stop_cb)
{
unsigned i;
audio_mixer_voice_t* voice = NULL;
bool res = false;
for (i = 0, voice = s_voices; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
{
if (voice->type == AUDIO_MIXER_TYPE_NONE)
{
switch (sound->type)
{
case AUDIO_MIXER_TYPE_WAV:
res = audio_mixer_play_wav(sound, voice, repeat, volume, stop_cb);
break;
case AUDIO_MIXER_TYPE_OGG:
#ifdef HAVE_STB_VORBIS
res = audio_mixer_play_ogg(sound, voice, repeat, volume, stop_cb);
#endif
break;
}
break;
}
}
if (res)
return voice;
return NULL;
}
void audio_mixer_stop(audio_mixer_voice_t* voice)
{
voice->stop_cb(voice, AUDIO_MIXER_SOUND_STOPPED);
}
static void mix_wav(float* buffer, size_t num_frames, audio_mixer_voice_t* voice)
{
int i;
unsigned buf_free = (unsigned)(num_frames * 2);
const audio_mixer_sound_t* sound = voice->sound;
unsigned pcm_available = sound->types.wav.frames
* 2 - voice->types.wav.position;
const float* pcm = sound->types.wav.pcm + voice->types.wav.position;
float volume = voice->volume;
again:
if (pcm_available < buf_free)
{
for (i = pcm_available; i != 0; i--)
*buffer++ += *pcm++ * volume;
if (voice->repeat)
{
if (voice->stop_cb)
voice->stop_cb(voice, AUDIO_MIXER_SOUND_REPEATED);
buf_free -= pcm_available;
pcm_available = sound->types.wav.frames * 2;
pcm = sound->types.wav.pcm;
voice->types.wav.position = 0;
goto again;
}
if (voice->stop_cb)
voice->stop_cb(voice, AUDIO_MIXER_SOUND_FINISHED);
voice->type = AUDIO_MIXER_TYPE_NONE;
}
else
{
for (i = buf_free; i != 0; i--)
*buffer++ += *pcm++ * volume;
voice->types.wav.position += buf_free;
}
}
#ifdef HAVE_STB_VORBIS
static void mix_ogg(float* buffer, size_t num_frames, audio_mixer_voice_t* voice)
{
int i;
float temp_buffer[AUDIO_MIXER_TEMP_OGG_BUFFER];
struct resampler_data info;
unsigned buf_free = num_frames * 2;
unsigned temp_samples = 0;
float volume = voice->volume;
float* pcm = NULL;
#if 0
const audio_mixer_sound_t* sound = voice->sound;
#endif
if (voice->types.ogg.position == voice->types.ogg.samples)
{
again:
temp_samples = stb_vorbis_get_samples_float_interleaved(
voice->types.ogg.stream, 2, temp_buffer,
AUDIO_MIXER_TEMP_OGG_BUFFER) * 2;
if (temp_samples == 0)
{
if (voice->repeat)
{
if (voice->stop_cb)
voice->stop_cb(voice, AUDIO_MIXER_SOUND_REPEATED);
stb_vorbis_seek_start(voice->types.ogg.stream);
goto again;
}
else
{
if (voice->stop_cb)
voice->stop_cb(voice, AUDIO_MIXER_SOUND_FINISHED);
voice->type = AUDIO_MIXER_TYPE_NONE;
return;
}
}
info.data_in = temp_buffer;
info.data_out = voice->types.ogg.buffer;
info.input_frames = temp_samples / 2;
info.output_frames = 0;
info.ratio = voice->types.ogg.ratio;
voice->types.ogg.resampler->process(voice->types.ogg.resampler_data, &info);
voice->types.ogg.position = 0;
voice->types.ogg.samples = voice->types.ogg.buf_samples;
}
pcm = voice->types.ogg.buffer + voice->types.ogg.position;
if (voice->types.ogg.samples < buf_free)
{
for (i = voice->types.ogg.samples; i != 0; i--)
*buffer++ += *pcm++ * volume;
buf_free -= voice->types.ogg.samples;
goto again;
}
else
{
int i;
for (i = buf_free; i != 0; --i )
*buffer++ += *pcm++ * volume;
voice->types.ogg.position += buf_free;
voice->types.ogg.samples -= buf_free;
}
}
#endif
void audio_mixer_mix(float* buffer, size_t num_frames)
{
unsigned i;
size_t j = 0;
float* sample = NULL;
audio_mixer_voice_t* voice = NULL;
for (i = 0, voice = s_voices; i < AUDIO_MIXER_MAX_VOICES; i++, voice++)
{
if (voice->type == AUDIO_MIXER_TYPE_WAV)
mix_wav(buffer, num_frames, voice);
#ifdef HAVE_STB_VORBIS
else if (voice->type == AUDIO_MIXER_TYPE_OGG)
mix_ogg(buffer, num_frames, voice);
#endif
}
for (j = 0, sample = buffer; j < num_frames; j++, sample++)
{
if (*sample < -1.0f)
*sample = -1.0f;
else if (*sample > 1.0f)
*sample = 1.0f;
}
}
+52
View File
@@ -0,0 +1,52 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2017 - Andre Leiradella
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __AUDIO_MIXER__H
#define __AUDIO_MIXER__H
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
#include <retro_common_api.h>
RETRO_BEGIN_DECLS
typedef struct audio_mixer_sound_t audio_mixer_sound_t;
typedef struct audio_mixer_voice_t audio_mixer_voice_t;
typedef void (*audio_mixer_stop_cb_t)(audio_mixer_voice_t* voice, unsigned reason);
/* Reasons passed to the stop callback. */
#define AUDIO_MIXER_SOUND_FINISHED 0
#define AUDIO_MIXER_SOUND_STOPPED 1
#define AUDIO_MIXER_SOUND_REPEATED 2
void audio_mixer_init(unsigned rate);
void audio_mixer_done(void);
audio_mixer_sound_t* audio_mixer_load_wav(const char* path);
audio_mixer_sound_t* audio_mixer_load_ogg(const char* path);
void audio_mixer_destroy(audio_mixer_sound_t* sound);
audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, float volume, audio_mixer_stop_cb_t stop_cb);
void audio_mixer_stop(audio_mixer_voice_t* voice);
void audio_mixer_mix(float* buffer, size_t num_frames);
RETRO_END_DECLS
#endif
+1 -1
View File
@@ -348,7 +348,7 @@ static void resampler_CC_upsample(void *re_, struct resampler_data *data)
}
#elif defined (__ARM_NEON__)
#elif defined (__ARM_NEON__) && !defined(DONT_WANT_ARM_OPTIMIZATIONS)
#define CC_RESAMPLER_IDENT "NEON"
+1 -1
View File
@@ -140,7 +140,7 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data)
driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv);
i = drv.len;
i = (int)drv.len;
if (i >= 0)
camera_driver = (const camera_driver_t*)camera_driver_find_handle(i);
+500 -55
View File
@@ -23,26 +23,28 @@
#include <libretro.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "../config.h"
#endif
#ifdef HAVE_MENU
#include "menu/menu_driver.h"
#include "menu/menu_entries.h"
#include "../menu/menu_driver.h"
#include "../menu/menu_entries.h"
#endif
#include "cheevos.h"
#include "command.h"
#include "dynamic.h"
#include "network/net_http_special.h"
#include "tasks/tasks_internal.h"
#include "configuration.h"
#include "performance_counters.h"
#include "msg_hash.h"
#include "runloop.h"
#include "core.h"
#include "verbosity.h"
#include "../command.h"
#include "../dynamic.h"
#include "../configuration.h"
#include "../performance_counters.h"
#include "../msg_hash.h"
#include "../runloop.h"
#include "../core.h"
#include "../network/net_http_special.h"
#include "../tasks/tasks_internal.h"
#include "../verbosity.h"
/* Define this macro to prevent cheevos from being deactivated. */
#undef CHEEVOS_DONT_DEACTIVATE
@@ -82,6 +84,9 @@
#define CHEEVOS_JSON_KEY_CONSOLE_ID 0x071656e5U
#define CHEEVOS_JSON_KEY_TOKEN 0x0e2dbd26U
#define CHEEVOS_JSON_KEY_FLAGS 0x0d2e96b2U
#define CHEEVOS_JSON_KEY_LEADERBOARDS 0xf1247d2dU
#define CHEEVOS_JSON_KEY_MEM 0x0b8807e4U
#define CHEEVOS_JSON_KEY_FORMAT 0xb341208eU
enum
{
@@ -241,9 +246,11 @@ typedef struct
typedef struct
{
int in_cheevos;
int in_lboards;
uint32_t field_hash;
unsigned core_count;
unsigned unofficial_count;
unsigned lboard_count;
} cheevos_countud_t;
typedef struct
@@ -255,13 +262,15 @@ typedef struct
typedef struct
{
int in_cheevos;
int in_lboards;
int is_console_id;
unsigned core_count;
unsigned unofficial_count;
unsigned lboard_count;
cheevos_field_t *field;
cheevos_field_t id, memaddr, title, desc, points, author;
cheevos_field_t modified, created, badge, flags;
cheevos_field_t modified, created, badge, flags, format;
} cheevos_readud_t;
typedef struct
@@ -271,6 +280,32 @@ typedef struct
const uint32_t *ext_hashes;
} cheevos_finder_t;
typedef struct
{
cheevos_var_t var;
int multiplier;
} cheevos_term_t;
typedef struct
{
cheevos_term_t *terms;
unsigned count;
} cheevos_expr_t;
typedef struct
{
unsigned id;
const char *title;
const char *description;
int active;
int last_value;
cheevos_condition_t start;
cheevos_condition_t cancel;
cheevos_condition_t submit;
cheevos_expr_t value;
} cheevos_leaderboard_t;
typedef struct
{
int console_id;
@@ -278,25 +313,34 @@ typedef struct
cheevoset_t core;
cheevoset_t unofficial;
cheevos_leaderboard_t *leaderboards;
unsigned lboard_count;
char token[32];
retro_ctx_memory_info_t meminfo[4];
} cheevos_locals_t;
static cheevos_locals_t cheevos_locals =
{
0,
true,
{NULL, 0},
{NULL, 0},
{0}
/* console_id */ 0,
/* core_supports */ true,
/* core */ {NULL, 0},
/* unofficial */ {NULL, 0},
/* leaderboards */ NULL,
/* lboard_count */ 0,
/* token */ {0},
{
/* meminfo[0] */ {NULL, 0, 0},
/* meminfo[1] */ {NULL, 0, 0},
/* meminfo[2] */ {NULL, 0, 0},
/* meminfo[3] */ {NULL, 0, 0}
}
};
bool cheevos_loaded = false;
int cheats_are_enabled = 0;
int cheats_were_enabled = 0;
bool cheevos_loaded = false;
int cheats_are_enabled = 0;
int cheats_were_enabled = 0;
/*****************************************************************************
Supporting functions.
@@ -405,6 +449,16 @@ static void cheevos_add_uint(char** aux, size_t* left, unsigned v)
cheevos_add_string(aux, left, buffer);
}
static void cheevos_add_int(char** aux, size_t* left, int v)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d", v);
buffer[sizeof(buffer) - 1] = 0;
cheevos_add_string(aux, left, buffer);
}
static void cheevos_log_var(const cheevos_var_t* var)
{
RARCH_LOG("CHEEVOS size: %s\n",
@@ -608,6 +662,43 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo)
cheevos_build_memaddr(&cheevo->condition, memaddr, sizeof(memaddr));
RARCH_LOG("CHEEVOS memaddr (computed): %s\n", memaddr);
}
static void cheevos_log_lboard(const cheevos_leaderboard_t* lb)
{
char mem[256];
char* aux;
size_t left;
unsigned i;
RARCH_LOG("CHEEVOS leaderboard %p\n", lb);
RARCH_LOG("CHEEVOS id: %u\n", lb->id);
RARCH_LOG("CHEEVOS title: %s\n", lb->title);
RARCH_LOG("CHEEVOS desc: %s\n", lb->description);
cheevos_build_memaddr(&lb->start, mem, sizeof(mem));
RARCH_LOG("CHEEVOS start: %s\n", mem);
cheevos_build_memaddr(&lb->cancel, mem, sizeof(mem));
RARCH_LOG("CHEEVOS cancel: %s\n", mem);
cheevos_build_memaddr(&lb->submit, mem, sizeof(mem));
RARCH_LOG("CHEEVOS submit: %s\n", mem);
left = sizeof(mem);
aux = mem;
for (i = 0; i < lb->value.count; i++)
{
if (i != 0)
cheevos_add_char(&aux, &left, '_');
cheevos_add_var(&lb->value.terms[i].var, &aux, &left);
cheevos_add_char(&aux, &left, '*');
cheevos_add_int(&aux, &left, lb->value.terms[i].multiplier);
}
RARCH_LOG("CHEEVOS value: %s\n", mem);
}
#endif
static uint32_t cheevos_djb2(const char* str, size_t length)
@@ -633,11 +724,19 @@ static int cheevos_http_get(const char **result, size_t *size,
int ret = net_http_get(result, size, url, timeout);
#endif
if (ret == NET_HTTP_GET_OK)
{
if (*result != NULL)
{
return ret;
}
RARCH_ERR("CHEEVOS error during HTTP GET: ok.\n");
return NET_HTTP_GET_CONNECT_ERROR;
}
switch (ret)
{
case NET_HTTP_GET_OK:
return ret;
case NET_HTTP_GET_MALFORMED_URL:
msg = "malformed url";
break;
@@ -651,11 +750,11 @@ static int cheevos_http_get(const char **result, size_t *size,
break;
default:
msg = "?";
msg = "unknown error";
break;
}
RARCH_ERR("CHEEVOS error getting %s: %s.\n", url, msg);
RARCH_ERR("CHEEVOS error during HTTP GET: %s.\n", msg);
return ret;
}
@@ -756,6 +855,7 @@ static int cheevos_count__json_end_array(void *userdata)
{
cheevos_countud_t* ud = (cheevos_countud_t*)userdata;
ud->in_cheevos = 0;
ud->in_lboards = 0;
return 0;
}
@@ -767,6 +867,8 @@ static int cheevos_count__json_key(void *userdata,
if (ud->field_hash == CHEEVOS_JSON_KEY_ACHIEVEMENTS)
ud->in_cheevos = 1;
else if (ud->field_hash == CHEEVOS_JSON_KEY_LEADERBOARDS)
ud->in_lboards = 1;
return 0;
}
@@ -785,12 +887,15 @@ static int cheevos_count__json_number(void *userdata,
else if (flags == 5)
ud->unofficial_count++; /* Unofficial achievements */
}
else if (ud->in_lboards && ud->field_hash == CHEEVOS_JSON_KEY_ID)
ud->lboard_count++;
return 0;
}
static int cheevos_count_cheevos(const char *json,
unsigned *core_count, unsigned *unofficial_count)
unsigned *core_count, unsigned *unofficial_count,
unsigned *lboard_count)
{
static const jsonsax_handlers_t handlers =
{
@@ -813,11 +918,13 @@ static int cheevos_count_cheevos(const char *json,
ud.in_cheevos = 0;
ud.core_count = 0;
ud.unofficial_count = 0;
ud.lboard_count = 0;
res = jsonsax_parse(json, &handlers, (void*)&ud);
*core_count = ud.core_count;
*unofficial_count = ud.unofficial_count;
*lboard_count = ud.lboard_count;
return res;
}
@@ -872,8 +979,8 @@ static unsigned cheevos_read_hits(const char **memaddr)
if (*str == '(' || *str == '.')
{
num_hits = strtol(str + 1, &end, 10);
str = end + 1;
num_hits = (unsigned)strtol(str + 1, &end, 10);
str = end + 1;
}
*memaddr = str;
@@ -1002,8 +1109,8 @@ void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value)
{
if (((desc->core.start ^ var->value) & desc->core.select) == 0)
{
var->bank_id = desc - system->mmaps.descriptors;
var->value = cheevos_reduce(
var->bank_id = (int)(desc - system->mmaps.descriptors);
var->value = (unsigned)cheevos_reduce(
(var->value - desc->core.start) & desc->disconnect_mask,
desc->core.disconnect);
@@ -1061,7 +1168,12 @@ static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr)
if (toupper(*str) == 'H')
str++;
else
{
if (toupper(*str) == 'V')
str++;
base = 10;
}
}
if (var->type != CHEEVOS_VAR_TYPE_VALUE_COMP)
@@ -1072,7 +1184,7 @@ static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr)
str++;
}
var->value = strtol(str, &end, base);
var->value = (unsigned)strtol(str, &end, base);
*memaddr = end;
switch (var->type)
@@ -1256,6 +1368,117 @@ static int cheevos_parse_condition(cheevos_condition_t *condition, const char* m
return 0;
}
#ifdef CHEEVOS_ENABLE_LBOARDS
static void cheevos_free_condition(cheevos_condition_t* condition)
{
unsigned i;
if (condition->condsets)
{
for (i = 0; i < condition->count; i++)
{
free((void*)condition->condsets[i].conds);
}
free((void*)condition->condsets);
}
}
#endif
/*****************************************************************************
Parse the Mem field of leaderboards.
*****************************************************************************/
#ifdef CHEEVOS_ENABLE_LBOARDS
static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem)
{
const char* aux;
char* end;
unsigned i;
expr->count = 1;
for (aux = mem; *aux != '"'; aux++)
{
expr->count += *aux == '_';
}
expr->terms = (cheevos_term_t*)calloc(expr->count, sizeof(cheevos_term_t));
if (!expr->terms)
return -1;
for (i = 0, aux = mem; i < expr->count; i++)
{
cheevos_parse_var(&expr->terms[i].var, &aux);
if (*aux != '*')
{
free((void*)expr->terms);
return -1;
}
expr->terms[i].multiplier = (int)strtol(aux + 1, &end, 10);
aux = end + 1;
}
return 0;
}
#endif
#ifdef CHEEVOS_ENABLE_LBOARDS
static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem)
{
lb->start.condsets = NULL;
lb->cancel.condsets = NULL;
lb->submit.condsets = NULL;
lb->value.terms = NULL;
for (;;)
{
if (*mem == 'S' && mem[1] == 'T' && mem[2] == 'A' && mem[3] == ':')
{
if (cheevos_parse_condition(&lb->start, mem + 4))
goto error;
}
else if (*mem == 'C' && mem[1] == 'A' && mem[2] == 'N' && mem[3] == ':')
{
if (cheevos_parse_condition(&lb->cancel, mem + 4))
goto error;
}
else if (*mem == 'S' && mem[1] == 'U' && mem[2] == 'B' && mem[3] == ':')
{
if (cheevos_parse_condition(&lb->submit, mem + 4))
goto error;
}
else if (*mem == 'V' && mem[1] == 'A' && mem[2] == 'L' && mem[3] == ':')
{
if (cheevos_parse_expression(&lb->value, mem + 4))
goto error;
}
else
goto error;
for (mem += 4;; mem++)
{
if (*mem == ':' && mem[1] == ':')
{
mem += 2;
break;
}
else if (*mem == '"')
return 0;
}
}
error:
cheevos_free_condition(&lb->start);
cheevos_free_condition(&lb->cancel);
cheevos_free_condition(&lb->submit);
free((void*)lb->value.terms);
return -1;
}
#endif
/*****************************************************************************
Load achievements from a JSON string.
*****************************************************************************/
@@ -1282,12 +1505,12 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud)
else
cheevo = cheevos_locals.unofficial.cheevos + ud->unofficial_count++;
cheevo->id = strtol(ud->id.string, NULL, 10);
cheevo->id = (unsigned)strtol(ud->id.string, NULL, 10);
cheevo->title = cheevos_dupstr(&ud->title);
cheevo->description = cheevos_dupstr(&ud->desc);
cheevo->author = cheevos_dupstr(&ud->author);
cheevo->badge = cheevos_dupstr(&ud->badge);
cheevo->points = strtol(ud->points.string, NULL, 10);
cheevo->points = (unsigned)strtol(ud->points.string, NULL, 10);
cheevo->dirty = 0;
cheevo->active = CHEEVOS_ACTIVE_SOFTCORE | CHEEVOS_ACTIVE_HARDCORE;
cheevo->last = 1;
@@ -1317,11 +1540,40 @@ error:
return -1;
}
#ifdef CHEEVOS_ENABLE_LBOARDS
static int cheevos_new_lboard(cheevos_readud_t *ud)
{
cheevos_leaderboard_t *lboard = cheevos_locals.leaderboards + ud->lboard_count++;
lboard->id = strtol(ud->id.string, NULL, 10);
lboard->title = cheevos_dupstr(&ud->title);
lboard->description = cheevos_dupstr(&ud->desc);
if (!lboard->title || !lboard->description)
goto error;
if (cheevos_parse_mem(lboard, ud->memaddr.string))
goto error;
#ifdef CHEEVOS_VERBOSE
cheevos_log_lboard(lboard);
#endif
return 0;
error:
free((void*)lboard->title);
free((void*)lboard->description);
return -1;
}
#endif
static int cheevos_read__json_key( void *userdata,
const char *name, size_t length)
{
cheevos_readud_t *ud = (cheevos_readud_t*)userdata;
uint32_t hash = cheevos_djb2(name, length);
int common = ud->in_cheevos || ud->in_lboards;
ud->field = NULL;
@@ -1330,23 +1582,30 @@ static int cheevos_read__json_key( void *userdata,
case CHEEVOS_JSON_KEY_ACHIEVEMENTS:
ud->in_cheevos = 1;
break;
case CHEEVOS_JSON_KEY_LEADERBOARDS:
ud->in_lboards = 1;
break;
case CHEEVOS_JSON_KEY_CONSOLE_ID:
ud->is_console_id = 1;
break;
case CHEEVOS_JSON_KEY_ID:
if (ud->in_cheevos)
if (common)
ud->field = &ud->id;
break;
case CHEEVOS_JSON_KEY_MEMADDR:
if (ud->in_cheevos)
ud->field = &ud->memaddr;
break;
case CHEEVOS_JSON_KEY_MEM:
if (ud->in_lboards)
ud->field = &ud->memaddr;
break;
case CHEEVOS_JSON_KEY_TITLE:
if (ud->in_cheevos)
if (common)
ud->field = &ud->title;
break;
case CHEEVOS_JSON_KEY_DESCRIPTION:
if (ud->in_cheevos)
if (common)
ud->field = &ud->desc;
break;
case CHEEVOS_JSON_KEY_POINTS:
@@ -1373,6 +1632,10 @@ static int cheevos_read__json_key( void *userdata,
if (ud->in_cheevos)
ud->field = &ud->flags;
break;
case CHEEVOS_JSON_KEY_FORMAT:
if (ud->in_lboards)
ud->field = &ud->format;
break;
default:
break;
}
@@ -1406,7 +1669,7 @@ static int cheevos_read__json_number(void *userdata,
}
else if (ud->is_console_id)
{
cheevos_locals.console_id = strtol(number, NULL, 10);
cheevos_locals.console_id = (int)strtol(number, NULL, 10);
ud->is_console_id = 0;
}
@@ -1419,6 +1682,10 @@ static int cheevos_read__json_end_object(void *userdata)
if (ud->in_cheevos)
return cheevos_new_cheevo(ud);
#ifdef CHEEVOS_ENABLE_LBOARDS
else if (ud->in_lboards)
return cheevos_new_lboard(ud);
#endif
return 0;
}
@@ -1427,6 +1694,7 @@ static int cheevos_read__json_end_array(void *userdata)
{
cheevos_readud_t *ud = (cheevos_readud_t*)userdata;
ud->in_cheevos = 0;
ud->in_lboards = 0;
return 0;
}
@@ -1448,7 +1716,7 @@ static int cheevos_parse(const char *json)
NULL
};
unsigned core_count, unofficial_count;
unsigned core_count, unofficial_count, lboard_count;
int res;
cheevos_readud_t ud;
settings_t *settings = config_get_ptr();
@@ -1458,7 +1726,8 @@ static int cheevos_parse(const char *json)
return 0;
/* Count the number of achievements in the JSON file. */
res = cheevos_count_cheevos(json, &core_count, &unofficial_count);
res = cheevos_count_cheevos(json, &core_count, &unofficial_count,
&lboard_count);
if (res != JSONSAX_OK)
return -1;
@@ -1473,21 +1742,30 @@ static int cheevos_parse(const char *json)
calloc(unofficial_count, sizeof(cheevo_t));
cheevos_locals.unofficial.count = unofficial_count;
if (!cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos)
cheevos_locals.leaderboards = (cheevos_leaderboard_t*)
calloc(lboard_count, sizeof(cheevos_leaderboard_t));
cheevos_locals.lboard_count = lboard_count;
if ( !cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos
|| !cheevos_locals.leaderboards)
{
free((void*)cheevos_locals.core.cheevos);
free((void*)cheevos_locals.unofficial.cheevos);
cheevos_locals.core.count = cheevos_locals.unofficial.count = 0;
free((void*)cheevos_locals.leaderboards);
cheevos_locals.core.count = cheevos_locals.unofficial.count =
cheevos_locals.lboard_count = 0;
return -1;
}
/* Load the achievements. */
ud.in_cheevos = 0;
ud.in_lboards = 0;
ud.is_console_id = 0;
ud.field = NULL;
ud.core_count = 0;
ud.unofficial_count = 0;
ud.lboard_count = 0;
if (jsonsax_parse(json, &handlers, (void*)&ud) != JSONSAX_OK)
goto error;
@@ -1535,7 +1813,6 @@ static unsigned cheevos_get_var_value(cheevos_var_t *var)
if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS
|| var->type == CHEEVOS_VAR_TYPE_DELTA_MEM)
{
/* TODO Check with Scott if the bank id is needed */
const uint8_t *memory = cheevos_get_memory(var);
unsigned live_val = 0;
@@ -1950,6 +2227,162 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set)
}
}
#ifdef CHEEVOS_ENABLE_LBOARDS
static int cheevos_test_lboard_condition(const cheevos_condition_t* condition)
{
int dirty_conds = 0;
int reset_conds = 0;
int ret_val = 0;
int ret_val_sub_cond = condition->count == 1;
cheevos_condset_t *condset = condition->condsets;
const cheevos_condset_t *end = condset + condition->count;
if (condset < end)
{
ret_val = cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0);
condset++;
}
while (condset < end)
{
ret_val_sub_cond |= cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0);
condset++;
}
if (reset_conds)
{
for (condset = condition->condsets; condset < end; condset++)
cheevos_reset_cond_set(condset, 0);
}
return ret_val && ret_val_sub_cond;
}
static int cheevos_expr_value(cheevos_expr_t* expr)
{
cheevos_term_t* term = expr->terms;
unsigned i;
int value = 0;
for (i = expr->count; i != 0; i--, term++)
{
value += cheevos_get_var_value(&term->var) * term->multiplier;
}
return value;
}
static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard,
char* url, size_t url_size)
{
settings_t *settings = config_get_ptr();
char signature[64];
MD5_CTX ctx;
uint8_t hash[16];
hash[0] = '\0';
snprintf(signature, sizeof(signature), "%u%s%u", lboard->id,
settings->cheevos.username, lboard->id);
MD5_Init(&ctx);
MD5_Update(&ctx, (void*)signature, strlen(signature));
MD5_Final(hash, &ctx);
snprintf(
url, url_size,
"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",
settings->cheevos.username, cheevos_locals.token, lboard->id,
lboard->last_value,
hash[ 0], hash[ 1], hash[ 2], hash[ 3],
hash[ 4], hash[ 5], hash[ 6], hash[ 7],
hash[ 8], hash[ 9], hash[10], hash[11],
hash[12], hash[13], hash[14], hash[15]
);
url[url_size - 1] = 0;
#ifdef CHEEVOS_LOG_URLS
cheevos_log_url("CHEEVOS url to submit the leaderboard: %s\n", url);
#endif
}
#endif
#ifdef CHEEVOS_ENABLE_LBOARDS
static void cheevos_lboard_submit(void *task_data, void *user_data, const char *error)
{
cheevos_leaderboard_t *lboard = (cheevos_leaderboard_t *)user_data;
if (error == NULL)
{
RARCH_LOG("CHEEVOS submitted leaderboard %u.\n", lboard->id);
}
else
RARCH_ERR("CHEEVOS error submitting leaderboard %u\n", lboard->id);
#if 0
{
char url[256];
url[0] = '\0';
RARCH_ERR("CHEEVOS error submitting leaderboard %u, retrying...\n", lboard->id);
cheevos_make_lboard_url(lboard, url, sizeof(url));
task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard);
}
#endif
}
#endif
#ifdef CHEEVOS_ENABLE_LBOARDS
static void cheevos_test_leaderboards(void)
{
cheevos_leaderboard_t* lboard = cheevos_locals.leaderboards;
unsigned i;
for (i = cheevos_locals.lboard_count; i != 0; i--, lboard++)
{
if (lboard->active)
{
int value = cheevos_expr_value(&lboard->value);
if (value != lboard->last_value)
{
#ifdef CHEEVOS_VERBOSE
RARCH_LOG("CHEEVOS value lboard %s %u\n", lboard->title, value);
#endif
lboard->last_value = value;
}
if (cheevos_test_lboard_condition(&lboard->submit))
{
char url[256];
cheevos_make_lboard_url(lboard, url, sizeof(url));
task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard);
RARCH_LOG("CHEEVOS submit lboard %s\n", lboard->title);
}
if (cheevos_test_lboard_condition(&lboard->cancel))
{
RARCH_LOG("CHEEVOS cancel lboard %s\n", lboard->title);
lboard->active = 0;
}
}
else
{
if (cheevos_test_lboard_condition(&lboard->start))
{
RARCH_LOG("CHEEVOS start lboard %s\n", lboard->title);
lboard->active = 1;
lboard->last_value = -1;
}
}
}
}
#endif
/*****************************************************************************
Free the loaded achievements.
*****************************************************************************/
@@ -2065,7 +2498,7 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout)
if (!res)
{
RARCH_LOG("CHEEVOS got game id %s.\n", game_id);
return strtoul(game_id, NULL, 10);
return (unsigned)strtoul(game_id, NULL, 10);
}
}
@@ -2698,13 +3131,17 @@ void cheevos_reset_game(void)
const cheevo_t *end = cheevo + cheevos_locals.core.count;
for (; cheevo < end; cheevo++)
{
cheevo->last = 1;
}
cheevo = cheevos_locals.unofficial.cheevos;
end = cheevo + cheevos_locals.unofficial.count;
for (; cheevo < end; cheevo++)
{
cheevo->last = 1;
}
}
void cheevos_populate_menu(void *data, bool hardcore)
@@ -2814,15 +3251,23 @@ void cheevos_populate_menu(void *data, bool hardcore)
bool cheevos_get_description(cheevos_ctx_desc_t *desc)
{
cheevo_t *cheevos = cheevos_locals.core.cheevos;
if (desc->idx >= cheevos_locals.core.count)
if (cheevos_loaded)
{
cheevos = cheevos_locals.unofficial.cheevos;
desc->idx -= cheevos_locals.unofficial.count;
}
cheevo_t *cheevos = cheevos_locals.core.cheevos;
strlcpy(desc->s, cheevos[desc->idx].description, desc->len);
if (desc->idx >= cheevos_locals.core.count)
{
cheevos = cheevos_locals.unofficial.cheevos;
desc->idx -= cheevos_locals.unofficial.count;
}
strlcpy(desc->s, cheevos[desc->idx].description, desc->len);
}
else
{
*desc->s = 0;
}
return true;
}
@@ -2842,7 +3287,7 @@ bool cheevos_unload(void)
cheevos_free_cheevo_set(&cheevos_locals.core);
cheevos_free_cheevo_set(&cheevos_locals.unofficial);
cheevos_loaded = false;
cheevos_loaded = 0;
return true;
}
@@ -2881,7 +3326,7 @@ void cheevos_test(void)
if (settings->cheevos.test_unofficial)
cheevos_test_cheevo_set(&cheevos_locals.unofficial);
#if 0
#ifdef CHEEVOS_ENABLE_LBOARDS
cheevos_test_leaderboards();
#endif
}
View File
File renamed without changes.
+26 -28
View File
@@ -43,7 +43,7 @@
#endif
#ifdef HAVE_CHEEVOS
#include "cheevos.h"
#include "cheevos/cheevos.h"
#endif
#ifdef HAVE_MENU
@@ -1315,7 +1315,7 @@ static void command_event_set_savestate_auto_index(void)
while ((end > dir_elem) && isdigit((int)end[-1]))
end--;
idx = strtoul(end, NULL, 0);
idx = (unsigned)strtoul(end, NULL, 0);
if (idx > max_idx)
max_idx = idx;
}
@@ -1350,15 +1350,6 @@ static bool event_init_content(void)
content_get_status(&contentless, &is_inited);
if (contentless)
{
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL))
RARCH_ERR("%s\n", msg_hash_to_str(MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY));
#endif
return true;
}
command_event_set_savestate_auto_index();
if (event_load_save_files())
@@ -1630,7 +1621,10 @@ static void command_event_save_current_config(enum override_type type)
switch (type)
{
case OVERRIDE_NONE:
if (!path_is_empty(RARCH_PATH_CONFIG))
if (path_is_empty(RARCH_PATH_CONFIG))
strlcpy(msg, "Config directory not set, cannot save configuration.",
sizeof(msg));
else
command_event_save_config(path_get(RARCH_PATH_CONFIG), msg, sizeof(msg));
break;
case OVERRIDE_GAME:
@@ -1697,11 +1691,12 @@ static void command_event_undo_load_state(char *s, size_t len)
msg_hash_to_str(MSG_UNDID_LOAD_STATE), len);
}
static void command_event_main_state(unsigned cmd)
static bool command_event_main_state(unsigned cmd)
{
retro_ctx_size_info_t info;
char path[PATH_MAX_LENGTH];
char msg[128];
bool ret = false;
global_t *global = global_get_ptr();
bool push_msg = true;
@@ -1729,11 +1724,13 @@ static void command_event_main_state(unsigned cmd)
{
case CMD_EVENT_SAVE_STATE:
content_save_state(path, true, false);
ret = true;
push_msg = false;
break;
case CMD_EVENT_LOAD_STATE:
if (content_load_state(path, false, false))
{
ret = true;
#ifdef HAVE_NETWORKING
netplay_driver_ctl(RARCH_NETPLAY_CTL_LOAD_SAVESTATE, NULL);
#endif
@@ -1742,9 +1739,11 @@ static void command_event_main_state(unsigned cmd)
break;
case CMD_EVENT_UNDO_LOAD_STATE:
command_event_undo_load_state(msg, sizeof(msg));
ret = true;
break;
case CMD_EVENT_UNDO_SAVE_STATE:
command_event_undo_save_state(msg, sizeof(msg));
ret = true;
break;
}
}
@@ -1755,6 +1754,8 @@ static void command_event_main_state(unsigned cmd)
if (push_msg)
runloop_msg_queue_push(msg, 2, 180, true);
RARCH_LOG("%s\n", msg);
return ret;
}
void handle_quit_event(void)
@@ -1895,15 +1896,13 @@ bool command_event(enum event_command cmd, void *data)
return false;
#endif
command_event_main_state(cmd);
return command_event_main_state(cmd);
}
break;
case CMD_EVENT_UNDO_LOAD_STATE:
command_event_main_state(cmd);
break;
return command_event_main_state(cmd);
case CMD_EVENT_UNDO_SAVE_STATE:
command_event_main_state(cmd);
break;
return command_event_main_state(cmd);
case CMD_EVENT_RESIZE_WINDOWED_SCALE:
return command_event_resize_windowed_scale();
case CMD_EVENT_MENU_TOGGLE:
@@ -1927,6 +1926,9 @@ bool command_event(enum event_command cmd, void *data)
core_reset();
#ifdef HAVE_CHEEVOS
cheevos_reset_game();
#endif
#if HAVE_NETWORKING
netplay_driver_ctl(RARCH_NETPLAY_CTL_RESET, NULL);
#endif
break;
case CMD_EVENT_SAVE_STATE:
@@ -1939,10 +1941,8 @@ bool command_event(enum event_command cmd, void *data)
if (settings->savestate_auto_index)
settings->state_slot++;
command_event_main_state(cmd);
}
break;
return command_event_main_state(cmd);
case CMD_EVENT_SAVE_STATE_DECREMENT:
{
settings_t *settings = config_get_ptr();
@@ -1974,12 +1974,7 @@ bool command_event(enum event_command cmd, void *data)
command_event(CMD_EVENT_RESTORE_DEFAULT_SHADER_PRESET, NULL);
if (is_inited)
if (!task_push_content_load_default(
NULL, NULL,
&content_info,
CORE_TYPE_DUMMY,
CONTENT_MODE_LOAD_NOTHING_WITH_DUMMY_CORE,
NULL, NULL))
if (!task_push_start_dummy_core(&content_info))
return false;
#ifdef HAVE_DYNAMIC
#ifdef HAVE_MENU
@@ -2051,7 +2046,7 @@ bool command_event(enum event_command cmd, void *data)
#endif
{
if (settings->rewind_enable)
state_manager_event_init(settings->rewind_buffer_size);
state_manager_event_init((unsigned)settings->rewind_buffer_size);
}
}
break;
@@ -2507,9 +2502,12 @@ bool command_event(enum event_command cmd, void *data)
if (!init_netplay_deferred(
hostname->elems[0].data, atoi(hostname->elems[1].data)))
{
string_list_free(hostname);
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
return false;
}
string_list_free(hostname);
}
break;
case CMD_EVENT_NETPLAY_FLIP_PLAYERS:
+18 -1
View File
@@ -623,6 +623,9 @@ static bool xmb_show_images = true;
static bool xmb_show_music = true;
static bool xmb_show_video = true;
#endif
#ifdef HAVE_NETWORKING
static bool xmb_show_netplay = true;
#endif
static bool xmb_show_history = true;
#ifdef HAVE_LIBRETRODB
static bool xmb_show_add = true;
@@ -652,7 +655,7 @@ static const uint32_t menu_title_color = 0xff64ff64;
static bool default_block_config_read = false;
#endif
static bool default_game_specific_options = false;
static bool default_game_specific_options = true;
static bool default_auto_overrides_enable = true;
static bool default_auto_remaps_enable = true;
static bool default_auto_shaders_enable = true;
@@ -815,6 +818,18 @@ static const bool pause_nonactive = true;
* It is measured in seconds. A value of 0 disables autosave. */
static const unsigned autosave_interval = 0;
/* Publicly announce netplay */
static const bool netplay_public_announce = true;
/* Start netplay in spectator mode */
static const bool netplay_start_as_spectator = false;
/* Allow connections in slave mode */
static const bool netplay_allow_slaves = true;
/* Require connections only in slave mode */
static const bool netplay_require_slaves = false;
/* Netplay without savestates/rewind */
static const bool netplay_stateless_mode = false;
@@ -828,6 +843,8 @@ static const unsigned netplay_delay_frames = 16;
static const int netplay_check_frames = 30;
static const bool netplay_use_mitm_server = false;
/* On save state load, block SRAM from being overwritten.
* This could potentially lead to buggy games. */
static const bool block_sram_overwrite = false;
+21 -11
View File
@@ -728,8 +728,13 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
SETTING_BOOL("all_users_control_menu", &settings->input.all_users_control_menu, true, all_users_control_menu, false);
SETTING_BOOL("menu_swap_ok_cancel_buttons", &settings->input.menu_swap_ok_cancel_buttons, true, menu_swap_ok_cancel_buttons, false);
#ifdef HAVE_NETWORKING
SETTING_BOOL("netplay_stateless_mode", &settings->netplay.stateless_mode, false, netplay_stateless_mode, false);
SETTING_BOOL("netplay_public_announce", &settings->netplay.public_announce, true, netplay_public_announce, false);
SETTING_BOOL("netplay_start_as_spectator", &settings->netplay.start_as_spectator, false, netplay_start_as_spectator, false);
SETTING_BOOL("netplay_allow_slaves", &settings->netplay.allow_slaves, true, netplay_allow_slaves, false);
SETTING_BOOL("netplay_require_slaves", &settings->netplay.require_slaves, true, netplay_require_slaves, false);
SETTING_BOOL("netplay_stateless_mode", &settings->netplay.stateless_mode, true, netplay_stateless_mode, false);
SETTING_BOOL("netplay_client_swap_input", &settings->netplay.swap_input, true, netplay_client_swap_input, false);
SETTING_BOOL("netplay_use_mitm_server", &settings->netplay.use_mitm_server, true, netplay_use_mitm_server, false);
#endif
SETTING_BOOL("input_descriptor_label_show", &settings->input.input_descriptor_label_show, true, input_descriptor_label_show, false);
SETTING_BOOL("input_descriptor_hide_unbound", &settings->input.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false);
@@ -808,6 +813,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
#ifdef HAVE_FFMPEG
SETTING_BOOL("xmb_show_music", &settings->menu.xmb.show_music, true, xmb_show_music, false);
SETTING_BOOL("xmb_show_video", &settings->menu.xmb.show_video, true, xmb_show_video, false);
#endif
#ifdef HAVE_NETWORKING
SETTING_BOOL("xmb_show_netplay", &settings->menu.xmb.show_netplay, true, xmb_show_netplay, false);
#endif
SETTING_BOOL("xmb_show_history", &settings->menu.xmb.show_history, true, xmb_show_history, false);
#ifdef HAVE_LIBRETRODB
@@ -1157,9 +1165,9 @@ static void config_set_defaults(void)
settings->input.autoconf_binds[i][j].joykey = NO_BTN;
settings->input.autoconf_binds[i][j].joyaxis = AXIS_NONE;
}
settings->input.autoconfigured[i] = 0;
}
memset(settings->input.autoconfigured, 0,
sizeof(settings->input.autoconfigured));
/* Verify that binds are in proper order. */
for (i = 0; i < MAX_USERS; i++)
@@ -1328,9 +1336,16 @@ static void config_set_defaults(void)
#ifdef HAVE_MENU
if (!string_is_empty(g_defaults.dir.menu_config))
{
strlcpy(settings->directory.menu_config,
g_defaults.dir.menu_config,
sizeof(settings->directory.menu_config));
#if TARGET_OS_IPHONE
path_set(RARCH_PATH_CONFIG,
settings->directory.menu_config);
#endif
}
if (!string_is_empty(g_defaults.dir.menu_content))
strlcpy(settings->directory.menu_content,
g_defaults.dir.menu_content,
@@ -1671,7 +1686,7 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx)
}
if (string_is_equal("gl", settings->video.driver) ||
string_is_equal("d3d9", settings->video.driver))
string_is_equal("d3d", settings->video.driver))
{
if (enum_idx == FILE_PATH_SLANGP_EXTENSION)
return false;
@@ -2662,7 +2677,7 @@ static void save_keybind_hat(config_file_t *conf, const char *key,
const struct retro_keybind *bind)
{
char config[16];
unsigned hat = GET_HAT(bind->joykey);
unsigned hat = (unsigned)GET_HAT(bind->joykey);
const char *dir = NULL;
config[0] = '\0';
@@ -3377,12 +3392,7 @@ bool config_replace(bool config_save_on_exit, char *path)
/* Load core in new config. */
path_clear(RARCH_PATH_CORE);
if (!task_push_content_load_default(
NULL, NULL,
&content_info,
CORE_TYPE_DUMMY,
CONTENT_MODE_LOAD_NOTHING_WITH_DUMMY_CORE,
NULL, NULL))
if (!task_push_start_dummy_core(&content_info))
return false;
return true;
+6
View File
@@ -198,6 +198,7 @@ typedef struct settings
bool show_images;
bool show_music;
bool show_video;
bool show_netplay;
bool show_history;
bool show_add;
} xmb;
@@ -403,8 +404,12 @@ typedef struct settings
#ifdef HAVE_NETWORKING
struct
{
bool public_announce;
char server[255];
unsigned port;
bool start_as_spectator;
bool allow_slaves;
bool require_slaves;
bool stateless_mode;
int check_frames;
unsigned input_latency_frames_min;
@@ -413,6 +418,7 @@ typedef struct settings
bool nat_traversal;
char password[128];
char spectate_password[128];
bool use_mitm_server;
} netplay;
#endif
+47 -35
View File
@@ -59,6 +59,8 @@ static void core_info_list_resolve_all_extensions(
(strlen(core_info_list->list[i].supported_extensions) + 2);
}
all_ext_len += strlen("7z|") + strlen("zip|");
if (all_ext_len)
all_ext = (char*)calloc(1, all_ext_len);
@@ -76,6 +78,12 @@ static void core_info_list_resolve_all_extensions(
core_info_list->list[i].supported_extensions, all_ext_len);
strlcat(core_info_list->all_ext, "|", all_ext_len);
}
#ifdef HAVE_7ZIP
strlcat(core_info_list->all_ext, "7z|", all_ext_len);
#endif
#ifdef HAVE_ZLIB
strlcat(core_info_list->all_ext, "zip|", all_ext_len);
#endif
}
static void core_info_list_resolve_all_firmware(
@@ -820,61 +828,65 @@ bool core_info_unsupported_content_path(const char *path)
bool core_info_database_supports_content_path(const char *database_path, const char *path)
{
size_t i;
char *database = NULL;
const char *delim = NULL;
const char *archive_path = NULL;
const char *new_path = NULL;
const char *new_path = path_basename(database_path);
if (!core_info_curr_list)
if (string_is_empty(new_path))
return false;
new_path = path_basename(database_path);
database = strdup(new_path);
if (!string_is_empty(new_path))
database = strdup(new_path);
if (string_is_empty(database))
return false;
path_remove_extension(database);
delim = path_get_archive_delim(path);
if (delim)
archive_path = delim - 1;
/* if the path contains a compressed file and the core supports archives,
* we don't want to look at this file */
if (archive_path)
if (core_info_curr_list)
{
size_t i;
const char *delim = path_get_archive_delim(path);
if (delim)
{
const char *archive_path = delim - 1;
/* if the path contains a compressed file and the core supports archives,
* we don't want to look at this file */
if (archive_path)
{
for (i = 0; i < core_info_curr_list->count; i++)
{
const core_info_t *info = &core_info_curr_list->list[i];
if (!string_list_find_elem(info->databases_list, database))
continue;
if ( !string_list_find_elem(info->supported_extensions_list, "zip")
&& !string_list_find_elem(info->supported_extensions_list, "7z"))
continue;
free(database);
return false;
}
}
}
for (i = 0; i < core_info_curr_list->count; i++)
{
const core_info_t *info = &core_info_curr_list->list[i];
if (!string_list_find_elem(info->supported_extensions_list,
path_get_extension(path)))
continue;
if (!string_list_find_elem(info->databases_list, database))
continue;
if ( !string_list_find_elem(info->supported_extensions_list, "zip")
&& !string_list_find_elem(info->supported_extensions_list, "7z"))
continue;
free(database);
return false;
return true;
}
}
for (i = 0; i < core_info_curr_list->count; i++)
{
const core_info_t *info = &core_info_curr_list->list[i];
if (!string_list_find_elem(info->supported_extensions_list, path_get_extension(path)))
continue;
if (!string_list_find_elem(info->databases_list, database))
continue;
free(database);
return true;
}
free(database);
return false;
}
+2 -2
View File
@@ -410,8 +410,8 @@ void IMAGE_CORE_PREFIX(retro_run)(void)
}
else if (last_image)
{
image_index = file_list->size - 1;
load_image = true;
image_index = (int)(file_list->size - 1);
load_image = true;
}
if (load_image)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+14 -14
View File
@@ -293,52 +293,52 @@ static int database_cursor_iterate(libretrodb_cursor_t *cur,
break;
case DB_CURSOR_CERO_RATING:
if (!string_is_empty(val_string))
db_info->cero_rating = strdup(val_string);
db_info->cero_rating = strdup(val_string);
break;
case DB_CURSOR_PEGI_RATING:
if (!string_is_empty(val_string))
db_info->pegi_rating = strdup(val_string);
db_info->pegi_rating = strdup(val_string);
break;
case DB_CURSOR_ENHANCEMENT_HW:
if (!string_is_empty(val_string))
db_info->enhancement_hw = strdup(val_string);
db_info->enhancement_hw = strdup(val_string);
break;
case DB_CURSOR_EDGE_MAGAZINE_REVIEW:
if (!string_is_empty(val_string))
db_info->edge_magazine_review = strdup(val_string);
break;
case DB_CURSOR_EDGE_MAGAZINE_RATING:
db_info->edge_magazine_rating = val->val.uint_;
db_info->edge_magazine_rating = (unsigned)val->val.uint_;
break;
case DB_CURSOR_EDGE_MAGAZINE_ISSUE:
db_info->edge_magazine_issue = val->val.uint_;
db_info->edge_magazine_issue = (unsigned)val->val.uint_;
break;
case DB_CURSOR_FAMITSU_MAGAZINE_RATING:
db_info->famitsu_magazine_rating = val->val.uint_;
db_info->famitsu_magazine_rating = (unsigned)val->val.uint_;
break;
case DB_CURSOR_TGDB_RATING:
db_info->tgdb_rating = val->val.uint_;
db_info->tgdb_rating = (unsigned)val->val.uint_;
break;
case DB_CURSOR_MAX_USERS:
db_info->max_users = val->val.uint_;
db_info->max_users = (unsigned)val->val.uint_;
break;
case DB_CURSOR_RELEASEDATE_MONTH:
db_info->releasemonth = val->val.uint_;
db_info->releasemonth = (unsigned)val->val.uint_;
break;
case DB_CURSOR_RELEASEDATE_YEAR:
db_info->releaseyear = val->val.uint_;
db_info->releaseyear = (unsigned)val->val.uint_;
break;
case DB_CURSOR_RUMBLE_SUPPORTED:
db_info->rumble_supported = val->val.uint_;
db_info->rumble_supported = (int)val->val.uint_;
break;
case DB_CURSOR_COOP_SUPPORTED:
db_info->coop_supported = val->val.uint_;
db_info->coop_supported = (int)val->val.uint_;
break;
case DB_CURSOR_ANALOG_SUPPORTED:
db_info->analog_supported = val->val.uint_;
db_info->analog_supported = (int)val->val.uint_;
break;
case DB_CURSOR_SIZE:
db_info->size = val->val.uint_;
db_info->size = (unsigned)val->val.uint_;
break;
case DB_CURSOR_CHECKSUM_CRC32:
db_info->crc32 = swap_if_little32(*(uint32_t*)val->val.binary.buff);
+684
View File
@@ -0,0 +1,684 @@
$Id: Changelog.txt,v 1.226 2016/12/16 08:57:19 nanard Exp $
miniUPnP client Changelog.
2016/11/11:
check strlen before memcmp in XML parsing portlistingparse.c
fix build under SOLARIS and CYGWIN
2016/10/11:
Add python 3 compatibility to IGD test
VERSION 2.0 : released 2016/04/19
2016/01/24:
change miniwget to return HTTP status code
increments API_VERSION to 16
2016/01/22:
Improve UPNPIGD_IsConnected() to check if WAN address is not private.
parse HTTP response status line in miniwget.c
2015/10/26:
snprintf() overflow check. check overflow in simpleUPnPcommand2()
2015/10/25:
fix compilation with old macs
fix compilation with mingw32 (for Appveyor)
fix python module for python <= 2.3
2015/10/08:
Change sameport to localport
see https://github.com/miniupnp/miniupnp/pull/120
increments API_VERSION to 15
2015/09/15:
Fix buffer overflow in igd_desc_parse.c/IGDstartelt()
Discovered by Aleksandar Nikolic of Cisco Talos
2015/08/28:
move ssdpDiscoverDevices() to minissdpc.c
2015/08/27:
avoid unix socket leak in getDevicesFromMiniSSDPD()
2015/08/16:
Also accept "Up" as ConnectionStatus value
2015/07/23:
split getDevicesFromMiniSSDPD
add ttl argument to upnpDiscover() functions
increments API_VERSION to 14
2015/07/22:
Read USN from SSDP messages.
2015/07/15:
Check malloc/calloc
2015/06/16:
update getDevicesFromMiniSSDPD() to process longer minissdpd
responses
2015/05/22:
add searchalltypes param to upnpDiscoverDevices()
increments API_VERSION to 13
2015/04/30:
upnpc: output version on the terminal
2015/04/27:
_BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE
fix CMakeLists.txt COMPILE_DEFINITIONS
fix getDevicesFromMiniSSDPD() not setting scope_id
improve -r command of upnpc command line tool
2014/11/17:
search all :
upnpDiscoverDevices() / upnpDiscoverAll() functions
listdevices executable
increment API_VERSION to 12
validate igd_desc_parse
2014/11/13:
increment API_VERSION to 11
2014/11/05:
simplified function GetUPNPUrls()
2014/09/11:
use remoteHost arg of DeletePortMapping
2014/09/06:
Fix python3 build
2014/07/01:
Fix parsing of IGD2 root descriptions
2014/06/10:
rename LIBSPEC to MINIUPNP_LIBSPEC
2014/05/15:
Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange
2014/02/05:
handle EINPROGRESS after connect()
2014/02/03:
minixml now handle XML comments
VERSION 1.9 : released 2014/01/31
2014/01/31:
added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
increment API_VERSION to 10
2013/12/09:
--help and -h arguments in upnpc.c
2013/10/07:
fixed potential buffer overrun in miniwget.c
Modified UPNP_GetValidIGD() to check for ExternalIpAddress
2013/08/01:
define MAXHOSTNAMELEN if not already done
2013/06/06:
update upnpreplyparse to allow larger values (128 chars instead of 64)
2013/05/14:
Update upnpreplyparse to take into account "empty" elements
validate upnpreplyparse.c code with "make check"
2013/05/03:
Fix Solaris build thanks to Maciej Małecki
2013/04/27:
Fix testminiwget.sh for BSD
2013/03/23:
Fixed Makefile for *BSD
2013/03/11:
Update Makefile to use JNAerator version 0.11
2013/02/11:
Fix testminiwget.sh for use with dash
Use $(DESTDIR) in Makefile
VERSION 1.8 : released 2013/02/06
2012/10/16:
fix testminiwget with no IPv6 support
2012/09/27:
Rename all include guards to not clash with C99
(7.1.3 Reserved identifiers).
2012/08/30:
Added -e option to upnpc program (set description for port mappings)
2012/08/29:
Python 3 support (thanks to Christopher Foo)
2012/08/11:
Fix a memory link in UPNP_GetValidIGD()
Try to handle scope id in link local IPv6 URL under MS Windows
2012/07/20:
Disable HAS_IP_MREQN on DragonFly BSD
2012/06/28:
GetUPNPUrls() now inserts scope into link-local IPv6 addresses
2012/06/23:
More error return checks in upnpc.c
#define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
parseURL() now parses IPv6 addresses scope
new parameter for miniwget() : IPv6 address scope
increment API_VERSION to 9
2012/06/20:
fixed CMakeLists.txt
2012/05/29
Improvements in testminiwget.sh
VERSION 1.7 : released 2012/05/24
2012/05/01:
Cleanup settings of CFLAGS in Makefile
Fix signed/unsigned integer comparaisons
2012/04/20:
Allow to specify protocol with TCP or UDP for -A option
2012/04/09:
Only try to fetch XML description once in UPNP_GetValidIGD()
Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
2012/04/05:
minor improvements to minihttptestserver.c
2012/03/15:
upnperrors.c returns valid error string for unrecognized error codes
2012/03/08:
make minihttptestserver listen on loopback interface instead of 0.0.0.0
2012/01/25:
Maven installation thanks to Alexey Kuznetsov
2012/01/21:
Replace WIN32 macro by _WIN32
2012/01/19:
Fixes in java wrappers thanks to Alexey Kuznetsov :
https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
Make and install .deb packages (python) thanks to Alexey Kuznetsov :
https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
2012/01/07:
The multicast interface can now be specified by name with IPv4.
2012/01/02:
Install man page
2011/11/25:
added header to Port Mappings list in upnpc.c
2011/10/09:
Makefile : make clean now removes jnaerator generated files.
MINIUPNPC_VERSION in miniupnpc.h (updated by make)
2011/09/12:
added rootdescURL to UPNPUrls structure.
VERSION 1.6 : released 2011/07/25
2011/07/25:
Update doc for version 1.6 release
2011/06/18:
Fix for windows in miniwget.c
2011/06/04:
display remote host in port mapping listing
2011/06/03:
Fix in make install : there were missing headers
2011/05/26:
Fix the socket leak in miniwget thanks to Richard Marsh.
Permit to add leaseduration in -a command. Display lease duration.
2011/05/15:
Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
2011/05/09:
add a test in testminiwget.sh.
more error checking in miniwget.c
2011/05/06:
Adding some tool to test and validate miniwget.c
simplified and debugged miniwget.c
2011/04/11:
moving ReceiveData() to a receivedata.c file.
parsing presentation url
adding IGD v2 WANIPv6FirewallControl commands
2011/04/10:
update of miniupnpcmodule.c
comments in miniwget.c, update in testminiwget
Adding errors codes from IGD v2
new functions in upnpc.c for IGD v2
2011/04/09:
Support for litteral ip v6 address in miniwget
2011/04/08:
Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
Updating APIVERSION
Supporting IPV6 in upnpDiscover()
Adding a -6 option to upnpc command line tool
2011/03/18:
miniwget/parseURL() : return an error when url param is null.
fixing GetListOfPortMappings()
2011/03/14:
upnpDiscover() now reporting an error code.
improvements in comments.
2011/03/11:
adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
2011/02/15:
Implementation of GetListOfPortMappings()
2011/02/07:
updates to minixml to support character data starting with spaces
minixml now support CDATA
upnpreplyparse treats <NewPortListing> specificaly
change in simpleUPnPcommand to return the buffer (simplification)
2011/02/06:
Added leaseDuration argument to AddPortMapping()
Starting to implement GetListOfPortMappings()
2011/01/11:
updating wingenminiupnpcstrings.c
2011/01/04:
improving updateminiupnpcstrings.sh
VERSION 1.5 : released 2011/01/01
2010/12/21:
use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
2010/12/11:
Improvements on getHTTPResponse() code.
2010/12/09:
new code for miniwget that handle Chunked transfer encoding
using getHTTPResponse() in SOAP call code
Adding MANIFEST.in for 'python setup.py bdist_rpm'
2010/11/25:
changes to minissdpc.c to compile under Win32.
see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729
2010/09/17:
Various improvement to Makefile from Michał Górny
2010/08/05:
Adding the script "external-ip.sh" from Reuben Hawkins
2010/06/09:
update to python module to match modification made on 2010/04/05
update to Java test code to match modification made on 2010/04/05
all UPNP_* function now return an error if the SOAP request failed
at HTTP level.
2010/04/17:
Using GetBestRoute() under win32 in order to find the
right interface to use.
2010/04/12:
Retrying with HTTP/1.1 if HTTP/1.0 failed. see
http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
2010/04/07:
avoid returning duplicates in upnpDiscover()
2010/04/05:
Create a connecthostport.h/.c with connecthostport() function
and use it in miniwget and miniupnpc.
Use getnameinfo() instead of inet_ntop or inet_ntoa
Work to make miniupnpc IPV6 compatible...
Add java test code.
Big changes in order to support device having both WANIPConnection
and WANPPPConnection.
2010/04/04:
Use getaddrinfo() instead of gethostbyname() in miniwget.
2010/01/06:
#define _DARWIN_C_SOURCE for Mac OS X
2009/12/19:
Improve MinGW32 build
2009/12/11:
adding a MSVC9 project to build the static library and executable
2009/12/10:
Fixing some compilation stuff for Windows/MinGW
2009/12/07:
adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS
some fixes for Windows when using virtual ethernet adapters (it is the
case with VMWare installed).
2009/12/04:
some fixes for AmigaOS compilation
Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked
transfer encoding)
2009/12/03:
updating printIDG and testigddescparse.c for debug.
modifications to compile under AmigaOS
adding a testminiwget program
Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked
transfer encoding
2009/11/26:
fixing updateminiupnpcstrings.sh to take into account
which command that does not return an error code.
VERSION 1.4 : released 2009/10/30
2009/10/16:
using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module.
2009/10/10:
Some fixes for compilation under Solaris
compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464
2009/09/21:
fixing the code to ignore EINTR during connect() calls.
2009/08/07:
Set socket timeout for connect()
Some cleanup in miniwget.c
2009/08/04:
remove multiple redirections with -d in upnpc.c
Print textual error code in upnpc.c
Ignore EINTR during the connect() and poll() calls.
2009/07/29:
fix in updateminiupnpcstrings.sh if OS name contains "/"
Sending a correct value for MX: field in SSDP request
2009/07/20:
Change the Makefile to compile under Mac OS X
Fixed a stackoverflow in getDevicesFromMiniSSDPD()
2009/07/09:
Compile under Haiku
generate miniupnpcstrings.h.in from miniupnpcstrings.h
2009/06/04:
patching to compile under CygWin and cross compile for minGW
VERSION 1.3 :
2009/04/17:
updating python module
Use strtoull() when using C99
2009/02/28:
Fixed miniwget.c for compiling under sun
2008/12/18:
cleanup in Makefile (thanks to Paul de Weerd)
minissdpc.c : win32 compatibility
miniupnpc.c : changed xmlns prefix from 'm' to 'u'
Removed NDEBUG (using DEBUG)
2008/10/14:
Added the ExternalHost argument to DeletePortMapping()
2008/10/11:
Added the ExternalHost argument to AddPortMapping()
Put a correct User-Agent: header in HTTP requests.
VERSION 1.2 :
2008/10/07:
Update docs
2008/09/25:
Integrated sameport patch from Dario Meloni : Added a "sameport"
argument to upnpDiscover().
2008/07/18:
small modif to make Clang happy :)
2008/07/17:
#define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
2008/07/14:
include declspec.h in installation (to /usr/include/miniupnpc)
VERSION 1.1 :
2008/07/04:
standard options for install/ln instead of gnu-specific stuff.
2008/07/03:
now builds a .dll and .lib with win32. (mingw32)
2008/04/28:
make install now install the binary of the upnpc tool
2008/04/27:
added testupnpigd.py
added error strings for miniupnpc "internal" errors
improved python module error/exception reporting.
2008/04/23:
Completely rewrite igd_desc_parse.c in order to be compatible with
Linksys WAG200G
Added testigddescparse
updated python module
VERSION 1.0 :
2008/02/21:
put some #ifdef DEBUG around DisplayNameValueList()
2008/02/18:
Improved error reporting in upnpcommands.c
UPNP_GetStatusInfo() returns LastConnectionError
2008/02/16:
better error handling in minisoap.c
improving display of "valid IGD found" in upnpc.c
2008/02/03:
Fixing UPNP_GetValidIGD()
improved make install :)
2007/12/22:
Adding upnperrors.c/h to provide a strupnperror() function
used to translate UPnP error codes to string.
2007/12/19:
Fixing getDevicesFromMiniSSDPD()
improved error reporting of UPnP functions
2007/12/18:
It is now possible to specify a different location for MiniSSDPd socket.
working with MiniSSDPd is now more efficient.
python module improved.
2007/12/16:
improving error reporting
2007/12/13:
Try to improve compatibility by using HTTP/1.0 instead of 1.1 and
XML a bit different for SOAP.
2007/11/25:
fixed select() call for linux
2007/11/15:
Added -fPIC to CFLAG for better shared library code.
2007/11/02:
Fixed a potential socket leak in miniwget2()
2007/10/16:
added a parameter to upnpDiscover() in order to allow the use of another
interface than the default multicast interface.
2007/10/12:
Fixed the creation of symbolic link in Makefile
2007/10/08:
Added man page
2007/10/02:
fixed memory bug in GetUPNPUrls()
2007/10/01:
fixes in the Makefile
Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly.
Added SONAME in the shared library to please debian :)
fixed MS Windows compilation (minissdpd is not available under MS Windows).
2007/09/25:
small change to Makefile to be able to install in a different location
(default is /usr)
2007/09/24:
now compiling both shared and static library
2007/09/19:
Cosmetic changes on upnpc.c
2007/09/02:
adapting to new miniSSDPd (release version ?)
2007/08/31:
Usage of miniSSDPd to skip discovery process.
2007/08/27:
fixed python module to allow compilation with Python older than Python 2.4
2007/06/12:
Added a python module.
2007/05/19:
Fixed compilation under MinGW
2007/05/15:
fixed a memory leak in AddPortMapping()
Added testupnpreplyparse executable to check the parsing of
upnp soap messages
minixml now ignore namespace prefixes.
2007/04/26:
upnpc now displays external ip address with -s or -l
2007/04/11:
changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210"
2007/03/19:
cleanup in miniwget.c
2007/03/01:
Small typo fix...
2007/01/30:
Now parsing the HTTP header from SOAP responses in order to
get content-length value.
2007/01/29:
Fixed the Soap Query to speedup the HTTP request.
added some Win32 DLL stuff...
2007/01/27:
Fixed some WIN32 compatibility issues
2006/12/14:
Added UPNPIGD_IsConnected() function in miniupnp.c/.h
Added UPNP_GetValidIGD() in miniupnp.c/.h
cleaned upnpc.c main(). now using UPNP_GetValidIGD()
2006/12/07:
Version 1.0-RC1 released
2006/12/03:
Minor changes to compile under SunOS/Solaris
2006/11/30:
made a minixml parser validator program
updated minixml to handle attributes correctly
2006/11/22:
Added a -r option to the upnpc sample thanks to Alexander Hubmann.
2006/11/19:
Cleanup code to make it more ANSI C compliant
2006/11/10:
detect and display local lan address.
2006/11/04:
Packets and Bytes Sent/Received are now unsigned int.
2006/11/01:
Bug fix thanks to Giuseppe D'Angelo
2006/10/31:
C++ compatibility for .h files.
Added a way to get ip Address on the LAN used to reach the IGD.
2006/10/25:
Added M-SEARCH to the services in the discovery process.
2006/10/22:
updated the Makefile to use makedepend, added a "make install"
update Makefile
2006/10/20:
fixing the description url parsing thanks to patch sent by
Wayne Dawe.
Fixed/translated some comments.
Implemented a better discover process, first looking
for IGD then for root devices (as some devices only reply to
M-SEARCH for root devices).
2006/09/02:
added freeUPNPDevlist() function.
2006/08/04:
More command line arguments checking
2006/08/01:
Added the .bat file to compile under Win32 with minGW32
2006/07/31:
Fixed the rootdesc parser (igd_desc_parse.c)
2006/07/20:
parseMSEARCHReply() is now returning the ST: line as well
starting changes to detect several UPnP devices on the network
2006/07/19:
using GetCommonLinkProperties to get down/upload bitrate
+27
View File
@@ -0,0 +1,27 @@
MiniUPnPc
Copyright (c) 2005-2016, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
+5
View File
@@ -0,0 +1,5 @@
include README
include miniupnpcmodule.c
include setup.py
include *.h
include libminiupnpc.a
+274
View File
@@ -0,0 +1,274 @@
# $Id: Makefile,v 1.134 2016/10/07 09:04:36 nanard Exp $
# MiniUPnP Project
# http://miniupnp.free.fr/
# http://miniupnp.tuxfamily.org/
# https://github.com/miniupnp/miniupnp
# (c) 2005-2016 Thomas Bernard
# to install use :
# $ make DESTDIR=/tmp/dummylocation install
# or
# $ INSTALLPREFIX=/usr/local make install
# or
# $ make install (default INSTALLPREFIX is /usr)
OS = $(shell uname -s)
VERSION = $(shell cat VERSION)
ifeq ($(OS), Darwin)
JARSUFFIX=mac
LIBTOOL ?= $(shell which libtool)
endif
ifeq ($(OS), Linux)
JARSUFFIX=linux
endif
ifneq (,$(findstring NT-5.1,$(OS)))
JARSUFFIX=win32
endif
HAVE_IPV6 ?= yes
export HAVE_IPV6
CC ?= gcc
#AR = gar
#CFLAGS = -O -g -DDEBUG
CFLAGS ?= -O
CFLAGS += -Wall
CFLAGS += -W -Wstrict-prototypes
CFLAGS += -fno-common
CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT
CFLAGS += -DMINIUPNPC_GET_SRC_ADDR
CFLAGS += -D_BSD_SOURCE
CFLAGS += -D_DEFAULT_SOURCE
ifeq ($(OS), NetBSD)
CFLAGS += -D_NETBSD_SOURCE
endif
ifneq ($(OS), FreeBSD)
ifneq ($(OS), Darwin)
#CFLAGS += -D_POSIX_C_SOURCE=200112L
CFLAGS += -D_XOPEN_SOURCE=600
endif
endif
#CFLAGS += -ansi
# -DNO_GETADDRINFO
INSTALL = install
SH = /bin/sh
ifeq (SunOS, $(OS))
LDLIBS=-lsocket -lnsl -lresolv
CFLAGS += -D__EXTENSIONS__
CFLAGS += -std=c99
endif
# APIVERSION is used to build SONAME
APIVERSION = 16
SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \
upnpcommands.c upnpreplyparse.c \
minixmlvalid.c minissdpc.c \
upnperrors.c \
connecthostport.c portlistingparse.c receivedata.c \
upnpdev.c miniupnpcmodule.c
LIBOBJS = miniwget.o minixml.o igd_desc_parse.o minisoap.o \
miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \
connecthostport.o portlistingparse.o receivedata.o upnpdev.o
ifneq ($(OS), AmigaOS)
ifeq (,$(findstring CYGWIN,$(OS)))
CFLAGS := -fPIC $(CFLAGS)
endif
LIBOBJS := $(LIBOBJS) minissdpc.o
endif
OBJS = $(patsubst %.c,%.o,$(SRCS))
# HEADERS to install
HEADERS = miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h \
upnpreplyparse.h upnperrors.h miniupnpctypes.h \
portlistingparse.h \
upnpdev.h \
miniupnpc_declspec.h
# library names
LIBRARY = libminiupnpc.a
ifeq ($(OS), Darwin)
SHAREDLIBRARY = libminiupnpc.dylib
SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib
CFLAGS := -D_DARWIN_C_SOURCE $(CFLAGS)
else
ifeq ($(JARSUFFIX), win32)
SHAREDLIBRARY = miniupnpc.dll
else
# Linux/BSD/etc.
SHAREDLIBRARY = libminiupnpc.so
SONAME = $(SHAREDLIBRARY).$(APIVERSION)
endif
endif
EXECUTABLES = upnpc-static
ifneq ($(OS), AmigaOS)
EXECUTABLES := $(EXECUTABLES) upnpc-shared
endif
LIBDIR ?= lib
# install directories
ifeq ($(strip $(PREFIX)),)
INSTALLPREFIX ?= /usr
else
INSTALLPREFIX ?= $(PREFIX)
endif
INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc
INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR)
INSTALLDIRBIN = $(INSTALLPREFIX)/bin
INSTALLDIRMAN = $(INSTALLPREFIX)/share/man
FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES)
ifneq ($(OS), AmigaOS)
FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY)
endif
.PHONY: install clean depend all check test everything \
updateversion
# validateminixml validateminiwget
all: $(LIBRARY) $(EXECUTABLES)
test: check
check: validateminixml validateminiwget validateupnpreplyparse \
validateportlistingparse validateigddescparse
everything: all
validateminixml: minixmlvalid
@echo "minixml validation test"
./minixmlvalid
touch $@
validateminiwget: testminiwget minihttptestserver testminiwget.sh
@echo "miniwget validation test"
./testminiwget.sh
touch $@
validateupnpreplyparse: testupnpreplyparse testupnpreplyparse.sh
@echo "upnpreplyparse validation test"
./testupnpreplyparse.sh
touch $@
validateportlistingparse: testportlistingparse
@echo "portlistingparse validation test"
./testportlistingparse
touch $@
validateigddescparse: testigddescparse
@echo "igd desc parse validation test"
./testigddescparse testdesc/new_LiveBox_desc.xml testdesc/new_LiveBox_desc.values
./testigddescparse testdesc/linksys_WAG200G_desc.xml testdesc/linksys_WAG200G_desc.values
touch $@
clean:
$(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h
distclean: clean
updateversion: miniupnpc.h
cp miniupnpc.h miniupnpc.h.bak
sed 's/\(.*MINIUPNPC_API_VERSION\s\+\)[0-9]\+/\1$(APIVERSION)/' < miniupnpc.h.bak > miniupnpc.h
install: updateversion $(FILESTOINSTALL)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC)
$(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB)
$(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB)
ifneq ($(OS), AmigaOS)
$(INSTALL) -m 644 $(SHAREDLIBRARY) $(DESTDIR)$(INSTALLDIRLIB)/$(SONAME)
ln -fs $(SONAME) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY)
endif
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN)
ifeq ($(OS), AmigaOS)
$(INSTALL) -m 755 upnpc-static $(DESTDIR)$(INSTALLDIRBIN)/upnpc
else
$(INSTALL) -m 755 upnpc-shared $(DESTDIR)$(INSTALLDIRBIN)/upnpc
endif
$(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip
ifneq ($(OS), AmigaOS)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRMAN)/man3
$(INSTALL) -m 644 man3/miniupnpc.3 $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3
ifeq ($(OS), Linux)
gzip -f $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3
endif
endif
install-static: updateversion $(FILESTOINSTALL)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC)
$(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB)
$(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB)
$(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN)
$(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip
cleaninstall:
$(RM) -r $(DESTDIR)$(INSTALLDIRINC)
$(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(LIBRARY)
$(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY)
depend:
makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null
$(LIBRARY): $(LIBOBJS)
ifeq ($(OS), Darwin)
$(LIBTOOL) -static -o $@ $?
else
$(AR) crs $@ $?
endif
$(SHAREDLIBRARY): $(LIBOBJS)
ifeq ($(OS), Darwin)
# $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^
$(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(INSTALLDIRLIB)/$(SONAME) -o $@ $^
else
$(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^
endif
upnpc-static: $(LIBRARY)
$(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS)
upnpc-shared: $(SHAREDLIBRARY)
$(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS)
minixmlvalid: minixml.o minixmlvalid.o
miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION
$(SH) updateminiupnpcstrings.sh
# DO NOT DELETE THIS LINE -- make depend depends on it.
igd_desc_parse.o: igd_desc_parse.h
miniupnpc.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h upnpdev.h
miniupnpc.o: minissdpc.h miniwget.h minisoap.h minixml.h upnpcommands.h
miniupnpc.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h
miniupnpc.o: connecthostport.h
minixml.o: minixml.h
minisoap.o: minisoap.h miniupnpcstrings.h
miniwget.o: miniupnpcstrings.h miniwget.h miniupnpc_declspec.h
miniwget.o: connecthostport.h receivedata.h
upnpcommands.o: upnpcommands.h upnpreplyparse.h portlistingparse.h
upnpcommands.o: miniupnpc_declspec.h miniupnpctypes.h miniupnpc.h
upnpcommands.o: igd_desc_parse.h upnpdev.h
upnpreplyparse.o: upnpreplyparse.h minixml.h
minixmlvalid.o: minixml.h
minissdpc.o: minissdpc.h miniupnpc_declspec.h upnpdev.h miniupnpc.h
minissdpc.o: igd_desc_parse.h receivedata.h codelength.h
upnperrors.o: upnperrors.h miniupnpc_declspec.h upnpcommands.h
upnperrors.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h
upnperrors.o: miniupnpc.h igd_desc_parse.h upnpdev.h
connecthostport.o: connecthostport.h
portlistingparse.o: portlistingparse.h miniupnpc_declspec.h miniupnpctypes.h
portlistingparse.o: minixml.h
receivedata.o: receivedata.h
upnpdev.o: upnpdev.h miniupnpc_declspec.h
testportlistingparse.o: miniupnpctypes.h
miniupnpcmodule.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h
miniupnpcmodule.o: upnpdev.h upnpcommands.h upnpreplyparse.h
miniupnpcmodule.o: portlistingparse.h miniupnpctypes.h upnperrors.h
+64
View File
@@ -0,0 +1,64 @@
Project: miniupnp
Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
github: https://github.com/miniupnp/miniupnp
freecode: http://freecode.com/projects/miniupnp
Author: Thomas Bernard
Copyright (c) 2005-2016 Thomas Bernard
This software is subject to the conditions detailed in the
LICENSE file provided within this distribution.
* miniUPnP Client - miniUPnPc *
To compile, simply run 'gmake' (could be 'make' on your system).
Under win32, to compile with MinGW, type "mingw32make.bat".
MS Visual C solution and project files are supplied in the msvc/ subdirectory.
The compilation is known to work under linux, FreeBSD,
OpenBSD, MacOS X, AmigaOS and cygwin.
The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
To install the library and headers on the system use :
> su
> make install
> exit
alternatively, to install into a specific location, use :
> INSTALLPREFIX=/usr/local make install
upnpc.c is a sample client using the libminiupnpc.
To use the libminiupnpc in your application, link it with
libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
upnpcommands.h and miniwget.h :
- upnpDiscover()
- UPNP_GetValidIGD()
- miniwget()
- parserootdesc()
- GetUPNPUrls()
- UPNP_* (calling UPNP methods)
Note : use #include <miniupnpc/miniupnpc.h> etc... for the includes
and -lminiupnpc for the link
Discovery process is speeded up when MiniSSDPd is running on the machine.
* Python module *
you can build a python module with 'make pythonmodule'
and install it with 'make installpythonmodule'.
setup.py (and setupmingw32.py) are included in the distribution.
Feel free to contact me if you have any problem :
e-mail : [email protected]
If you are using libminiupnpc in your application, please
send me an email !
For any question, you can use the web forum :
http://miniupnp.tuxfamily.org/forum/
Bugs should be reported on github :
https://github.com/miniupnp/miniupnp/issues
+1
View File
@@ -0,0 +1 @@
2.0
+172
View File
@@ -0,0 +1,172 @@
$Id: apiversions.txt,v 1.9 2016/01/24 17:24:36 nanard Exp $
Differences in API between miniUPnPc versions
API version 16
added "status_code" argument to getHTTPResponse(), miniwget() and miniwget_getaddr()
updated macro :
#define MINIUPNPC_API_VERSION 16
API version 15
changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice()
to "localport". When 0 or 1, behaviour is not changed, but it can take
any other value between 2 and 65535
Existing programs should be compatible
updated macro :
#define MINIUPNPC_API_VERSION 15
API version 14
miniupnpc.h
add ttl argument to upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice()
upnpDiscoverDevices()
getDevicesFromMiniSSDPD() :
connectToMiniSSDPD() / disconnectFromMiniSSDPD()
requestDevicesFromMiniSSDPD() / receiveDevicesFromMiniSSDPD()
updated macro :
#define MINIUPNPC_API_VERSION 14
API version 13
miniupnpc.h:
add searchalltype param to upnpDiscoverDevices() function
updated macro :
#define MINIUPNPC_API_VERSION 13
API version 12
miniupnpc.h :
add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices()
functions
updated macros :
#define MINIUPNPC_API_VERSION 12
API version 11
upnpreplyparse.h / portlistingparse.h :
removed usage of sys/queue.h / bsdqueue.h
miniupnpc.h:
updated macros :
#define MINIUPNPC_API_VERSION 11
====================== miniUPnPc version 1.9 ======================
API version 10
upnpcommands.h:
added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
miniupnpc.h:
updated macros :
#define MINIUPNPC_VERSION "1.9"
#define MINIUPNPC_API_VERSION 10
====================== miniUPnPc version 1.8 ======================
API version 9
miniupnpc.h:
updated macros :
#define MINIUPNPC_VERSION "1.8"
#define MINIUPNPC_API_VERSION 9
added "unsigned int scope_id;" to struct UPNPDev
added scope_id argument to GetUPNPUrls()
====================== miniUPnPc version 1.7 ======================
API version 8
miniupnpc.h :
add new macros :
#define MINIUPNPC_VERSION "1.7"
#define MINIUPNPC_API_VERSION 8
add rootdescURL to struct UPNPUrls
====================== miniUPnPc version 1.6 ======================
API version 8
Adding support for IPv6.
igd_desc_parse.h :
struct IGDdatas_service :
add char presentationurl[MINIUPNPC_URL_MAXSIZE];
struct IGDdatas :
add struct IGDdatas_service IPv6FC;
miniupnpc.h :
new macros :
#define UPNPDISCOVER_SUCCESS (0)
#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
#define UPNPDISCOVER_SOCKET_ERROR (-101)
#define UPNPDISCOVER_MEMORY_ERROR (-102)
simpleUPnPcommand() prototype changed (but is normaly not used by API users)
add arguments ipv6 and error to upnpDiscover() :
struct UPNPDev *
upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int sameport,
int ipv6,
int * error);
add controlURL_6FC member to struct UPNPUrls :
struct UPNPUrls {
char * controlURL;
char * ipcondescURL;
char * controlURL_CIF;
char * controlURL_6FC;
};
upnpcommands.h :
add leaseDuration argument to UPNP_AddPortMapping()
add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry()
add UPNP_GetListOfPortMappings() function (IGDv2)
add IGDv2 IPv6 related functions :
UPNP_GetFirewallStatus()
UPNP_GetOutboundPinholeTimeout()
UPNP_AddPinhole()
UPNP_UpdatePinhole()
UPNP_DeletePinhole()
UPNP_CheckPinholeWorking()
UPNP_GetPinholePackets()
====================== miniUPnPc version 1.5 ======================
API version 5
new function :
int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
new macro in upnpcommands.h :
#define UPNPCOMMAND_HTTP_ERROR
====================== miniUPnPc version 1.4 ======================
Same API as version 1.3
====================== miniUPnPc version 1.3 ======================
API version 4
Use UNSIGNED_INTEGER type for
UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(),
UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived()
Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping()
====================== miniUPnPc version 1.2 ======================
API version 3
added sameport argument to upnpDiscover()
struct UPNPDev *
upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int sameport);
====================== miniUPnPc Version 1.1 ======================
Same API as 1.0
====================== miniUPnPc Version 1.0 ======================
API version 2
struct UPNPDev {
struct UPNPDev * pNext;
char * descURL;
char * st;
char buffer[2];
};
struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock);
+54
View File
@@ -0,0 +1,54 @@
/* $Id: codelength.h,v 1.3 2011/07/30 13:10:05 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2015 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#ifndef CODELENGTH_H_INCLUDED
#define CODELENGTH_H_INCLUDED
/* Encode length by using 7bit per Byte :
* Most significant bit of each byte specifies that the
* following byte is part of the code */
/* n : unsigned
* p : unsigned char *
*/
#define DECODELENGTH(n, p) n = 0; \
do { n = (n << 7) | (*p & 0x7f); } \
while((*(p++)&0x80) && (n<(1<<25)));
/* n : unsigned
* READ : function/macro to read one byte (unsigned char)
*/
#define DECODELENGTH_READ(n, READ) \
n = 0; \
do { \
unsigned char c; \
READ(c); \
n = (n << 7) | (c & 0x07f); \
if(!(c&0x80)) break; \
} while(n<(1<<25));
/* n : unsigned
* p : unsigned char *
* p_limit : unsigned char *
*/
#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
n = 0; \
do { \
if((p) >= (p_limit)) break; \
n = (n << 7) | (*(p) & 0x7f); \
} while((*((p)++)&0x80) && (n<(1<<25)));
/* n : unsigned
* p : unsigned char *
*/
#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
if(n>=16384) *(p++) = (n >> 14) | 0x80; \
if(n>=128) *(p++) = (n >> 7) | 0x80; \
*(p++) = n & 0x7f;
#endif /* CODELENGTH_H_INCLUDED */
+264
View File
@@ -0,0 +1,264 @@
/* $Id: connecthostport.c,v 1.15 2015/10/09 16:26:19 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2010-2016 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
/* use getaddrinfo() or gethostbyname()
* uncomment the following line in order to use gethostbyname() */
#ifdef NO_GETADDRINFO
#define USE_GETHOSTBYNAME
#endif
#include <string.h>
#include <stdio.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#define MAXHOSTNAMELEN 64
#define snprintf _snprintf
#define herror
#define socklen_t int
#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/types.h>
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
#include <sys/time.h>
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
#include <sys/param.h>
#include <sys/select.h>
#include <errno.h>
#define closesocket close
#include <netdb.h>
#include <netinet/in.h>
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
#ifndef USE_GETHOSTBYNAME
#include <sys/socket.h>
#include <sys/select.h>
#endif /* #ifndef USE_GETHOSTBYNAME */
#endif /* #else _WIN32 */
/* definition of PRINT_SOCKET_ERROR */
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif
#if defined(__amigaos__) || defined(__amigaos4__)
#define herror(A) printf("%s\n", A)
#endif
#include "connecthostport.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
/* connecthostport()
* return a socket connected (TCP) to the host and port
* or -1 in case of error */
int connecthostport(const char * host, unsigned short port,
unsigned int scope_id)
{
int s, n;
#ifdef USE_GETHOSTBYNAME
struct sockaddr_in dest;
struct hostent *hp;
#else /* #ifdef USE_GETHOSTBYNAME */
char tmp_host[MAXHOSTNAMELEN+1];
char port_str[8];
struct addrinfo *ai, *p;
struct addrinfo hints;
#endif /* #ifdef USE_GETHOSTBYNAME */
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
struct timeval timeout;
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
#ifdef USE_GETHOSTBYNAME
hp = gethostbyname(host);
if(hp == NULL)
{
herror(host);
return -1;
}
memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
s = socket(PF_INET, SOCK_STREAM, 0);
if(s < 0)
{
PRINT_SOCKET_ERROR("socket");
return -1;
}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
/* setting a 3 seconds timeout for the connect() call */
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO");
}
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO");
}
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
dest.sin_family = AF_INET;
dest.sin_port = htons(port);
n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
#ifdef MINIUPNPC_IGNORE_EINTR
/* EINTR The system call was interrupted by a signal that was caught
* EINPROGRESS The socket is nonblocking and the connection cannot
* be completed immediately. */
while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
{
socklen_t len;
fd_set wset;
int err;
FD_ZERO(&wset);
FD_SET(s, &wset);
if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
continue;
/*len = 0;*/
/*n = getpeername(s, NULL, &len);*/
len = sizeof(err);
if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
PRINT_SOCKET_ERROR("getsockopt");
closesocket(s);
return -1;
}
if(err != 0) {
errno = err;
n = -1;
}
}
#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
if(n<0)
{
PRINT_SOCKET_ERROR("connect");
closesocket(s);
return -1;
}
#else /* #ifdef USE_GETHOSTBYNAME */
/* use getaddrinfo() instead of gethostbyname() */
memset(&hints, 0, sizeof(hints));
/* hints.ai_flags = AI_ADDRCONFIG; */
#ifdef AI_NUMERICSERV
hints.ai_flags = AI_NUMERICSERV;
#endif
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
/* hints.ai_protocol = IPPROTO_TCP; */
snprintf(port_str, sizeof(port_str), "%hu", port);
if(host[0] == '[')
{
/* literal ip v6 address */
int i, j;
for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
{
tmp_host[i] = host[j];
if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */
j+=2; /* skip "25" */
}
tmp_host[i] = '\0';
}
else
{
strncpy(tmp_host, host, MAXHOSTNAMELEN);
}
tmp_host[MAXHOSTNAMELEN] = '\0';
n = getaddrinfo(tmp_host, port_str, &hints, &ai);
if(n != 0)
{
#ifdef _WIN32
fprintf(stderr, "getaddrinfo() error : %d\n", n);
#else
fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
#endif
return -1;
}
s = -1;
for(p = ai; p; p = p->ai_next)
{
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if(s < 0)
continue;
if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
addr6->sin6_scope_id = scope_id;
}
#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
/* setting a 3 seconds timeout for the connect() call */
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(struct timeval)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
}
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(struct timeval)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt");
}
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
n = connect(s, p->ai_addr, p->ai_addrlen);
#ifdef MINIUPNPC_IGNORE_EINTR
/* EINTR The system call was interrupted by a signal that was caught
* EINPROGRESS The socket is nonblocking and the connection cannot
* be completed immediately. */
while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
{
socklen_t len;
fd_set wset;
int err;
FD_ZERO(&wset);
FD_SET(s, &wset);
if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
continue;
/*len = 0;*/
/*n = getpeername(s, NULL, &len);*/
len = sizeof(err);
if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
PRINT_SOCKET_ERROR("getsockopt");
closesocket(s);
freeaddrinfo(ai);
return -1;
}
if(err != 0) {
errno = err;
n = -1;
}
}
#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
if(n < 0)
{
closesocket(s);
continue;
}
else
{
break;
}
}
freeaddrinfo(ai);
if(s < 0)
{
PRINT_SOCKET_ERROR("socket");
return -1;
}
if(n < 0)
{
PRINT_SOCKET_ERROR("connect");
return -1;
}
#endif /* #ifdef USE_GETHOSTBYNAME */
return s;
}
+18
View File
@@ -0,0 +1,18 @@
/* $Id: connecthostport.h,v 1.2 2012/06/23 22:32:33 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2010-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef CONNECTHOSTPORT_H_INCLUDED
#define CONNECTHOSTPORT_H_INCLUDED
/* connecthostport()
* return a socket connected (TCP) to the host and port
* or -1 in case of error */
int connecthostport(const char * host, unsigned short port,
unsigned int scope_id);
#endif
+123
View File
@@ -0,0 +1,123 @@
/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */
/* Project : miniupnp
* http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#include "igd_desc_parse.h"
#include <stdio.h>
#include <string.h>
/* Start element handler :
* update nesting level counter and copy element name */
void IGDstartelt(void * d, const char * name, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
if(l >= MINIUPNPC_URL_MAXSIZE)
l = MINIUPNPC_URL_MAXSIZE-1;
memcpy(datas->cureltname, name, l);
datas->cureltname[l] = '\0';
datas->level++;
if( (l==7) && !memcmp(name, "service", l) ) {
datas->tmp.controlurl[0] = '\0';
datas->tmp.eventsuburl[0] = '\0';
datas->tmp.scpdurl[0] = '\0';
datas->tmp.servicetype[0] = '\0';
}
}
#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1))
/* End element handler :
* update nesting level counter and update parser state if
* service element is parsed */
void IGDendelt(void * d, const char * name, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
datas->level--;
/*printf("endelt %2d %.*s\n", datas->level, l, name);*/
if( (l==7) && !memcmp(name, "service", l) )
{
if(COMPARE(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) {
memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
} else if(COMPARE(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) {
memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
} else if(COMPARE(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANIPConnection:")
|| COMPARE(datas->tmp.servicetype,
"urn:schemas-upnp-org:service:WANPPPConnection:") ) {
if(datas->first.servicetype[0] == '\0') {
memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
} else {
memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
}
}
}
}
/* Data handler :
* copy data depending on the current element name and state */
void IGDdata(void * d, const char * data, int l)
{
struct IGDdatas * datas = (struct IGDdatas *)d;
char * dstmember = 0;
/*printf("%2d %s : %.*s\n",
datas->level, datas->cureltname, l, data); */
if( !strcmp(datas->cureltname, "URLBase") )
dstmember = datas->urlbase;
else if( !strcmp(datas->cureltname, "presentationURL") )
dstmember = datas->presentationurl;
else if( !strcmp(datas->cureltname, "serviceType") )
dstmember = datas->tmp.servicetype;
else if( !strcmp(datas->cureltname, "controlURL") )
dstmember = datas->tmp.controlurl;
else if( !strcmp(datas->cureltname, "eventSubURL") )
dstmember = datas->tmp.eventsuburl;
else if( !strcmp(datas->cureltname, "SCPDURL") )
dstmember = datas->tmp.scpdurl;
/* else if( !strcmp(datas->cureltname, "deviceType") )
dstmember = datas->devicetype_tmp;*/
if(dstmember)
{
if(l>=MINIUPNPC_URL_MAXSIZE)
l = MINIUPNPC_URL_MAXSIZE-1;
memcpy(dstmember, data, l);
dstmember[l] = '\0';
}
}
#ifdef DEBUG
void printIGD(struct IGDdatas * d)
{
printf("urlbase = '%s'\n", d->urlbase);
printf("WAN Device (Common interface config) :\n");
/*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
printf(" serviceType = '%s'\n", d->CIF.servicetype);
printf(" controlURL = '%s'\n", d->CIF.controlurl);
printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
printf("primary WAN Connection Device (IP or PPP Connection):\n");
/*printf(" deviceType = '%s'\n", d->first.devicetype);*/
printf(" servicetype = '%s'\n", d->first.servicetype);
printf(" controlURL = '%s'\n", d->first.controlurl);
printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
printf(" SCPDURL = '%s'\n", d->first.scpdurl);
printf("secondary WAN Connection Device (IP or PPP Connection):\n");
/*printf(" deviceType = '%s'\n", d->second.devicetype);*/
printf(" servicetype = '%s'\n", d->second.servicetype);
printf(" controlURL = '%s'\n", d->second.controlurl);
printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
printf(" SCPDURL = '%s'\n", d->second.scpdurl);
printf("WAN IPv6 Firewall Control :\n");
/*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
}
#endif /* DEBUG */
+49
View File
@@ -0,0 +1,49 @@
/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */
/* Project : miniupnp
* http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2014 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef IGD_DESC_PARSE_H_INCLUDED
#define IGD_DESC_PARSE_H_INCLUDED
/* Structure to store the result of the parsing of UPnP
* descriptions of Internet Gateway Devices */
#define MINIUPNPC_URL_MAXSIZE (128)
struct IGDdatas_service {
char controlurl[MINIUPNPC_URL_MAXSIZE];
char eventsuburl[MINIUPNPC_URL_MAXSIZE];
char scpdurl[MINIUPNPC_URL_MAXSIZE];
char servicetype[MINIUPNPC_URL_MAXSIZE];
/*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
};
struct IGDdatas {
char cureltname[MINIUPNPC_URL_MAXSIZE];
char urlbase[MINIUPNPC_URL_MAXSIZE];
char presentationurl[MINIUPNPC_URL_MAXSIZE];
int level;
/*int state;*/
/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
struct IGDdatas_service CIF;
/* "urn:schemas-upnp-org:service:WANIPConnection:1"
* "urn:schemas-upnp-org:service:WANPPPConnection:1" */
struct IGDdatas_service first;
/* if both WANIPConnection and WANPPPConnection are present */
struct IGDdatas_service second;
/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
struct IGDdatas_service IPv6FC;
/* tmp */
struct IGDdatas_service tmp;
};
void IGDstartelt(void *, const char *, int);
void IGDendelt(void *, const char *, int);
void IGDdata(void *, const char *, int);
#ifdef DEBUG
void printIGD(struct IGDdatas *);
#endif /* DEBUG */
#endif /* IGD_DESC_PARSE_H_INCLUDED */
+123
View File
@@ -0,0 +1,123 @@
/* $Id: minisoap.c,v 1.23 2014/11/04 22:31:55 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
*
* Minimal SOAP implementation for UPnP protocol.
*/
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#include <winsock2.h>
#define snprintf _snprintf
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include "minisoap.h"
#include "miniupnpcstrings.h"
/* only for malloc */
#include <stdlib.h>
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif
/* httpWrite sends the headers and the body to the socket
* and returns the number of bytes sent */
static int
httpWrite(int fd, const char * body, int bodysize,
const char * headers, int headerssize)
{
int n = 0;
/*n = write(fd, headers, headerssize);*/
/*if(bodysize>0)
n += write(fd, body, bodysize);*/
/* Note : my old linksys router only took into account
* soap request that are sent into only one packet */
char * p;
/* TODO: AVOID MALLOC, we could use writev() for that */
p = (char*)malloc(headerssize+bodysize);
if(!p)
return -1;
memcpy(p, headers, headerssize);
memcpy(p+headerssize, body, bodysize);
/*n = write(fd, p, headerssize+bodysize);*/
n = (int)send(fd, p, headerssize+bodysize, 0);
if(n<0) {
PRINT_SOCKET_ERROR("send");
}
/* disable send on the socket */
/* draytek routers dont seems to like that... */
#if 0
#ifdef _WIN32
if(shutdown(fd, SD_SEND)<0) {
#else
if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/
#endif
PRINT_SOCKET_ERROR("shutdown");
}
#endif
free(p);
return n;
}
/* self explanatory */
int soapPostSubmit(int fd,
const char * url,
const char * host,
unsigned short port,
const char * action,
const char * body,
const char * httpversion)
{
int bodysize;
char headerbuf[512];
int headerssize;
char portstr[8];
bodysize = (int)strlen(body);
/* We are not using keep-alive HTTP connections.
* HTTP/1.1 needs the header Connection: close to do that.
* This is the default with HTTP/1.0
* Using HTTP/1.1 means we need to support chunked transfer-encoding :
* When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
* transfer encoding. */
/* Connection: Close is normally there only in HTTP/1.1 but who knows */
portstr[0] = '\0';
if(port != 80)
snprintf(portstr, sizeof(portstr), ":%hu", port);
headerssize = snprintf(headerbuf, sizeof(headerbuf),
"POST %s HTTP/%s\r\n"
"Host: %s%s\r\n"
"User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
"Content-Length: %d\r\n"
"Content-Type: text/xml\r\n"
"SOAPAction: \"%s\"\r\n"
"Connection: Close\r\n"
"Cache-Control: no-cache\r\n" /* ??? */
"Pragma: no-cache\r\n"
"\r\n",
url, httpversion, host, portstr, bodysize, action);
if ((unsigned int)headerssize >= sizeof(headerbuf))
return -1;
#ifdef DEBUG
/*printf("SOAP request : headersize=%d bodysize=%d\n",
headerssize, bodysize);
*/
printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
url, httpversion, host, portstr);
printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
printf("Headers :\n%s", headerbuf);
printf("Body :\n%s\n", body);
#endif
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
}
+15
View File
@@ -0,0 +1,15 @@
/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#ifndef MINISOAP_H_INCLUDED
#define MINISOAP_H_INCLUDED
/*int httpWrite(int, const char *, int, const char *);*/
int soapPostSubmit(int, const char *, const char *, unsigned short,
const char *, const char *, const char *);
#endif
+878
View File
@@ -0,0 +1,878 @@
/* $Id: minissdpc.c,v 1.32 2016/10/07 09:04:36 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2017 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
/*#include <syslog.h>*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#if defined (__NetBSD__)
#include <net/if.h>
#endif
#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#include <iphlpapi.h>
#include <winsock.h>
#define snprintf _snprintf
#if !defined(_MSC_VER)
#include <stdint.h>
#else /* !defined(_MSC_VER) */
typedef unsigned short uint16_t;
#endif /* !defined(_MSC_VER) */
#ifndef strncasecmp
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#define strncasecmp _memicmp
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
#endif /* _WIN32 */
#if defined(__amigaos__) || defined(__amigaos4__)
#include <sys/socket.h>
#endif /* defined(__amigaos__) || defined(__amigaos4__) */
#if defined(__amigaos__)
#define uint16_t unsigned short
#endif /* defined(__amigaos__) */
/* Hack */
#define UNIX_PATH_LEN 108
struct sockaddr_un {
uint16_t sun_family;
char sun_path[UNIX_PATH_LEN];
};
#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#define closesocket close
#endif
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif
#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__)
#define HAS_IP_MREQN
#endif
#if !defined(HAS_IP_MREQN) && !defined(_WIN32)
#include <sys/ioctl.h>
#if defined(__sun)
#include <sys/sockio.h>
#endif
#endif
#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN)
/* Several versions of glibc don't define this structure,
* define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */
struct ip_mreqn
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_address; /* local IP address of interface */
int imr_ifindex; /* Interface index */
};
#endif
#if defined(__amigaos__) || defined(__amigaos4__)
/* Amiga OS specific stuff */
#define TIMEVAL struct timeval
#endif
#include "minissdpc.h"
#include "miniupnpc.h"
#include "receivedata.h"
#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__))
#include "codelength.h"
struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error)
{
struct UPNPDev * devlist = NULL;
int s;
int res;
s = connectToMiniSSDPD(socketpath);
if (s < 0) {
if (error)
*error = s;
return NULL;
}
res = requestDevicesFromMiniSSDPD(s, devtype);
if (res < 0) {
if (error)
*error = res;
} else {
devlist = receiveDevicesFromMiniSSDPD(s, error);
}
disconnectFromMiniSSDPD(s);
return devlist;
}
/* macros used to read from unix socket */
#define READ_BYTE_BUFFER(c) \
if((int)bufferindex >= n) { \
n = read(s, buffer, sizeof(buffer)); \
if(n<=0) break; \
bufferindex = 0; \
} \
c = buffer[bufferindex++];
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif /* MIN */
#define READ_COPY_BUFFER(dst, len) \
for(l = len, p = (unsigned char *)dst; l > 0; ) { \
unsigned int lcopy; \
if((int)bufferindex >= n) { \
n = read(s, buffer, sizeof(buffer)); \
if(n<=0) break; \
bufferindex = 0; \
} \
lcopy = MIN(l, (n - bufferindex)); \
memcpy(p, buffer + bufferindex, lcopy); \
l -= lcopy; \
p += lcopy; \
bufferindex += lcopy; \
}
#define READ_DISCARD_BUFFER(len) \
for(l = len; l > 0; ) { \
unsigned int lcopy; \
if(bufferindex >= n) { \
n = read(s, buffer, sizeof(buffer)); \
if(n<=0) break; \
bufferindex = 0; \
} \
lcopy = MIN(l, (n - bufferindex)); \
l -= lcopy; \
bufferindex += lcopy; \
}
int
connectToMiniSSDPD(const char * socketpath)
{
int s;
struct sockaddr_un addr;
#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun)
struct timeval timeout;
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
s = socket(AF_UNIX, SOCK_STREAM, 0);
if(s < 0)
{
/*syslog(LOG_ERR, "socket(unix): %m");*/
perror("socket(unix)");
return MINISSDPC_SOCKET_ERROR;
}
#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun)
/* setting a 3 seconds timeout */
/* not supported for AF_UNIX sockets under Solaris */
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
{
perror("setsockopt SO_RCVTIMEO unix");
}
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
{
perror("setsockopt SO_SNDTIMEO unix");
}
#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
if(!socketpath)
socketpath = "/var/run/minissdpd.sock";
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
/* TODO : check if we need to handle the EINTR */
if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
{
/*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
close(s);
return MINISSDPC_SOCKET_ERROR;
}
return s;
}
int
disconnectFromMiniSSDPD(int s)
{
if (close(s) < 0)
return MINISSDPC_SOCKET_ERROR;
return MINISSDPC_SUCCESS;
}
int
requestDevicesFromMiniSSDPD(int s, const char * devtype)
{
unsigned char buffer[256];
unsigned char * p;
unsigned int l;
unsigned stsize = (unsigned)strlen(devtype);
if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8))
{
buffer[0] = 3; /* request type 3 : everything */
}
else
{
buffer[0] = 1; /* request type 1 : request devices/services by type */
}
p = buffer + 1;
l = stsize; CODELENGTH(l, p);
if(p + stsize > buffer + sizeof(buffer))
{
/* devtype is too long ! */
#ifdef DEBUG
fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n",
stsize, (unsigned)sizeof(buffer));
#endif /* DEBUG */
return MINISSDPC_INVALID_INPUT;
}
memcpy(p, devtype, stsize);
p += stsize;
if(write(s, buffer, p - buffer) < 0)
{
/*syslog(LOG_ERR, "write(): %m");*/
perror("minissdpc.c: write()");
return MINISSDPC_SOCKET_ERROR;
}
return MINISSDPC_SUCCESS;
}
struct UPNPDev *
receiveDevicesFromMiniSSDPD(int s, int * error)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = NULL;
unsigned char buffer[256];
ssize_t n;
unsigned char * p;
unsigned char * url;
unsigned char * st;
unsigned int bufferindex;
unsigned int i, ndev;
unsigned int urlsize, stsize, usnsize, l;
n = read(s, buffer, sizeof(buffer));
if(n<=0)
{
perror("minissdpc.c: read()");
if (error)
*error = MINISSDPC_SOCKET_ERROR;
return NULL;
}
ndev = buffer[0];
bufferindex = 1;
for(i = 0; i < ndev; i++)
{
DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER);
if(n<=0) {
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
return devlist;
}
#ifdef DEBUG
printf(" urlsize=%u", urlsize);
#endif /* DEBUG */
url = (unsigned char*)malloc(urlsize);
if(url == NULL)
{
if (error)
*error = MINISSDPC_MEMORY_ERROR;
return devlist;
}
READ_COPY_BUFFER(url, urlsize);
if(n<=0)
{
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
goto free_url_and_return;
}
DECODELENGTH_READ(stsize, READ_BYTE_BUFFER);
if(n<=0)
{
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
goto free_url_and_return;
}
#ifdef DEBUG
printf(" stsize=%u", stsize);
#endif /* DEBUG */
st = (unsigned char*)malloc(stsize);
if (st == NULL) {
if (error)
*error = MINISSDPC_MEMORY_ERROR;
goto free_url_and_return;
}
READ_COPY_BUFFER(st, stsize);
if(n<=0) {
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
goto free_url_and_st_and_return;
}
DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER);
if(n<=0) {
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
goto free_url_and_st_and_return;
}
#ifdef DEBUG
printf(" usnsize=%u\n", usnsize);
#endif /* DEBUG */
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize);
if(tmp == NULL) {
if (error)
*error = MINISSDPC_MEMORY_ERROR;
goto free_url_and_st_and_return;
}
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
memcpy(tmp->buffer, url, urlsize);
tmp->buffer[urlsize] = '\0';
memcpy(tmp->st, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
free(url);
free(st);
url = NULL;
st = NULL;
tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize;
READ_COPY_BUFFER(tmp->usn, usnsize);
if(n<=0) {
if (error)
*error = MINISSDPC_INVALID_SERVER_REPLY;
goto free_tmp_and_return;
}
tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */
devlist = tmp;
}
if (error)
*error = MINISSDPC_SUCCESS;
return devlist;
free_url_and_st_and_return:
free(st);
free_url_and_return:
free(url);
return devlist;
free_tmp_and_return:
free(tmp);
return devlist;
}
#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */
/* parseMSEARCHReply()
* the last 4 arguments are filled during the parsing :
* - location/locationsize : "location:" field of the SSDP reply packet
* - st/stsize : "st:" field of the SSDP reply packet.
* The strings are NOT null terminated */
static void
parseMSEARCHReply(const char * reply, int size,
const char * * location, int * locationsize,
const char * * st, int * stsize,
const char * * usn, int * usnsize)
{
int a, b, i;
i = 0;
a = i; /* start of the line */
b = 0; /* end of the "header" (position of the colon) */
while(i<size)
{
switch(reply[i])
{
case ':':
if(b==0)
{
b = i; /* end of the "header" */
/*for(j=a; j<b; j++)
{
putchar(reply[j]);
}
*/
}
break;
case '\x0a':
case '\x0d':
if(b!=0)
{
/*for(j=b+1; j<i; j++)
{
putchar(reply[j]);
}
putchar('\n');*/
/* skip the colon and white spaces */
do { b++; } while(reply[b]==' ');
if(0==strncasecmp(reply+a, "location", 8))
{
*location = reply+b;
*locationsize = i-b;
}
else if(0==strncasecmp(reply+a, "st", 2))
{
*st = reply+b;
*stsize = i-b;
}
else if(0==strncasecmp(reply+a, "usn", 3))
{
*usn = reply+b;
*usnsize = i-b;
}
b = 0;
}
a = i+1;
break;
default:
break;
}
i++;
}
}
/* port upnp discover : SSDP protocol */
#define SSDP_PORT 1900
#define XSTR(s) MINISSDPC_STR(s)
#define MINISSDPC_STR(s) #s
#define UPNP_MCAST_ADDR "239.255.255.250"
/* for IPv6 */
#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
/* direct discovery if minissdpd responses are not sufficient */
/* ssdpDiscoverDevices() :
* return a chained list of all devices found or NULL if
* no devices was found.
* It is up to the caller to free the chained list
* delay is in millisecond (poll).
* UDA v1.1 says :
* The TTL for the IP packet SHOULD default to 2 and
* SHOULD be configurable. */
struct UPNPDev *
ssdpDiscoverDevices(const char * const deviceTypes[],
int delay, const char * multicastif,
int localport,
int ipv6, unsigned char ttl,
int * error,
int searchalltypes)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = 0;
unsigned int scope_id = 0;
int opt = 1;
static const char MSearchMsgFmt[] =
"M-SEARCH * HTTP/1.1\r\n"
"HOST: %s:" XSTR(SSDP_PORT) "\r\n"
"ST: %s\r\n"
"MAN: \"ssdp:discover\"\r\n"
"MX: %u\r\n"
"\r\n";
int deviceIndex;
char bufr[1536]; /* reception and emission buffer */
int sudp;
int n;
struct sockaddr_storage sockudp_r;
unsigned int mx;
#ifdef NO_GETADDRINFO
struct sockaddr_storage sockudp_w;
#else
int rv;
struct addrinfo hints, *servinfo, *p;
#endif
#ifdef _WIN32
MIB_IPFORWARDROW ip_forward;
unsigned long _ttl = (unsigned long)ttl;
#endif
int linklocal = 1;
if(error)
*error = MINISSDPC_UNKNOWN_ERROR;
if(localport==UPNP_LOCAL_PORT_SAME)
localport = SSDP_PORT;
#ifdef _WIN32
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
#else
sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
#endif
if(sudp < 0)
{
if(error)
*error = MINISSDPC_SOCKET_ERROR;
PRINT_SOCKET_ERROR("socket");
return NULL;
}
/* reception */
memset(&sockudp_r, 0, sizeof(struct sockaddr_storage));
if(ipv6) {
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
p->sin6_family = AF_INET6;
if(localport > 0 && localport < 65536)
p->sin6_port = htons((unsigned short)localport);
p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
} else {
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
p->sin_family = AF_INET;
if(localport > 0 && localport < 65536)
p->sin_port = htons((unsigned short)localport);
p->sin_addr.s_addr = INADDR_ANY;
}
#ifdef _WIN32
/* This code could help us to use the right Network interface for
* SSDP multicast traffic */
/* Get IP associated with the index given in the ip_forward struct
* in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
if(!ipv6
&& (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
DWORD dwRetVal = 0;
PMIB_IPADDRTABLE pIPAddrTable;
DWORD dwSize = 0;
#ifdef DEBUG
IN_ADDR IPAddr;
#endif
int i;
#ifdef DEBUG
printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop);
#endif
pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE));
if(pIPAddrTable) {
if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
free(pIPAddrTable);
pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize);
}
}
if(pIPAddrTable) {
dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
if (dwRetVal == NO_ERROR) {
#ifdef DEBUG
printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
#endif
for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) {
#ifdef DEBUG
printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex);
IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) );
IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) );
IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr);
printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize);
printf("\tType and State[%d]:", i);
printf("\n");
#endif
if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) {
/* Set the address of this interface to be used */
struct in_addr mc_if;
memset(&mc_if, 0, sizeof(mc_if));
mc_if.s_addr = pIPAddrTable->table[i].dwAddr;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
PRINT_SOCKET_ERROR("setsockopt");
}
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr;
#ifndef DEBUG
break;
#endif
}
}
}
free(pIPAddrTable);
pIPAddrTable = NULL;
}
}
#endif /* _WIN32 */
#ifdef _WIN32
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
#else
if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
#endif
{
if(error)
*error = MINISSDPC_SOCKET_ERROR;
PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)");
return NULL;
}
#ifdef _WIN32
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0)
#else /* _WIN32 */
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
#endif /* _WIN32 */
{
/* not a fatal error */
PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)");
}
if(multicastif)
{
if(ipv6) {
#if !defined(_WIN32)
/* according to MSDN, if_nametoindex() is supported since
* MS Windows Vista and MS Windows Server 2008.
* http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF");
}
#else
#ifdef DEBUG
printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
#endif
#endif
} else {
struct in_addr mc_if;
mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
if(mc_if.s_addr != INADDR_NONE)
{
((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
}
} else {
#ifdef HAS_IP_MREQN
/* was not an ip address, try with an interface name */
struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
memset(&reqn, 0, sizeof(struct ip_mreqn));
reqn.imr_ifindex = if_nametoindex(multicastif);
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
}
#elif !defined(_WIN32)
struct ifreq ifr;
int ifrlen = sizeof(ifr);
strncpy(ifr.ifr_name, multicastif, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0)
{
PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)");
}
mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
{
PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
}
#else /* _WIN32 */
#ifdef DEBUG
printf("Setting of multicast interface not supported with interface name.\n");
#endif
#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */
}
}
}
/* Before sending the packed, we first "bind" in order to be able
* to receive the response */
if (bind(sudp, (const struct sockaddr *)&sockudp_r,
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
{
if(error)
*error = MINISSDPC_SOCKET_ERROR;
PRINT_SOCKET_ERROR("bind");
closesocket(sudp);
return NULL;
}
if(error)
*error = MINISSDPC_SUCCESS;
/* Calculating maximum response time in seconds */
mx = ((unsigned int)delay) / 1000u;
if(mx == 0) {
mx = 1;
delay = 1000;
}
/* receiving SSDP response packet */
for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) {
/* sending the SSDP M-SEARCH packet */
n = snprintf(bufr, sizeof(bufr),
MSearchMsgFmt,
ipv6 ?
(linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]")
: UPNP_MCAST_ADDR,
deviceTypes[deviceIndex], mx);
if ((unsigned int)n >= sizeof(bufr)) {
if(error)
*error = MINISSDPC_MEMORY_ERROR;
goto error;
}
#ifdef DEBUG
/*printf("Sending %s", bufr);*/
printf("Sending M-SEARCH request to %s with ST: %s\n",
ipv6 ?
(linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]")
: UPNP_MCAST_ADDR,
deviceTypes[deviceIndex]);
#endif
#ifdef NO_GETADDRINFO
/* the following code is not using getaddrinfo */
/* emission */
memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
if(ipv6) {
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
p->sin6_family = AF_INET6;
p->sin6_port = htons(SSDP_PORT);
inet_pton(AF_INET6,
linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
&(p->sin6_addr));
} else {
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
p->sin_family = AF_INET;
p->sin_port = htons(SSDP_PORT);
p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
}
n = sendto(sudp, bufr, n, 0, &sockudp_w,
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
if (n < 0) {
if(error)
*error = MINISSDPC_SOCKET_ERROR;
PRINT_SOCKET_ERROR("sendto");
break;
}
#else /* #ifdef NO_GETADDRINFO */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */
hints.ai_socktype = SOCK_DGRAM;
/*hints.ai_flags = */
if ((rv = getaddrinfo(ipv6
? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
: UPNP_MCAST_ADDR,
XSTR(SSDP_PORT), &hints, &servinfo)) != 0) {
if(error)
*error = MINISSDPC_SOCKET_ERROR;
#ifdef _WIN32
fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
#else
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
#endif
break;
}
for(p = servinfo; p; p = p->ai_next) {
n = (int)sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
if (n < 0) {
#ifdef DEBUG
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf);
}
#endif
PRINT_SOCKET_ERROR("sendto");
continue;
}
}
freeaddrinfo(servinfo);
if(n < 0) {
if(error)
*error = MINISSDPC_SOCKET_ERROR;
break;
}
#endif /* #ifdef NO_GETADDRINFO */
/* Waiting for SSDP REPLY packet to M-SEARCH
* if searchalltypes is set, enter the loop only
* when the last deviceType is reached */
if(!searchalltypes || !deviceTypes[deviceIndex + 1]) do {
n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
if (n < 0) {
/* error */
if(error)
*error = MINISSDPC_SOCKET_ERROR;
goto error;
} else if (n == 0) {
/* no data or Time Out */
#ifdef DEBUG
printf("NODATA or TIMEOUT\n");
#endif /* DEBUG */
if (devlist && !searchalltypes) {
/* found some devices, stop now*/
if(error)
*error = MINISSDPC_SUCCESS;
goto error;
}
} else {
const char * descURL=NULL;
int urlsize=0;
const char * st=NULL;
int stsize=0;
const char * usn=NULL;
int usnsize=0;
parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize);
if(st&&descURL) {
#ifdef DEBUG
printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n",
stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
#endif /* DEBUG */
for(tmp=devlist; tmp; tmp = tmp->pNext) {
if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
tmp->descURL[urlsize] == '\0' &&
memcmp(tmp->st, st, stsize) == 0 &&
tmp->st[stsize] == '\0' &&
(usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) &&
tmp->usn[usnsize] == '\0')
break;
}
/* at the exit of the loop above, tmp is null if
* no duplicate device was found */
if(tmp)
continue;
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize);
if(!tmp) {
/* memory allocation error */
if(error)
*error = MINISSDPC_MEMORY_ERROR;
goto error;
}
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
tmp->usn = tmp->st + 1 + stsize;
memcpy(tmp->buffer, descURL, urlsize);
tmp->buffer[urlsize] = '\0';
memcpy(tmp->st, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
if(usn != NULL)
memcpy(tmp->usn, usn, usnsize);
tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
tmp->scope_id = scope_id;
devlist = tmp;
}
}
} while(n > 0);
if(ipv6) {
/* switch linklocal flag */
if(linklocal) {
linklocal = 0;
--deviceIndex;
} else {
linklocal = 1;
}
}
}
error:
closesocket(sudp);
return devlist;
}
+58
View File
@@ -0,0 +1,58 @@
/* $Id: minissdpc.h,v 1.6 2015/09/18 12:45:16 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef MINISSDPC_H_INCLUDED
#define MINISSDPC_H_INCLUDED
#include "miniupnpc_declspec.h"
#include "upnpdev.h"
/* error codes : */
#define MINISSDPC_SUCCESS (0)
#define MINISSDPC_UNKNOWN_ERROR (-1)
#define MINISSDPC_SOCKET_ERROR (-101)
#define MINISSDPC_MEMORY_ERROR (-102)
#define MINISSDPC_INVALID_INPUT (-103)
#define MINISSDPC_INVALID_SERVER_REPLY (-104)
#ifdef __cplusplus
extern "C" {
#endif
#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__))
MINIUPNP_LIBSPEC struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error);
MINIUPNP_LIBSPEC int
connectToMiniSSDPD(const char * socketpath);
MINIUPNP_LIBSPEC int
disconnectFromMiniSSDPD(int fd);
MINIUPNP_LIBSPEC int
requestDevicesFromMiniSSDPD(int fd, const char * devtype);
MINIUPNP_LIBSPEC struct UPNPDev *
receiveDevicesFromMiniSSDPD(int fd, int * error);
#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */
MINIUPNP_LIBSPEC struct UPNPDev *
ssdpDiscoverDevices(const char * const deviceTypes[],
int delay, const char * multicastif,
int localport,
int ipv6, unsigned char ttl,
int * error,
int searchalltypes);
#ifdef __cplusplus
}
#endif
#endif
+722
View File
@@ -0,0 +1,722 @@
/* $Id: miniupnpc.c,v 1.148 2016/01/24 17:24:36 nanard Exp $ */
/* vim: tabstop=4 shiftwidth=4 noexpandtab
* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2016 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
/* Win32 Specific includes and defines */
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#include <iphlpapi.h>
#define snprintf _snprintf
#define strdup _strdup
#ifndef strncasecmp
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#define strncasecmp _memicmp
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
#define MAXHOSTNAMELEN 64
#else /* #ifdef _WIN32 */
/* Standard POSIX includes */
#include <unistd.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
/* Amiga OS 3 specific stuff */
#define socklen_t int
#else
#include <sys/select.h>
#endif
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h>
#endif
#include <strings.h>
#include <errno.h>
#define closesocket close
#endif /* #else _WIN32 */
#ifdef __GNU__
#define MAXHOSTNAMELEN 64
#endif
#include "miniupnpc.h"
#include "minissdpc.h"
#include "miniwget.h"
#include "minisoap.h"
#include "minixml.h"
#include "upnpcommands.h"
#include "connecthostport.h"
/* compare the begining of a string with a constant string */
#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1))
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
#define SOAPPREFIX "s"
#define SERVICEPREFIX "u"
#define SERVICEPREFIX2 'u'
/* check if an ip address is a private (LAN) address
* see https://tools.ietf.org/html/rfc1918 */
static int is_rfc1918addr(const char * addr)
{
/* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */
if(COMPARE(addr, "192.168."))
return 1;
/* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */
if(COMPARE(addr, "10."))
return 1;
/* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */
if(COMPARE(addr, "172.")) {
int i = atoi(addr + 4);
if((16 <= i) && (i <= 31))
return 1;
}
return 0;
}
/* root description parsing */
MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
{
struct xmlparser parser;
/* xmlparser object */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = data;
parser.starteltfunc = IGDstartelt;
parser.endeltfunc = IGDendelt;
parser.datafunc = IGDdata;
parser.attfunc = 0;
parsexml(&parser);
#ifdef DEBUG
printIGD(data);
#endif
}
/* simpleUPnPcommand2 :
* not so simple !
* return values :
* pointer - OK
* NULL - error */
char * simpleUPnPcommand2(int s, const char * url, const char * service,
const char * action, struct UPNParg * args,
int * bufsize, const char * httpversion)
{
char hostname[MAXHOSTNAMELEN+1];
unsigned short port = 0;
char * path;
char soapact[128];
char soapbody[2048];
int soapbodylen;
char * buf;
int n;
int status_code;
*bufsize = 0;
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
if(args==NULL)
{
soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<" SOAPPREFIX ":Envelope "
"xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<" SOAPPREFIX ":Body>"
"<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">"
"</" SERVICEPREFIX ":%s>"
"</" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>"
"\r\n", action, service, action);
if ((unsigned int)soapbodylen >= sizeof(soapbody))
return NULL;
}
else
{
char * p;
const char * pe, * pv;
const char * const pend = soapbody + sizeof(soapbody);
soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<" SOAPPREFIX ":Envelope "
"xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<" SOAPPREFIX ":Body>"
"<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">",
action, service);
if ((unsigned int)soapbodylen >= sizeof(soapbody))
return NULL;
p = soapbody + soapbodylen;
while(args->elt)
{
if(p >= pend) /* check for space to write next byte */
return NULL;
*(p++) = '<';
pe = args->elt;
while(p < pend && *pe)
*(p++) = *(pe++);
if(p >= pend) /* check for space to write next byte */
return NULL;
*(p++) = '>';
if((pv = args->val))
{
while(p < pend && *pv)
*(p++) = *(pv++);
}
if((p+2) > pend) /* check for space to write next 2 bytes */
return NULL;
*(p++) = '<';
*(p++) = '/';
pe = args->elt;
while(p < pend && *pe)
*(p++) = *(pe++);
if(p >= pend) /* check for space to write next byte */
return NULL;
*(p++) = '>';
args++;
}
if((p+4) > pend) /* check for space to write next 4 bytes */
return NULL;
*(p++) = '<';
*(p++) = '/';
*(p++) = SERVICEPREFIX2;
*(p++) = ':';
pe = action;
while(p < pend && *pe)
*(p++) = *(pe++);
strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
pend - p);
if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */
return NULL;
}
if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
if(s < 0) {
s = connecthostport(hostname, port, 0);
if(s < 0) {
/* failed to connect */
return NULL;
}
}
n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
if(n<=0) {
#ifdef DEBUG
printf("Error sending SOAP request\n");
#endif
closesocket(s);
return NULL;
}
buf = (char*)getHTTPResponse(s, bufsize, &status_code);
#ifdef DEBUG
if(*bufsize > 0 && buf)
{
printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf);
}
else
{
printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize);
}
#endif
closesocket(s);
return buf;
}
/* simpleUPnPcommand :
* not so simple !
* return values :
* pointer - OK
* NULL - error */
char * simpleUPnPcommand(int s, const char * url, const char * service,
const char * action, struct UPNParg * args,
int * bufsize)
{
char * buf;
#if 1
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
#else
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
if (!buf || *bufsize == 0)
{
#if DEBUG
printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
#endif
buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
}
#endif
return buf;
}
/* upnpDiscoverDevices() :
* return a chained list of all devices found or NULL if
* no devices was found.
* It is up to the caller to free the chained list
* delay is in millisecond (poll).
* UDA v1.1 says :
* The TTL for the IP packet SHOULD default to 2 and
* SHOULD be configurable. */
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverDevices(const char * const deviceTypes[],
int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error,
int searchalltypes)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = 0;
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
int deviceIndex;
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
if(error)
*error = UPNPDISCOVER_UNKNOWN_ERROR;
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
/* first try to get infos from minissdpd ! */
if(!minissdpdsock)
minissdpdsock = "/var/run/minissdpd.sock";
for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) {
struct UPNPDev * minissdpd_devlist;
int only_rootdevice = 1;
minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex],
minissdpdsock, 0);
if(minissdpd_devlist) {
#ifdef DEBUG
printf("returned by MiniSSDPD: %s\t%s\n",
minissdpd_devlist->st, minissdpd_devlist->descURL);
#endif /* DEBUG */
if(!strstr(minissdpd_devlist->st, "rootdevice"))
only_rootdevice = 0;
for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) {
#ifdef DEBUG
printf("returned by MiniSSDPD: %s\t%s\n",
tmp->pNext->st, tmp->pNext->descURL);
#endif /* DEBUG */
if(!strstr(tmp->st, "rootdevice"))
only_rootdevice = 0;
}
tmp->pNext = devlist;
devlist = minissdpd_devlist;
if(!searchalltypes && !only_rootdevice)
break;
}
}
for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) {
/* We return what we have found if it was not only a rootdevice */
if(!strstr(tmp->st, "rootdevice")) {
if(error)
*error = UPNPDISCOVER_SUCCESS;
return devlist;
}
}
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* direct discovery if minissdpd responses are not sufficient */
{
struct UPNPDev * discovered_devlist;
discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport,
ipv6, ttl, error, searchalltypes);
if(devlist == NULL)
devlist = discovered_devlist;
else {
for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext);
tmp->pNext = discovered_devlist;
}
}
return devlist;
}
/* upnpDiscover() Discover IGD device */
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error)
{
static const char * const deviceList[] = {
#if 0
"urn:schemas-upnp-org:device:InternetGatewayDevice:2",
"urn:schemas-upnp-org:service:WANIPConnection:2",
#endif
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
"urn:schemas-upnp-org:service:WANIPConnection:1",
"urn:schemas-upnp-org:service:WANPPPConnection:1",
"upnp:rootdevice",
/*"ssdp:all",*/
0
};
return upnpDiscoverDevices(deviceList,
delay, multicastif, minissdpdsock, localport,
ipv6, ttl, error, 0);
}
/* upnpDiscoverAll() Discover all UPnP devices */
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverAll(int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error)
{
static const char * const deviceList[] = {
/*"upnp:rootdevice",*/
"ssdp:all",
0
};
return upnpDiscoverDevices(deviceList,
delay, multicastif, minissdpdsock, localport,
ipv6, ttl, error, 0);
}
/* upnpDiscoverDevice() Discover a specific device */
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error)
{
const char * const deviceList[] = {
device,
0
};
return upnpDiscoverDevices(deviceList,
delay, multicastif, minissdpdsock, localport,
ipv6, ttl, error, 0);
}
static char *
build_absolute_url(const char * baseurl, const char * descURL,
const char * url, unsigned int scope_id)
{
int l, n;
char * s;
const char * base;
char * p;
#if defined(IF_NAMESIZE) && !defined(_WIN32)
char ifname[IF_NAMESIZE];
#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
char scope_str[8];
#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */
if( (url[0] == 'h')
&&(url[1] == 't')
&&(url[2] == 't')
&&(url[3] == 'p')
&&(url[4] == ':')
&&(url[5] == '/')
&&(url[6] == '/'))
return strdup(url);
base = (baseurl[0] == '\0') ? descURL : baseurl;
n = (int)strlen(base);
if(n > 7) {
p = (char*)strchr(base + 7, '/');
if(p)
n = (int)(p - base);
}
l = (int)(n + strlen(url) + 1);
if(url[0] != '/')
l++;
if(scope_id != 0) {
#if defined(IF_NAMESIZE) && !defined(_WIN32)
if(if_indextoname(scope_id, ifname)) {
l += 3 + strlen(ifname); /* 3 == strlen(%25) */
}
#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
/* under windows, scope is numerical */
l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */
}
s = (char*)malloc(l);
if(s == NULL) return NULL;
memcpy(s, base, n);
if(scope_id != 0) {
s[n] = '\0';
if(0 == memcmp(s, "http://[fe80:", 13)) {
/* this is a linklocal IPv6 address */
p = strchr(s, ']');
if(p) {
/* insert %25<scope> into URL */
#if defined(IF_NAMESIZE) && !defined(_WIN32)
memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, ifname, strlen(ifname));
n += 3 + strlen(ifname);
#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
memcpy(p, "%25", 3);
memcpy(p + 3, scope_str, strlen(scope_str));
n += 3 + strlen(scope_str);
#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */
}
}
}
if(url[0] != '/')
s[n++] = '/';
memcpy(s + n, url, l - n);
return s;
}
/* Prepare the Urls for usage...
*/
MINIUPNP_LIBSPEC void
GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
const char * descURL, unsigned int scope_id)
{
/* strdup descURL */
urls->rootdescURL = strdup(descURL);
/* get description of WANIPConnection */
urls->ipcondescURL = build_absolute_url(data->urlbase, descURL,
data->first.scpdurl, scope_id);
urls->controlURL = build_absolute_url(data->urlbase, descURL,
data->first.controlurl, scope_id);
urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL,
data->CIF.controlurl, scope_id);
urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL,
data->IPv6FC.controlurl, scope_id);
#ifdef DEBUG
printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL);
printf("urls->controlURL='%s'\n", urls->controlURL);
printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF);
printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC);
#endif
}
MINIUPNP_LIBSPEC void
FreeUPNPUrls(struct UPNPUrls * urls)
{
if(!urls)
return;
free(urls->controlURL);
urls->controlURL = 0;
free(urls->ipcondescURL);
urls->ipcondescURL = 0;
free(urls->controlURL_CIF);
urls->controlURL_CIF = 0;
free(urls->controlURL_6FC);
urls->controlURL_6FC = 0;
free(urls->rootdescURL);
urls->rootdescURL = 0;
}
int
UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
{
char status[64];
unsigned int uptime;
status[0] = '\0';
UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
status, &uptime, NULL);
if(0 == strcmp("Connected", status))
return 1;
else if(0 == strcmp("Up", status)) /* Also accept "Up" */
return 1;
else
return 0;
}
/* UPNP_GetValidIGD() :
* return values :
* -1 = Internal error
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as
* not connected
* 3 = an UPnP device has been found but was not recognized as an IGD
*
* In any positive non zero return case, the urls and data structures
* passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to
* free allocated memory.
*/
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen)
{
struct xml_desc {
char * xml;
int size;
int is_igd;
} * desc = NULL;
struct UPNPDev * dev;
int ndev = 0;
int i;
int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
int n_igd = 0;
char extIpAddr[16];
char myLanAddr[40];
int status_code = -1;
if(!devlist)
{
#ifdef DEBUG
printf("Empty devlist\n");
#endif
return 0;
}
/* counting total number of devices in the list */
for(dev = devlist; dev; dev = dev->pNext)
ndev++;
if(ndev > 0)
{
desc = (struct xml_desc*)calloc(ndev, sizeof(struct xml_desc));
if(!desc)
return -1; /* memory allocation error */
}
/* Step 1 : downloading descriptions and testing type */
for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
{
/* we should choose an internet gateway device.
* with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
desc[i].xml = (char*)miniwget_getaddr(dev->descURL, &(desc[i].size),
myLanAddr, sizeof(myLanAddr),
dev->scope_id, &status_code);
#ifdef DEBUG
if(!desc[i].xml)
{
printf("error getting XML description %s\n", dev->descURL);
}
#endif
if(desc[i].xml)
{
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(desc[i].xml, desc[i].size, data);
if(COMPARE(data->CIF.servicetype,
"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
{
desc[i].is_igd = 1;
n_igd++;
if(lanaddr)
strncpy(lanaddr, myLanAddr, lanaddrlen);
}
}
}
/* iterate the list to find a device depending on state */
for(state = 1; state <= 3; state++)
{
for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
{
if(desc[i].xml)
{
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(desc[i].xml, desc[i].size, data);
if(desc[i].is_igd || state >= 3 )
{
int is_connected;
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
/* in state 2 and 3 we dont test if device is connected ! */
if(state >= 2)
goto free_and_return;
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, is_connected);
#endif
/* checks that status is connected AND there is a external IP address assigned */
if(is_connected &&
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
goto free_and_return;
}
FreeUPNPUrls(urls);
if(data->second.servicetype[0] != '\0') {
#ifdef DEBUG
printf("We tried %s, now we try %s !\n",
data->first.servicetype, data->second.servicetype);
#endif
/* swaping WANPPPConnection and WANIPConnection ! */
memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
is_connected = UPNPIGD_IsConnected(urls, data);
#ifdef DEBUG
printf("UPNPIGD_IsConnected(%s) = %d\n",
urls->controlURL, is_connected);
#endif
if(is_connected &&
(UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) {
if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
&& (0 != strcmp(extIpAddr, "0.0.0.0")))
goto free_and_return;
}
FreeUPNPUrls(urls);
}
}
memset(data, 0, sizeof(struct IGDdatas));
}
}
}
state = 0;
free_and_return:
if(desc) {
for(i = 0; i < ndev; i++) {
if(desc[i].xml) {
free(desc[i].xml);
}
}
free(desc);
}
return state;
}
/* UPNP_GetIGDFromUrl()
* Used when skipping the discovery process.
* return value :
* 0 - Not ok
* 1 - OK */
int
UPNP_GetIGDFromUrl(const char * rootdescurl,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen)
{
char * descXML;
int descXMLsize = 0;
descXML = (char*)miniwget_getaddr(rootdescurl, &descXMLsize,
lanaddr, lanaddrlen, 0, NULL);
if(descXML) {
memset(data, 0, sizeof(struct IGDdatas));
memset(urls, 0, sizeof(struct UPNPUrls));
parserootdesc(descXML, descXMLsize, data);
free(descXML);
descXML = NULL;
GetUPNPUrls(urls, data, rootdescurl, 0);
return 1;
} else {
return 0;
}
}
+45
View File
@@ -0,0 +1,45 @@
LIBRARY
; miniupnpc library
miniupnpc
EXPORTS
; miniupnpc
upnpDiscover
freeUPNPDevlist
parserootdesc
UPNP_GetValidIGD
UPNP_GetIGDFromUrl
GetUPNPUrls
FreeUPNPUrls
; miniwget
miniwget
miniwget_getaddr
; upnpcommands
UPNP_GetTotalBytesSent
UPNP_GetTotalBytesReceived
UPNP_GetTotalPacketsSent
UPNP_GetTotalPacketsReceived
UPNP_GetStatusInfo
UPNP_GetConnectionTypeInfo
UPNP_GetExternalIPAddress
UPNP_GetLinkLayerMaxBitRates
UPNP_AddPortMapping
UPNP_AddAnyPortMapping
UPNP_DeletePortMapping
UPNP_DeletePortMappingRange
UPNP_GetPortMappingNumberOfEntries
UPNP_GetSpecificPortMappingEntry
UPNP_GetGenericPortMappingEntry
UPNP_GetListOfPortMappings
UPNP_AddPinhole
UPNP_CheckPinholeWorking
UPNP_UpdatePinhole
UPNP_GetPinholePackets
UPNP_DeletePinhole
UPNP_GetFirewallStatus
UPNP_GetOutboundPinholeTimeout
; upnperrors
strupnperror
; portlistingparse
ParsePortListing
FreePortListing
+152
View File
@@ -0,0 +1,152 @@
/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
* Copyright (c) 2005-2016 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef MINIUPNPC_H_INCLUDED
#define MINIUPNPC_H_INCLUDED
#include "miniupnpc_declspec.h"
#include "igd_desc_parse.h"
#include "upnpdev.h"
/* error codes : */
#define UPNPDISCOVER_SUCCESS (0)
#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
#define UPNPDISCOVER_SOCKET_ERROR (-101)
#define UPNPDISCOVER_MEMORY_ERROR (-102)
/* versions : */
#define MINIUPNPC_VERSION "2.0"
#define MINIUPNPC_API_VERSION 16
/* Source port:
Using "1" as an alias for 1900 for backwards compatability
(presuming one would have used that for the "sameport" parameter) */
#define UPNP_LOCAL_PORT_ANY 0
#define UPNP_LOCAL_PORT_SAME 1
#ifdef __cplusplus
extern "C" {
#endif
/* Structures definitions : */
struct UPNParg { const char * elt; const char * val; };
char *
simpleUPnPcommand(int, const char *, const char *,
const char *, struct UPNParg *,
int *);
/* upnpDiscover()
* discover UPnP devices on the network.
* The discovered devices are returned as a chained list.
* It is up to the caller to free the list with freeUPNPDevlist().
* delay (in millisecond) is the maximum time for waiting any device
* response.
* If available, device list will be obtained from MiniSSDPd.
* Default path for minissdpd socket will be used if minissdpdsock argument
* is NULL.
* If multicastif is not NULL, it will be used instead of the default
* multicast interface for sending SSDP discover packets.
* If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent
* from the source port 1900 (same as destination port), if set to
* UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will
* be attempted as the source port.
* "searchalltypes" parameter is useful when searching several types,
* if 0, the discovery will stop with the first type returning results.
* TTL should default to 2. */
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error);
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverAll(int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error);
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error);
MINIUPNP_LIBSPEC struct UPNPDev *
upnpDiscoverDevices(const char * const deviceTypes[],
int delay, const char * multicastif,
const char * minissdpdsock, int localport,
int ipv6, unsigned char ttl,
int * error,
int searchalltypes);
/* parserootdesc() :
* parse root XML description of a UPnP device and fill the IGDdatas
* structure. */
MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
/* structure used to get fast access to urls
* controlURL: controlURL of the WANIPConnection
* ipcondescURL: url of the description of the WANIPConnection
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
* controlURL_6FC: controlURL of the WANIPv6FirewallControl
*/
struct UPNPUrls {
char * controlURL;
char * ipcondescURL;
char * controlURL_CIF;
char * controlURL_6FC;
char * rootdescURL;
};
/* UPNP_GetValidIGD() :
* return values :
* 0 = NO IGD found
* 1 = A valid connected IGD has been found
* 2 = A valid IGD has been found but it reported as
* not connected
* 3 = an UPnP device has been found but was not recognized as an IGD
*
* In any non zero return case, the urls and data structures
* passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
* free allocated memory.
*/
MINIUPNP_LIBSPEC int
UPNP_GetValidIGD(struct UPNPDev * devlist,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen);
/* UPNP_GetIGDFromUrl()
* Used when skipping the discovery process.
* When succeding, urls, data, and lanaddr arguments are set.
* return value :
* 0 - Not ok
* 1 - OK */
MINIUPNP_LIBSPEC int
UPNP_GetIGDFromUrl(const char * rootdescurl,
struct UPNPUrls * urls,
struct IGDdatas * data,
char * lanaddr, int lanaddrlen);
MINIUPNP_LIBSPEC void
GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
const char *, unsigned int);
MINIUPNP_LIBSPEC void
FreeUPNPUrls(struct UPNPUrls *);
/* return 0 or 1 */
MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
#ifdef __cplusplus
}
#endif
#endif
+12
View File
@@ -0,0 +1,12 @@
#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED
#define MINIUPNPC_DECLSPEC_H_INCLUDED
#if defined(__GNUC__) && __GNUC__ >= 4
/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
#define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default")))
#else
#define MINIUPNP_LIBSPEC
#endif
#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */
+23
View File
@@ -0,0 +1,23 @@
/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2005-2014 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef MINIUPNPCSTRINGS_H_INCLUDED
#define MINIUPNPCSTRINGS_H_INCLUDED
#define OS_STRING "OS/version"
#define MINIUPNPC_VERSION_STRING "version"
#if 0
/* according to "UPnP Device Architecture 1.0" */
#define UPNP_VERSION_STRING "UPnP/1.0"
#else
/* according to "UPnP Device Architecture 1.1" */
#define UPNP_VERSION_STRING "UPnP/1.1"
#endif
#endif
+19
View File
@@ -0,0 +1,19 @@
/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
* Author : Thomas Bernard
* Copyright (c) 2011 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided within this distribution */
#ifndef MINIUPNPCTYPES_H_INCLUDED
#define MINIUPNPCTYPES_H_INCLUDED
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
#define UNSIGNED_INTEGER unsigned long long
#define STRTOUI strtoull
#else
#define UNSIGNED_INTEGER unsigned int
#define STRTOUI strtoul
#endif
#endif
+661
View File
@@ -0,0 +1,661 @@
/* $Id: miniwget.c,v 1.75 2016/01/24 17:24:36 nanard Exp $ */
/* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2016 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#define MAXHOSTNAMELEN 64
#define snprintf _snprintf
#define socklen_t int
#ifndef strncasecmp
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#define strncasecmp _memicmp
#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/param.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
#define socklen_t int
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#define closesocket close
#include <strings.h>
#endif /* #else _WIN32 */
#ifdef __GNU__
#define MAXHOSTNAMELEN 64
#endif /* __GNU__ */
#ifndef MIN
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif /* MIN */
#include "miniupnpcstrings.h"
#include "miniwget.h"
#include "connecthostport.h"
#include "receivedata.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
/*
* Read a HTTP response from a socket.
* Process Content-Length and Transfer-encoding headers.
* return a pointer to the content buffer, which length is saved
* to the length parameter.
*/
void *
getHTTPResponse(int s, int * size, int * status_code)
{
char buf[2048];
int n;
int endofheaders = 0;
int chunked = 0;
int content_length = -1;
unsigned int chunksize = 0;
unsigned int bytestocopy = 0;
/* buffers : */
char * header_buf;
unsigned int header_buf_len = 2048;
unsigned int header_buf_used = 0;
char * content_buf;
unsigned int content_buf_len = 2048;
unsigned int content_buf_used = 0;
char chunksize_buf[32];
unsigned int chunksize_buf_index;
#ifdef DEBUG
char * reason_phrase = NULL;
int reason_phrase_len = 0;
#endif
if(status_code) *status_code = -1;
header_buf = (char*)malloc(header_buf_len);
if(header_buf == NULL)
{
#ifdef DEBUG
fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
#endif /* DEBUG */
*size = -1;
return NULL;
}
content_buf = (char*)malloc(content_buf_len);
if(content_buf == NULL)
{
free(header_buf);
#ifdef DEBUG
fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
#endif /* DEBUG */
*size = -1;
return NULL;
}
chunksize_buf[0] = '\0';
chunksize_buf_index = 0;
while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0)
{
if(endofheaders == 0)
{
int i;
int linestart=0;
int colon=0;
int valuestart=0;
if(header_buf_used + n > header_buf_len) {
char * tmp = (char*)realloc(header_buf, header_buf_used + n);
if(tmp == NULL) {
/* memory allocation error */
free(header_buf);
free(content_buf);
*size = -1;
return NULL;
}
header_buf = tmp;
header_buf_len = header_buf_used + n;
}
memcpy(header_buf + header_buf_used, buf, n);
header_buf_used += n;
/* search for CR LF CR LF (end of headers)
* recognize also LF LF */
i = 0;
while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
if(header_buf[i] == '\r') {
i++;
if(header_buf[i] == '\n') {
i++;
if(i < (int)header_buf_used && header_buf[i] == '\r') {
i++;
if(i < (int)header_buf_used && header_buf[i] == '\n') {
endofheaders = i+1;
}
}
}
} else if(header_buf[i] == '\n') {
i++;
if(header_buf[i] == '\n') {
endofheaders = i+1;
}
}
i++;
}
if(endofheaders == 0)
continue;
/* parse header lines */
for(i = 0; i < endofheaders - 1; i++) {
if(linestart > 0 && colon <= linestart && header_buf[i]==':')
{
colon = i;
while(i < (endofheaders-1)
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
i++;
valuestart = i + 1;
}
/* detecting end of line */
else if(header_buf[i]=='\r' || header_buf[i]=='\n')
{
if(linestart == 0 && status_code)
{
/* Status line
* HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
int sp;
for(sp = 0; sp < i; sp++)
if(header_buf[sp] == ' ')
{
if(*status_code < 0)
*status_code = atoi(header_buf + sp + 1);
else
{
#ifdef DEBUG
reason_phrase = header_buf + sp + 1;
reason_phrase_len = i - sp - 1;
#endif
break;
}
}
#ifdef DEBUG
printf("HTTP status code = %d, Reason phrase = %.*s\n",
*status_code, reason_phrase_len, reason_phrase);
#endif
}
else if(colon > linestart && valuestart > colon)
{
#ifdef DEBUG
printf("header='%.*s', value='%.*s'\n",
colon-linestart, header_buf+linestart,
i-valuestart, header_buf+valuestart);
#endif
if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
{
content_length = atoi(header_buf+valuestart);
#ifdef DEBUG
printf("Content-Length: %d\n", content_length);
#endif
}
else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
&& 0==strncasecmp(header_buf+valuestart, "chunked", 7))
{
#ifdef DEBUG
printf("chunked transfer-encoding!\n");
#endif
chunked = 1;
}
}
while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
i++;
linestart = i;
colon = linestart;
valuestart = 0;
}
}
/* copy the remaining of the received data back to buf */
n = header_buf_used - endofheaders;
memcpy(buf, header_buf + endofheaders, n);
/* if(headers) */
}
if(endofheaders)
{
/* content */
if(chunked)
{
int i = 0;
while(i < n)
{
if(chunksize == 0)
{
/* reading chunk size */
if(chunksize_buf_index == 0) {
/* skipping any leading CR LF */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') i++;
}
while(i<n && isxdigit(buf[i])
&& chunksize_buf_index < (sizeof(chunksize_buf)-1))
{
chunksize_buf[chunksize_buf_index++] = buf[i];
chunksize_buf[chunksize_buf_index] = '\0';
i++;
}
while(i<n && buf[i] != '\r' && buf[i] != '\n')
i++; /* discarding chunk-extension */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') {
unsigned int j;
for(j = 0; j < chunksize_buf_index; j++) {
if(chunksize_buf[j] >= '0'
&& chunksize_buf[j] <= '9')
chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
else
chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
}
chunksize_buf[0] = '\0';
chunksize_buf_index = 0;
i++;
} else {
/* not finished to get chunksize */
continue;
}
#ifdef DEBUG
printf("chunksize = %u (%x)\n", chunksize, chunksize);
#endif
if(chunksize == 0)
{
#ifdef DEBUG
printf("end of HTTP content - %d %d\n", i, n);
/*printf("'%.*s'\n", n-i, buf+i);*/
#endif
goto end_of_stream;
}
}
bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
if((content_buf_used + bytestocopy) > content_buf_len)
{
char * tmp;
if(content_length >= (int)(content_buf_used + bytestocopy)) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + bytestocopy;
}
tmp = (char*)realloc(content_buf, content_buf_len);
if(tmp == NULL) {
/* memory allocation error */
free(content_buf);
free(header_buf);
*size = -1;
return NULL;
}
content_buf = tmp;
}
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
content_buf_used += bytestocopy;
i += bytestocopy;
chunksize -= bytestocopy;
}
}
else
{
/* not chunked */
if(content_length > 0
&& (int)(content_buf_used + n) > content_length) {
/* skipping additional bytes */
n = content_length - content_buf_used;
}
if(content_buf_used + n > content_buf_len)
{
char * tmp;
if(content_length >= (int)(content_buf_used + n)) {
content_buf_len = content_length;
} else {
content_buf_len = content_buf_used + n;
}
tmp = (char*)realloc(content_buf, content_buf_len);
if(tmp == NULL) {
/* memory allocation error */
free(content_buf);
free(header_buf);
*size = -1;
return NULL;
}
content_buf = tmp;
}
memcpy(content_buf + content_buf_used, buf, n);
content_buf_used += n;
}
}
/* use the Content-Length header value if available */
if(content_length > 0 && (int)content_buf_used >= content_length)
{
#ifdef DEBUG
printf("End of HTTP content\n");
#endif
break;
}
}
end_of_stream:
free(header_buf); header_buf = NULL;
*size = content_buf_used;
if(content_buf_used == 0)
{
free(content_buf);
content_buf = NULL;
}
return content_buf;
}
/* miniwget3() :
* do all the work.
* Return NULL if something failed. */
static void *
miniwget3(const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len,
const char * httpversion, unsigned int scope_id,
int * status_code)
{
char buf[2048];
int s;
int n;
int len;
int sent;
void * content;
*size = 0;
s = connecthostport(host, port, scope_id);
if(s < 0)
return NULL;
/* get address for caller ! */
if(addr_str)
{
struct sockaddr_storage saddr;
socklen_t saddrlen;
saddrlen = sizeof(saddr);
if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
{
perror("getsockname");
}
else
{
#if defined(__amigaos__) && !defined(__amigaos4__)
/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
* But his function make a string with the port : nn.nn.nn.nn:port */
/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
NULL, addr_str, (DWORD *)&addr_str_len))
{
printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
}*/
/* the following code is only compatible with ip v4 addresses */
strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
#else
#if 0
if(saddr.sa_family == AF_INET6) {
inet_ntop(AF_INET6,
&(((struct sockaddr_in6 *)&saddr)->sin6_addr),
addr_str, addr_str_len);
} else {
inet_ntop(AF_INET,
&(((struct sockaddr_in *)&saddr)->sin_addr),
addr_str, addr_str_len);
}
#endif
/* getnameinfo return ip v6 address with the scope identifier
* such as : 2a01:e35:8b2b:7330::%4281128194 */
n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
addr_str, addr_str_len,
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
if(n != 0) {
#ifdef _WIN32
fprintf(stderr, "getnameinfo() failed : %d\n", n);
#else
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
#endif
}
#endif
}
#ifdef DEBUG
printf("address miniwget : %s\n", addr_str);
#endif
}
len = snprintf(buf, sizeof(buf),
"GET %s HTTP/%s\r\n"
"Host: %s:%d\r\n"
"Connection: Close\r\n"
"User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
"\r\n",
path, httpversion, host, port);
if ((unsigned int)len >= sizeof(buf))
{
closesocket(s);
return NULL;
}
sent = 0;
/* sending the HTTP request */
while(sent < len)
{
n = (int)send(s, buf+sent, len-sent, 0);
if(n < 0)
{
perror("send");
closesocket(s);
return NULL;
}
else
{
sent += n;
}
}
content = getHTTPResponse(s, size, status_code);
closesocket(s);
return content;
}
/* miniwget2() :
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
static void *
miniwget2(const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len,
unsigned int scope_id, int * status_code)
{
char * respbuffer;
#if 1
respbuffer = (char*)miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1",
scope_id, status_code);
#else
respbuffer = (char*)miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.0",
scope_id, status_code);
if (*size == 0)
{
#ifdef DEBUG
printf("Retrying with HTTP/1.1\n");
#endif
free(respbuffer);
respbuffer = miniwget3(host, port, path, size,
addr_str, addr_str_len, "1.1",
scope_id, status_code);
}
#endif
return respbuffer;
}
/* parseURL()
* arguments :
* url : source string not modified
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
* port : port (destination)
* path : pointer to the path part of the URL
*
* Return values :
* 0 - Failure
* 1 - Success */
int
parseURL(const char * url,
char * hostname, unsigned short * port,
char * * path, unsigned int * scope_id)
{
char * p1, *p2, *p3;
if(!url)
return 0;
p1 = (char*)strstr(url, "://");
if(!p1)
return 0;
p1 += 3;
if( (url[0]!='h') || (url[1]!='t')
||(url[2]!='t') || (url[3]!='p'))
return 0;
memset(hostname, 0, MAXHOSTNAMELEN + 1);
if(*p1 == '[')
{
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
char * scope;
scope = strchr(p1, '%');
p2 = strchr(p1, ']');
if(p2 && scope && scope < p2 && scope_id) {
/* parse scope */
#ifdef IF_NAMESIZE
char tmp[IF_NAMESIZE];
int l;
scope++;
/* "%25" is just '%' in URL encoding */
if(scope[0] == '2' && scope[1] == '5')
scope += 2; /* skip "25" */
l = (int)(p2 - scope);
if(l >= IF_NAMESIZE)
l = IF_NAMESIZE - 1;
memcpy(tmp, scope, l);
tmp[l] = '\0';
*scope_id = if_nametoindex(tmp);
if(*scope_id == 0) {
*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
}
#else
/* under windows, scope is numerical */
char tmp[8];
int l;
scope++;
/* "%25" is just '%' in URL encoding */
if(scope[0] == '2' && scope[1] == '5')
scope += 2; /* skip "25" */
l = p2 - scope;
if(l >= sizeof(tmp))
l = sizeof(tmp) - 1;
memcpy(tmp, scope, l);
tmp[l] = '\0';
*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
#endif
}
p3 = strchr(p1, '/');
if(p2 && p3)
{
p2++;
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
if(*p2 == ':')
{
*port = 0;
p2++;
while( (*p2 >= '0') && (*p2 <= '9'))
{
*port *= 10;
*port += (unsigned short)(*p2 - '0');
p2++;
}
}
else
{
*port = 80;
}
*path = p3;
return 1;
}
}
p2 = strchr(p1, ':');
p3 = strchr(p1, '/');
if(!p3)
return 0;
if(!p2 || (p2>p3))
{
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
*port = 80;
}
else
{
strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
*port = 0;
p2++;
while( (*p2 >= '0') && (*p2 <= '9'))
{
*port *= 10;
*port += (unsigned short)(*p2 - '0');
p2++;
}
}
*path = p3;
return 1;
}
void *
miniwget(const char * url, int * size,
unsigned int scope_id, int * status_code)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#ifdef DEBUG
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
}
void *
miniwget_getaddr(const char * url, int * size,
char * addr, int addrlen, unsigned int scope_id,
int * status_code)
{
unsigned short port;
char * path;
/* protocol://host:port/path */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(addr)
addr[0] = '\0';
if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#ifdef DEBUG
printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
hostname, port, path, scope_id);
#endif
return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
}
+30
View File
@@ -0,0 +1,30 @@
/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005-2016 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef MINIWGET_H_INCLUDED
#define MINIWGET_H_INCLUDED
#include "miniupnpc_declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code);
MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *);
MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *);
int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
#ifdef __cplusplus
}
#endif
#endif
+229
View File
@@ -0,0 +1,229 @@
/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */
/* minixml.c : the minimum size a xml parser can be ! */
/* Project : miniupnp
* webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author : Thomas Bernard
Copyright (c) 2005-2014, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include "minixml.h"
/* parseatt : used to parse the argument list
* return 0 (false) in case of success and -1 (true) if the end
* of the xmlbuffer is reached. */
static int parseatt(struct xmlparser * p)
{
const char * attname;
int attnamelen;
const char * attvalue;
int attvaluelen;
while(p->xml < p->xmlend)
{
if(*p->xml=='/' || *p->xml=='>')
return 0;
if( !IS_WHITE_SPACE(*p->xml) )
{
char sep;
attname = p->xml;
attnamelen = 0;
while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
{
attnamelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
while(*(p->xml++) != '=')
{
if(p->xml >= p->xmlend)
return -1;
}
while(IS_WHITE_SPACE(*p->xml))
{
p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
sep = *p->xml;
if(sep=='\'' || sep=='\"')
{
p->xml++;
if(p->xml >= p->xmlend)
return -1;
attvalue = p->xml;
attvaluelen = 0;
while(*p->xml != sep)
{
attvaluelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
}
else
{
attvalue = p->xml;
attvaluelen = 0;
while( !IS_WHITE_SPACE(*p->xml)
&& *p->xml != '>' && *p->xml != '/')
{
attvaluelen++; p->xml++;
if(p->xml >= p->xmlend)
return -1;
}
}
/*printf("%.*s='%.*s'\n",
attnamelen, attname, attvaluelen, attvalue);*/
if(p->attfunc)
p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
}
p->xml++;
}
return -1;
}
/* parseelt parse the xml stream and
* call the callback functions when needed... */
static void parseelt(struct xmlparser * p)
{
int i;
const char * elementname;
while(p->xml < (p->xmlend - 1))
{
if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4)))
{
p->xml += 3;
/* ignore comments */
do
{
p->xml++;
if ((p->xml + 3) >= p->xmlend)
return;
}
while(memcmp(p->xml, "-->", 3) != 0);
p->xml += 3;
}
else if((p->xml)[0]=='<' && (p->xml)[1]!='?')
{
i = 0; elementname = ++p->xml;
while( !IS_WHITE_SPACE(*p->xml)
&& (*p->xml!='>') && (*p->xml!='/')
)
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
/* to ignore namespace : */
if(*p->xml==':')
{
i = 0;
elementname = ++p->xml;
}
}
if(i>0)
{
if(p->starteltfunc)
p->starteltfunc(p->data, elementname, i);
if(parseatt(p))
return;
if(*p->xml!='/')
{
const char * data;
i = 0; data = ++p->xml;
if (p->xml >= p->xmlend)
return;
while( IS_WHITE_SPACE(*p->xml) )
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
}
if(memcmp(p->xml, "<![CDATA[", 9) == 0)
{
/* CDATA handling */
p->xml += 9;
data = p->xml;
i = 0;
while(memcmp(p->xml, "]]>", 3) != 0)
{
i++; p->xml++;
if ((p->xml + 3) >= p->xmlend)
return;
}
if(i>0 && p->datafunc)
p->datafunc(p->data, data, i);
while(*p->xml!='<')
{
p->xml++;
if (p->xml >= p->xmlend)
return;
}
}
else
{
while(*p->xml!='<')
{
i++; p->xml++;
if ((p->xml + 1) >= p->xmlend)
return;
}
if(i>0 && p->datafunc && *(p->xml + 1) == '/')
p->datafunc(p->data, data, i);
}
}
}
else if(*p->xml == '/')
{
i = 0; elementname = ++p->xml;
if (p->xml >= p->xmlend)
return;
while((*p->xml != '>'))
{
i++; p->xml++;
if (p->xml >= p->xmlend)
return;
}
if(p->endeltfunc)
p->endeltfunc(p->data, elementname, i);
p->xml++;
}
}
else
{
p->xml++;
}
}
}
/* the parser must be initialized before calling this function */
void parsexml(struct xmlparser * parser)
{
parser->xml = parser->xmlstart;
parser->xmlend = parser->xmlstart + parser->xmlsize;
parseelt(parser);
}
+37
View File
@@ -0,0 +1,37 @@
/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */
/* minimal xml parser
*
* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution.
* */
#ifndef MINIXML_H_INCLUDED
#define MINIXML_H_INCLUDED
#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
/* if a callback function pointer is set to NULL,
* the function is not called */
struct xmlparser {
const char *xmlstart;
const char *xmlend;
const char *xml; /* pointer to current character */
int xmlsize;
void * data;
void (*starteltfunc) (void *, const char *, int);
void (*endeltfunc) (void *, const char *, int);
void (*datafunc) (void *, const char *, int);
void (*attfunc) (void *, const char *, int, const char *, int);
};
/* parsexml()
* the xmlparser structure must be initialized before the call
* the following structure members have to be initialized :
* xmlstart, xmlsize, data, *func
* xml is for internal usage, xmlend is computed automatically */
void parsexml(struct xmlparser *);
#endif
+171
View File
@@ -0,0 +1,171 @@
/* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011-2016 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <string.h>
#include <stdlib.h>
#ifdef DEBUG
#include <stdio.h>
#endif /* DEBUG */
#include "portlistingparse.h"
#include "minixml.h"
/* list of the elements */
static const struct {
const portMappingElt code;
const char * const str;
} elements[] = {
{ PortMappingEntry, "PortMappingEntry"},
{ NewRemoteHost, "NewRemoteHost"},
{ NewExternalPort, "NewExternalPort"},
{ NewProtocol, "NewProtocol"},
{ NewInternalPort, "NewInternalPort"},
{ NewInternalClient, "NewInternalClient"},
{ NewEnabled, "NewEnabled"},
{ NewDescription, "NewDescription"},
{ NewLeaseTime, "NewLeaseTime"},
{ PortMappingEltNone, NULL}
};
/* Helper function */
static UNSIGNED_INTEGER
atoui(const char * p, int l)
{
UNSIGNED_INTEGER r = 0;
while(l > 0 && *p)
{
if(*p >= '0' && *p <= '9')
r = r*10 + (*p - '0');
else
break;
p++;
l--;
}
return r;
}
/* Start element handler */
static void
startelt(void * d, const char * name, int l)
{
int i;
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
pdata->curelt = PortMappingEltNone;
for(i = 0; elements[i].str; i++)
{
if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0)
{
pdata->curelt = elements[i].code;
break;
}
}
if(pdata->curelt == PortMappingEntry)
{
struct PortMapping * pm;
pm = (struct PortMapping*)calloc(1, sizeof(struct PortMapping));
if(pm == NULL)
{
/* malloc error */
#ifdef DEBUG
fprintf(stderr, "%s: error allocating memory",
"startelt");
#endif /* DEBUG */
return;
}
pm->l_next = pdata->l_head; /* insert in list */
pdata->l_head = pm;
}
}
/* End element handler */
static void
endelt(void * d, const char * name, int l)
{
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
(void)name;
(void)l;
pdata->curelt = PortMappingEltNone;
}
/* Data handler */
static void portlisting_data(void * d, const char * data, int l)
{
struct PortMapping * pm;
struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
pm = pdata->l_head;
if(!pm)
return;
if(l > 63)
l = 63;
switch(pdata->curelt)
{
case NewRemoteHost:
memcpy(pm->remoteHost, data, l);
pm->remoteHost[l] = '\0';
break;
case NewExternalPort:
pm->externalPort = (unsigned short)atoui(data, l);
break;
case NewProtocol:
if(l > 3)
l = 3;
memcpy(pm->protocol, data, l);
pm->protocol[l] = '\0';
break;
case NewInternalPort:
pm->internalPort = (unsigned short)atoui(data, l);
break;
case NewInternalClient:
memcpy(pm->internalClient, data, l);
pm->internalClient[l] = '\0';
break;
case NewEnabled:
pm->enabled = (unsigned char)atoui(data, l);
break;
case NewDescription:
memcpy(pm->description, data, l);
pm->description[l] = '\0';
break;
case NewLeaseTime:
pm->leaseTime = atoui(data, l);
break;
default:
break;
}
}
/* Parse the PortMappingList XML document for IGD version 2
*/
void
ParsePortListing(const char * buffer, int bufsize,
struct PortMappingParserData * pdata)
{
struct xmlparser parser;
memset(pdata, 0, sizeof(struct PortMappingParserData));
/* init xmlparser */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = pdata;
parser.starteltfunc = startelt;
parser.endeltfunc = endelt;
parser.datafunc = portlisting_data;
parser.attfunc = 0;
parsexml(&parser);
}
void
FreePortListing(struct PortMappingParserData * pdata)
{
struct PortMapping * pm;
while((pm = pdata->l_head) != NULL)
{
/* remove from list */
pdata->l_head = pm->l_next;
free(pm);
}
}
+65
View File
@@ -0,0 +1,65 @@
/* $Id: portlistingparse.h,v 1.10 2014/11/01 10:37:32 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2011-2015 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef PORTLISTINGPARSE_H_INCLUDED
#define PORTLISTINGPARSE_H_INCLUDED
#include "miniupnpc_declspec.h"
/* for the definition of UNSIGNED_INTEGER */
#include "miniupnpctypes.h"
#ifdef __cplusplus
extern "C" {
#endif
/* sample of PortMappingEntry :
<p:PortMappingEntry>
<p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
<p:NewExternalPort>2345</p:NewExternalPort>
<p:NewProtocol>TCP</p:NewProtocol>
<p:NewInternalPort>2345</p:NewInternalPort>
<p:NewInternalClient>192.168.1.137</p:NewInternalClient>
<p:NewEnabled>1</p:NewEnabled>
<p:NewDescription>dooom</p:NewDescription>
<p:NewLeaseTime>345</p:NewLeaseTime>
</p:PortMappingEntry>
*/
typedef enum { PortMappingEltNone,
PortMappingEntry, NewRemoteHost,
NewExternalPort, NewProtocol,
NewInternalPort, NewInternalClient,
NewEnabled, NewDescription,
NewLeaseTime } portMappingElt;
struct PortMapping {
struct PortMapping * l_next; /* list next element */
UNSIGNED_INTEGER leaseTime;
unsigned short externalPort;
unsigned short internalPort;
char remoteHost[64];
char internalClient[64];
char description[64];
char protocol[4];
unsigned char enabled;
};
struct PortMappingParserData {
struct PortMapping * l_head; /* list head */
portMappingElt curelt;
};
MINIUPNP_LIBSPEC void
ParsePortListing(const char * buffer, int bufsize,
struct PortMappingParserData * pdata);
MINIUPNP_LIBSPEC void
FreePortListing(struct PortMappingParserData * pdata);
#ifdef __cplusplus
}
#endif
#endif
+106
View File
@@ -0,0 +1,106 @@
/* $Id: receivedata.c,v 1.7 2015/11/09 21:51:41 nanard Exp $ */
/* Project : miniupnp
* Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2011-2014 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else /* _WIN32 */
#include <unistd.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
#define socklen_t int
#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
#include <netinet/in.h>
#if !defined(__amigaos__) && !defined(__amigaos4__)
#include <poll.h>
#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */
#include <errno.h>
#define MINIUPNPC_IGNORE_EINTR
#endif /* _WIN32 */
#ifdef _WIN32
#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
#else
#define PRINT_SOCKET_ERROR(x) perror(x)
#endif
#include "receivedata.h"
int
receivedata(int socket,
char * data, int length,
int timeout, unsigned int * scope_id)
{
#ifdef MINIUPNPC_GET_SRC_ADDR
struct sockaddr_storage src_addr;
socklen_t src_addr_len = sizeof(src_addr);
#endif /* MINIUPNPC_GET_SRC_ADDR */
int n;
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
/* using poll */
struct pollfd fds[1]; /* for the poll */
#ifdef MINIUPNPC_IGNORE_EINTR
do {
#endif /* MINIUPNPC_IGNORE_EINTR */
fds[0].fd = socket;
fds[0].events = POLLIN;
n = poll(fds, 1, timeout);
#ifdef MINIUPNPC_IGNORE_EINTR
} while(n < 0 && errno == EINTR);
#endif /* MINIUPNPC_IGNORE_EINTR */
if(n < 0) {
PRINT_SOCKET_ERROR("poll");
return -1;
} else if(n == 0) {
/* timeout */
return 0;
}
#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
/* using select under _WIN32 and amigaos */
fd_set socketSet;
TIMEVAL timeval;
FD_ZERO(&socketSet);
FD_SET(socket, &socketSet);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
if(n < 0) {
PRINT_SOCKET_ERROR("select");
return -1;
} else if(n == 0) {
return 0;
}
#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
#ifdef MINIUPNPC_GET_SRC_ADDR
memset(&src_addr, 0, sizeof(src_addr));
n = recvfrom(socket, data, length, 0,
(struct sockaddr *)&src_addr, &src_addr_len);
#else /* MINIUPNPC_GET_SRC_ADDR */
n = (int)recv(socket, data, length, 0);
#endif /* MINIUPNPC_GET_SRC_ADDR */
if(n<0)
{
PRINT_SOCKET_ERROR("recv");
}
#ifdef MINIUPNPC_GET_SRC_ADDR
if (src_addr.ss_family == AF_INET6) {
const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
#ifdef DEBUG
printf("scope_id=%u\n", src_addr6->sin6_scope_id);
#endif /* DEBUG */
if(scope_id)
*scope_id = src_addr6->sin6_scope_id;
}
#endif /* MINIUPNPC_GET_SRC_ADDR */
return n;
}
+19
View File
@@ -0,0 +1,19 @@
/* $Id: receivedata.h,v 1.3 2012/06/23 22:34:47 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* Author: Thomas Bernard
* Copyright (c) 2011-2012 Thomas Bernard
* This software is subjects to the conditions detailed
* in the LICENCE file provided within this distribution */
#ifndef RECEIVEDATA_H_INCLUDED
#define RECEIVEDATA_H_INCLUDED
/* Reads data from the specified socket.
* Returns the number of bytes read if successful, zero if no bytes were
* read or if we timed out. Returns negative if there was an error. */
int receivedata(int socket,
char * data, int length,
int timeout, unsigned int * scope_id);
#endif
+53
View File
@@ -0,0 +1,53 @@
#! /bin/sh
# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $
# project miniupnp : http://miniupnp.free.fr/
# (c) 2009 Thomas Bernard
FILE=miniupnpcstrings.h
TMPFILE=miniupnpcstrings.h.tmp
TEMPLATE_FILE=${FILE}.in
# detecting the OS name and version
OS_NAME=`uname -s`
OS_VERSION=`uname -r`
if [ -f /etc/debian_version ]; then
OS_NAME=Debian
OS_VERSION=`cat /etc/debian_version`
fi
# use lsb_release (Linux Standard Base) when available
LSB_RELEASE=`which lsb_release`
if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then
OS_NAME=`${LSB_RELEASE} -i -s`
OS_VERSION=`${LSB_RELEASE} -r -s`
case $OS_NAME in
Debian)
#OS_VERSION=`${LSB_RELEASE} -c -s`
;;
Ubuntu)
#OS_VERSION=`${LSB_RELEASE} -c -s`
;;
esac
fi
# on AmigaOS 3, uname -r returns "unknown", so we use uname -v
if [ "$OS_NAME" = "AmigaOS" ]; then
if [ "$OS_VERSION" = "unknown" ]; then
OS_VERSION=`uname -v`
fi
fi
echo "Detected OS [$OS_NAME] version [$OS_VERSION]"
MINIUPNPC_VERSION=`cat VERSION`
echo "MiniUPnPc version [${MINIUPNPC_VERSION}]"
EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|"
#echo $EXPR
test -f ${FILE}.in
echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE."
sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE
EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|"
echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE."
sed -e "$EXPR" < $TMPFILE > $FILE
rm $TMPFILE
+1240
View File
File diff suppressed because it is too large. Load diff
+348
View File
@@ -0,0 +1,348 @@
/* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2015 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided within this distribution */
#ifndef UPNPCOMMANDS_H_INCLUDED
#define UPNPCOMMANDS_H_INCLUDED
#include "upnpreplyparse.h"
#include "portlistingparse.h"
#include "miniupnpc_declspec.h"
#include "miniupnpctypes.h"
/* MiniUPnPc return codes : */
#define UPNPCOMMAND_SUCCESS (0)
#define UPNPCOMMAND_UNKNOWN_ERROR (-1)
#define UPNPCOMMAND_INVALID_ARGS (-2)
#define UPNPCOMMAND_HTTP_ERROR (-3)
#define UPNPCOMMAND_INVALID_RESPONSE (-4)
#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5)
#ifdef __cplusplus
extern "C" {
#endif
MINIUPNP_LIBSPEC UNSIGNED_INTEGER
UPNP_GetTotalBytesSent(const char * controlURL,
const char * servicetype);
MINIUPNP_LIBSPEC UNSIGNED_INTEGER
UPNP_GetTotalBytesReceived(const char * controlURL,
const char * servicetype);
MINIUPNP_LIBSPEC UNSIGNED_INTEGER
UPNP_GetTotalPacketsSent(const char * controlURL,
const char * servicetype);
MINIUPNP_LIBSPEC UNSIGNED_INTEGER
UPNP_GetTotalPacketsReceived(const char * controlURL,
const char * servicetype);
/* UPNP_GetStatusInfo()
* status and lastconnerror are 64 byte buffers
* Return values :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
* or a UPnP Error code */
MINIUPNP_LIBSPEC int
UPNP_GetStatusInfo(const char * controlURL,
const char * servicetype,
char * status,
unsigned int * uptime,
char * lastconnerror);
/* UPNP_GetConnectionTypeInfo()
* argument connectionType is a 64 character buffer
* Return Values :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
* or a UPnP Error code */
MINIUPNP_LIBSPEC int
UPNP_GetConnectionTypeInfo(const char * controlURL,
const char * servicetype,
char * connectionType);
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
*
* possible UPnP Errors :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control. */
MINIUPNP_LIBSPEC int
UPNP_GetExternalIPAddress(const char * controlURL,
const char * servicetype,
char * extIpAdd);
/* UPNP_GetLinkLayerMaxBitRates()
* call WANCommonInterfaceConfig:1#GetCommonLinkProperties
*
* return values :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
* or a UPnP Error Code. */
MINIUPNP_LIBSPEC int
UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
const char* servicetype,
unsigned int * bitrateDown,
unsigned int * bitrateUp);
/* UPNP_AddPortMapping()
* if desc is NULL, it will be defaulted to "libminiupnpc"
* remoteHost is usually NULL because IGD don't support it.
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
*
* List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control.
* 606 Action not authorized - The action requested REQUIRES authorization and
* the sender was not authorized.
* 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
* wild-carded
* 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts
* with a mapping assigned previously to another client
* 724 SamePortValuesRequired - Internal and External port values
* must be the same
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
* permanent lease times on port mappings
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
* and cannot be a specific IP address or DNS name
* 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and
* cannot be a specific port value
* 728 NoPortMapsAvailable - There are not enough free ports available to
* complete port mapping.
* 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
* due to conflict with other mechanisms.
* 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
*/
MINIUPNP_LIBSPEC int
UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * extPort,
const char * inPort,
const char * inClient,
const char * desc,
const char * proto,
const char * remoteHost,
const char * leaseDuration);
/* UPNP_AddAnyPortMapping()
* if desc is NULL, it will be defaulted to "libminiupnpc"
* remoteHost is usually NULL because IGD don't support it.
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
*
* List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control.
* 606 Action not authorized - The action requested REQUIRES authorization and
* the sender was not authorized.
* 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
* wild-carded
* 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
* 728 NoPortMapsAvailable - There are not enough free ports available to
* complete port mapping.
* 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
* due to conflict with other mechanisms.
* 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
*/
MINIUPNP_LIBSPEC int
UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
const char * extPort,
const char * inPort,
const char * inClient,
const char * desc,
const char * proto,
const char * remoteHost,
const char * leaseDuration,
char * reservedPort);
/* UPNP_DeletePortMapping()
* Use same argument values as what was used for AddPortMapping().
* remoteHost is usually NULL because IGD don't support it.
* Return Values :
* 0 : SUCCESS
* NON ZERO : error. Either an UPnP error code or an undefined error.
*
* List of possible UPnP errors for DeletePortMapping :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 606 Action not authorized - The action requested REQUIRES authorization
* and the sender was not authorized.
* 714 NoSuchEntryInArray - The specified value does not exist in the array */
MINIUPNP_LIBSPEC int
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto,
const char * remoteHost);
/* UPNP_DeletePortRangeMapping()
* Use same argument values as what was used for AddPortMapping().
* remoteHost is usually NULL because IGD don't support it.
* Return Values :
* 0 : SUCCESS
* NON ZERO : error. Either an UPnP error code or an undefined error.
*
* List of possible UPnP errors for DeletePortMapping :
* 606 Action not authorized - The action requested REQUIRES authorization
* and the sender was not authorized.
* 730 PortMappingNotFound - This error message is returned if no port
* mapping is found in the specified range.
* 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */
MINIUPNP_LIBSPEC int
UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
const char * extPortStart, const char * extPortEnd,
const char * proto,
const char * manage);
/* UPNP_GetPortMappingNumberOfEntries()
* not supported by all routers */
MINIUPNP_LIBSPEC int
UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
const char* servicetype,
unsigned int * num);
/* UPNP_GetSpecificPortMappingEntry()
* retrieves an existing port mapping
* params :
* in extPort
* in proto
* in remoteHost
* out intClient (16 bytes)
* out intPort (6 bytes)
* out desc (80 bytes)
* out enabled (4 bytes)
* out leaseDuration (16 bytes)
*
* return value :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
* or a UPnP Error Code.
*
* List of possible UPnP errors for _GetSpecificPortMappingEntry :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control.
* 606 Action not authorized - The action requested REQUIRES authorization
* and the sender was not authorized.
* 714 NoSuchEntryInArray - The specified value does not exist in the array.
*/
MINIUPNP_LIBSPEC int
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * extPort,
const char * proto,
const char * remoteHost,
char * intClient,
char * intPort,
char * desc,
char * enabled,
char * leaseDuration);
/* UPNP_GetGenericPortMappingEntry()
* params :
* in index
* out extPort (6 bytes)
* out intClient (16 bytes)
* out intPort (6 bytes)
* out protocol (4 bytes)
* out desc (80 bytes)
* out enabled (4 bytes)
* out rHost (64 bytes)
* out duration (16 bytes)
*
* return value :
* UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
* or a UPnP Error Code.
*
* Possible UPNP Error codes :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 606 Action not authorized - The action requested REQUIRES authorization
* and the sender was not authorized.
* 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds
*/
MINIUPNP_LIBSPEC int
UPNP_GetGenericPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * index,
char * extPort,
char * intClient,
char * intPort,
char * protocol,
char * desc,
char * enabled,
char * rHost,
char * duration);
/* UPNP_GetListOfPortMappings() Available in IGD v2
*
*
* Possible UPNP Error codes :
* 606 Action not Authorized
* 730 PortMappingNotFound - no port mapping is found in the specified range.
* 733 InconsistantParameters - NewStartPort and NewEndPort values are not
* consistent.
*/
MINIUPNP_LIBSPEC int
UPNP_GetListOfPortMappings(const char * controlURL,
const char * servicetype,
const char * startPort,
const char * endPort,
const char * protocol,
const char * numberOfPorts,
struct PortMappingParserData * data);
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
MINIUPNP_LIBSPEC int
UPNP_GetFirewallStatus(const char * controlURL,
const char * servicetype,
int * firewallEnabled,
int * inboundPinholeAllowed);
MINIUPNP_LIBSPEC int
UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
const char * remoteHost,
const char * remotePort,
const char * intClient,
const char * intPort,
const char * proto,
int * opTimeout);
MINIUPNP_LIBSPEC int
UPNP_AddPinhole(const char * controlURL, const char * servicetype,
const char * remoteHost,
const char * remotePort,
const char * intClient,
const char * intPort,
const char * proto,
const char * leaseTime,
char * uniqueID);
MINIUPNP_LIBSPEC int
UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
const char * uniqueID,
const char * leaseTime);
MINIUPNP_LIBSPEC int
UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
MINIUPNP_LIBSPEC int
UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
const char * uniqueID, int * isWorking);
MINIUPNP_LIBSPEC int
UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
const char * uniqueID, int * packets);
#ifdef __cplusplus
}
#endif
#endif
+23
View File
@@ -0,0 +1,23 @@
/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
/* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2015 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#include <stdlib.h>
#include "upnpdev.h"
/* freeUPNPDevlist() should be used to
* free the chained list returned by upnpDiscover() */
void freeUPNPDevlist(struct UPNPDev * devlist)
{
struct UPNPDev * next;
while(devlist)
{
next = devlist->pNext;
free(devlist);
devlist = next;
}
}
+36
View File
@@ -0,0 +1,36 @@
/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
/* Project : miniupnp
* Web : http://miniupnp.free.fr/
* Author : Thomas BERNARD
* copyright (c) 2005-2015 Thomas Bernard
* This software is subjet to the conditions detailed in the
* provided LICENSE file. */
#ifndef UPNPDEV_H_INCLUDED
#define UPNPDEV_H_INCLUDED
#include "miniupnpc_declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
struct UPNPDev {
struct UPNPDev * pNext;
char * descURL;
char * st;
unsigned int scope_id;
char * usn;
char buffer[3];
};
/* freeUPNPDevlist()
* free list returned by upnpDiscover() */
MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
#ifdef __cplusplus
}
#endif
#endif /* UPNPDEV_H_INCLUDED */
+107
View File
@@ -0,0 +1,107 @@
/* $Id: upnperrors.c,v 1.5 2011/04/10 11:19:36 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2007 Thomas Bernard
* All Right reserved.
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#include <string.h>
#include "upnperrors.h"
#include "upnpcommands.h"
#include "miniupnpc.h"
const char * strupnperror(int err)
{
const char * s = NULL;
switch(err) {
case UPNPCOMMAND_SUCCESS:
s = "Success";
break;
case UPNPCOMMAND_UNKNOWN_ERROR:
s = "Miniupnpc Unknown Error";
break;
case UPNPCOMMAND_INVALID_ARGS:
s = "Miniupnpc Invalid Arguments";
break;
case UPNPCOMMAND_INVALID_RESPONSE:
s = "Miniupnpc Invalid response";
break;
case UPNPDISCOVER_SOCKET_ERROR:
s = "Miniupnpc Socket error";
break;
case UPNPDISCOVER_MEMORY_ERROR:
s = "Miniupnpc Memory allocation error";
break;
case 401:
s = "Invalid Action";
break;
case 402:
s = "Invalid Args";
break;
case 501:
s = "Action Failed";
break;
case 606:
s = "Action not authorized";
break;
case 701:
s = "PinholeSpaceExhausted";
break;
case 702:
s = "FirewallDisabled";
break;
case 703:
s = "InboundPinholeNotAllowed";
break;
case 704:
s = "NoSuchEntry";
break;
case 705:
s = "ProtocolNotSupported";
break;
case 706:
s = "InternalPortWildcardingNotAllowed";
break;
case 707:
s = "ProtocolWildcardingNotAllowed";
break;
case 708:
s = "WildcardNotPermittedInSrcIP";
break;
case 709:
s = "NoPacketSent";
break;
case 713:
s = "SpecifiedArrayIndexInvalid";
break;
case 714:
s = "NoSuchEntryInArray";
break;
case 715:
s = "WildCardNotPermittedInSrcIP";
break;
case 716:
s = "WildCardNotPermittedInExtPort";
break;
case 718:
s = "ConflictInMappingEntry";
break;
case 724:
s = "SamePortValuesRequired";
break;
case 725:
s = "OnlyPermanentLeasesSupported";
break;
case 726:
s = "RemoteHostOnlySupportsWildcard";
break;
case 727:
s = "ExternalPortOnlySupportsWildcard";
break;
default:
s = "UnknownError";
break;
}
return s;
}
+26
View File
@@ -0,0 +1,26 @@
/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */
/* (c) 2007-2015 Thomas Bernard
* All rights reserved.
* MiniUPnP Project.
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#ifndef UPNPERRORS_H_INCLUDED
#define UPNPERRORS_H_INCLUDED
#include "miniupnpc_declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
/* strupnperror()
* Return a string description of the UPnP error code
* or NULL for undefinded errors */
MINIUPNP_LIBSPEC const char * strupnperror(int err);
#ifdef __cplusplus
}
#endif
#endif
+197
View File
@@ -0,0 +1,197 @@
/* $Id: upnpreplyparse.c,v 1.19 2015/07/15 10:29:11 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2015 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "upnpreplyparse.h"
#include "minixml.h"
static void
NameValueParserStartElt(void * d, const char * name, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
data->topelt = 1;
if(l>63)
l = 63;
memcpy(data->curelt, name, l);
data->curelt[l] = '\0';
data->cdata = NULL;
data->cdatalen = 0;
}
static void
NameValueParserEndElt(void * d, const char * name, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
struct NameValue * nv;
(void)name;
(void)l;
if(!data->topelt)
return;
if(strcmp(data->curelt, "NewPortListing") != 0)
{
int l;
/* standard case. Limited to n chars strings */
l = data->cdatalen;
nv = (struct NameValue*)malloc(sizeof(struct NameValue));
if(nv == NULL)
{
/* malloc error */
#ifdef DEBUG
fprintf(stderr, "%s: error allocating memory",
"NameValueParserEndElt");
#endif /* DEBUG */
return;
}
if(l>=(int)sizeof(nv->value))
l = sizeof(nv->value) - 1;
strncpy(nv->name, data->curelt, 64);
nv->name[63] = '\0';
if(data->cdata != NULL)
{
memcpy(nv->value, data->cdata, l);
nv->value[l] = '\0';
}
else
{
nv->value[0] = '\0';
}
nv->l_next = data->l_head; /* insert in list */
data->l_head = nv;
}
data->cdata = NULL;
data->cdatalen = 0;
data->topelt = 0;
}
static void
NameValueParserGetData(void * d, const char * datas, int l)
{
struct NameValueParserData * data = (struct NameValueParserData *)d;
if(strcmp(data->curelt, "NewPortListing") == 0)
{
/* specific case for NewPortListing which is a XML Document */
data->portListing = (char*)malloc(l + 1);
if(!data->portListing)
{
/* malloc error */
#ifdef DEBUG
fprintf(stderr, "%s: error allocating memory",
"NameValueParserGetData");
#endif /* DEBUG */
return;
}
memcpy(data->portListing, datas, l);
data->portListing[l] = '\0';
data->portListingLength = l;
}
else
{
/* standard case. */
data->cdata = datas;
data->cdatalen = l;
}
}
void
ParseNameValue(const char * buffer, int bufsize,
struct NameValueParserData * data)
{
struct xmlparser parser;
data->l_head = NULL;
data->portListing = NULL;
data->portListingLength = 0;
/* init xmlparser object */
parser.xmlstart = buffer;
parser.xmlsize = bufsize;
parser.data = data;
parser.starteltfunc = NameValueParserStartElt;
parser.endeltfunc = NameValueParserEndElt;
parser.datafunc = NameValueParserGetData;
parser.attfunc = 0;
parsexml(&parser);
}
void
ClearNameValueList(struct NameValueParserData * pdata)
{
struct NameValue * nv;
if(pdata->portListing)
{
free(pdata->portListing);
pdata->portListing = NULL;
pdata->portListingLength = 0;
}
while((nv = pdata->l_head) != NULL)
{
pdata->l_head = nv->l_next;
free(nv);
}
}
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name)
{
struct NameValue * nv;
char * p = NULL;
for(nv = pdata->l_head;
(nv != NULL) && (p == NULL);
nv = nv->l_next)
{
if(strcmp(nv->name, Name) == 0)
p = nv->value;
}
return p;
}
#if 0
/* useless now that minixml ignores namespaces by itself */
char *
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
const char * Name)
{
struct NameValue * nv;
char * p = NULL;
char * pname;
for(nv = pdata->head.lh_first;
(nv != NULL) && (p == NULL);
nv = nv->entries.le_next)
{
pname = strrchr(nv->name, ':');
if(pname)
pname++;
else
pname = nv->name;
if(strcmp(pname, Name)==0)
p = nv->value;
}
return p;
}
#endif
/* debug all-in-one function
* do parsing then display to stdout */
#ifdef DEBUG
void
DisplayNameValueList(char * buffer, int bufsize)
{
struct NameValueParserData pdata;
struct NameValue * nv;
ParseNameValue(buffer, bufsize, &pdata);
for(nv = pdata.l_head;
nv != NULL;
nv = nv->l_next)
{
printf("%s = %s\n", nv->name, nv->value);
}
ClearNameValueList(&pdata);
}
#endif /* DEBUG */
+63
View File
@@ -0,0 +1,63 @@
/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */
/* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2013 Thomas Bernard
* This software is subject to the conditions detailed
* in the LICENCE file provided within the distribution */
#ifndef UPNPREPLYPARSE_H_INCLUDED
#define UPNPREPLYPARSE_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
struct NameValue {
struct NameValue * l_next;
char name[64];
char value[128];
};
struct NameValueParserData {
struct NameValue * l_head;
char curelt[64];
char * portListing;
int portListingLength;
int topelt;
const char * cdata;
int cdatalen;
};
/* ParseNameValue() */
void
ParseNameValue(const char * buffer, int bufsize,
struct NameValueParserData * data);
/* ClearNameValueList() */
void
ClearNameValueList(struct NameValueParserData * pdata);
/* GetValueFromNameValueList() */
char *
GetValueFromNameValueList(struct NameValueParserData * pdata,
const char * Name);
#if 0
/* GetValueFromNameValueListIgnoreNS() */
char *
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
const char * Name);
#endif
/* DisplayNameValueList() */
#ifdef DEBUG
void
DisplayNameValueList(char * buffer, int bufsize);
#endif
#ifdef __cplusplus
}
#endif
#endif
+5128 -2618
View File
File diff suppressed because it is too large. Load diff
+5297
View File
File diff suppressed because it is too large. Load diff
+1 -2
View File
@@ -33,7 +33,7 @@
#endif
#ifdef HAVE_CHEEVOS
#include "cheevos.h"
#include "cheevos/cheevos.h"
#endif
#ifdef HAVE_NETWORKING
@@ -252,7 +252,6 @@ static bool load_dynamic_core(void)
RARCH_ERR("Error(s): %s\n", dylib_error());
runloop_msg_queue_push(msg_hash_to_str(MSG_FAILED_TO_OPEN_LIBRETRO_CORE), 1, 180, true);
retroarch_fail(1, "load_dynamic_core()");
return false;
}
+34 -8
View File
@@ -49,6 +49,8 @@ static dylib_t dwmlib;
static bool dwm_composition_disabled;
static bool console_needs_free;
static void gfx_dwm_shutdown(void)
{
if (dwmlib)
@@ -345,13 +347,34 @@ static void frontend_win32_attach_console(void)
{
#ifdef _WIN32
#ifdef _WIN32_WINNT_WINXP
if (!AttachConsole(ATTACH_PARENT_PROCESS))
/* msys will start the process with FILE_TYPE_PIPE connected.
* cmd will start the process with FILE_TYPE_UNKNOWN connected (since this is subsystem windows application
* ... UNLESS stdout/stderr were redirected (then FILE_TYPE_DISK will be connected most likely)
* explorer will start the process with NOTHING connected.
*
* Now, let's not reconnect anything that's already connected.
* If any are disconnected, open a console, and connect to them.
* In case we're launched from msys or cmd, try attaching to the parent process console first.
* Take care to leave a record of what we did, so we can undo it precisely
*/
bool need_stdout = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_UNKNOWN);
bool need_stderr = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN);
if(need_stdout || need_stderr)
{
AllocConsole();
AttachConsole( GetCurrentProcessId()) ;
freopen( "CON", "w", stdout );
freopen( "CON", "w", stderr );
if(!AttachConsole( ATTACH_PARENT_PROCESS))
{
AllocConsole();
}
if(need_stdout) freopen( "CONOUT$", "w", stdout );
if(need_stderr) freopen( "CONOUT$", "w", stderr );
console_needs_free = true;
}
#endif
#endif
}
@@ -360,12 +383,15 @@ static void frontend_win32_detach_console(void)
{
#if defined(_WIN32) && !defined(_XBOX)
#ifdef _WIN32_WINNT_WINXP
if (!AttachConsole(ATTACH_PARENT_PROCESS))
if(console_needs_free)
{
HWND wnd = GetConsoleWindow();
/* we don't reconnect stdout/stderr to anything here, because by definition, they weren't connected to anything in the first place. */
FreeConsole();
PostMessage(wnd, WM_CLOSE, 0, 0);
console_needs_free = false;
}
#endif
#endif
}
+1 -2
View File
@@ -110,12 +110,11 @@ int rarch_main(int argc, char *argv[], void *data)
info.args = args;
info.environ_get = frontend_driver_environment_get_ptr();
if (!task_push_content_load_default(
if (!task_push_load_content_from_cli(
NULL,
NULL,
&info,
CORE_TYPE_PLAIN,
CONTENT_MODE_LOAD_FROM_CLI,
NULL,
NULL))
return 1;
+27 -6
View File
@@ -1800,7 +1800,7 @@ static bool vulkan_create_display_surface(gfx_ctx_vulkan_data_t *vk,
VkDisplayModePropertiesKHR *modes = NULL;
unsigned dpy, i, j;
uint32_t best_plane = UINT32_MAX;
VkDisplayPlaneAlphaFlagsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
VkDisplaySurfaceCreateInfoKHR create_info = { VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR };
VkDisplayModeKHR best_mode = VK_NULL_HANDLE;
@@ -1937,9 +1937,7 @@ out:
create_info.planeStackIndex = planes[best_plane].currentStackIndex;
create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
create_info.globalAlpha = 1.0f;
/* TODO/FIXME - why is this cast needed for CXX_BUILD? Why is
* alpha_mode not just VkDisplayPlaneAlphaFlagBitsKHR to begin with? */
create_info.alphaMode = (VkDisplayPlaneAlphaFlagBitsKHR)alpha_mode;
create_info.alphaMode = alpha_mode;
create_info.imageExtent.width = *width;
create_info.imageExtent.height = *height;
@@ -2271,6 +2269,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
VkPresentModeKHR swapchain_present_mode = VK_PRESENT_MODE_FIFO_KHR;
settings_t *settings = config_get_ptr();
VkCompositeAlphaFlagBitsKHR composite = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
vkDeviceWaitIdle(vk->context.device);
@@ -2325,6 +2324,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
vkGetPhysicalDeviceSurfaceFormatsKHR(vk->context.gpu,
vk->vk_surface, &format_count, formats);
format.format = VK_FORMAT_UNDEFINED;
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
{
format = formats[0];
@@ -2338,7 +2338,19 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
return false;
}
format = formats[0];
for (i = 0; i < format_count; i++)
{
if (
formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
formats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32)
{
format = formats[i];
}
}
if (format.format == VK_FORMAT_UNDEFINED)
format = formats[0];
}
if (surface_properties.currentExtent.width == -1)
@@ -2371,6 +2383,15 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
else
pre_transform = surface_properties.currentTransform;
if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
composite = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
composite = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
composite = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
composite = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
old_swapchain = vk->swapchain;
info.surface = vk->vk_surface;
@@ -2382,7 +2403,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
info.imageArrayLayers = 1;
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.preTransform = pre_transform;
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
info.compositeAlpha = composite;
info.presentMode = swapchain_present_mode;
info.clipped = true;
info.oldSwapchain = old_swapchain;
+1 -1
View File
@@ -331,7 +331,7 @@ typedef struct vk
struct
{
bool blend;
VkPipeline pipelines[8];
VkPipeline pipelines[7 * 2];
struct vk_texture blank_texture;
} display;
+5 -9
View File
@@ -316,11 +316,10 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam)
{
/* Our previous core supports the current rom */
content_ctx_info_t content_info = {0};
task_push_content_load_default(
NULL, NULL,
task_push_load_content_with_current_core_from_companion_ui(
NULL,
&content_info,
CORE_TYPE_PLAIN,
CONTENT_MODE_LOAD_CONTENT_WITH_CURRENT_CORE_FROM_COMPANION_UI,
NULL, NULL);
return 0;
}
@@ -334,11 +333,9 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam)
const core_info_t *info = (const core_info_t*)&core_info[0];
if (info)
task_push_content_load_default(
task_push_load_content_with_new_core_from_companion_ui(
info->path, NULL,
&content_info,
CORE_TYPE_PLAIN,
CONTENT_MODE_LOAD_CONTENT_WITH_NEW_CORE_FROM_COMPANION_UI,
NULL, NULL);
}
else
@@ -347,11 +344,10 @@ static int win32_drag_query_file(HWND hwnd, WPARAM wparam)
if(DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_PICKCORE),
hwnd,PickCoreProc,(LPARAM)NULL)==IDOK)
{
task_push_content_load_default(
NULL, NULL,
task_push_load_content_with_current_core_from_companion_ui(
NULL,
&content_info,
CORE_TYPE_PLAIN,
CONTENT_MODE_LOAD_CONTENT_WITH_CURRENT_CORE_FROM_COMPANION_UI,
NULL, NULL);
}
}
+12 -135
View File
@@ -16,8 +16,6 @@
#include <bcm_host.h>
#include <rthreads/rthreads.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
@@ -36,10 +34,6 @@ struct dispmanx_page
/* Each page contains it's own resource handler
* instead of pointing to in by page number */
DISPMANX_RESOURCE_HANDLE_T resource;
bool used;
/* Each page has it's own mutex for
* isolating it's used flag access. */
slock_t *page_used_mutex;
/* This field will allow us to access the
* main _dispvars struct from the vsync CB function */
@@ -57,10 +51,7 @@ struct dispmanx_surface
struct dispmanx_page *pages;
/* the page that's currently on screen */
struct dispmanx_page *current_page;
/*The page to wich we will dump the render. We need to know this
* already when we enter the surface update function. No time to wait
* for free pages before blitting and showing the just rendered frame! */
struct dispmanx_page *next_page;
bool flip_page;
unsigned int bpp;
VC_RECT_T src_rect;
@@ -102,12 +93,6 @@ struct dispmanx_video
unsigned int dispmanx_width;
unsigned int dispmanx_height;
/* For threading */
scond_t *vsync_condition;
slock_t *vsync_cond_mutex;
slock_t *pending_mutex;
unsigned int pageflip_pending;
/* Menu */
bool menu_active;
@@ -129,94 +114,15 @@ struct dispmanx_video
float aspect_ratio;
};
/* If no free page is available when called, wait for a page flip. */
static struct dispmanx_page *dispmanx_get_free_page(void *data, struct dispmanx_surface *surface)
{
unsigned i;
struct dispmanx_video *_dispvars = data;
struct dispmanx_page *page = NULL;
while (!page)
{
/* Try to find a free page */
for (i = 0; i < surface->numpages; ++i)
{
if (!surface->pages[i].used)
{
page = (surface->pages) + i;
break;
}
}
/* If no page is free at the moment,
* wait until a free page is freed by vsync CB. */
if (!page)
{
slock_lock(_dispvars->vsync_cond_mutex);
scond_wait(_dispvars->vsync_condition, _dispvars->vsync_cond_mutex);
slock_unlock(_dispvars->vsync_cond_mutex);
}
}
/* We mark the choosen page as used */
slock_lock(page->page_used_mutex);
page->used = true;
slock_unlock(page->page_used_mutex);
return page;
}
static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
{
struct dispmanx_page *page = data;
struct dispmanx_surface *surface = page->surface;
/* Marking the page as free must be done before the signaling
* so when update_main continues (it won't continue until we signal)
* we can chose this page as free */
if (surface->current_page)
{
slock_lock(surface->current_page->page_used_mutex);
/* We mark as free the page that was visible until now */
surface->current_page->used = false;
slock_unlock(surface->current_page->page_used_mutex);
}
/* The page on which we issued the flip that
* caused this callback becomes the visible one */
surface->current_page = page;
/* These two things must be isolated "atomically" to avoid getting
* a false positive in the pending_mutex test in update_main. */
slock_lock(page->dispvars->pending_mutex);
page->dispvars->pageflip_pending--;
scond_signal(page->dispvars->vsync_condition);
slock_unlock(page->dispvars->pending_mutex);
}
static void dispmanx_surface_free(void *data, struct dispmanx_surface **sp)
{
int i;
struct dispmanx_video *_dispvars = data;
struct dispmanx_surface *surface = *sp;
/* What if we run into the vsync cb code after freeing the surface?
* We could be trying to get non-existant lock, signal non-existant condition..
* So we wait for any pending flips to complete before freeing any surface. */
slock_lock(_dispvars->pending_mutex);
if (_dispvars->pageflip_pending > 0)
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
slock_unlock(_dispvars->pending_mutex);
for (i = 0; i < surface->numpages; i++)
{
vc_dispmanx_resource_delete(surface->pages[i].resource);
surface->pages[i].used = false;
slock_free(surface->pages[i].page_used_mutex);
}
free(surface->pages);
@@ -260,16 +166,12 @@ static void dispmanx_surface_setup(void *data, int src_width, int src_height,
for (i = 0; i < surface->numpages; i++)
{
surface->pages[i].used = false;
surface->pages[i].surface = surface;
surface->pages[i].dispvars = _dispvars;
surface->pages[i].page_used_mutex = slock_new();
}
/* No need to mutex this access to the "used" member because
* the flipping/callbacks are not still running */
surface->next_page = &(surface->pages[0]);
surface->next_page->used = true;
/* We blit to page 0 first */
surface->flip_page = 0;
/* The "visible" width obtained from the core pitch. We blit based on
* the "visible" width, for cores with things between scanlines. */
@@ -325,40 +227,24 @@ static void dispmanx_surface_update_async(void *data, const void *frame,
static void dispmanx_surface_update(void *data, const void *frame,
struct dispmanx_surface *surface)
{
/* Updating is very delicate: we REALLY want to show the just rendered frame ASAP,
* so we dump and issue flip, and then we can wait for free pages, but we don't
* want to wait for free pages at the beggining of the update or we will be
* adding lag! */
struct dispmanx_video *_dispvars = data;
struct dispmanx_page *page = NULL;
page = &surface->pages[surface->flip_page];
/* Frame blitting */
vc_dispmanx_resource_write_data(surface->next_page->resource, surface->pixformat,
vc_dispmanx_resource_write_data(page->resource, surface->pixformat,
surface->pitch, (void*)frame, &(surface->bmp_rect));
/* Dispmanx doesn't support more than one pending pageflip. Doing so would overwrite
* the page in the callback function, so we would be always freeing the same page. */
slock_lock(_dispvars->pending_mutex);
if (_dispvars->pageflip_pending > 0)
scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex);
slock_unlock(_dispvars->pending_mutex);
/* Issue a page flip that will be done at the next vsync. */
_dispvars->update = vc_dispmanx_update_start(0);
vc_dispmanx_element_change_source(_dispvars->update, surface->element,
surface->next_page->resource);
page->resource);
vc_dispmanx_update_submit(_dispvars->update,
dispmanx_vsync_callback, (void*)(surface->next_page));
vc_dispmanx_update_submit_sync(_dispvars->update);
slock_lock(_dispvars->pending_mutex);
_dispvars->pageflip_pending++;
slock_unlock(_dispvars->pending_mutex);
/* Get the next page ready for our next surface_update re-entry.
* It's OK to wait now that we've issued the flip to the last produced frame! */
surface->next_page = dispmanx_get_free_page(_dispvars, surface);
surface->flip_page = !surface->flip_page;
}
/* Enable/disable bilinear filtering. */
@@ -414,7 +300,6 @@ static void *dispmanx_gfx_init(const video_info_t *video,
/* Setup surface parameters */
_dispvars->vc_image_ptr = 0;
_dispvars->pageflip_pending = 0;
_dispvars->menu_active = false;
_dispvars->rgb32 = video->rgb32;
@@ -424,10 +309,7 @@ static void *dispmanx_gfx_init(const video_info_t *video,
* before we get to gfx_frame(). */
_dispvars->aspect_ratio = video_driver_get_aspect_ratio();
/* Initialize the rest of the mutexes and conditions. */
_dispvars->vsync_condition = scond_new();
_dispvars->vsync_cond_mutex = slock_new();
_dispvars->pending_mutex = slock_new();
/* Initialize the rest of video variables. */
_dispvars->core_width = 0;
_dispvars->core_height = 0;
_dispvars->menu_width = 0;
@@ -695,11 +577,6 @@ static void dispmanx_gfx_free(void *data)
vc_dispmanx_display_close(_dispvars->display);
bcm_host_deinit();
/* Destroy mutexes and conditions. */
slock_free(_dispvars->pending_mutex);
slock_free(_dispvars->vsync_cond_mutex);
scond_free(_dispvars->vsync_condition);
free(_dispvars);
}
+2 -2
View File
@@ -2748,7 +2748,7 @@ static int video_texture_load_wrap_gl_mipmap(void *data)
return 0;
video_texture_load_gl((struct texture_image*)data,
TEXTURE_FILTER_MIPMAP_LINEAR, &id);
return id;
return (int)id;
}
static int video_texture_load_wrap_gl(void *data)
@@ -2759,7 +2759,7 @@ static int video_texture_load_wrap_gl(void *data)
return 0;
video_texture_load_gl((struct texture_image*)data,
TEXTURE_FILTER_LINEAR, &id);
return id;
return (int)id;
}
#endif
+1
View File
@@ -505,6 +505,7 @@ static bool sdl2_gfx_frame(void *data, const void *frame, unsigned width,
{
static struct retro_perf_counter sdl_copy_frame = {0};
SDL_RenderClear(vid->renderer);
sdl_refresh_input_size(vid, false, vid->video.rgb32, width, height, pitch);
performance_counter_init(sdl_copy_frame, "sdl_copy_frame");
+12 -9
View File
@@ -222,14 +222,14 @@ static bool vga_gfx_frame(void *data, const void *frame,
for (x = 0; x < VGA_WIDTH; x++)
{
/* scale incoming frame to fit the screen */
unsigned scaled_x = (width / (float)VGA_WIDTH) * x;
unsigned scaled_y = (height / (float)VGA_HEIGHT) * y;
unsigned scaled_x = (width * x) / VGA_WIDTH;
unsigned scaled_y = (height * y) / VGA_HEIGHT;
unsigned short pixel = ((unsigned short*)frame_to_copy)[width * scaled_y + scaled_x];
/* convert RGB565 to BGR332 */
unsigned r = (7.0f / 31.0f) * ((pixel & 0xF800) >> 11);
unsigned g = (7.0f / 63.0f) * ((pixel & 0x07E0) >> 5);
unsigned b = (3.0f / 31.0f) * ((pixel & 0x001F) >> 0);
unsigned r = ((pixel & 0xF800) >> 13);
unsigned g = ((pixel & 0x07E0) >> 8);
unsigned b = ((pixel & 0x001F) >> 3);
vga_frame[VGA_WIDTH * y + x] = (b << 6) | (g << 3) | r;
}
@@ -368,10 +368,13 @@ static void vga_set_texture_frame(void *data,
{
for(x = 0; x < VGA_WIDTH; x++)
{
unsigned short pixel = video_frame[width * y + x];
unsigned r = (7.0f / 15.0f) * ((pixel & 0xF000) >> 12);
unsigned g = (7.0f / 15.0f) * ((pixel & 0xF00) >> 8);
unsigned b = (3.0f / 15.0f) * ((pixel & 0xF0) >> 4);
/* scale incoming frame to fit the screen */
unsigned scaled_x = (width * x) / VGA_WIDTH;
unsigned scaled_y = (height * y) / VGA_HEIGHT;
unsigned short pixel = video_frame[width * scaled_y + scaled_x];
unsigned r = ((pixel & 0xF000) >> 13);
unsigned g = ((pixel & 0xF00) >> 9);
unsigned b = ((pixel & 0xF0) >> 6);
vga_menu_frame[VGA_WIDTH * y + x] = (b << 6) | (g << 3) | r;
}
}
+79 -24
View File
@@ -225,6 +225,18 @@ static void vulkan_init_pipelines(
#include "vulkan_shaders/pipeline_ribbon_simple.frag.inc"
;
static const uint32_t pipeline_snow_simple_frag[] =
#include "vulkan_shaders/pipeline_snow_simple.frag.inc"
;
static const uint32_t pipeline_snow_frag[] =
#include "vulkan_shaders/pipeline_snow.frag.inc"
;
static const uint32_t pipeline_bokeh_frag[] =
#include "vulkan_shaders/pipeline_bokeh.frag.inc"
;
unsigned i;
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
@@ -390,17 +402,38 @@ static void vulkan_init_pipelines(
vkDestroyShaderModule(vk->context->device, shader_stages[1].module, NULL);
/* Other menu pipelines. */
for (i = 0; i < 4; i++)
for (i = 0; i < ARRAY_SIZE(vk->display.pipelines) - 4; i++)
{
if (i & 2)
switch (i >> 1)
{
module_info.codeSize = sizeof(pipeline_ribbon_simple_vert);
module_info.pCode = pipeline_ribbon_simple_vert;
}
else
{
module_info.codeSize = sizeof(pipeline_ribbon_vert);
module_info.pCode = pipeline_ribbon_vert;
case 0:
module_info.codeSize = sizeof(pipeline_ribbon_vert);
module_info.pCode = pipeline_ribbon_vert;
break;
case 1:
module_info.codeSize = sizeof(pipeline_ribbon_simple_vert);
module_info.pCode = pipeline_ribbon_simple_vert;
break;
case 2:
module_info.codeSize = sizeof(alpha_blend_vert);
module_info.pCode = alpha_blend_vert;
break;
case 3:
module_info.codeSize = sizeof(alpha_blend_vert);
module_info.pCode = alpha_blend_vert;
break;
case 4:
module_info.codeSize = sizeof(alpha_blend_vert);
module_info.pCode = alpha_blend_vert;
break;
default:
retro_assert(0 && "No shader for menu pipeline.");
break;
}
shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
@@ -408,15 +441,36 @@ static void vulkan_init_pipelines(
vkCreateShaderModule(vk->context->device,
&module_info, NULL, &shader_stages[0].module);
if (i & 2)
switch (i >> 1)
{
module_info.codeSize = sizeof(pipeline_ribbon_simple_frag);
module_info.pCode = pipeline_ribbon_simple_frag;
}
else
{
module_info.codeSize = sizeof(pipeline_ribbon_frag);
module_info.pCode = pipeline_ribbon_frag;
case 0:
module_info.codeSize = sizeof(pipeline_ribbon_frag);
module_info.pCode = pipeline_ribbon_frag;
break;
case 1:
module_info.codeSize = sizeof(pipeline_ribbon_simple_frag);
module_info.pCode = pipeline_ribbon_simple_frag;
break;
case 2:
module_info.codeSize = sizeof(pipeline_snow_simple_frag);
module_info.pCode = pipeline_snow_simple_frag;
break;
case 3:
module_info.codeSize = sizeof(pipeline_snow_frag);
module_info.pCode = pipeline_snow_frag;
break;
case 4:
module_info.codeSize = sizeof(pipeline_bokeh_frag);
module_info.pCode = pipeline_bokeh_frag;
break;
default:
retro_assert(0 && "No shader for menu pipeline.");
break;
}
shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
@@ -639,7 +693,7 @@ static void vulkan_deinit_pipelines(vk_t *vk)
vkDestroyPipeline(vk->context->device,
vk->pipelines.font, NULL);
for (i = 0; i < 8; i++)
for (i = 0; i < ARRAY_SIZE(vk->display.pipelines); i++)
vkDestroyPipeline(vk->context->device,
vk->display.pipelines[i], NULL);
}
@@ -1524,7 +1578,6 @@ static bool vulkan_frame(void *data, const void *frame,
unsigned pitch, const char *msg, video_frame_info_t *video_info)
{
VkSemaphore signal_semaphores[2];
VkClearValue clear_value;
vk_t *vk = (vk_t*)data;
struct vk_per_frame *chain = NULL;
static struct retro_perf_counter frame_run = {0};
@@ -1537,6 +1590,7 @@ static bool vulkan_frame(void *data, const void *frame,
bool waits_for_semaphores = false;
unsigned width = video_info->width;
unsigned height = video_info->height;
VkClearValue clear_color;
VkCommandBufferBeginInfo begin_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
@@ -1711,16 +1765,17 @@ static bool vulkan_frame(void *data, const void *frame,
(vulkan_filter_chain_t*)vk->filter_chain,
vk->cmd, &vk->vk_vp);
/* Render to backbuffer. */
clear_value.color.float32[0] = 0.0f;
clear_value.color.float32[1] = 0.0f;
clear_value.color.float32[2] = 0.0f;
clear_value.color.float32[3] = 1.0f;
rp_info.renderPass = vk->render_pass;
rp_info.framebuffer = chain->backbuffer.framebuffer;
rp_info.renderArea.extent.width = vk->context->swapchain_width;
rp_info.renderArea.extent.height = vk->context->swapchain_height;
rp_info.clearValueCount = 1;
rp_info.pClearValues = &clear_value;
rp_info.pClearValues = &clear_color;
clear_color.color.float32[0] = 0.0f;
clear_color.color.float32[1] = 0.0f;
clear_color.color.float32[2] = 0.0f;
clear_color.color.float32[3] = 0.0f;
/* Prepare backbuffer for rendering. We don't use WSI semaphores here. */
vulkan_image_layout_transition(vk, vk->cmd, chain->backbuffer.image,
@@ -0,0 +1,39 @@
#version 310 es
precision mediump float;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec2 OutputSize;
float time;
} constants;
layout(location = 0) out vec4 FragColor;
void main(void)
{
float speed = constants.time * 4.0;
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / constants.OutputSize;
uv.x *= constants.OutputSize.x / constants.OutputSize.y;
vec3 color = vec3(0.0);
for( int i=0; i < 8; i++ )
{
float pha = sin(float(i) * 546.13 + 1.0) * 0.5 + 0.5;
float siz = pow(sin(float(i) * 651.74 + 5.0) * 0.5 + 0.5, 4.0);
float pox = sin(float(i) * 321.55 + 4.1) * constants.OutputSize.x / constants.OutputSize.y;
float rad = 0.1 + 0.5 * siz + sin(pha + siz) / 4.0;
vec2 pos = vec2(pox + sin(speed / 15. + pha + siz), - 1.0 - rad + (2.0 + 2.0 * rad) * fract(pha + 0.3 * (speed / 7.) * (0.2 + 0.8 * siz)));
float dis = length(uv - pos);
if(dis < rad)
{
vec3 col = mix(vec3(0.194 * sin(speed / 6.0) + 0.3, 0.2, 0.3 * pha), vec3(1.1 * sin(speed / 9.0) + 0.3, 0.2 * pha, 0.4), 0.5 + 0.5 * sin(float(i)));
color += col.zyx * (1.0 - smoothstep(rad * 0.15, rad, dis));
}
}
color *= sqrt(1.5 - 0.5 * length(uv));
FragColor = vec4(color.r, color.g, color.b , 0.5);
}
@@ -0,0 +1,407 @@
{0x07230203,0x00010000,0x000d0001,0x000000da,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
0x00000000,0x0000001b,0x000000d1,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
0x7269645f,0x69746365,0x00006576,0x00080004,
0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,
0x69645f65,0x74636572,0x00657669,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00040005,
0x00000008,0x65657073,0x00000064,0x00030005,
0x0000000c,0x004f4255,0x00040006,0x0000000c,
0x00000000,0x0050564d,0x00060006,0x0000000c,
0x00000001,0x7074754f,0x69537475,0x0000657a,
0x00050006,0x0000000c,0x00000002,0x656d6974,
0x00000000,0x00050005,0x0000000e,0x736e6f63,
0x746e6174,0x00000073,0x00030005,0x00000017,
0x00007675,0x00060005,0x0000001b,0x465f6c67,
0x43676172,0x64726f6f,0x00000000,0x00040005,
0x00000034,0x6f6c6f63,0x00000072,0x00030005,
0x00000038,0x00000069,0x00030005,0x00000043,
0x00616870,0x00030005,0x0000004e,0x007a6973,
0x00030005,0x00000059,0x00786f70,0x00030005,
0x00000067,0x00646172,0x00030005,0x00000072,
0x00736f70,0x00030005,0x00000093,0x00736964,
0x00030005,0x0000009d,0x006c6f63,0x00050005,
0x000000d1,0x67617246,0x6f6c6f43,0x00000072,
0x00030047,0x00000008,0x00000000,0x00040048,
0x0000000c,0x00000000,0x00000005,0x00040048,
0x0000000c,0x00000000,0x00000000,0x00050048,
0x0000000c,0x00000000,0x00000023,0x00000000,
0x00050048,0x0000000c,0x00000000,0x00000007,
0x00000010,0x00040048,0x0000000c,0x00000001,
0x00000000,0x00050048,0x0000000c,0x00000001,
0x00000023,0x00000040,0x00040048,0x0000000c,
0x00000002,0x00000000,0x00050048,0x0000000c,
0x00000002,0x00000023,0x00000048,0x00030047,
0x0000000c,0x00000002,0x00040047,0x0000000e,
0x00000022,0x00000000,0x00040047,0x0000000e,
0x00000021,0x00000000,0x00030047,0x00000013,
0x00000000,0x00030047,0x00000015,0x00000000,
0x00030047,0x00000017,0x00000000,0x00040047,
0x0000001b,0x0000000b,0x0000000f,0x00030047,
0x00000022,0x00000000,0x00030047,0x00000029,
0x00000000,0x00030047,0x0000002c,0x00000000,
0x00030047,0x0000002d,0x00000000,0x00030047,
0x0000002f,0x00000000,0x00030047,0x00000030,
0x00000000,0x00030047,0x00000034,0x00000000,
0x00030047,0x00000038,0x00000000,0x00030047,
0x0000003f,0x00000000,0x00030047,0x00000043,
0x00000000,0x00030047,0x00000044,0x00000000,
0x00030047,0x00000045,0x00000000,0x00030047,
0x00000047,0x00000000,0x00030047,0x00000049,
0x00000000,0x00030047,0x0000004a,0x00000000,
0x00030047,0x0000004c,0x00000000,0x00030047,
0x0000004d,0x00000000,0x00030047,0x0000004e,
0x00000000,0x00030047,0x0000004f,0x00000000,
0x00030047,0x00000050,0x00000000,0x00030047,
0x00000052,0x00000000,0x00030047,0x00000054,
0x00000000,0x00030047,0x00000055,0x00000000,
0x00030047,0x00000056,0x00000000,0x00030047,
0x00000057,0x00000000,0x00030047,0x00000058,
0x00000000,0x00030047,0x00000059,0x00000000,
0x00030047,0x0000005a,0x00000000,0x00030047,
0x0000005b,0x00000000,0x00030047,0x0000005d,
0x00000000,0x00030047,0x0000005f,0x00000000,
0x00030047,0x00000060,0x00000000,0x00030047,
0x00000062,0x00000000,0x00030047,0x00000063,
0x00000000,0x00030047,0x00000065,0x00000000,
0x00030047,0x00000066,0x00000000,0x00030047,
0x00000067,0x00000000,0x00030047,0x00000069,
0x00000000,0x00030047,0x0000006a,0x00000000,
0x00030047,0x0000006b,0x00000000,0x00030047,
0x0000006c,0x00000000,0x00030047,0x0000006d,
0x00000000,0x00030047,0x0000006e,0x00000000,
0x00030047,0x0000006f,0x00000000,0x00030047,
0x00000070,0x00000000,0x00030047,0x00000071,
0x00000000,0x00030047,0x00000072,0x00000000,
0x00030047,0x00000073,0x00000000,0x00030047,
0x00000074,0x00000000,0x00030047,0x00000076,
0x00000000,0x00030047,0x00000077,0x00000000,
0x00030047,0x00000078,0x00000000,0x00030047,
0x00000079,0x00000000,0x00030047,0x0000007a,
0x00000000,0x00030047,0x0000007b,0x00000000,
0x00030047,0x0000007c,0x00000000,0x00030047,
0x0000007d,0x00000000,0x00030047,0x0000007e,
0x00000000,0x00030047,0x0000007f,0x00000000,
0x00030047,0x00000080,0x00000000,0x00030047,
0x00000081,0x00000000,0x00030047,0x00000082,
0x00000000,0x00030047,0x00000084,0x00000000,
0x00030047,0x00000086,0x00000000,0x00030047,
0x00000087,0x00000000,0x00030047,0x0000008a,
0x00000000,0x00030047,0x0000008b,0x00000000,
0x00030047,0x0000008c,0x00000000,0x00030047,
0x0000008d,0x00000000,0x00030047,0x0000008e,
0x00000000,0x00030047,0x0000008f,0x00000000,
0x00030047,0x00000090,0x00000000,0x00030047,
0x00000091,0x00000000,0x00030047,0x00000092,
0x00000000,0x00030047,0x00000093,0x00000000,
0x00030047,0x00000094,0x00000000,0x00030047,
0x00000095,0x00000000,0x00030047,0x00000096,
0x00000000,0x00030047,0x00000097,0x00000000,
0x00030047,0x00000098,0x00000000,0x00030047,
0x00000099,0x00000000,0x00030047,0x0000009d,
0x00000000,0x00030047,0x0000009f,0x00000000,
0x00030047,0x000000a1,0x00000000,0x00030047,
0x000000a2,0x00000000,0x00030047,0x000000a3,
0x00000000,0x00030047,0x000000a4,0x00000000,
0x00030047,0x000000a5,0x00000000,0x00030047,
0x000000a6,0x00000000,0x00030047,0x000000a7,
0x00000000,0x00030047,0x000000a9,0x00000000,
0x00030047,0x000000ab,0x00000000,0x00030047,
0x000000ac,0x00000000,0x00030047,0x000000ad,
0x00000000,0x00030047,0x000000ae,0x00000000,
0x00030047,0x000000af,0x00000000,0x00030047,
0x000000b0,0x00000000,0x00030047,0x000000b2,
0x00000000,0x00030047,0x000000b3,0x00000000,
0x00030047,0x000000b4,0x00000000,0x00030047,
0x000000b5,0x00000000,0x00030047,0x000000b6,
0x00000000,0x00030047,0x000000b7,0x00000000,
0x00030047,0x000000b8,0x00000000,0x00030047,
0x000000b9,0x00000000,0x00030047,0x000000ba,
0x00000000,0x00030047,0x000000bb,0x00000000,
0x00030047,0x000000bc,0x00000000,0x00030047,
0x000000be,0x00000000,0x00030047,0x000000bf,
0x00000000,0x00030047,0x000000c0,0x00000000,
0x00030047,0x000000c1,0x00000000,0x00030047,
0x000000c2,0x00000000,0x00030047,0x000000c3,
0x00000000,0x00030047,0x000000c4,0x00000000,
0x00030047,0x000000c5,0x00000000,0x00030047,
0x000000c6,0x00000000,0x00030047,0x000000c7,
0x00000000,0x00030047,0x000000c9,0x00000000,
0x00030047,0x000000ca,0x00000000,0x00030047,
0x000000cb,0x00000000,0x00030047,0x000000cc,
0x00000000,0x00030047,0x000000cd,0x00000000,
0x00030047,0x000000ce,0x00000000,0x00030047,
0x000000cf,0x00000000,0x00030047,0x000000d1,
0x00000000,0x00040047,0x000000d1,0x0000001e,
0x00000000,0x00030047,0x000000d3,0x00000000,
0x00030047,0x000000d5,0x00000000,0x00030047,
0x000000d8,0x00000000,0x00030047,0x000000d9,
0x00000000,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,
0x00000020,0x00040020,0x00000007,0x00000007,
0x00000006,0x00040017,0x00000009,0x00000006,
0x00000004,0x00040018,0x0000000a,0x00000009,
0x00000004,0x00040017,0x0000000b,0x00000006,
0x00000002,0x0005001e,0x0000000c,0x0000000a,
0x0000000b,0x00000006,0x00040020,0x0000000d,
0x00000002,0x0000000c,0x0004003b,0x0000000d,
0x0000000e,0x00000002,0x00040015,0x0000000f,
0x00000020,0x00000001,0x0004002b,0x0000000f,
0x00000010,0x00000002,0x00040020,0x00000011,
0x00000002,0x00000006,0x0004002b,0x00000006,
0x00000014,0x40800000,0x00040020,0x00000016,
0x00000007,0x0000000b,0x0004002b,0x00000006,
0x00000018,0xbf800000,0x0004002b,0x00000006,
0x00000019,0x40000000,0x00040020,0x0000001a,
0x00000001,0x00000009,0x0004003b,0x0000001a,
0x0000001b,0x00000001,0x0004002b,0x0000000f,
0x0000001f,0x00000001,0x00040020,0x00000020,
0x00000002,0x0000000b,0x00040015,0x00000026,
0x00000020,0x00000000,0x0004002b,0x00000026,
0x00000027,0x00000000,0x0004002b,0x00000026,
0x0000002a,0x00000001,0x00040017,0x00000032,
0x00000006,0x00000003,0x00040020,0x00000033,
0x00000007,0x00000032,0x0004002b,0x00000006,
0x00000035,0x00000000,0x0006002c,0x00000032,
0x00000036,0x00000035,0x00000035,0x00000035,
0x00040020,0x00000037,0x00000007,0x0000000f,
0x0004002b,0x0000000f,0x00000039,0x00000000,
0x0004002b,0x0000000f,0x00000040,0x00000008,
0x00020014,0x00000041,0x0004002b,0x00000006,
0x00000046,0x44088852,0x0004002b,0x00000006,
0x00000048,0x3f800000,0x0004002b,0x00000006,
0x0000004b,0x3f000000,0x0004002b,0x00000006,
0x00000051,0x4422ef5c,0x0004002b,0x00000006,
0x00000053,0x40a00000,0x0004002b,0x00000006,
0x0000005c,0x43a0c666,0x0004002b,0x00000006,
0x0000005e,0x40833333,0x0004002b,0x00000006,
0x00000068,0x3dcccccd,0x0004002b,0x00000006,
0x00000075,0x41700000,0x0004002b,0x00000006,
0x00000083,0x3e99999a,0x0004002b,0x00000006,
0x00000085,0x40e00000,0x0004002b,0x00000006,
0x00000088,0x3e4ccccd,0x0004002b,0x00000006,
0x00000089,0x3f4ccccd,0x0004002b,0x00000006,
0x0000009e,0x3e46a7f0,0x0004002b,0x00000006,
0x000000a0,0x40c00000,0x0004002b,0x00000006,
0x000000a8,0x3f8ccccd,0x0004002b,0x00000006,
0x000000aa,0x41100000,0x0004002b,0x00000006,
0x000000b1,0x3ecccccd,0x0004002b,0x00000006,
0x000000bd,0x3e19999a,0x0004002b,0x00000006,
0x000000c8,0x3fc00000,0x00040020,0x000000d0,
0x00000003,0x00000009,0x0004003b,0x000000d0,
0x000000d1,0x00000003,0x0004002b,0x00000026,
0x000000d6,0x00000002,0x00050036,0x00000002,
0x00000004,0x00000000,0x00000003,0x000200f8,
0x00000005,0x0004003b,0x00000007,0x00000008,
0x00000007,0x0004003b,0x00000016,0x00000017,
0x00000007,0x0004003b,0x00000033,0x00000034,
0x00000007,0x0004003b,0x00000037,0x00000038,
0x00000007,0x0004003b,0x00000007,0x00000043,
0x00000007,0x0004003b,0x00000007,0x0000004e,
0x00000007,0x0004003b,0x00000007,0x00000059,
0x00000007,0x0004003b,0x00000007,0x00000067,
0x00000007,0x0004003b,0x00000016,0x00000072,
0x00000007,0x0004003b,0x00000007,0x00000093,
0x00000007,0x0004003b,0x00000033,0x0000009d,
0x00000007,0x00050041,0x00000011,0x00000012,
0x0000000e,0x00000010,0x0004003d,0x00000006,
0x00000013,0x00000012,0x00050085,0x00000006,
0x00000015,0x00000013,0x00000014,0x0003003e,
0x00000008,0x00000015,0x0004003d,0x00000009,
0x0000001c,0x0000001b,0x0007004f,0x0000000b,
0x0000001d,0x0000001c,0x0000001c,0x00000000,
0x00000001,0x0005008e,0x0000000b,0x0000001e,
0x0000001d,0x00000019,0x00050041,0x00000020,
0x00000021,0x0000000e,0x0000001f,0x0004003d,
0x0000000b,0x00000022,0x00000021,0x00050088,
0x0000000b,0x00000023,0x0000001e,0x00000022,
0x00050050,0x0000000b,0x00000024,0x00000018,
0x00000018,0x00050081,0x0000000b,0x00000025,
0x00000024,0x00000023,0x0003003e,0x00000017,
0x00000025,0x00060041,0x00000011,0x00000028,
0x0000000e,0x0000001f,0x00000027,0x0004003d,
0x00000006,0x00000029,0x00000028,0x00060041,
0x00000011,0x0000002b,0x0000000e,0x0000001f,
0x0000002a,0x0004003d,0x00000006,0x0000002c,
0x0000002b,0x00050088,0x00000006,0x0000002d,
0x00000029,0x0000002c,0x00050041,0x00000007,
0x0000002e,0x00000017,0x00000027,0x0004003d,
0x00000006,0x0000002f,0x0000002e,0x00050085,
0x00000006,0x00000030,0x0000002f,0x0000002d,
0x00050041,0x00000007,0x00000031,0x00000017,
0x00000027,0x0003003e,0x00000031,0x00000030,
0x0003003e,0x00000034,0x00000036,0x0003003e,
0x00000038,0x00000039,0x000200f9,0x0000003a,
0x000200f8,0x0000003a,0x000400f6,0x0000003c,
0x0000003d,0x00000000,0x000200f9,0x0000003e,
0x000200f8,0x0000003e,0x0004003d,0x0000000f,
0x0000003f,0x00000038,0x000500b1,0x00000041,
0x00000042,0x0000003f,0x00000040,0x000400fa,
0x00000042,0x0000003b,0x0000003c,0x000200f8,
0x0000003b,0x0004003d,0x0000000f,0x00000044,
0x00000038,0x0004006f,0x00000006,0x00000045,
0x00000044,0x00050085,0x00000006,0x00000047,
0x00000045,0x00000046,0x00050081,0x00000006,
0x00000049,0x00000047,0x00000048,0x0006000c,
0x00000006,0x0000004a,0x00000001,0x0000000d,
0x00000049,0x00050085,0x00000006,0x0000004c,
0x0000004a,0x0000004b,0x00050081,0x00000006,
0x0000004d,0x0000004c,0x0000004b,0x0003003e,
0x00000043,0x0000004d,0x0004003d,0x0000000f,
0x0000004f,0x00000038,0x0004006f,0x00000006,
0x00000050,0x0000004f,0x00050085,0x00000006,
0x00000052,0x00000050,0x00000051,0x00050081,
0x00000006,0x00000054,0x00000052,0x00000053,
0x0006000c,0x00000006,0x00000055,0x00000001,
0x0000000d,0x00000054,0x00050085,0x00000006,
0x00000056,0x00000055,0x0000004b,0x00050081,
0x00000006,0x00000057,0x00000056,0x0000004b,
0x0007000c,0x00000006,0x00000058,0x00000001,
0x0000001a,0x00000057,0x00000014,0x0003003e,
0x0000004e,0x00000058,0x0004003d,0x0000000f,
0x0000005a,0x00000038,0x0004006f,0x00000006,
0x0000005b,0x0000005a,0x00050085,0x00000006,
0x0000005d,0x0000005b,0x0000005c,0x00050081,
0x00000006,0x0000005f,0x0000005d,0x0000005e,
0x0006000c,0x00000006,0x00000060,0x00000001,
0x0000000d,0x0000005f,0x00060041,0x00000011,
0x00000061,0x0000000e,0x0000001f,0x00000027,
0x0004003d,0x00000006,0x00000062,0x00000061,
0x00050085,0x00000006,0x00000063,0x00000060,
0x00000062,0x00060041,0x00000011,0x00000064,
0x0000000e,0x0000001f,0x0000002a,0x0004003d,
0x00000006,0x00000065,0x00000064,0x00050088,
0x00000006,0x00000066,0x00000063,0x00000065,
0x0003003e,0x00000059,0x00000066,0x0004003d,
0x00000006,0x00000069,0x0000004e,0x00050085,
0x00000006,0x0000006a,0x0000004b,0x00000069,
0x00050081,0x00000006,0x0000006b,0x00000068,
0x0000006a,0x0004003d,0x00000006,0x0000006c,
0x00000043,0x0004003d,0x00000006,0x0000006d,
0x0000004e,0x00050081,0x00000006,0x0000006e,
0x0000006c,0x0000006d,0x0006000c,0x00000006,
0x0000006f,0x00000001,0x0000000d,0x0000006e,
0x00050088,0x00000006,0x00000070,0x0000006f,
0x00000014,0x00050081,0x00000006,0x00000071,
0x0000006b,0x00000070,0x0003003e,0x00000067,
0x00000071,0x0004003d,0x00000006,0x00000073,
0x00000059,0x0004003d,0x00000006,0x00000074,
0x00000008,0x00050088,0x00000006,0x00000076,
0x00000074,0x00000075,0x0004003d,0x00000006,
0x00000077,0x00000043,0x00050081,0x00000006,
0x00000078,0x00000076,0x00000077,0x0004003d,
0x00000006,0x00000079,0x0000004e,0x00050081,
0x00000006,0x0000007a,0x00000078,0x00000079,
0x0006000c,0x00000006,0x0000007b,0x00000001,
0x0000000d,0x0000007a,0x00050081,0x00000006,
0x0000007c,0x00000073,0x0000007b,0x0004003d,
0x00000006,0x0000007d,0x00000067,0x00050083,
0x00000006,0x0000007e,0x00000018,0x0000007d,
0x0004003d,0x00000006,0x0000007f,0x00000067,
0x00050085,0x00000006,0x00000080,0x00000019,
0x0000007f,0x00050081,0x00000006,0x00000081,
0x00000019,0x00000080,0x0004003d,0x00000006,
0x00000082,0x00000043,0x0004003d,0x00000006,
0x00000084,0x00000008,0x00050088,0x00000006,
0x00000086,0x00000084,0x00000085,0x00050085,
0x00000006,0x00000087,0x00000083,0x00000086,
0x0004003d,0x00000006,0x0000008a,0x0000004e,
0x00050085,0x00000006,0x0000008b,0x00000089,
0x0000008a,0x00050081,0x00000006,0x0000008c,
0x00000088,0x0000008b,0x00050085,0x00000006,
0x0000008d,0x00000087,0x0000008c,0x00050081,
0x00000006,0x0000008e,0x00000082,0x0000008d,
0x0006000c,0x00000006,0x0000008f,0x00000001,
0x0000000a,0x0000008e,0x00050085,0x00000006,
0x00000090,0x00000081,0x0000008f,0x00050081,
0x00000006,0x00000091,0x0000007e,0x00000090,
0x00050050,0x0000000b,0x00000092,0x0000007c,
0x00000091,0x0003003e,0x00000072,0x00000092,
0x0004003d,0x0000000b,0x00000094,0x00000017,
0x0004003d,0x0000000b,0x00000095,0x00000072,
0x00050083,0x0000000b,0x00000096,0x00000094,
0x00000095,0x0006000c,0x00000006,0x00000097,
0x00000001,0x00000042,0x00000096,0x0003003e,
0x00000093,0x00000097,0x0004003d,0x00000006,
0x00000098,0x00000093,0x0004003d,0x00000006,
0x00000099,0x00000067,0x000500b8,0x00000041,
0x0000009a,0x00000098,0x00000099,0x000300f7,
0x0000009c,0x00000000,0x000400fa,0x0000009a,
0x0000009b,0x0000009c,0x000200f8,0x0000009b,
0x0004003d,0x00000006,0x0000009f,0x00000008,
0x00050088,0x00000006,0x000000a1,0x0000009f,
0x000000a0,0x0006000c,0x00000006,0x000000a2,
0x00000001,0x0000000d,0x000000a1,0x00050085,
0x00000006,0x000000a3,0x0000009e,0x000000a2,
0x00050081,0x00000006,0x000000a4,0x000000a3,
0x00000083,0x0004003d,0x00000006,0x000000a5,
0x00000043,0x00050085,0x00000006,0x000000a6,
0x00000083,0x000000a5,0x00060050,0x00000032,
0x000000a7,0x000000a4,0x00000088,0x000000a6,
0x0004003d,0x00000006,0x000000a9,0x00000008,
0x00050088,0x00000006,0x000000ab,0x000000a9,
0x000000aa,0x0006000c,0x00000006,0x000000ac,
0x00000001,0x0000000d,0x000000ab,0x00050085,
0x00000006,0x000000ad,0x000000a8,0x000000ac,
0x00050081,0x00000006,0x000000ae,0x000000ad,
0x00000083,0x0004003d,0x00000006,0x000000af,
0x00000043,0x00050085,0x00000006,0x000000b0,
0x00000088,0x000000af,0x00060050,0x00000032,
0x000000b2,0x000000ae,0x000000b0,0x000000b1,
0x0004003d,0x0000000f,0x000000b3,0x00000038,
0x0004006f,0x00000006,0x000000b4,0x000000b3,
0x0006000c,0x00000006,0x000000b5,0x00000001,
0x0000000d,0x000000b4,0x00050085,0x00000006,
0x000000b6,0x0000004b,0x000000b5,0x00050081,
0x00000006,0x000000b7,0x0000004b,0x000000b6,
0x00060050,0x00000032,0x000000b8,0x000000b7,
0x000000b7,0x000000b7,0x0008000c,0x00000032,
0x000000b9,0x00000001,0x0000002e,0x000000a7,
0x000000b2,0x000000b8,0x0003003e,0x0000009d,
0x000000b9,0x0004003d,0x00000032,0x000000ba,
0x0000009d,0x0008004f,0x00000032,0x000000bb,
0x000000ba,0x000000ba,0x00000002,0x00000001,
0x00000000,0x0004003d,0x00000006,0x000000bc,
0x00000067,0x00050085,0x00000006,0x000000be,
0x000000bc,0x000000bd,0x0004003d,0x00000006,
0x000000bf,0x00000067,0x0004003d,0x00000006,
0x000000c0,0x00000093,0x0008000c,0x00000006,
0x000000c1,0x00000001,0x00000031,0x000000be,
0x000000bf,0x000000c0,0x00050083,0x00000006,
0x000000c2,0x00000048,0x000000c1,0x0005008e,
0x00000032,0x000000c3,0x000000bb,0x000000c2,
0x0004003d,0x00000032,0x000000c4,0x00000034,
0x00050081,0x00000032,0x000000c5,0x000000c4,
0x000000c3,0x0003003e,0x00000034,0x000000c5,
0x000200f9,0x0000009c,0x000200f8,0x0000009c,
0x000200f9,0x0000003d,0x000200f8,0x0000003d,
0x0004003d,0x0000000f,0x000000c6,0x00000038,
0x00050080,0x0000000f,0x000000c7,0x000000c6,
0x0000001f,0x0003003e,0x00000038,0x000000c7,
0x000200f9,0x0000003a,0x000200f8,0x0000003c,
0x0004003d,0x0000000b,0x000000c9,0x00000017,
0x0006000c,0x00000006,0x000000ca,0x00000001,
0x00000042,0x000000c9,0x00050085,0x00000006,
0x000000cb,0x0000004b,0x000000ca,0x00050083,
0x00000006,0x000000cc,0x000000c8,0x000000cb,
0x0006000c,0x00000006,0x000000cd,0x00000001,
0x0000001f,0x000000cc,0x0004003d,0x00000032,
0x000000ce,0x00000034,0x0005008e,0x00000032,
0x000000cf,0x000000ce,0x000000cd,0x0003003e,
0x00000034,0x000000cf,0x00050041,0x00000007,
0x000000d2,0x00000034,0x00000027,0x0004003d,
0x00000006,0x000000d3,0x000000d2,0x00050041,
0x00000007,0x000000d4,0x00000034,0x0000002a,
0x0004003d,0x00000006,0x000000d5,0x000000d4,
0x00050041,0x00000007,0x000000d7,0x00000034,
0x000000d6,0x0004003d,0x00000006,0x000000d8,
0x000000d7,0x00070050,0x00000009,0x000000d9,
0x000000d3,0x000000d5,0x000000d8,0x0000004b,
0x0003003e,0x000000d1,0x000000d9,0x000100fd,
0x00010038}
@@ -0,0 +1,76 @@
#version 310 es
precision mediump float;
layout(std140, set = 0, binding = 0) uniform UBO
{
mat4 MVP;
vec2 OutputSize;
float time;
} constants;
layout(location = 0) out vec4 FragColor;
const float baseScale = 3.5; // [1.0 .. 10.0]
const float density = 0.7; // [0.01 .. 1.0]
const float speed = 0.25; // [0.1 .. 1.0]
float rand(vec2 co)
{
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
float dist_func(vec2 distv)
{
float dist = sqrt((distv.x * distv.x) + (distv.y * distv.y)) * (40.0 / baseScale);
dist = clamp(dist, 0.0, 1.0);
return cos(dist * (3.14159265358 * 0.5)) * 0.5;
}
float random_dots(vec2 co)
{
float part = 1.0 / 20.0;
vec2 cd = floor(co / part);
float p = rand(cd);
if (p > 0.005 * (density * 40.0))
return 0.0;
vec2 dpos = (vec2(fract(p * 2.0) , p) + vec2(2.0, 2.0)) * 0.25;
vec2 cellpos = fract(co / part);
vec2 distv = (cellpos - dpos);
return dist_func(distv);
}
float snow(vec2 pos, float time, float scale)
{
// add wobble
pos.x += cos(pos.y * 1.2 + time * 3.14159 * 2.0 + 1.0 / scale) / (8.0 / scale) * 4.0;
// add gravity
pos += time * scale * vec2(-0.5, 1.0) * 4.0;
return random_dots(pos / scale) * (scale * 0.5 + 0.5);
}
void main(void)
{
float tim = constants.time * 0.4 * speed;
vec2 pos = gl_FragCoord.xy / constants.OutputSize.xx;
pos.y = 1.0 - pos.y; // Flip Y
float a = 0.0;
// Each of these is a layer of snow
// Remove some for better performance
// Changing the scale (3rd value) will mess with the looping
a += snow(pos, tim, 1.0);
a += snow(pos, tim, 0.7);
a += snow(pos, tim, 0.6);
a += snow(pos, tim, 0.5);
a += snow(pos, tim, 0.4);
a += snow(pos, tim, 0.3);
a += snow(pos, tim, 0.25);
a += snow(pos, tim, 0.125);
a = a * min(pos.y * 4.0, 1.0);
FragColor = vec4(1.0, 1.0, 1.0, a);
}
@@ -0,0 +1,523 @@
{0x07230203,0x00010000,0x00080001,0x00000109,
0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,
0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,
0x00000000,0x000000ac,0x00000105,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000001,
0x00000136,0x000a0004,0x475f4c47,0x4c474f4f,
0x70635f45,0x74735f70,0x5f656c79,0x656e696c,
0x7269645f,0x69746365,0x00006576,0x00080004,
0x475f4c47,0x4c474f4f,0x6e695f45,0x64756c63,
0x69645f65,0x74636572,0x00657669,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00050005,
0x0000000b,0x646e6172,0x32667628,0x0000003b,
0x00030005,0x0000000a,0x00006f63,0x00060005,
0x0000000e,0x74736964,0x6e75665f,0x66762863,
0x00003b32,0x00040005,0x0000000d,0x74736964,
0x00000076,0x00070005,0x00000011,0x646e6172,
0x645f6d6f,0x2873746f,0x3b326676,0x00000000,
0x00030005,0x00000010,0x00006f63,0x00060005,
0x00000018,0x776f6e73,0x32667628,0x3b31663b,
0x003b3166,0x00030005,0x00000015,0x00736f70,
0x00040005,0x00000016,0x656d6974,0x00000000,
0x00040005,0x00000017,0x6c616373,0x00000065,
0x00040005,0x00000025,0x74736964,0x00000000,
0x00040005,0x00000043,0x74726170,0x00000000,
0x00030005,0x00000045,0x00006463,0x00030005,
0x0000004b,0x00000070,0x00040005,0x0000004c,
0x61726170,0x0000006d,0x00040005,0x00000056,
0x736f7064,0x00000000,0x00040005,0x00000061,
0x6c6c6563,0x00736f70,0x00040005,0x00000067,
0x74736964,0x00000076,0x00040005,0x0000006b,
0x61726170,0x0000006d,0x00040005,0x00000094,
0x61726170,0x0000006d,0x00030005,0x0000009c,
0x006d6974,0x00030005,0x0000009f,0x004f4255,
0x00040006,0x0000009f,0x00000000,0x0050564d,
0x00060006,0x0000009f,0x00000001,0x7074754f,
0x69537475,0x0000657a,0x00050006,0x0000009f,
0x00000002,0x656d6974,0x00000000,0x00050005,
0x000000a1,0x736e6f63,0x746e6174,0x00000073,
0x00030005,0x000000aa,0x00736f70,0x00060005,
0x000000ac,0x465f6c67,0x43676172,0x64726f6f,
0x00000000,0x00030005,0x000000b9,0x00000061,
0x00040005,0x000000ba,0x61726170,0x0000006d,
0x00040005,0x000000bc,0x61726170,0x0000006d,
0x00040005,0x000000be,0x61726170,0x0000006d,
0x00040005,0x000000c3,0x61726170,0x0000006d,
0x00040005,0x000000c5,0x61726170,0x0000006d,
0x00040005,0x000000c7,0x61726170,0x0000006d,
0x00040005,0x000000cc,0x61726170,0x0000006d,
0x00040005,0x000000ce,0x61726170,0x0000006d,
0x00040005,0x000000d0,0x61726170,0x0000006d,
0x00040005,0x000000d4,0x61726170,0x0000006d,
0x00040005,0x000000d6,0x61726170,0x0000006d,
0x00040005,0x000000d8,0x61726170,0x0000006d,
0x00040005,0x000000dc,0x61726170,0x0000006d,
0x00040005,0x000000de,0x61726170,0x0000006d,
0x00040005,0x000000e0,0x61726170,0x0000006d,
0x00040005,0x000000e5,0x61726170,0x0000006d,
0x00040005,0x000000e7,0x61726170,0x0000006d,
0x00040005,0x000000e9,0x61726170,0x0000006d,
0x00040005,0x000000ed,0x61726170,0x0000006d,
0x00040005,0x000000ef,0x61726170,0x0000006d,
0x00040005,0x000000f1,0x61726170,0x0000006d,
0x00040005,0x000000f6,0x61726170,0x0000006d,
0x00040005,0x000000f8,0x61726170,0x0000006d,
0x00040005,0x000000fa,0x61726170,0x0000006d,
0x00050005,0x00000105,0x67617246,0x6f6c6f43,
0x00000072,0x00030047,0x0000000b,0x00000000,
0x00030047,0x0000000a,0x00000000,0x00030047,
0x0000000e,0x00000000,0x00030047,0x0000000d,
0x00000000,0x00030047,0x00000011,0x00000000,
0x00030047,0x00000010,0x00000000,0x00030047,
0x00000018,0x00000000,0x00030047,0x00000015,
0x00000000,0x00030047,0x00000016,0x00000000,
0x00030047,0x00000017,0x00000000,0x00030047,
0x0000001a,0x00000000,0x00030047,0x0000001e,
0x00000000,0x00030047,0x0000001f,0x00000000,
0x00030047,0x00000021,0x00000000,0x00030047,
0x00000022,0x00000000,0x00030047,0x00000025,
0x00000000,0x00030047,0x00000029,0x00000000,
0x00030047,0x0000002b,0x00000000,0x00030047,
0x0000002c,0x00000000,0x00030047,0x0000002f,
0x00000000,0x00030047,0x00000031,0x00000000,
0x00030047,0x00000032,0x00000000,0x00030047,
0x00000033,0x00000000,0x00030047,0x00000034,
0x00000000,0x00030047,0x00000036,0x00000000,
0x00030047,0x00000037,0x00000000,0x00030047,
0x0000003a,0x00000000,0x00030047,0x0000003b,
0x00000000,0x00030047,0x0000003d,0x00000000,
0x00030047,0x0000003e,0x00000000,0x00030047,
0x00000040,0x00000000,0x00030047,0x00000043,
0x00000000,0x00030047,0x00000045,0x00000000,
0x00030047,0x00000046,0x00000000,0x00030047,
0x00000047,0x00000000,0x00030047,0x00000048,
0x00000000,0x00030047,0x00000049,0x00000000,
0x00030047,0x0000004a,0x00000000,0x00030047,
0x0000004b,0x00000000,0x00030047,0x0000004d,
0x00000000,0x00030047,0x0000004e,0x00000000,
0x00030047,0x0000004f,0x00000000,0x00030047,
0x00000056,0x00000000,0x00030047,0x00000057,
0x00000000,0x00030047,0x00000059,0x00000000,
0x00030047,0x0000005a,0x00000000,0x00030047,
0x0000005b,0x00000000,0x00030047,0x0000005c,
0x00000000,0x00030047,0x0000005e,0x00000000,
0x00030047,0x00000060,0x00000000,0x00030047,
0x00000061,0x00000000,0x00030047,0x00000062,
0x00000000,0x00030047,0x00000063,0x00000000,
0x00030047,0x00000064,0x00000000,0x00030047,
0x00000065,0x00000000,0x00030047,0x00000066,
0x00000000,0x00030047,0x00000067,0x00000000,
0x00030047,0x00000068,0x00000000,0x00030047,
0x00000069,0x00000000,0x00030047,0x0000006a,
0x00000000,0x00030047,0x0000006c,0x00000000,
0x00030047,0x0000006d,0x00000000,0x00030047,
0x00000071,0x00000000,0x00030047,0x00000073,
0x00000000,0x00030047,0x00000074,0x00000000,
0x00030047,0x00000076,0x00000000,0x00030047,
0x00000077,0x00000000,0x00030047,0x00000078,
0x00000000,0x00030047,0x00000079,0x00000000,
0x00030047,0x0000007a,0x00000000,0x00030047,
0x0000007b,0x00000000,0x00030047,0x0000007c,
0x00000000,0x00030047,0x0000007e,0x00000000,
0x00030047,0x0000007f,0x00000000,0x00030047,
0x00000080,0x00000000,0x00030047,0x00000082,
0x00000000,0x00030047,0x00000084,0x00000000,
0x00030047,0x00000085,0x00000000,0x00030047,
0x00000087,0x00000000,0x00030047,0x00000088,
0x00000000,0x00030047,0x00000089,0x00000000,
0x00030047,0x0000008c,0x00000000,0x00030047,
0x0000008d,0x00000000,0x00030047,0x0000008e,
0x00000000,0x00030047,0x0000008f,0x00000000,
0x00030047,0x00000090,0x00000000,0x00030047,
0x00000091,0x00000000,0x00030047,0x00000092,
0x00000000,0x00030047,0x00000093,0x00000000,
0x00030047,0x00000095,0x00000000,0x00030047,
0x00000096,0x00000000,0x00030047,0x00000097,
0x00000000,0x00030047,0x00000098,0x00000000,
0x00030047,0x00000099,0x00000000,0x00030047,
0x0000009c,0x00000000,0x00040048,0x0000009f,
0x00000000,0x00000005,0x00040048,0x0000009f,
0x00000000,0x00000000,0x00050048,0x0000009f,
0x00000000,0x00000023,0x00000000,0x00050048,
0x0000009f,0x00000000,0x00000007,0x00000010,
0x00040048,0x0000009f,0x00000001,0x00000000,
0x00050048,0x0000009f,0x00000001,0x00000023,
0x00000040,0x00040048,0x0000009f,0x00000002,
0x00000000,0x00050048,0x0000009f,0x00000002,
0x00000023,0x00000048,0x00030047,0x0000009f,
0x00000002,0x00040047,0x000000a1,0x00000022,
0x00000000,0x00040047,0x000000a1,0x00000021,
0x00000000,0x00030047,0x000000a6,0x00000000,
0x00030047,0x000000a8,0x00000000,0x00030047,
0x000000a9,0x00000000,0x00030047,0x000000aa,
0x00000000,0x00040047,0x000000ac,0x0000000b,
0x0000000f,0x00030047,0x000000b2,0x00000000,
0x00030047,0x000000b3,0x00000000,0x00030047,
0x000000b6,0x00000000,0x00030047,0x000000b7,
0x00000000,0x00030047,0x000000b9,0x00000000,
0x00030047,0x000000bb,0x00000000,0x00030047,
0x000000bd,0x00000000,0x00030047,0x000000bf,
0x00000000,0x00030047,0x000000c0,0x00000000,
0x00030047,0x000000c1,0x00000000,0x00030047,
0x000000c4,0x00000000,0x00030047,0x000000c6,
0x00000000,0x00030047,0x000000c8,0x00000000,
0x00030047,0x000000c9,0x00000000,0x00030047,
0x000000ca,0x00000000,0x00030047,0x000000cd,
0x00000000,0x00030047,0x000000cf,0x00000000,
0x00030047,0x000000d1,0x00000000,0x00030047,
0x000000d2,0x00000000,0x00030047,0x000000d3,
0x00000000,0x00030047,0x000000d5,0x00000000,
0x00030047,0x000000d7,0x00000000,0x00030047,
0x000000d9,0x00000000,0x00030047,0x000000da,
0x00000000,0x00030047,0x000000db,0x00000000,
0x00030047,0x000000dd,0x00000000,0x00030047,
0x000000df,0x00000000,0x00030047,0x000000e1,
0x00000000,0x00030047,0x000000e2,0x00000000,
0x00030047,0x000000e3,0x00000000,0x00030047,
0x000000e6,0x00000000,0x00030047,0x000000e8,
0x00000000,0x00030047,0x000000ea,0x00000000,
0x00030047,0x000000eb,0x00000000,0x00030047,
0x000000ec,0x00000000,0x00030047,0x000000ee,
0x00000000,0x00030047,0x000000f0,0x00000000,
0x00030047,0x000000f2,0x00000000,0x00030047,
0x000000f3,0x00000000,0x00030047,0x000000f4,
0x00000000,0x00030047,0x000000f7,0x00000000,
0x00030047,0x000000f9,0x00000000,0x00030047,
0x000000fb,0x00000000,0x00030047,0x000000fc,
0x00000000,0x00030047,0x000000fd,0x00000000,
0x00030047,0x000000fe,0x00000000,0x00030047,
0x00000100,0x00000000,0x00030047,0x00000101,
0x00000000,0x00030047,0x00000102,0x00000000,
0x00030047,0x00000103,0x00000000,0x00030047,
0x00000105,0x00000000,0x00040047,0x00000105,
0x0000001e,0x00000000,0x00030047,0x00000106,
0x00000000,0x00030047,0x00000107,0x00000000,
0x00030047,0x00000108,0x00000000,0x00030047,
0x000000c2,0x00000000,0x00030047,0x0000005f,
0x00000000,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,
0x00000020,0x00040017,0x00000007,0x00000006,
0x00000002,0x00040020,0x00000008,0x00000007,
0x00000007,0x00040021,0x00000009,0x00000006,
0x00000008,0x00040020,0x00000013,0x00000007,
0x00000006,0x00060021,0x00000014,0x00000006,
0x00000008,0x00000013,0x00000013,0x0004002b,
0x00000006,0x0000001b,0x414fd639,0x0004002b,
0x00000006,0x0000001c,0x429c774c,0x0005002c,
0x00000007,0x0000001d,0x0000001b,0x0000001c,
0x0004002b,0x00000006,0x00000020,0x472aee8c,
0x00040015,0x00000026,0x00000020,0x00000000,
0x0004002b,0x00000026,0x00000027,0x00000000,
0x0004002b,0x00000026,0x0000002d,0x00000001,
0x0004002b,0x00000006,0x00000035,0x4136db6e,
0x0004002b,0x00000006,0x00000038,0x00000000,
0x0004002b,0x00000006,0x00000039,0x3f800000,
0x0004002b,0x00000006,0x0000003c,0x3fc90fdb,
0x0004002b,0x00000006,0x0000003f,0x3f000000,
0x0004002b,0x00000006,0x00000044,0x3d4ccccd,
0x0004002b,0x00000006,0x00000050,0x3e0f5c29,
0x00020014,0x00000051,0x0004002b,0x00000006,
0x00000058,0x40000000,0x0005002c,0x00000007,
0x0000005d,0x00000058,0x00000058,0x0004002b,
0x00000006,0x0000005f,0x3e800000,0x0004002b,
0x00000006,0x00000072,0x3f99999a,0x0004002b,
0x00000006,0x00000075,0x40490fd0,0x0004002b,
0x00000006,0x0000007d,0x41000000,0x0004002b,
0x00000006,0x00000081,0x40800000,0x0004002b,
0x00000006,0x0000008a,0xbf000000,0x0005002c,
0x00000007,0x0000008b,0x0000008a,0x00000039,
0x00040017,0x0000009d,0x00000006,0x00000004,
0x00040018,0x0000009e,0x0000009d,0x00000004,
0x0005001e,0x0000009f,0x0000009e,0x00000007,
0x00000006,0x00040020,0x000000a0,0x00000002,
0x0000009f,0x0004003b,0x000000a0,0x000000a1,
0x00000002,0x00040015,0x000000a2,0x00000020,
0x00000001,0x0004002b,0x000000a2,0x000000a3,
0x00000002,0x00040020,0x000000a4,0x00000002,
0x00000006,0x0004002b,0x00000006,0x000000a7,
0x3ecccccd,0x00040020,0x000000ab,0x00000001,
0x0000009d,0x0004003b,0x000000ab,0x000000ac,
0x00000001,0x0004002b,0x000000a2,0x000000af,
0x00000001,0x00040020,0x000000b0,0x00000002,
0x00000007,0x0004002b,0x00000006,0x000000c2,
0x3f333333,0x0004002b,0x00000006,0x000000cb,
0x3f19999a,0x0004002b,0x00000006,0x000000e4,
0x3e99999a,0x0004002b,0x00000006,0x000000f5,
0x3e000000,0x00040020,0x00000104,0x00000003,
0x0000009d,0x0004003b,0x00000104,0x00000105,
0x00000003,0x0004002b,0x00000006,0x00000108,
0x40600000,0x00050036,0x00000002,0x00000004,
0x00000000,0x00000003,0x000200f8,0x00000005,
0x0004003b,0x00000013,0x0000009c,0x00000007,
0x0004003b,0x00000008,0x000000aa,0x00000007,
0x0004003b,0x00000013,0x000000b9,0x00000007,
0x0004003b,0x00000008,0x000000ba,0x00000007,
0x0004003b,0x00000013,0x000000bc,0x00000007,
0x0004003b,0x00000013,0x000000be,0x00000007,
0x0004003b,0x00000008,0x000000c3,0x00000007,
0x0004003b,0x00000013,0x000000c5,0x00000007,
0x0004003b,0x00000013,0x000000c7,0x00000007,
0x0004003b,0x00000008,0x000000cc,0x00000007,
0x0004003b,0x00000013,0x000000ce,0x00000007,
0x0004003b,0x00000013,0x000000d0,0x00000007,
0x0004003b,0x00000008,0x000000d4,0x00000007,
0x0004003b,0x00000013,0x000000d6,0x00000007,
0x0004003b,0x00000013,0x000000d8,0x00000007,
0x0004003b,0x00000008,0x000000dc,0x00000007,
0x0004003b,0x00000013,0x000000de,0x00000007,
0x0004003b,0x00000013,0x000000e0,0x00000007,
0x0004003b,0x00000008,0x000000e5,0x00000007,
0x0004003b,0x00000013,0x000000e7,0x00000007,
0x0004003b,0x00000013,0x000000e9,0x00000007,
0x0004003b,0x00000008,0x000000ed,0x00000007,
0x0004003b,0x00000013,0x000000ef,0x00000007,
0x0004003b,0x00000013,0x000000f1,0x00000007,
0x0004003b,0x00000008,0x000000f6,0x00000007,
0x0004003b,0x00000013,0x000000f8,0x00000007,
0x0004003b,0x00000013,0x000000fa,0x00000007,
0x00050041,0x000000a4,0x000000a5,0x000000a1,
0x000000a3,0x0004003d,0x00000006,0x000000a6,
0x000000a5,0x00050085,0x00000006,0x000000a8,
0x000000a6,0x000000a7,0x00050085,0x00000006,
0x000000a9,0x000000a8,0x0000005f,0x0003003e,
0x0000009c,0x000000a9,0x0004003d,0x0000009d,
0x000000ad,0x000000ac,0x0007004f,0x00000007,
0x000000ae,0x000000ad,0x000000ad,0x00000000,
0x00000001,0x00050041,0x000000b0,0x000000b1,
0x000000a1,0x000000af,0x0004003d,0x00000007,
0x000000b2,0x000000b1,0x0007004f,0x00000007,
0x000000b3,0x000000b2,0x000000b2,0x00000000,
0x00000000,0x00050088,0x00000007,0x000000b4,
0x000000ae,0x000000b3,0x0003003e,0x000000aa,
0x000000b4,0x00050041,0x00000013,0x000000b5,
0x000000aa,0x0000002d,0x0004003d,0x00000006,
0x000000b6,0x000000b5,0x00050083,0x00000006,
0x000000b7,0x00000039,0x000000b6,0x00050041,
0x00000013,0x000000b8,0x000000aa,0x0000002d,
0x0003003e,0x000000b8,0x000000b7,0x0003003e,
0x000000b9,0x00000038,0x0004003d,0x00000007,
0x000000bb,0x000000aa,0x0003003e,0x000000ba,
0x000000bb,0x0004003d,0x00000006,0x000000bd,
0x0000009c,0x0003003e,0x000000bc,0x000000bd,
0x0003003e,0x000000be,0x00000039,0x00070039,
0x00000006,0x000000bf,0x00000018,0x000000ba,
0x000000bc,0x000000be,0x0004003d,0x00000006,
0x000000c0,0x000000b9,0x00050081,0x00000006,
0x000000c1,0x000000c0,0x000000bf,0x0003003e,
0x000000b9,0x000000c1,0x0004003d,0x00000007,
0x000000c4,0x000000aa,0x0003003e,0x000000c3,
0x000000c4,0x0004003d,0x00000006,0x000000c6,
0x0000009c,0x0003003e,0x000000c5,0x000000c6,
0x0003003e,0x000000c7,0x000000c2,0x00070039,
0x00000006,0x000000c8,0x00000018,0x000000c3,
0x000000c5,0x000000c7,0x0004003d,0x00000006,
0x000000c9,0x000000b9,0x00050081,0x00000006,
0x000000ca,0x000000c9,0x000000c8,0x0003003e,
0x000000b9,0x000000ca,0x0004003d,0x00000007,
0x000000cd,0x000000aa,0x0003003e,0x000000cc,
0x000000cd,0x0004003d,0x00000006,0x000000cf,
0x0000009c,0x0003003e,0x000000ce,0x000000cf,
0x0003003e,0x000000d0,0x000000cb,0x00070039,
0x00000006,0x000000d1,0x00000018,0x000000cc,
0x000000ce,0x000000d0,0x0004003d,0x00000006,
0x000000d2,0x000000b9,0x00050081,0x00000006,
0x000000d3,0x000000d2,0x000000d1,0x0003003e,
0x000000b9,0x000000d3,0x0004003d,0x00000007,
0x000000d5,0x000000aa,0x0003003e,0x000000d4,
0x000000d5,0x0004003d,0x00000006,0x000000d7,
0x0000009c,0x0003003e,0x000000d6,0x000000d7,
0x0003003e,0x000000d8,0x0000003f,0x00070039,
0x00000006,0x000000d9,0x00000018,0x000000d4,
0x000000d6,0x000000d8,0x0004003d,0x00000006,
0x000000da,0x000000b9,0x00050081,0x00000006,
0x000000db,0x000000da,0x000000d9,0x0003003e,
0x000000b9,0x000000db,0x0004003d,0x00000007,
0x000000dd,0x000000aa,0x0003003e,0x000000dc,
0x000000dd,0x0004003d,0x00000006,0x000000df,
0x0000009c,0x0003003e,0x000000de,0x000000df,
0x0003003e,0x000000e0,0x000000a7,0x00070039,
0x00000006,0x000000e1,0x00000018,0x000000dc,
0x000000de,0x000000e0,0x0004003d,0x00000006,
0x000000e2,0x000000b9,0x00050081,0x00000006,
0x000000e3,0x000000e2,0x000000e1,0x0003003e,
0x000000b9,0x000000e3,0x0004003d,0x00000007,
0x000000e6,0x000000aa,0x0003003e,0x000000e5,
0x000000e6,0x0004003d,0x00000006,0x000000e8,
0x0000009c,0x0003003e,0x000000e7,0x000000e8,
0x0003003e,0x000000e9,0x000000e4,0x00070039,
0x00000006,0x000000ea,0x00000018,0x000000e5,
0x000000e7,0x000000e9,0x0004003d,0x00000006,
0x000000eb,0x000000b9,0x00050081,0x00000006,
0x000000ec,0x000000eb,0x000000ea,0x0003003e,
0x000000b9,0x000000ec,0x0004003d,0x00000007,
0x000000ee,0x000000aa,0x0003003e,0x000000ed,
0x000000ee,0x0004003d,0x00000006,0x000000f0,
0x0000009c,0x0003003e,0x000000ef,0x000000f0,
0x0003003e,0x000000f1,0x0000005f,0x00070039,
0x00000006,0x000000f2,0x00000018,0x000000ed,
0x000000ef,0x000000f1,0x0004003d,0x00000006,
0x000000f3,0x000000b9,0x00050081,0x00000006,
0x000000f4,0x000000f3,0x000000f2,0x0003003e,
0x000000b9,0x000000f4,0x0004003d,0x00000007,
0x000000f7,0x000000aa,0x0003003e,0x000000f6,
0x000000f7,0x0004003d,0x00000006,0x000000f9,
0x0000009c,0x0003003e,0x000000f8,0x000000f9,
0x0003003e,0x000000fa,0x000000f5,0x00070039,
0x00000006,0x000000fb,0x00000018,0x000000f6,
0x000000f8,0x000000fa,0x0004003d,0x00000006,
0x000000fc,0x000000b9,0x00050081,0x00000006,
0x000000fd,0x000000fc,0x000000fb,0x0003003e,
0x000000b9,0x000000fd,0x0004003d,0x00000006,
0x000000fe,0x000000b9,0x00050041,0x00000013,
0x000000ff,0x000000aa,0x0000002d,0x0004003d,
0x00000006,0x00000100,0x000000ff,0x00050085,
0x00000006,0x00000101,0x00000100,0x00000081,
0x0007000c,0x00000006,0x00000102,0x00000001,
0x00000025,0x00000101,0x00000039,0x00050085,
0x00000006,0x00000103,0x000000fe,0x00000102,
0x0003003e,0x000000b9,0x00000103,0x0004003d,
0x00000006,0x00000106,0x000000b9,0x00070050,
0x0000009d,0x00000107,0x00000039,0x00000039,
0x00000039,0x00000106,0x0003003e,0x00000105,
0x00000107,0x000100fd,0x00010038,0x00050036,
0x00000006,0x0000000b,0x00000000,0x00000009,
0x00030037,0x00000008,0x0000000a,0x000200f8,
0x0000000c,0x0004003d,0x00000007,0x0000001a,
0x0000000a,0x00050094,0x00000006,0x0000001e,
0x0000001a,0x0000001d,0x0006000c,0x00000006,
0x0000001f,0x00000001,0x0000000d,0x0000001e,
0x00050085,0x00000006,0x00000021,0x0000001f,
0x00000020,0x0006000c,0x00000006,0x00000022,
0x00000001,0x0000000a,0x00000021,0x000200fe,
0x00000022,0x00010038,0x00050036,0x00000006,
0x0000000e,0x00000000,0x00000009,0x00030037,
0x00000008,0x0000000d,0x000200f8,0x0000000f,
0x0004003b,0x00000013,0x00000025,0x00000007,
0x00050041,0x00000013,0x00000028,0x0000000d,
0x00000027,0x0004003d,0x00000006,0x00000029,
0x00000028,0x00050041,0x00000013,0x0000002a,
0x0000000d,0x00000027,0x0004003d,0x00000006,
0x0000002b,0x0000002a,0x00050085,0x00000006,
0x0000002c,0x00000029,0x0000002b,0x00050041,
0x00000013,0x0000002e,0x0000000d,0x0000002d,
0x0004003d,0x00000006,0x0000002f,0x0000002e,
0x00050041,0x00000013,0x00000030,0x0000000d,
0x0000002d,0x0004003d,0x00000006,0x00000031,
0x00000030,0x00050085,0x00000006,0x00000032,
0x0000002f,0x00000031,0x00050081,0x00000006,
0x00000033,0x0000002c,0x00000032,0x0006000c,
0x00000006,0x00000034,0x00000001,0x0000001f,
0x00000033,0x00050085,0x00000006,0x00000036,
0x00000034,0x00000035,0x0003003e,0x00000025,
0x00000036,0x0004003d,0x00000006,0x00000037,
0x00000025,0x0008000c,0x00000006,0x0000003a,
0x00000001,0x0000002b,0x00000037,0x00000038,
0x00000039,0x0003003e,0x00000025,0x0000003a,
0x0004003d,0x00000006,0x0000003b,0x00000025,
0x00050085,0x00000006,0x0000003d,0x0000003b,
0x0000003c,0x0006000c,0x00000006,0x0000003e,
0x00000001,0x0000000e,0x0000003d,0x00050085,
0x00000006,0x00000040,0x0000003e,0x0000003f,
0x000200fe,0x00000040,0x00010038,0x00050036,
0x00000006,0x00000011,0x00000000,0x00000009,
0x00030037,0x00000008,0x00000010,0x000200f8,
0x00000012,0x0004003b,0x00000013,0x00000043,
0x00000007,0x0004003b,0x00000008,0x00000045,
0x00000007,0x0004003b,0x00000013,0x0000004b,
0x00000007,0x0004003b,0x00000008,0x0000004c,
0x00000007,0x0004003b,0x00000008,0x00000056,
0x00000007,0x0004003b,0x00000008,0x00000061,
0x00000007,0x0004003b,0x00000008,0x00000067,
0x00000007,0x0004003b,0x00000008,0x0000006b,
0x00000007,0x0003003e,0x00000043,0x00000044,
0x0004003d,0x00000007,0x00000046,0x00000010,
0x0004003d,0x00000006,0x00000047,0x00000043,
0x00050050,0x00000007,0x00000048,0x00000047,
0x00000047,0x00050088,0x00000007,0x00000049,
0x00000046,0x00000048,0x0006000c,0x00000007,
0x0000004a,0x00000001,0x00000008,0x00000049,
0x0003003e,0x00000045,0x0000004a,0x0004003d,
0x00000007,0x0000004d,0x00000045,0x0003003e,
0x0000004c,0x0000004d,0x00050039,0x00000006,
0x0000004e,0x0000000b,0x0000004c,0x0003003e,
0x0000004b,0x0000004e,0x0004003d,0x00000006,
0x0000004f,0x0000004b,0x000500ba,0x00000051,
0x00000052,0x0000004f,0x00000050,0x000300f7,
0x00000054,0x00000000,0x000400fa,0x00000052,
0x00000053,0x00000054,0x000200f8,0x00000053,
0x000200fe,0x00000038,0x000200f8,0x00000054,
0x0004003d,0x00000006,0x00000057,0x0000004b,
0x00050085,0x00000006,0x00000059,0x00000057,
0x00000058,0x0006000c,0x00000006,0x0000005a,
0x00000001,0x0000000a,0x00000059,0x0004003d,
0x00000006,0x0000005b,0x0000004b,0x00050050,
0x00000007,0x0000005c,0x0000005a,0x0000005b,
0x00050081,0x00000007,0x0000005e,0x0000005c,
0x0000005d,0x0005008e,0x00000007,0x00000060,
0x0000005e,0x0000005f,0x0003003e,0x00000056,
0x00000060,0x0004003d,0x00000007,0x00000062,
0x00000010,0x0004003d,0x00000006,0x00000063,
0x00000043,0x00050050,0x00000007,0x00000064,
0x00000063,0x00000063,0x00050088,0x00000007,
0x00000065,0x00000062,0x00000064,0x0006000c,
0x00000007,0x00000066,0x00000001,0x0000000a,
0x00000065,0x0003003e,0x00000061,0x00000066,
0x0004003d,0x00000007,0x00000068,0x00000061,
0x0004003d,0x00000007,0x00000069,0x00000056,
0x00050083,0x00000007,0x0000006a,0x00000068,
0x00000069,0x0003003e,0x00000067,0x0000006a,
0x0004003d,0x00000007,0x0000006c,0x00000067,
0x0003003e,0x0000006b,0x0000006c,0x00050039,
0x00000006,0x0000006d,0x0000000e,0x0000006b,
0x000200fe,0x0000006d,0x00010038,0x00050036,
0x00000006,0x00000018,0x00000000,0x00000014,
0x00030037,0x00000008,0x00000015,0x00030037,
0x00000013,0x00000016,0x00030037,0x00000013,
0x00000017,0x000200f8,0x00000019,0x0004003b,
0x00000008,0x00000094,0x00000007,0x00050041,
0x00000013,0x00000070,0x00000015,0x0000002d,
0x0004003d,0x00000006,0x00000071,0x00000070,
0x00050085,0x00000006,0x00000073,0x00000071,
0x00000072,0x0004003d,0x00000006,0x00000074,
0x00000016,0x00050085,0x00000006,0x00000076,
0x00000074,0x00000075,0x00050085,0x00000006,
0x00000077,0x00000076,0x00000058,0x00050081,
0x00000006,0x00000078,0x00000073,0x00000077,
0x0004003d,0x00000006,0x00000079,0x00000017,
0x00050088,0x00000006,0x0000007a,0x00000039,
0x00000079,0x00050081,0x00000006,0x0000007b,
0x00000078,0x0000007a,0x0006000c,0x00000006,
0x0000007c,0x00000001,0x0000000e,0x0000007b,
0x0004003d,0x00000006,0x0000007e,0x00000017,
0x00050088,0x00000006,0x0000007f,0x0000007d,
0x0000007e,0x00050088,0x00000006,0x00000080,
0x0000007c,0x0000007f,0x00050085,0x00000006,
0x00000082,0x00000080,0x00000081,0x00050041,
0x00000013,0x00000083,0x00000015,0x00000027,
0x0004003d,0x00000006,0x00000084,0x00000083,
0x00050081,0x00000006,0x00000085,0x00000084,
0x00000082,0x00050041,0x00000013,0x00000086,
0x00000015,0x00000027,0x0003003e,0x00000086,
0x00000085,0x0004003d,0x00000006,0x00000087,
0x00000016,0x0004003d,0x00000006,0x00000088,
0x00000017,0x00050085,0x00000006,0x00000089,
0x00000087,0x00000088,0x0005008e,0x00000007,
0x0000008c,0x0000008b,0x00000089,0x0005008e,
0x00000007,0x0000008d,0x0000008c,0x00000081,
0x0004003d,0x00000007,0x0000008e,0x00000015,
0x00050081,0x00000007,0x0000008f,0x0000008e,
0x0000008d,0x0003003e,0x00000015,0x0000008f,
0x0004003d,0x00000007,0x00000090,0x00000015,
0x0004003d,0x00000006,0x00000091,0x00000017,
0x00050050,0x00000007,0x00000092,0x00000091,
0x00000091,0x00050088,0x00000007,0x00000093,
0x00000090,0x00000092,0x0003003e,0x00000094,
0x00000093,0x00050039,0x00000006,0x00000095,
0x00000011,0x00000094,0x0004003d,0x00000006,
0x00000096,0x00000017,0x00050085,0x00000006,
0x00000097,0x00000096,0x0000003f,0x00050081,
0x00000006,0x00000098,0x00000097,0x0000003f,
0x00050085,0x00000006,0x00000099,0x00000095,
0x00000098,0x000200fe,0x00000099,0x00010038}
@@ -1,18 +1,18 @@
#version 310 es
precision highp float;
precision mediump float;
layout(std140, set = 0, binding = 0) uniform UBO
{
vec4 OutputSize;
mat4 MVP;
vec2 OutputSize;
float time;
} global;
} constants;
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
float baseScale = 1.25; // [1.0 .. 10.0]
float density = 0.5; // [0.01 .. 1.0]
float speed = 0.15; // [0.1 .. 1.0]
const float baseScale = 1.25; // [1.0 .. 10.0]
const float density = 0.5; // [0.01 .. 1.0]
const float speed = 0.15; // [0.1 .. 1.0]
float rand(vec2 co)
{
@@ -29,7 +29,7 @@ float dist_func(vec2 distv)
float random_dots(vec2 co)
{
float part = 1.0 / 20.0;
vec2 cd = floor(co / vec2(part));
vec2 cd = floor(co / part);
float p = rand(cd);
if (p > 0.005 * (density * 40.0))
@@ -47,19 +47,17 @@ float snow(vec2 pos, float time, float scale)
{
// add wobble
pos.x += cos(pos.y * 1.2 + time * 3.14159 * 2.0 + 1.0 / scale) / (8.0 / scale) * 4.0;
// add gravity
pos += time * scale * vec2(-0.5, 1.0) * 4.0;
return random_dots(pos / vec2(scale)) * (scale * 0.5 + 0.5);
return random_dots(pos / scale) * (scale * 0.5 + 0.5);
}
void main()
void main(void)
{
float tim = global.time * 0.4 * speed;
vec2 pos = vTexCoord.xy / global.OutputSize.xx;
float tim = constants.time * 0.4 * speed;
vec2 pos = gl_FragCoord.xy / constants.OutputSize.xx;
pos.y = 1.0 - pos.y; // Flip Y
float a = 0.0;
// Each of these is a layer of snow
// Remove some for better performance
// Changing the scale (3rd value) will mess with the looping
@@ -72,6 +70,7 @@ void main()
a += snow(pos, tim, 0.25);
a += snow(pos, tim, 0.125);
a = a * min(pos.y * 4.0, 1.0);
FragColor = vec4(1.0, 1.0, 1.0, a);
}
Loaded 100 of 315 files, more files were not shown because too many files have changed in this diff. Show more