Compare commits

...
254 Commits
Author SHA1 Message Date
Autechre bc23d070de Update CHANGES.md 2021-04-30 18:19:36 +02:00
twinaphex 951ea6baaf Bump up to version 1.9.2 2021-04-30 17:49:54 +02:00
Autechre 84ab14cb83 Merge pull request #12281 from eadmaster/multi_patch
added multi-softpatching support + OSD messages for patches (#9947)
2021-04-30 16:00:43 +02:00
eadmaster 019130298a added multi-softpatching support + OSD messages for patches (#9947)
fixed Travis error
2021-04-30 14:12:47 +02:00
Autechre 99917368b4 Merge pull request #12341 from jdgleaver/dingux-autosave
OpenDingux: Enable 'SaveRAM Autosave Interval' by default
2021-04-30 00:03:41 +02:00
jdgleaver 5f12edaae4 OpenDingux: Enable 'SaveRAM Autosave Interval' by default 2021-04-29 15:15:12 +01:00
Autechre 8eb8b44e83 Merge pull request #12327 from repojohnray/config_h
Set -I. at the beginning to include the right config.h
2021-04-29 15:44:41 +02:00
Autechre 9c534c3550 Merge pull request #12339 from jdgleaver/dingux-ra-bin
(.gitlab-ci.yml) Add 'raw' retroarch binary to OpenDingux (+Beta) job artifacts
2021-04-29 15:10:07 +02:00
Autechre 10c1361751 Merge pull request #12337 from Jamiras/ff_slow
enforce minimum fastforward_ratio of 1.0
2021-04-29 15:09:55 +02:00
Autechre 2153cd8e2c Merge pull request #12338 from jdgleaver/config-file-append-fix
Fix config file appending and 'including'
2021-04-29 15:08:32 +02:00
jdgleaver 95cea8cc5d (.gitlab-ci.yml) Add 'raw' retroarch binary to OpenDingux (+Beta) job artifacts 2021-04-29 13:01:44 +01:00
jdgleaver 02630d998e Fix config file appending and 'including' 2021-04-29 12:29:47 +01:00
Jamiras 77d04af845 enforce minimum fastforward_ratio of 1.0 2021-04-28 22:43:48 -06:00
Autechre 42e01acfa1 Merge pull request #12335 from MrHuu/master
(3DS) Change default asset directory
2021-04-28 22:10:27 +02:00
Autechre b2faff6bf9 Merge pull request #12334 from jdgleaver/core-info-hash-collision
(core_info) Prevent potential hash collisions when searching for cores
2021-04-28 22:09:41 +02:00
MrHuu a58236d69d (3DS) Change default asset directory 2021-04-28 19:59:03 +02:00
jdgleaver 3bc2758d51 (core_info) Prevent potential hash collisions when searching for cores 2021-04-28 17:52:15 +01:00
Autechre 40f6f7b803 Merge pull request #12333 from jdgleaver/config-file-hashmap-update
(config_file) Modify hash map usage for proper compatibility with updated RHMAP implementation
2021-04-28 18:38:43 +02:00
jdgleaver b1a7d3e995 (config_file) Modify hash map usage for proper compatibility with updated RHMAP implementation 2021-04-28 17:34:24 +01:00
Autechre 7fc636c623 Merge pull request #12332 from Alcaro/master
Track the complete string in rhmap
2021-04-28 17:05:27 +02:00
Alcaro 2c5c4647e3 Track the complete string in rhmap 2021-04-28 16:09:45 +02:00
Autechre 2702ce693b Merge pull request #12328 from jdgleaver/7zip-update
Update 7-Zip dependency to latest stable version (fixes CHD support on static platforms)
2021-04-28 15:12:41 +02:00
Autechre 71836cacdb Merge pull request #12331 from bulzipke/master
(3DS) Load overlay texture images as BGR colors
2021-04-28 13:28:33 +02:00
jdgleaver a501dfd680 Update 7-Zip dependency to latest stable version (fixes CHD support on static platforms) 2021-04-28 12:00:50 +01:00
bulzipke 7e7615c97c (3DS) Load overlay texture images as BGR colors 2021-04-28 19:16:14 +09:00
Autechre a4d955357d Merge pull request #12329 from IAmBoring/patch
MSVC Vulkan Buildfix
2021-04-28 11:57:46 +02:00
IAmBoring 9c0aec1d19 MSVC Vulkan Buildfix 2021-04-27 20:45:52 +00:00
repojohnray 28541fe826 Set -I. at the beginning to include the right config.h
This is done to avoid to include for instance valgrind/config.h as the main config.h
2021-04-27 17:37:27 +02:00
Autechre 8466a213e8 Merge pull request #12324 from devnexen/macos_vulkan_build_fix
macOS with vulkan build fix
2021-04-26 22:16:24 +02:00
Autechre 0cd0ce87f5 Merge pull request #12323 from bulzipke/master
(3DS) Load texture images as BGR colors
2021-04-26 22:15:57 +02:00
David Carlier c7f3fa2b5d macOS with vulkan build fix 2021-04-26 20:31:15 +01:00
Autechre f601f4ce70 Merge pull request #12311 from gblues/gblues/runloop-state 2021-04-26 19:43:49 +02:00
bulzipke 56a0300db5 Load texture images as BGR colors 2021-04-27 01:58:41 +09:00
Nathan Strong d7075296e3 Move runloop data to static struct
== DETAILS
As part of a larger project to reduce/eliminate global state, this commit does the following:

1. move all the `runloop_` members of the `rarch_st` struct to a separate structure
2. create a static instance of that struct in retroarch.c
3. switch all references of `p_rarch->runloop_*` to `runloop_state.*`
4. remove the extraneous `runloop_` prefix on the new struct's members
2021-04-26 09:21:01 -07:00
Autechre a904b1665f Merge pull request #12321 from jdgleaver/core-info-optimisation
(core_info) Performance optimisations + code clean-ups/refactors
2021-04-26 16:45:49 +02:00
jdgleaver f4511f6fa4 (core_info) Performance optimisations + code clean-ups/refactors 2021-04-26 14:30:31 +01:00
Autechre 1d81841091 Merge pull request #12308 from sonninnos/cheat-log
Silence unappropriate cheatfile logging
2021-04-25 23:44:22 +02:00
Autechre d339d5eab5 Merge pull request #12313 from MrHuu/master
(3DS) Enable gfx_widgets / overlays
2021-04-25 23:44:13 +02:00
Autechre 9d13b090d8 Merge pull request #12317 from devnexen/mac_m1_cpu_features
cpu detection detection vfp unit for Darwin.
2021-04-25 23:43:57 +02:00
David CARLIER 6f898e611c cpu detection detection vfp unit for Darwin. 2021-04-24 22:58:14 +01:00
MrHuu 1235a7435e (3DS) Enable gfx_widgets / overlays 2021-04-24 15:36:03 +02:00
sonninnos 2ebf46e241 Silence unappropriate cheatfile logging 2021-04-23 18:44:02 +03:00
twinaphex d2af1e905c Fix runahead 2021-04-23 13:18:29 +02:00
twinaphex be255ff269 (gfx_animation.c) Simplify some functions 2021-04-22 19:30:20 +02:00
twinaphex 0211e7749e Simplify gfx_animation_ticker_generic 2021-04-22 18:48:14 +02:00
Autechre d24f808d79 Merge pull request #12294 from ToKe79/lakka_timezone
Lakka: add menu for time zone setting
2021-04-22 18:38:19 +02:00
Autechre 6d42481c37 Merge pull request #12301 from jdgleaver/search-filter-cheats-overlays
Add search filter support to cheats and overlays file browser menus
2021-04-22 18:32:49 +02:00
jdgleaver 80753ac741 Add search filter support to cheats and overlays file browser menus 2021-04-22 16:56:57 +01:00
Autechre 93e467913e Merge pull request #12300 from jdgleaver/rgui-scaling-menu-fix
(RGUI) Fix display of 'Video > Scaling' menu when 'Lock Menu Aspect Ratio' is enabled
2021-04-22 17:49:13 +02:00
jdgleaver fc283123bb (RGUI) Fix display of 'Video > Scaling' menu when 'Lock Menu Aspect Ratio' is enabled 2021-04-22 15:55:59 +01:00
Autechre 5998c561ee Merge pull request #12299 from sinusinu/master
GDI: Fix non-ASCII text rendering
2021-04-22 14:24:47 +02:00
Woohyun Shin 4e8a71d034 GDI: Fix non-ASCII text rendering 2021-04-22 20:38:58 +09:00
Autechre d458729f6c Merge pull request #12297 from Szunti/sdl_input_crash_if_analog_bound 2021-04-22 03:25:32 +02:00
Szunti 3191fec54c Fix crash in sdl input driver when analogs are bound. 2021-04-22 03:20:39 +02:00
Autechre 7a5559aba0 Merge pull request #12295 from jdgleaver/config-file-hash-map 2021-04-22 00:35:35 +02:00
jdgleaver 29d5963cad (config_file) Use hash map to optimise key/value lookups 2021-04-21 17:33:36 +01:00
Tomáš Kelemen (vudiq) 90529c62b2 Lakka: add menu for time zone setting
This adds new entry under Settings -> Services (where all Lakka related
services are currently available, such as switches for services like
SSH, Samba, etc.). By adding this the users do not have to use the
command line / access the file system directly to change their local
time zone to adjust the date/time displayed in RetroArch.
2021-04-21 18:12:42 +02:00
twinaphex ae21979b7c Remove unused variable 2021-04-21 15:58:51 +02:00
Autechre 09c3ef0f6a Merge pull request #12290 from devnexen/mac_timer_upd
Mac intel and arm64 timer change proposal.
2021-04-21 15:59:33 +02:00
twinaphex ba791b7de8 Add better fix that targets all statically linked platforms instead of 2021-04-21 15:58:18 +02:00
Autechre 0ddfbd976c Merge pull request #12292 from Jamiras/cheevos_supervision_mmap
(cheevos) update achievement memory maps
2021-04-21 06:50:02 +02:00
Jamiras d4ba7579d1 update achievement memory maps 2021-04-20 20:08:46 -06:00
twinaphex 220bc434be Get rid of strcpy_alloc 2021-04-21 02:25:51 +02:00
David CARLIER 2932a835fc Mac intel and arm64 timer change proposal. 2021-04-20 21:38:01 +01:00
twinaphex e88fad00a5 copy_core_to_temp_file - get rid of a bunch of strcat_alloc calls,
instead just use fill_pathname_join once and have retroarch_tmp_path
be a fixed stack array variable
2021-04-20 21:29:02 +02:00
Autechre 36d274d460 Merge pull request #12288 from ToKe79/lakka-change-handlers-squash-warnings
Make Lakka change handlers use the setting pointer
2021-04-20 20:31:15 +02:00
twinaphex 4c4d5e5837 (core_info.c) Cleanups 2021-04-20 19:46:11 +02:00
twinaphex 769fb7cd02 Cleanup 2021-04-20 19:35:59 +02:00
twinaphex 0cc5b29558 Use path_basename for instances where we don't have to deal
with compressed files in archives
2021-04-20 19:14:47 +02:00
Tomáš Kelemen (vudiq) 191171802b Make Lakka change handlers use the setting pointer
These change handler functions had incorrect parameter (void *) instead
of (rarch_setting_t *) and were also spawning new local pointer to the
settings and other local variables, which was not necessary, as one can
use the value from the call (setting->target.value.boolean in these
cases).

I have also modified the systemd_sevice_toggle function. Before it
looked like it was creating / deleting the file in both child and parent
processes and started / stopped the systemd service in the child
process. Now both actions (creation / deletion of file and start / stop
of service) are done in the child process.

Below are the compiler warnings about incompatible pointer types:

```
menu/menu_setting.c: In function ‘setting_append_list’:
menu/menu_setting.c:18520:58: warning: assignment to ‘change_handler_t’ {aka ‘void (*)(struct rarch_setting *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
18520 |             (*list)[list_info->index - 1].change_handler = ssh_enable_toggle_change_handler;
      |                                                          ^
menu/menu_setting.c:18536:58: warning: assignment to ‘change_handler_t’ {aka ‘void (*)(struct rarch_setting *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
18536 |             (*list)[list_info->index - 1].change_handler = samba_enable_toggle_change_handler;
      |                                                          ^
menu/menu_setting.c:18552:58: warning: assignment to ‘change_handler_t’ {aka ‘void (*)(struct rarch_setting *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
18552 |             (*list)[list_info->index - 1].change_handler = bluetooth_enable_toggle_change_handler;
      |                                                          ^
menu/menu_setting.c:18568:58: warning: assignment to ‘change_handler_t’ {aka ‘void (*)(struct rarch_setting *)’} from incompatible pointer type ‘void (*)(void *)’ [-Wincompatible-pointer-types]
18568 |             (*list)[list_info->index - 1].change_handler = localap_enable_toggle_change_handler;
      |                                                          ^
```
2021-04-20 19:14:10 +02:00
Autechre 32b626704e Merge pull request #12286 from jdgleaver/file-browser-search-filter
Enhanced 'Load Content' file browser search functionality
2021-04-20 18:14:05 +02:00
jdgleaver b193fd0ba9 Enhanced 'Load Content' file browser search functionality 2021-04-20 15:49:22 +01:00
Autechre 7317b6b98e Merge pull request #12285 from alphanu1/master
Fixed CRTSwitchRes framebuffer bug
2021-04-20 00:21:17 +02:00
Ben 799fcdb5e0 Fixed CRTSwitchRes framebuffer bug 2021-04-19 07:38:38 -07:00
Autechre 6b021f8d14 Merge pull request #12283 from libretro/revert-12011-video-resolution
Revert "Screen Resolution option fixes"
2021-04-17 19:33:37 +02:00
Autechre a56fcfb24a Revert "Screen Resolution option fixes" 2021-04-17 19:33:23 +02:00
twinaphex 1811bd6885 Fix issue in https://github.com/libretro/neocd_libretro/issues/58 2021-04-16 19:34:06 +02:00
twinaphex 46a37b9bd9 Silence some warnings 2021-04-16 17:55:19 +02:00
Autechre 3fcd645a73 Merge pull request #12277 from devnexen/arm64_build_fix_proposal
run fast mode disable for 64 bits invalid instructions.
2021-04-16 17:35:18 +02:00
David CARLIER 7cbee3dc8f run fast mode disable for 64 bits invalid instructions. 2021-04-16 08:33:01 +01:00
twinaphex 9812f368e7 Move more of these static variables out of retroarch_data.h 2021-04-15 19:51:40 +02:00
twinaphex 0f4dbcfc53 move arrays over to only function that uses them 2021-04-15 19:51:40 +02:00
Autechre fb79927c05 Merge pull request #12273 from jdgleaver/font-texture-bleed-fix
(freetype/stb_unicode/bitmapfont) Prevent texture bleed when rendering text at non-integer scales
2021-04-15 19:44:57 +02:00
jdgleaver fc05c0805b (freetype/stb_unicode/bitmapfont) Prevent texture bleed when rendering text at non-integer scales 2021-04-15 17:24:32 +01:00
Autechre b69e023736 Merge pull request #12270 from jdgleaver/rgui-transparency
(RGUI) Add option to disable menu transparency
2021-04-15 16:28:43 +02:00
jdgleaver 54c45bd54e (RGUI) Add option to disable menu transparency 2021-04-15 12:32:39 +01:00
twinaphex 67c06d17bb command_event_runtime_log_deinit - put verbosity_is_enabled check around
this
2021-04-15 08:08:08 +02:00
twinaphex b91a1f4788 Silence warning 2021-04-15 07:39:25 +02:00
twinaphex 9f902c8bd4 input_joypad_analog_button - only call fabs when input value is not 0 2021-04-15 07:27:43 +02:00
twinaphex 52454591aa Small cleanup to input_joypad_analog_button 2021-04-15 07:22:59 +02:00
twinaphex cfe9d60f51 Get rid of button_is_pressed 2021-04-15 06:55:35 +02:00
Autechre 36bf1ad112 Merge pull request #12268 from digitalisland-nino/dracula_ozone
(ozone) new theme: Dracula
2021-04-15 02:00:07 +02:00
digitalisland-nino 6f29c1ff94 Created new Ozone Dracula color theme.
Copied RGUI Dracula theme localized strings to new Ozone Dracula theme.

Copied RGUI Dracula theme localized strings to new Ozone Dracula theme.

Added Ozone Dracula color theme to UI.

Added Ozone Dracula color theme entry.
2021-04-14 22:18:18 +02:00
Autechre 58080d6157 Merge pull request #12267 from Jamiras/cheevos_patch_addr_no_ach
allow rcheevos_patch_address to be called on game without achievements
2021-04-14 17:43:18 +02:00
digitalisland-nino 45bf867d38 Copied RGUI Dracula theme localized strings to new Ozone Dracula theme. 2021-04-14 16:49:59 +02:00
Autechre eb578557c0 Update CHANGES.md 2021-04-14 16:32:08 +02:00
Jamiras 299a471af2 allow rcheevos_patch_address to be called on game without achievements 2021-04-14 08:20:20 -06:00
twinaphex 4ec8b82388 Cleanups 2021-04-14 03:46:50 +02:00
twinaphex 5ae5463f52 (menu_setting.c) Cleanups 2021-04-14 02:26:20 +02:00
twinaphex 9a994eb777 Split up general_write_handler/general_read_handler some more 2021-04-14 01:55:38 +02:00
twinaphex bdfbc86ecb Simplifications in general_write_handler 2021-04-14 01:22:49 +02:00
Autechre b5d983cddf Merge pull request #12264 from jdgleaver/screensaver-animation
(XMB/GLUI/Ozone) Add optional menu screensaver animations
2021-04-13 17:48:53 +02:00
twinaphex 65c01b35ec Go back to Discord RPC I/O Thread codepath for now - the non-I/O
thread codepath seems to be unreliable for now
2021-04-13 16:44:46 +02:00
jdgleaver a6cffc0e29 (XMB/GLUI/Ozone) Add optional menu screensaver animations 2021-04-13 15:36:57 +01:00
alphanu1 5658ea7047 Multi monitor fix. (#12260)
This fix allows for the use of multi monitor when using CRTSwitchres. It fixes a bug that causes a crash.
Delete function will no longer try to delete resolutions from outputs that have not had resolutions added.
2021-04-12 14:55:33 +02:00
twinaphex 7f3b9e8a89 Attempt to fix max problems on all platforms 2021-04-12 06:51:01 +02:00
twinaphex 7fe2ad81a0 HAVE_CLIP_WINDOW - don't define for this anything below MSVC 2005 2021-04-12 05:38:43 +02:00
twinaphex dcc266df12 (MSVC) Buildfix 2021-04-12 05:25:30 +02:00
twinaphex d07043fe26 Reduce size of local char variables 2021-04-11 19:28:59 +02:00
twinaphex 2f0f724813 Use more path_basename_nocompression where we don't have to deal with
archive files
2021-04-11 18:46:50 +02:00
twinaphex fc5b557a10 use fill_pathname_join_concat if we want to set a filename path
with extension instead of doing fill_pathname_join and then
fill_pathname_noext
2021-04-11 18:37:42 +02:00
twinaphex 116bf8058a Don't need this variable in this loop 2021-04-11 18:19:51 +02:00
twinaphex 050f44382b input_remapping_save_file - simplifications 2021-04-11 18:16:18 +02:00
twinaphex 1392eebfa0 Use path_basename_nocompression some more 2021-04-11 17:48:44 +02:00
twinaphex 544a17926b Use path_basename_nocompression where we are sure we are not
dealing with a filename with a compressed archive hash
2021-04-11 17:44:41 +02:00
twinaphex 637cff628f * Simplify RARCH_CTL_IS_CORE_LOADED
* Create specialized function path_basename_nocompression
2021-04-11 17:27:31 +02:00
twinaphex 3841fecc59 Cleanups 2021-04-11 17:01:13 +02:00
twinaphex f1cf5ceb82 (input drivers) Cut down on code duplication 2021-04-11 16:31:46 +02:00
twinaphex 40c39de5e3 Move old_libretro_device/old_analog_dpad_mode to global struct 2021-04-11 16:02:47 +02:00
twinaphex 0087be2a53 Cleanup input_remapping_load_file/input_remapping_save_file - none
of these huge char arrays were needed, wrong size being passed
to snprintf, fill_pathname_join, k loop variable unneeded, etc.
2021-04-11 14:36:51 +02:00
twinaphex d9cacc0b8c Other cleanups - wrong size being passed to snprintf for s3, etc. 2021-04-11 14:18:14 +02:00
twinaphex 370751551f Some further optimizations - key_strings doesn't need to be inside
the loop
2021-04-11 14:11:12 +02:00
twinaphex ac8e1b88e4 input_remapping_load_file/input_remapping_save_file - char arrays
were way too big
2021-04-11 14:03:03 +02:00
twinaphex aa0a9f18d5 Fix crash that could happen after loading a remap file manually -
config file was being freed at the end of input_remapping_load_file
when the menu_cbs_ok.c function was still using it afterwards - move
the config_file_free outside of the function and free manually
afterwards when we're done
2021-04-11 13:48:25 +02:00
twinaphex 05a2623875 (udev input) Cut down on code duplication 2021-04-11 06:37:49 +02:00
twinaphex 1f506615d3 (x11_input.c) Cut down on code duplication 2021-04-11 06:29:36 +02:00
twinaphex bc08e325ce Travis buildfix 2021-04-11 02:22:35 +02:00
twinaphex a8f410ed40 slang_preprocess_parse_parameters - get rid of one local variable 2021-04-11 01:49:41 +02:00
twinaphex f29a4b51cc Put this behind VULKAN_DEBUG ifdef 2021-04-11 00:15:06 +02:00
twinaphex 924b5830ba (shader_gl_core) Remove std::string usage and std::to_string usage 2021-04-11 00:09:40 +02:00
twinaphex ab877c429f (Qt) Use string append() where possible 2021-04-10 23:57:31 +02:00
Autechre 97e5e6beee Merge pull request #12256 from Jamiras/cheevos_local_addr_warning
(cheevos) attempt to silence return-local-addr warning
2021-04-10 23:43:47 +02:00
Jamiras 5530b7022f attempt to silence return-local-addr warning 2021-04-10 14:51:41 -06:00
twinaphex 0aa266a6ca build_stage_source - use std::string reserve and append, significantly
faster
2021-04-10 22:11:26 +02:00
Autechre 0b52823f2c Merge pull request #12255 from libretro/destl
Destl
2021-04-10 22:10:53 +02:00
twinaphex 1273536752 Reduce get_semantic_name down to one version 2021-04-10 21:46:04 +02:00
twinaphex 59449600ad Cleanup retroarch_menu_running_finished 2021-04-10 21:04:00 +02:00
twinaphex c392a475ee Cleanups 2021-04-10 20:51:19 +02:00
twinaphex d024ff553f Cleanups 2021-04-10 20:47:04 +02:00
twinaphex b5d49b9e79 Avoid std::string allocations when possible (pt. 1) 2021-04-10 20:19:30 +02:00
twinaphex f0fa3c5861 (slang C++ files) take out using namespace std, explicitly refer to
std namespace
2021-04-10 19:42:59 +02:00
twinaphex 966dd62551 Fix warnings local variable hides parameter of the same name 2021-04-10 19:28:30 +02:00
twinaphex ca5ce839ce Small cleanups to button input handling code - several parameters
were no longer used
2021-04-10 19:06:56 +02:00
twinaphex 760fc6b3f7 Simplify button_is_pressed 2021-04-10 18:44:10 +02:00
twinaphex 372f939cc9 Simplify input_keys_pressed 2021-04-10 18:25:50 +02:00
twinaphex 5df321fcaa Cleanups 2021-04-10 18:19:20 +02:00
Autechre 10c9d485c4 Merge pull request #12254 from repojohnray/valgrind
Fix issue detected by valgrind
2021-04-10 17:52:45 +02:00
repojohnray 8f3e02e49c Fix issue detected by valgrind
==27741== Conditional jump or move depends on uninitialised value(s)
==27741==    at 0x6080F5: strlcpy_retro__ (compat_strl.c:38)
==27741==    by 0x60818A: strlcat_retro__ (compat_strl.c:60)
==27741==    by 0x49EDD7: fill_pathname_join_special_ext (file_path.c:843)
==27741==    by 0x4C78C8: config_load_remap (configuration.c:3765)
==27741==    by 0x4386FF: command_event_init_core (retroarch.c:12601)
==27741==    by 0x43B15E: command_event (retroarch.c:14000)
==27741==    by 0x468863: retroarch_main_init (retroarch.c:35231)
==27741==    by 0x487AED: content_load (task_content.c:607)
==27741==    by 0x48A3D3: task_load_content_internal (task_content.c:2068)
==27741==    by 0x48A6AD: task_push_load_content_from_cli (task_content.c:2162)
==27741==    by 0x43D66E: rarch_main (retroarch.c:15300)
==27741==    by 0x43D6ED: main (retroarch.c:15398)
==27741==  Uninitialised value was created by a stack allocation
==27741==    at 0x4C7730: config_load_remap (configuration.c:3721)
2021-04-10 17:30:56 +02:00
twinaphex 8b197e49bb accessibility_speak_priority - no longer dependent on settings pointer 2021-04-10 14:59:34 +02:00
twinaphex 200983f938 is_narrator_running -don't pass entire settings pointer 2021-04-10 14:24:41 +02:00
twinaphex dd7fe2e7e0 Cleanups 2021-04-10 14:19:52 +02:00
twinaphex 1e94070dca Simplify driver_adjust_system_rates 2021-04-10 13:39:47 +02:00
twinaphex 40ab6f839a Some cleanups to driver_adjust_system_rates 2021-04-10 13:32:27 +02:00
twinaphex 43cb646870 Turn video_driver_monitor_adjust_system_rates into pure function 2021-04-10 13:22:12 +02:00
twinaphex d1d9f96ab3 Turn audio_driver_monitor_adjust_system_rates into pure function 2021-04-10 13:11:01 +02:00
twinaphex d910f520d9 Don't pass entire settings pointer if we just need a few settings variables
to read
2021-04-10 13:03:53 +02:00
twinaphex 5ca666acee Cleanups, don't try to pass settings pointer to functions unless we have to 2021-04-10 03:01:25 +02:00
twinaphex 338c2eb2f0 Settings cleanups 2021-04-10 01:51:28 +02:00
twinaphex deccc4d8c6 Some refactors 2021-04-10 00:54:40 +02:00
twinaphex 204eaf0e76 Don't grab settings pointer inside video_driver_frame 2021-04-08 20:01:59 +02:00
twinaphex 421dbb19c2 Don't pass settings pointer if we just need a couple of variables
that we won't mutate
2021-04-08 19:45:30 +02:00
twinaphex 808f326209 Cleanups 2021-04-08 19:24:19 +02:00
twinaphex 9c5f365b2b Cleanups 2021-04-08 18:37:09 +02:00
twinaphex f7a5833cb0 Turn bunch of functions static 2021-04-08 18:33:46 +02:00
twinaphex 0d549fd42b Merge netplay_init.c into netplay_io.c 2021-04-08 18:16:24 +02:00
twinaphex 2a2f77f0dc Combine some netplay files into one 2021-04-08 18:09:02 +02:00
twinaphex 42bd709f67 Old MSVC buildfix 2021-04-08 17:31:23 +02:00
twinaphex 2c7226de20 Less pointer grabbing 2021-04-08 17:08:46 +02:00
twinaphex d6c243143d Simplifications to dir_init_shader_internal 2021-04-08 16:49:23 +02:00
Autechre 9ab6b9b308 Merge pull request #12247 from BarryJRowe/master
Accessibility speak fix.
2021-04-08 11:19:05 +02:00
Barry Rowe d80833d892 Accessibility speak fix. 2021-04-07 20:39:25 -07:00
twinaphex b7bc1fc51d Buildfixes 2021-04-08 03:27:58 +02:00
twinaphex 9f6a5e35de Get rid of more duplicate pointer grabbing 2021-04-08 02:02:30 +02:00
twinaphex f8ec815467 Cleanups 2021-04-08 01:54:44 +02:00
twinaphex fb1258b817 Set anim.update_timecb to NULL immediately after menu driver's 'free'
function has been called
2021-04-08 01:37:47 +02:00
twinaphex 5334ddd199 Don't call anim_get_ptr inside gfx_thumbnail.c 2021-04-08 01:30:42 +02:00
twinaphex e5e8e9b5d8 Expand widget init function 2021-04-08 00:51:10 +02:00
twinaphex 2e6393f082 Get rid of pointer grabbing for p_disp 2021-04-08 00:38:24 +02:00
twinaphex 95527fb566 Prevent some unnecessary variables being set 2021-04-08 00:22:29 +02:00
Autechre 03849b3e87 Update CHANGES.md 2021-04-07 13:54:20 +02:00
Autechre 3a4c19f82d Merge pull request #12246 from jdgleaver/odbeta-50hz
OpenDingux Beta: Add 50Hz support
2021-04-07 13:53:39 +02:00
jdgleaver c23e32a047 OpenDingux Beta: Add 50Hz support 2021-04-07 10:06:11 +01:00
Autechre 5e432a6586 Update CHANGES.md 2021-04-07 00:53:36 +02:00
twinaphex ea9f3f13ca (Apple OSX) Swallow 'escape' key being pressed - would previously make the game
go from fullscreen to windowed
2021-04-07 00:48:21 +02:00
twinaphex 412a1885b2 Cleanups 2021-04-07 00:42:38 +02:00
twinaphex 886a692f1a video_driver_init_internal - don't call small one-line functions - set
directly
2021-04-07 00:36:00 +02:00
twinaphex d5ebf9039c Cleanups 2021-04-06 23:05:40 +02:00
twinaphex 789cf29d28 Pass more pointers 2021-04-06 22:35:47 +02:00
Autechre 7cb5de7df4 Update CHANGES.md 2021-04-06 21:53:53 +02:00
Autechre c68c71f7b2 Update CHANGES.md 2021-04-06 21:50:31 +02:00
Autechre 09f1404c45 Update CHANGES.md 2021-04-06 21:50:17 +02:00
twinaphex f8a88fcb94 Cleanups 2021-04-06 20:17:06 +02:00
twinaphex 29a358ee3a Pass settings pointer around to more functions 2021-04-06 20:07:06 +02:00
twinaphex 29513919ca Rewrite retroarch_load_shader_preset_internal - no longer needs
p_rarch
2021-04-06 19:41:46 +02:00
twinaphex 45beb1bcdd Cleanups - pass pointers around instead of grabbing
p_rarch->configuration_settings everywhere; add some verbosity_enabled
checks
2021-04-06 19:31:04 +02:00
Autechre 166333a2cd Update CHANGES.md 2021-04-06 18:35:38 +02:00
twinaphex ebc567d03c (OSX Metal) Enable HAVE_ACCESSIBILITY and HAVE_TRANSLATE for TTS translation services 2021-04-06 18:33:26 +02:00
twinaphex 529c0f24da Silence some unused variable warnings 2021-04-06 18:29:59 +02:00
twinaphex 4855f371f1 Refactor accessibilty speak priority code - create LUT for
character/string pairs
2021-04-06 18:21:22 +02:00
twinaphex 76f000e4c8 Don't pass p_rarch around to other functions everywhere 2021-04-06 17:49:45 +02:00
twinaphex 2aea7a375d Input - turbocode - button ID is always below the threshold of
RARCH_FIRST_META_KEY, so put it inside the conditional
2021-04-06 15:59:44 +02:00
twinaphex 5cf2a7abd1 input_state_device - don't keep grabbing these pointers over and over 2021-04-06 14:42:30 +02:00
twinaphex d11c7cbbb1 Revert "Simplify input_state_device:"
This reverts commit 0b9bc85ddd.
2021-04-06 14:25:58 +02:00
Jonathan 5c6cd1b48a Add scaling to pointer input (#12213)
So far, if display is scaled, overlays gets correctly drawn but touch
input is not correctly scaled, resulting in an unusable overlay.

This happens for touches in menu too.

This commit aims to introduce this scaling factor adding it to the
config file, eg:

input_touch_scale = "2"
2021-04-06 13:15:43 +02:00
twinaphex cbec423413 Revert "Add git_version switch - to disable Git version, do"
This reverts commit c9b7122a08.
2021-04-06 11:22:21 +02:00
twinaphex 9910dfbee2 Replace strcpy_literal usage of trivial string setting 2021-04-06 11:21:28 +02:00
twinaphex e2b084b715 Cleanups 2021-04-05 23:54:52 +02:00
twinaphex 5f9197bcc2 Get rid of more manual pointer grabbing 2021-04-05 23:37:42 +02:00
twinaphex 0b9bc85ddd Simplify input_state_device:
* run it within a loop internally for button_mask enabled
* only one function call invocation in codebase
2021-04-05 22:54:13 +02:00
twinaphex 66ad300515 input_state_device - don't have remap_binds_enable ifdefs here 2021-04-05 22:32:06 +02:00
twinaphex 4ce66f0764 Cleanup command_event_init_controllers 2021-04-05 22:26:41 +02:00
twinaphex 0fc6116082 Some optimizations to menu_cbs_get_value callbacks 2021-04-05 21:17:54 +02:00
twinaphex 48af4fc704 Simplify find_driver functions 2021-04-05 21:06:17 +02:00
twinaphex 8c08b531d6 Simplify hw_render_context_name 2021-04-05 20:13:24 +02:00
twinaphex 966e0640af Style nits 2021-04-05 20:02:19 +02:00
twinaphex 0e26077a64 Add license headers 2021-04-05 19:58:18 +02:00
David G. Fandtwinaphex b830b33cf1 Rewrite commands and add new command type (#12233)
* (OSX non-Metal build) Set disable execute page protection

* Rewrite commands and add new command type

This moves commands to a separate file and creates a consistent
interface for them. It is now possible to use multiple command
interfaces simultaneously (stdin, network and UDS).
Implemented a new interface for Lakka, UDS based (so Linux only). This
allow other Lakka servies to send certain commands to Retroarch in a
secure and reliable way.

Co-authored-by: twinaphex <[email protected]>
2021-04-05 19:55:59 +02:00
twinaphex a989cfb987 Fix compilation error for older MSVC versions - cannot handle two ';'
one after another
2021-04-05 15:57:05 +02:00
twinaphex 5a0c0a26e3 Get rid of more disp_get_ptr calls 2021-04-05 15:22:45 +02:00
twinaphex cd016824f8 Get rid of disp_get_ptr pointer grabbing in gfx/widgets 2021-04-05 15:13:28 +02:00
twinaphex af00dca08b Get rid of some pointer grabbing for disp_get_ptr by making it
a part of video_frame_info
2021-04-05 14:55:28 +02:00
Autechre 115b08e0e1 Merge pull request #12232 from MrHuu/ctr_overlay
(3DS) Add HAVE_OVERLAY
2021-04-05 11:48:14 +02:00
Autechre daa6152868 Merge pull request #12235 from jdgleaver/odbeta-scaling-fix2
OpenDingux Beta: Fix IPU scaling when running GB/GBC/GG/NGP-resolution content
2021-04-05 11:41:18 +02:00
jdgleaver a81280939e OpenDingux Beta: Fix IPU scaling when running GB/GBC/GG/NGP-resolution content 2021-04-04 22:50:25 +01:00
MrHuu 8df97a0c75 (3DS) Add HAVE_OVERLAY 2021-04-04 22:50:59 +02:00
twinaphex 2fbcc99b24 RARCH_LOG_BUFFER - doesn't need early return 2021-04-04 20:05:00 +02:00
Autechre 77f48c8c8e Merge pull request #12229 from sonninnos/menu-nav-block
Block accidental diagonals in menu navigation
2021-04-04 15:16:16 +02:00
sonninnos aaf7e1fb0d Block accidental diagonals in menu navigation 2021-04-04 15:44:19 +03:00
twinaphex 9577f1a46f (OSX non-Metal build) Set disable execute page protection 2021-04-03 19:27:06 +02:00
Autechre 63e5a8b1b5 Merge pull request #12227 from ToddLa/mfi-player-index
prevent crash on controller connect.
2021-04-03 19:20:20 +02:00
Todd Laney be8dd0dba1 prevent crash on controller connect.
disable system button gestures on iOS 14.
remove deprecation warnings.
2021-04-03 09:28:49 -07:00
Autechre 9f17cb7a86 Update CHANGES.md 2021-04-03 16:27:23 +02:00
Autechre 70acb573d5 Merge pull request #12226 from repojohnray/mousex11gles
Fix xegl_ctx.c mouse activation
2021-04-03 16:23:59 +02:00
repojohnray 45047732a7 Fix xegl_ctx.c mouse activation
The mouse is not working when using opengles with x11. This fix adds the required notifications.
2021-04-03 15:56:06 +02:00
Autechre f7d0908ff1 Merge pull request #12219 from libretro/vita-vmalign 2021-04-03 01:49:21 +02:00
Francisco José García García 9f90833d2b [VITA] Align VM block size to 1MB 2021-04-02 19:50:09 +02:00
Autechre 93174dcd19 Merge pull request #12217 from jdgleaver/menu-screensaver 2021-04-02 15:26:30 +02:00
jdgleaver 72f08bb1b4 (RGUI) Fix LGTM warning - 'Multiplication result converted to larger type' 2021-04-02 10:16:47 +01:00
jdgleaver 371d0b7395 Add optional menu screensaver 2021-04-01 17:26:43 +01:00
Autechre 21b2ec6bd5 Merge pull request #12212 from DisasterMo/logging
Removed check for verbosity level in RARCH_LOG_V
2021-03-31 21:08:51 +02:00
Autechre 311c5c133c Merge pull request #12210 from jdgleaver/dingux-beta-gba-scaling
OpenDingux Beta: Fix IPU scaling when running GBA-resolution content
2021-03-31 20:06:46 +02:00
Autechre 551a671cc6 Merge pull request #12211 from kamicane/vrefresh
[DRM] set the correct video mode
2021-03-31 20:06:31 +02:00
Michael Burgardt f54098618e RARCH_LOG_V checking for verbosity level is not necessary and can cause
issues; removed said check.
2021-03-31 18:12:42 +02:00
Valerio Proietti fc69e73dcf [DRM] set the correct video mode
mode->vrefresh is a display-only value and should not be used for calculations
the drm context is now able to differentiate between, for example, [email protected] and [email protected] when setting the video mode
2021-03-31 13:13:27 +02:00
jdgleaver 41855bb6d4 OpenDingux Beta: Fix IPU scaling when running GBA-resolution content 2021-03-31 11:17:56 +01:00
Autechre e3ee0ac22b Merge pull request #12206 from jdgleaver/max-user-reinit
Ensure that 'retro_set_controller_port_device' is called when updating 'Max Users'
2021-03-30 08:36:07 +02:00
Autechre e65a891274 Merge pull request #12207 from jdgleaver/glui-turbo-icon
(GLUI) Add icon to 'Turbo Fire' menu entry
2021-03-30 08:35:45 +02:00
twinaphex 01944dd80e Put this big char array on heap for safety reasons 2021-03-30 01:19:50 +02:00
twinaphex ed6dd6d6d1 Fix get_thumbnail_paths 2021-03-29 17:42:32 +02:00
jdgleaver 6d13ace83a (GLUI) Add icon to 'Turbo Fire' menu entry 2021-03-29 15:50:32 +01:00
jdgleaver 32bdb49496 Ensure that 'retro_set_controller_port_device' is called when updating 'Max Users' 2021-03-29 15:32:29 +01:00
twinaphex cc8160d044 task_pl_thumbnail_download.c - put char string of 8192 length
on heap for all platforms
2021-03-29 09:28:26 +02:00
Autechre ba7900a3fb Merge pull request #12173 from crystalct/master
Some PSL1GHT fixes
2021-03-29 09:26:24 +02:00
CrystalCT b9ff6cb1d9 Some PSL1GHT fixes 2021-03-29 09:01:03 +02:00
232 changed files with 24744 additions and 17549 deletions

No files matched your search

+2
View File
@@ -392,6 +392,7 @@ build-retroarch-dingux-mips32:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch
- retroarch_rg350.opk
- ${MEDIA_PATH}
expire_in: 10 min
@@ -413,6 +414,7 @@ build-retroarch-dingux-odbeta-mips32:
- export NUMPROC=$(($(nproc)/3))
artifacts:
paths:
- retroarch
- retroarch_rg350_odbeta.opk
- ${MEDIA_PATH}
expire_in: 10 min
+47
View File
@@ -1,5 +1,52 @@
# Future
# 1.9.2
- 3DS: Enable graphics widgets / overlays
- 3DS: Load texture images as BGR colors
- 3DS: Change default asset directory
- CHEEVOS: Allow rcheevos_patch_address to be called on game without achievements
- CHEEVOS: Update achievement memory maps (add Supervision)
- CONFIG/FILE: Use hash map to optimise key/value lookups
- CORE INFO: Performance optimisations + code clean-ups/refactors
- CRT/SWITCHRES: Fixed CRTSwitchRes framebuffer bug
- DISCORD/RP: Fix regression
- DRM: set the correct video mode
- FASTFORWARD: Enforce minimum fastforward_ratio of 1.0
- FONTS/FREETYPE/STB_UNICODE/BITMAPFONT: Prevent texture bleed when rendering text at non-integer scales
- INPUT: Ensure that 'retro_set_controller_port_device' is called when updating 'Max Users'
- INPUT/XEGL/MOUSE: Fix xegl_ctx.c mouse activation
- INPUT/SDL: Fix crash in SDL input driver when analogs are bound.
- INPUT/POINTER: Add scaling to pointer input.
- INPUT REMAPPING: Fix regression on loading file
- INPUT REMAPPING: Fix regression where disabling input remapping would disable input
- IOS: Disable system button gestures on iOS 14
- IOS: Prevent potential crash on controller connect - randomly would get a crash when connecting a game controller while RA was running
- LAKKA: Add menu for time zone setting
- LOGGING: RARCH_LOG_V checking for verbosity level is not necessary and can cause issues; removed said check.
- LOGGING: Silence inappropriate cheatfile logging
- IOS/MAC: Add CPU VFP unit detection for Darwin
- MAC: Swallow 'escape' key being pressed - would previously make the game toggle between fullscreen and windowed
- MAC: Intel and ARM64 timer change proposal.
- MAC/ARM64: run_fast_mode disabled for 64 bits invalid instructions.
- MAC/OPENGL: Fix codesigning issue
- MAC/UNIVERSAL: Add TTS translation service support.
- MENU: Add optional menu screensaver
- MENU: Add search filter support to cheats and overlays file browser menus
- MENU/FILEBROWSER: Enhanced 'Load Content' file browser search functionality
- MENU/INPUT: Block accidental diagonals in menu navigation
- MENU/RGUI: Add option to disable menu transparency
- MENU/RGUI: Fix display of 'Video > Scaling' menu when 'Lock Menu Aspect Ratio' is enabled
- MENU/MATERIALUI: Add icon to 'Turbo Fire' menu entry
- MENU/OZONE: Ozone Dracula theme
- OPENDINGUX/BETA: Fix IPU scaling when running GBA-resolution content
- OPENDINGUX/BETA: Add 50Hz support
- OPENDINGUX: Enable 'SaveRAM Autosave Interval' by default
- PATCHES: Added multi-softpatching support + OSD messages for patches
- RHMAP: Track the complete string in rhmap
- VITA: Align VM block size to 1MB - should fix one of the issues with gpSP
- WINDOWS/GDI: Fix non-ASCII text rendering
- XEGL: Fix mouse not working when using OpenGLES with X11
# 1.9.1
- 3DS: Graphics widgets support
- 3DS: On error, only init gfx on salamander build. This prevents graphical issues if the gfx is already initialized.
+2 -2
View File
@@ -22,7 +22,7 @@ endif
OBJ :=
LIBS :=
DEF_FLAGS :=
DEF_FLAGS := -I.
ASFLAGS :=
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
@@ -118,7 +118,7 @@ ifneq ($(CXX_BUILD), 1)
CFLAGS += -D_GNU_SOURCE
endif
DEF_FLAGS += $(INCLUDE_DIRS) -I. -Ideps -Ideps/stb
DEF_FLAGS += $(INCLUDE_DIRS) -Ideps -Ideps/stb
CFLAGS += $(DEF_FLAGS)
CXXFLAGS += $(DEF_FLAGS) -D__STDC_CONSTANT_MACROS
+25 -19
View File
@@ -195,8 +195,8 @@ endif
ifeq ($(TARGET), retroarch_3ds)
OBJ += frontend/drivers/platform_ctr.o
endif
# Git Version
ifeq ($(HAVE_GIT_VERSION), 1)
GIT_VERSION_CACHEDIR = $(if $(OBJDIR),$(OBJDIR),$(CURDIR))
GIT_VERSION_CACHEFILE = $(GIT_VERSION_CACHEDIR)/git-version.cache
@@ -224,7 +224,6 @@ ifneq ($(GIT_VERSION),) # Enable version_git.o?
DEFINES += -DHAVE_GIT_VERSION -DGIT_VERSION=$(GIT_VERSION)
OBJ += version_git.o
endif
endif
# General object files
ifeq ($(HAVE_DR_MP3), 1)
@@ -233,6 +232,7 @@ endif
OBJ += frontend/frontend_driver.o \
retroarch.o \
command.o \
msg_hash.o \
intl/msg_hash_us.o \
$(LIBRETRO_COMM_DIR)/queues/task_queue.o \
@@ -988,12 +988,14 @@ ifeq ($(HAVE_MENU), 1)
OBJ += menu/drivers/materialui.o
DEFINES += -DHAVE_MATERIALUI
HAVE_ASSETS = 1
HAVE_MENU_SCREENSAVER = 1
endif
ifeq ($(HAVE_XMB), 1)
OBJ += menu/drivers/xmb.o
DEFINES += -DHAVE_XMB
HAVE_ASSETS = 1
HAVE_MENU_SCREENSAVER = 1
endif
ifeq ($(HAVE_OZONE), 1)
@@ -1005,12 +1007,17 @@ ifeq ($(HAVE_MENU), 1)
menu/drivers/ozone/ozone_sidebar.o
DEFINES += -DHAVE_OZONE
HAVE_ASSETS = 1
HAVE_MENU_SCREENSAVER = 1
endif
ifeq ($(HAVE_STRIPES), 1)
OBJ += menu/drivers/stripes.o
DEFINES += -DHAVE_STRIPES
endif
ifeq ($(HAVE_MENU_SCREENSAVER), 1)
OBJ += menu/menu_screensaver.o
endif
endif
ifeq ($(HAVE_BLUETOOTH), 1)
@@ -1863,20 +1870,24 @@ ifeq ($(HAVE_7ZIP),1)
INCLUDE_DIRS += -I$(DEPS_DIR)/7zip
HAVE_COMPRESSION = 1
DEFINES += -DHAVE_7ZIP -D_7ZIP_ST
7ZOBJ = $(DEPS_DIR)/7zip/7zIn.o \
$(DEPS_DIR)/7zip/Bra86.o \
$(DEPS_DIR)/7zip/7zFile.o \
$(DEPS_DIR)/7zip/7zStream.o \
7ZOBJ = $(DEPS_DIR)/7zip/7zArcIn.o \
$(DEPS_DIR)/7zip/7zBuf.o \
$(DEPS_DIR)/7zip/7zCrc.o \
$(DEPS_DIR)/7zip/7zCrcOpt.o \
$(DEPS_DIR)/7zip/7zDec.o \
$(DEPS_DIR)/7zip/CpuArch.o \
$(DEPS_DIR)/7zip/Delta.o \
$(DEPS_DIR)/7zip/LzFind.o \
$(DEPS_DIR)/7zip/LzmaDec.o \
$(DEPS_DIR)/7zip/LzmaEnc.o \
$(DEPS_DIR)/7zip/7zCrcOpt.o \
$(DEPS_DIR)/7zip/Bra.o \
$(DEPS_DIR)/7zip/7zDec.o \
$(DEPS_DIR)/7zip/Bcj2.o \
$(DEPS_DIR)/7zip/7zCrc.o \
$(DEPS_DIR)/7zip/Lzma2Dec.o \
$(DEPS_DIR)/7zip/7zBuf.o
$(DEPS_DIR)/7zip/LzmaEnc.o \
$(DEPS_DIR)/7zip/Bra.o \
$(DEPS_DIR)/7zip/Bra86.o \
$(DEPS_DIR)/7zip/BraIA64.o \
$(DEPS_DIR)/7zip/Bcj2.o \
$(DEPS_DIR)/7zip/7zFile.o \
$(DEPS_DIR)/7zip/7zStream.o
OBJ += $(LIBRETRO_COMM_DIR)/file/archive_file_7z.o \
$(7ZOBJ)
endif
@@ -2079,14 +2090,9 @@ ifeq ($(HAVE_NETWORKING), 1)
# Netplay
DEFINES += -DHAVE_NETWORK_CMD
OBJ += network/netplay/netplay_delta.o \
network/netplay/netplay_handshake.o \
network/netplay/netplay_init.o \
OBJ += network/netplay/netplay_handshake.o \
network/netplay/netplay_io.o \
network/netplay/netplay_keyboard.o \
network/netplay/netplay_sync.o \
network/netplay/netplay_discovery.o \
network/netplay/netplay_buf.o \
network/netplay/netplay_room_parse.o
# RetroAchievements
+3 -2
View File
@@ -51,14 +51,15 @@ DEFINES :=
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_RGUI -DHAVE_XMB -DHAVE_MATERIALUI -DHAVE_LIBRETRODB -DHAVE_CC_RESAMPLER
DEFINES += -DHAVE_ZLIB -DHAVE_7ZIP -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA
DEFINES += -DHAVE_ZLIB -DHAVE_7ZIP -D_7ZIP_ST -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA
DEFINES += -DHAVE_NETWORKING -DHAVE_CHEEVOS -DRC_DISABLE_LUA -DHAVE_ONLINE_UPDATER -DHAVE_UPDATE_CORES
#DEFINES += -DHAVE_UPDATE_ASSETS
DEFINES += -DHAVE_PATCH -DHAVE_RWAV
DEFINES += -DHAVE_SCREENSHOTS
DEFINES += -DHAVE_REWIND
DEFINES += -DHAVE_THREADS
#DEFINES += -DHAVE_GFX_WIDGETS
DEFINES += -DHAVE_GFX_WIDGETS
DEFINES += -DHAVE_OVERLAY
#DEFINES += -DHAVE_SOCKET_LEGACY
#-DHAVE_SSL -DHAVE_BUILTINMBEDTLS -DMBEDTLS_SSL_DEBUG_ALL
#ssl is currently incompatible with griffin due to use of the "static" flag on repeating functions that will conflict when included in one file
+1 -1
View File
@@ -1102,7 +1102,7 @@ ifeq ($(HAVE_RUNAHEAD), 1)
endif
ifeq ($(HAVE_7ZIP), 1)
CFLAGS += -DHAVE_7ZIP
CFLAGS += -DHAVE_7ZIP -D_7ZIP_ST
endif
ifeq ($(HAVE_SCREENSHOTS), 1)
+1 -1
View File
@@ -205,7 +205,7 @@ ifeq ($(HAVE_RUNAHEAD), 1)
endif
ifeq ($(HAVE_7ZIP), 1)
CFLAGS += -DHAVE_7ZIP
CFLAGS += -DHAVE_7ZIP -D_7ZIP_ST
endif
ifeq ($(HAVE_SCREENSHOTS), 1)
+1 -1
View File
@@ -29,7 +29,7 @@ CFLAGS = $(OPTIMIZE_LV) $(DISABLE_WARNINGS) -ffast-math -fsingle-precision-const
ASFLAGS = $(CFLAGS)
RARCH_DEFINES += -DPS2 -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS -DHAVE_RGUI
RARCH_DEFINES += -DHAVE_ZLIB -DHAVE_NO_BUILTINZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -DHAVE_CC_RESAMPLER -DHAVE_AUDIOMIXER
RARCH_DEFINES += -DHAVE_ZLIB -DHAVE_NO_BUILTINZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -D_7ZIP_ST -DHAVE_CC_RESAMPLER -DHAVE_AUDIOMIXER
RARCH_DEFINES += -DHAVE_DSP_FILTER
RARCH_DEFINES += -DHAVE_VIDEO_FILTER
+2 -2
View File
@@ -27,13 +27,13 @@ ELF_TARGET := retroarch_psl1ght.elf
SELF_TARGET := $(ELF_TARGET:.elf=.self)
CORE_PATH = pkg/psl1ght/pkg/USRDIR/cores/CORE.SELF
INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude
INCLUDE += -I. -Ips3/gcmgl/include/export -Ips3/include -Ideps -Ideps/stb -Ilibretro-common/include/compat/zlib -Ilibretro-common/include $(LIBPSL1GHT_INC) -Iinclude -Idefines
LIBDIRS += -L.
MACHDEP := -D__PSL1GHT__ -mcpu=cell
CFLAGS += -Wall $(MACHDEP) $(INCLUDE)
LDFLAGS := $(MACHDEP)
LIBS := -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl
LIBS := -lretro_psl1ght -laudio -lrsx -lgcm_sys -lnet -lio -lsysutil -lsysmodule -lm -ljpgdec -lpngdec -llv2 -lnet -lnetctl -lsysfs
# system platform
system_platform = unix
+1 -1
View File
@@ -23,7 +23,7 @@ INCDIR = deps deps/stb deps/7zip deps/pthreads deps/pthreads/platform/psp deps/p
CFLAGS = $(OPTIMIZE_LV) -G0 -std=gnu99 -ffast-math -fsingle-precision-constant
ASFLAGS = $(CFLAGS)
RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_AUDIOMIXER -DHAVE_RWAV -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_DSP_FILTER -DHAVE_VIDEO_FILTER -DHAVE_7ZIP -DHAVE_CC_RESAMPLER
RARCH_DEFINES = -DPSP -D_MIPS_ARCH_ALLEGREX -DHAVE_LANGEXTRA -DHAVE_ZLIB -DHAVE_AUDIOMIXER -DHAVE_RWAV -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS -DHAVE_RGUI -DHAVE_FILTERS_BUILTIN -DHAVE_DSP_FILTER -DHAVE_VIDEO_FILTER -DHAVE_7ZIP -D_7ZIP_ST -DHAVE_CC_RESAMPLER
LIBDIR =
LDFLAGS =
+1 -1
View File
@@ -222,7 +222,7 @@ ifeq ($(HAVE_RUNAHEAD), 1)
endif
ifeq ($(HAVE_7ZIP), 1)
CFLAGS += -DHAVE_7ZIP
CFLAGS += -DHAVE_7ZIP -D_7ZIP_ST
endif
ifeq ($(HAVE_SCREENSHOTS), 1)
+4 -2
View File
@@ -15,6 +15,8 @@ static int _newlib_vm_memblock;
extern int _newlib_heap_size_user __attribute__((weak));
extern int _newlib_vm_size_user __attribute__((weak));
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
void * _sbrk_r(struct _reent *reent, ptrdiff_t incr) {
if (sceKernelLockLwMutex((struct SceKernelLwMutexWork*)_newlib_sbrk_mutex, 1, 0) < 0)
goto fail;
@@ -36,8 +38,8 @@ void _init_vita_heap(void) {
int _newlib_vm_size = 0;
if (&_newlib_vm_size_user != NULL) {
_newlib_vm_size = _newlib_vm_size_user;
_newlib_vm_memblock = sceKernelAllocMemBlockForVM("code", _newlib_vm_size_user);
_newlib_vm_size = ALIGN(_newlib_vm_size_user, 0x100000);
_newlib_vm_memblock = sceKernelAllocMemBlockForVM("code", _newlib_vm_size);
if (_newlib_vm_memblock < 0){
//sceClibPrintf("sceKernelAllocMemBlockForVM failed\n");
+10 -12
View File
@@ -140,7 +140,6 @@ bool cheat_manager_save(
{
bool ret;
unsigned i;
char buf[PATH_MAX_LENGTH];
char cheats_file[PATH_MAX_LENGTH];
config_file_t *conf = NULL;
cheat_manager_t *cheat_st = &cheat_manager_state;
@@ -164,7 +163,7 @@ bool cheat_manager_save(
(char*)"cheat%u_repeat_add_to_address"
};
buf[0] = cheats_file[0] = '\0';
cheats_file[0] = '\0';
if (!cheat_st->cheats || cheat_st->size == 0)
return false;
@@ -172,11 +171,10 @@ bool cheat_manager_save(
if (!cheat_database)
strlcpy(cheats_file, path, sizeof(cheats_file));
else
{
fill_pathname_join(buf, cheat_database, path, sizeof(buf));
fill_pathname_noext(cheats_file, buf, ".cht", sizeof(cheats_file));
}
fill_pathname_join_concat(cheats_file,
cheat_database, path,
".cht",
sizeof(cheats_file));
if (!overwrite)
conf = config_file_new_from_path_to_string(cheats_file);
@@ -705,7 +703,7 @@ static bool cheat_manager_get_game_specific_filename(
return false;
core_name = system_info.library_name;
game_name = path_basename(global->name.cheatfile);
game_name = path_basename_nocompression(global->name.cheatfile);
if (string_is_empty(path_cheat_database) ||
string_is_empty(core_name) ||
@@ -739,8 +737,8 @@ void cheat_manager_load_game_specific_cheats(const char *path_cheat_database)
path_cheat_database,
false))
{
RARCH_LOG("[Cheats]: Load game-specific cheatfile: %s\n", cheat_file);
cheat_manager_load(cheat_file, true);
if (cheat_manager_load(cheat_file, true))
RARCH_LOG("[Cheats]: Load game-specific cheatfile: %s\n", cheat_file);
}
}
@@ -753,8 +751,8 @@ void cheat_manager_save_game_specific_cheats(const char *path_cheat_database)
path_cheat_database,
true))
{
RARCH_LOG("[Cheats]: Save game-specific cheatfile: %s\n", cheat_file);
cheat_manager_save(cheat_file, NULL, true);
if (cheat_manager_save(cheat_file, NULL, true))
RARCH_LOG("[Cheats]: Save game-specific cheatfile: %s\n", cheat_file);
}
}
+17 -4
View File
@@ -491,6 +491,12 @@ static void rcheevos_invalidate_address(unsigned address)
uint8_t* rcheevos_patch_address(unsigned address)
{
if (rcheevos_locals.memory.count == 0)
{
/* memory map was not previously initialized (no achievements for this game?) try now */
rcheevos_memory_init(&rcheevos_locals.memory, rcheevos_locals.patchdata.console_id);
}
return rcheevos_memory_find(&rcheevos_locals.memory, address);
}
@@ -1009,13 +1015,17 @@ static void rcheevos_award_achievement(rcheevos_locals_t *locals,
/* Take a screenshot of the achievement. */
if (settings && settings->bools.cheevos_auto_screenshot)
{
char shotname[8192];
size_t shotname_len = sizeof(char) * 8192;
char *shotname = (char*)malloc(shotname_len);
snprintf(shotname, sizeof(shotname), "%s/%s-cheevo-%u",
if (!shotname)
return;
snprintf(shotname, shotname_len, "%s/%s-cheevo-%u",
settings->paths.directory_screenshot,
path_basename(path_get(RARCH_PATH_BASENAME)),
cheevo->id);
shotname[sizeof(shotname) - 1] = '\0';
shotname[shotname_len - 1] = '\0';
if (take_screenshot(settings->paths.directory_screenshot,
shotname, true,
@@ -1028,6 +1038,7 @@ static void rcheevos_award_achievement(rcheevos_locals_t *locals,
CHEEVOS_LOG(
RCHEEVOS_TAG "Failed to capture screenshot for achievement %u\n",
cheevo->id);
free(shotname);
}
}
#endif
@@ -1471,10 +1482,12 @@ bool rcheevos_unload(void)
#endif
}
if (rcheevos_locals.memory.count > 0)
rcheevos_memory_destroy(&rcheevos_locals.memory);
if (rcheevos_locals.loaded)
{
rcheevos_free_patchdata(&rcheevos_locals.patchdata);
rcheevos_memory_destroy(&rcheevos_locals.memory);
#ifdef HAVE_MENU
cheevos_reset_menu_badges();
#endif
+534
View File
@@ -0,0 +1,534 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2021 - David G.F.
*
* 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 <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#ifdef HAVE_NETWORKING
#include <net/net_compat.h>
#include <net/net_socket.h>
#endif
#include <streams/stdin_stream.h>
#include <string/stdstring.h>
#include "verbosity.h"
#include "command.h"
#define CMD_BUF_SIZE 4096
#if defined(HAVE_COMMAND)
/* Generic command parse utilities */
static bool command_get_arg(const char *tok,
const char **arg, unsigned *index)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(map); i++)
{
if (string_is_equal(tok, map[i].str))
{
if (arg)
*arg = NULL;
if (index)
*index = i;
return true;
}
}
for (i = 0; i < ARRAY_SIZE(action_map); i++)
{
const char *str = strstr(tok, action_map[i].str);
if (str == tok)
{
const char *argument = str + strlen(action_map[i].str);
if (*argument != ' ' && *argument != '\0')
return false;
if (arg)
*arg = argument + 1;
if (index)
*index = i;
return true;
}
}
return false;
}
static void command_parse_sub_msg(command_t *handle, const char *tok)
{
const char *arg = NULL;
unsigned index = 0;
if (command_get_arg(tok, &arg, &index))
{
if (arg)
{
if (!action_map[index].action(handle, arg))
RARCH_ERR("Command \"%s\" failed.\n", arg);
}
else
handle->state[map[index].id] = true;
}
else
RARCH_WARN("%s \"%s\" %s.\n",
msg_hash_to_str(MSG_UNRECOGNIZED_COMMAND),
tok,
msg_hash_to_str(MSG_RECEIVED));
}
static void command_parse_msg(
command_t *handle, char *buf)
{
char *save = NULL;
const char *tok = strtok_r(buf, "\n", &save);
while (tok)
{
command_parse_sub_msg(handle, tok);
tok = strtok_r(NULL, "\n", &save);
}
}
#if defined(HAVE_NETWORK_CMD)
typedef struct
{
/* Network socket FD */
int net_fd;
/* Source address for the command received */
struct sockaddr_storage cmd_source;
/* Size of the previous structure in use */
socklen_t cmd_source_len;
} command_network_t;
static void network_command_reply(
command_t *cmd,
const char * data, size_t len)
{
command_network_t *netcmd = (command_network_t*)cmd->userptr;
/* Respond (fire and forget since it's UDP) */
sendto(netcmd->net_fd, data, len, 0,
(struct sockaddr*)&netcmd->cmd_source, netcmd->cmd_source_len);
}
static void network_command_free(command_t *handle)
{
command_network_t *netcmd = (command_network_t*)handle->userptr;
if (netcmd->net_fd >= 0)
socket_close(netcmd->net_fd);
free(netcmd);
free(handle);
}
static void command_network_poll(command_t *handle)
{
fd_set fds;
struct timeval tmp_tv = {0};
command_network_t *netcmd = (command_network_t*)handle->userptr;
if (netcmd->net_fd < 0)
return;
FD_ZERO(&fds);
FD_SET(netcmd->net_fd, &fds);
if (socket_select(netcmd->net_fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
return;
if (!FD_ISSET(netcmd->net_fd, &fds))
return;
for (;;)
{
ssize_t ret;
char buf[1024];
buf[0] = '\0';
ret = recvfrom(netcmd->net_fd, buf, sizeof(buf) - 1, 0,
(struct sockaddr*)&netcmd->cmd_source,
&netcmd->cmd_source_len);
if (ret <= 0)
break;
buf[ret] = '\0';
command_parse_msg(handle, buf);
}
}
command_t* command_network_new(uint16_t port)
{
struct addrinfo *res = NULL;
command_t *cmd = (command_t*)calloc(1, sizeof(command_t));
command_network_t *netcmd = (command_network_t*)calloc(
1, sizeof(command_network_t));
int fd = socket_init(
(void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM);
RARCH_LOG("%s %hu.\n",
msg_hash_to_str(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT),
(unsigned short)port);
if (fd < 0)
goto error;
netcmd->net_fd = fd;
cmd->userptr = netcmd;
cmd->poll = command_network_poll;
cmd->replier = network_command_reply;
cmd->destroy = network_command_free;
if (!socket_nonblock(netcmd->net_fd))
goto error;
if (!socket_bind(netcmd->net_fd, (void*)res))
{
RARCH_ERR("%s.\n",
msg_hash_to_str(MSG_FAILED_TO_BIND_SOCKET));
goto error;
}
freeaddrinfo_retro(res);
return cmd;
error:
if (res)
freeaddrinfo_retro(res);
free(netcmd);
free(cmd);
return NULL;
}
#endif
#if defined(HAVE_STDIN_CMD)
typedef struct
{
/* Buffer and pointer for stdin reads */
size_t stdin_buf_ptr;
char stdin_buf[CMD_BUF_SIZE];
} command_stdin_t;
static void stdin_command_reply(
command_t *cmd,
const char * data, size_t len)
{
/* Just write to stdout! */
fwrite(data, 1, len, stdout);
}
static void stdin_command_free(command_t *handle)
{
free(handle->userptr);
free(handle);
}
static void command_stdin_poll(command_t *handle)
{
ptrdiff_t msg_len;
char *last_newline = NULL;
command_stdin_t *stdincmd = (command_stdin_t*)handle->userptr;
ssize_t ret = read_stdin(
stdincmd->stdin_buf + stdincmd->stdin_buf_ptr,
CMD_BUF_SIZE - stdincmd->stdin_buf_ptr - 1);
if (ret == 0)
return;
stdincmd->stdin_buf_ptr += ret;
stdincmd->stdin_buf[stdincmd->stdin_buf_ptr] = '\0';
last_newline = strrchr(stdincmd->stdin_buf, '\n');
if (!last_newline)
{
/* We're receiving bogus data in pipe
* (no terminating newline), flush out the buffer. */
if (stdincmd->stdin_buf_ptr + 1 >= CMD_BUF_SIZE)
{
stdincmd->stdin_buf_ptr = 0;
stdincmd->stdin_buf[0] = '\0';
}
return;
}
*last_newline++ = '\0';
msg_len = last_newline - stdincmd->stdin_buf;
command_parse_msg(handle, stdincmd->stdin_buf);
memmove(stdincmd->stdin_buf, last_newline,
stdincmd->stdin_buf_ptr - msg_len);
stdincmd->stdin_buf_ptr -= msg_len;
}
command_t* command_stdin_new(void)
{
command_t *cmd;
command_stdin_t *stdincmd;
#ifndef _WIN32
#ifdef HAVE_NETWORKING
if (!socket_nonblock(STDIN_FILENO))
return NULL;
#endif
#endif
cmd = (command_t*)calloc(1, sizeof(command_t));
stdincmd = (command_stdin_t*)calloc(1, sizeof(command_stdin_t));
cmd->userptr = stdincmd;
cmd->poll = command_stdin_poll;
cmd->replier = stdin_command_reply;
cmd->destroy = stdin_command_free;
return cmd;
}
#endif
#if defined(HAVE_LAKKA)
#include <sys/un.h>
#define MAX_USER_CONNECTIONS 4
typedef struct
{
/* File descriptor for the domain socket */
int sfd;
/* Client sockets */
int userfd[MAX_USER_CONNECTIONS];
/* Last received user socket */
int last_fd;
} command_uds_t;
static void uds_command_reply(
command_t *cmd,
const char * data, size_t len)
{
command_uds_t *subcmd = (command_uds_t*)cmd->userptr;
write(subcmd->last_fd, data, len);
}
static void uds_command_free(command_t *handle)
{
int i;
command_uds_t *udscmd = (command_uds_t*)handle->userptr;
for (i = 0; i < MAX_USER_CONNECTIONS; i++)
if (udscmd->userfd[i] >= 0)
socket_close(udscmd->userfd[i]);
socket_close(udscmd->sfd);
free(handle->userptr);
free(handle);
}
static void command_uds_poll(command_t *handle)
{
int i;
fd_set fds;
command_uds_t *udscmd = (command_uds_t*)handle->userptr;
int maxfd = udscmd->sfd;
struct timeval tmp_tv = {0};
if (udscmd->sfd < 0)
return;
FD_ZERO(&fds);
FD_SET(udscmd->sfd, &fds);
for (i = 0; i < MAX_USER_CONNECTIONS; i++)
{
if (udscmd->userfd[i] >= 0)
{
maxfd = MAX(udscmd->userfd[i], maxfd);
FD_SET(udscmd->userfd[i], &fds);
}
}
if (socket_select(maxfd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
return;
/* Read data from clients and process commands */
for (i = 0; i < MAX_USER_CONNECTIONS; i++)
{
if (udscmd->userfd[i] >= 0 && FD_ISSET(udscmd->userfd[i], &fds))
{
while (1)
{
char buf[2048];
ssize_t ret = recv(udscmd->userfd[i], buf, sizeof(buf) - 1, 0);
if (ret < 0)
break; /* no more data */
if (!ret)
{
socket_close(udscmd->userfd[i]);
udscmd->userfd[i] = -1;
break;
}
buf[ret] = 0;
udscmd->last_fd = udscmd->userfd[i];
command_parse_msg(handle, buf);
}
}
}
if (FD_ISSET(udscmd->sfd, &fds))
{
/* Accepts new connections from clients */
int cfd = accept(udscmd->sfd, NULL, NULL);
if (cfd >= 0) {
if (!socket_nonblock(cfd))
socket_close(cfd);
else {
for (i = 0; i < MAX_USER_CONNECTIONS; i++)
if (udscmd->userfd[i] < 0)
{
udscmd->userfd[i] = cfd;
break;
}
}
}
}
}
command_t* command_uds_new(void)
{
int i;
command_t *cmd;
command_uds_t *subcmd;
struct sockaddr_un addr;
const char *sp = "retroarch/cmd";
socklen_t addrsz = offsetof(struct sockaddr_un, sun_path) + strlen(sp) + 1;
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return NULL;
/* use an abstract socket for simplicity */
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(&addr.sun_path[1], sp);
if (bind(fd, (struct sockaddr*)&addr, addrsz) < 0 ||
listen(fd, MAX_USER_CONNECTIONS) < 0)
{
socket_close(fd);
return NULL;
}
if (!socket_nonblock(fd))
{
socket_close(fd);
return NULL;
}
cmd = (command_t*)calloc(1, sizeof(command_t));
subcmd = (command_uds_t*)calloc(1, sizeof(command_uds_t));
subcmd->sfd = fd;
subcmd->last_fd = -1;
for (i = 0; i < MAX_USER_CONNECTIONS; i++)
subcmd->userfd[i] = -1;
cmd->userptr = subcmd;
cmd->poll = command_uds_poll;
cmd->replier = uds_command_reply;
cmd->destroy = uds_command_free;
return cmd;
}
#endif
/* Routines used to invoke retroarch command ... */
#ifdef HAVE_NETWORK_CMD
static bool command_verify(const char *cmd)
{
unsigned i;
if (command_get_arg(cmd, NULL, NULL))
return true;
RARCH_ERR("Command \"%s\" is not recognized by the program.\n", cmd);
RARCH_ERR("\tValid commands:\n");
for (i = 0; i < ARRAY_SIZE(map); i++)
RARCH_ERR("\t\t%s\n", map[i].str);
for (i = 0; i < ARRAY_SIZE(action_map); i++)
RARCH_ERR("\t\t%s %s\n", action_map[i].str, action_map[i].arg_desc);
return false;
}
bool command_network_send(const char *cmd_)
{
char *command = NULL;
char *save = NULL;
const char *cmd = NULL;
if (!network_init())
return false;
if (!(command = strdup(cmd_)))
return false;
cmd = strtok_r(command, ";", &save);
if (cmd)
{
uint16_t port = DEFAULT_NETWORK_CMD_PORT;
const char *port_ = NULL;
const char *host = strtok_r(NULL, ";", &save);
if (host)
port_ = strtok_r(NULL, ";", &save);
else
{
#ifdef _WIN32
host = "127.0.0.1";
#else
host = "localhost";
#endif
}
if (port_)
port = strtoul(port_, NULL, 0);
RARCH_LOG("%s: \"%s\" to %s:%hu\n",
msg_hash_to_str(MSG_SENDING_COMMAND),
cmd, host, (unsigned short)port);
if (command_verify(cmd) && udp_send_packet(host, port, cmd))
{
free(command);
return true;
}
}
free(command);
return false;
}
#endif
#endif
+147 -5
View File
@@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2016-2019 - Brad Parker
* Copyright (C) 2021 - David G.F.
*
* 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-
@@ -23,12 +23,46 @@
#include <boolean.h>
#include <retro_common_api.h>
#include "retroarch.h"
#include "input/input_defines.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
RETRO_BEGIN_DECLS
#define MAX_CMD_DRIVERS 3
#define DEFAULT_NETWORK_CMD_PORT 55355
struct cmd_map
{
const char *str;
unsigned id;
};
struct command_handler;
typedef void (*command_poller_t)(struct command_handler *cmd);
typedef void (*command_replier_t)(struct command_handler *cmd, const char * data, size_t len);
typedef void (*command_destructor_t)(struct command_handler *cmd);
struct command_handler
{
/* Interface to poll the driver */
command_poller_t poll;
/* Interface to reply */
command_replier_t replier;
/* Interface to delete the underlying command */
command_destructor_t destroy;
/* Underlying command storage */
void *userptr;
/* State received */
bool state[RARCH_BIND_LIST_END];
};
typedef struct command_handler command_t;
enum event_command
{
CMD_EVENT_NONE = 0,
@@ -166,7 +200,6 @@ enum event_command
CMD_EVENT_AUDIO_REINIT,
/* Resizes windowed scale. Will reinitialize video driver. */
CMD_EVENT_RESIZE_WINDOWED_SCALE,
CMD_EVENT_LOG_FILE_DEINIT,
/* Toggles disk eject. */
CMD_EVENT_DISK_EJECT_TOGGLE,
/* Cycle to next disk. */
@@ -205,17 +238,25 @@ enum event_command
CMD_EVENT_CHEAT_INDEX_MINUS,
CMD_EVENT_CHEAT_TOGGLE,
CMD_EVENT_AI_SERVICE_CALL,
CMD_EVENT_SAVE_FILES
CMD_EVENT_SAVE_FILES,
CMD_EVENT_CONTROLLER_INIT
};
typedef struct command command_t;
typedef struct command_handle
{
command_t *handle;
unsigned id;
} command_handle_t;
enum cmd_source_t
{
CMD_NONE = 0,
CMD_STDIN,
CMD_NETWORK
};
struct rarch_state;
/**
* command_event:
* @cmd : Command index.
@@ -226,6 +267,107 @@ typedef struct command_handle
**/
bool command_event(enum event_command action, void *data);
/* Constructors for the supported drivers */
command_t* command_network_new(uint16_t port);
command_t* command_stdin_new(void);
command_t* command_uds_new(void);
bool command_network_send(const char *cmd_);
/* These forward declarations need to be declared before
* the global state is declared */
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
bool command_set_shader(command_t *cmd, const char *arg);
#endif
#if defined(HAVE_COMMAND)
bool command_version(command_t *cmd, const char* arg);
bool command_get_status(command_t *cmd, const char* arg);
bool command_get_config_param(command_t *cmd, const char* arg);
bool command_show_osd_msg(command_t *cmd, const char* arg);
#ifdef HAVE_CHEEVOS
bool command_read_ram(command_t *cmd, const char *arg);
bool command_write_ram(command_t *cmd, const char *arg);
#endif
bool command_read_memory(command_t *cmd, const char *arg);
bool command_write_memory(command_t *cmd, const char *arg);
struct cmd_action_map
{
const char *str;
bool (*action)(command_t* cmd, const char *arg);
const char *arg_desc;
};
static const struct cmd_action_map action_map[] = {
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
{ "SET_SHADER", command_set_shader, "<shader path>" },
#endif
{ "VERSION", command_version, "No argument"},
{ "GET_STATUS", command_get_status, "No argument" },
{ "GET_CONFIG_PARAM", command_get_config_param, "<param name>" },
{ "SHOW_MSG", command_show_osd_msg, "No argument" },
#if defined(HAVE_CHEEVOS)
/* These functions use achievement addresses and only work if a game with achievements is
* loaded. READ_CORE_MEMORY and WRITE_CORE_MEMORY are preferred and use system addresses. */
{ "READ_CORE_RAM", command_read_ram, "<address> <number of bytes>" },
{ "WRITE_CORE_RAM", command_write_ram, "<address> <byte1> <byte2> ..." },
#endif
{ "READ_CORE_MEMORY", command_read_memory, "<address> <number of bytes>" },
{ "WRITE_CORE_MEMORY",command_write_memory, "<address> <byte1> <byte2> ..." },
};
static const struct cmd_map map[] = {
{ "FAST_FORWARD", RARCH_FAST_FORWARD_KEY },
{ "FAST_FORWARD_HOLD", RARCH_FAST_FORWARD_HOLD_KEY },
{ "SLOWMOTION", RARCH_SLOWMOTION_KEY },
{ "SLOWMOTION_HOLD", RARCH_SLOWMOTION_HOLD_KEY },
{ "LOAD_STATE", RARCH_LOAD_STATE_KEY },
{ "SAVE_STATE", RARCH_SAVE_STATE_KEY },
{ "FULLSCREEN_TOGGLE", RARCH_FULLSCREEN_TOGGLE_KEY },
{ "CLOSE_CONTENT", RARCH_CLOSE_CONTENT_KEY },
{ "QUIT", RARCH_QUIT_KEY },
{ "STATE_SLOT_PLUS", RARCH_STATE_SLOT_PLUS },
{ "STATE_SLOT_MINUS", RARCH_STATE_SLOT_MINUS },
{ "REWIND", RARCH_REWIND },
{ "BSV_RECORD_TOGGLE", RARCH_BSV_RECORD_TOGGLE },
{ "PAUSE_TOGGLE", RARCH_PAUSE_TOGGLE },
{ "FRAMEADVANCE", RARCH_FRAMEADVANCE },
{ "RESET", RARCH_RESET },
{ "SHADER_NEXT", RARCH_SHADER_NEXT },
{ "SHADER_PREV", RARCH_SHADER_PREV },
{ "CHEAT_INDEX_PLUS", RARCH_CHEAT_INDEX_PLUS },
{ "CHEAT_INDEX_MINUS", RARCH_CHEAT_INDEX_MINUS },
{ "CHEAT_TOGGLE", RARCH_CHEAT_TOGGLE },
{ "SCREENSHOT", RARCH_SCREENSHOT },
{ "MUTE", RARCH_MUTE },
{ "OSK", RARCH_OSK },
{ "FPS_TOGGLE", RARCH_FPS_TOGGLE },
{ "SEND_DEBUG_INFO", RARCH_SEND_DEBUG_INFO },
{ "NETPLAY_HOST_TOGGLE", RARCH_NETPLAY_HOST_TOGGLE },
{ "NETPLAY_GAME_WATCH", RARCH_NETPLAY_GAME_WATCH },
{ "VOLUME_UP", RARCH_VOLUME_UP },
{ "VOLUME_DOWN", RARCH_VOLUME_DOWN },
{ "OVERLAY_NEXT", RARCH_OVERLAY_NEXT },
{ "DISK_EJECT_TOGGLE", RARCH_DISK_EJECT_TOGGLE },
{ "DISK_NEXT", RARCH_DISK_NEXT },
{ "DISK_PREV", RARCH_DISK_PREV },
{ "GRAB_MOUSE_TOGGLE", RARCH_GRAB_MOUSE_TOGGLE },
{ "UI_COMPANION_TOGGLE", RARCH_UI_COMPANION_TOGGLE },
{ "GAME_FOCUS_TOGGLE", RARCH_GAME_FOCUS_TOGGLE },
{ "MENU_TOGGLE", RARCH_MENU_TOGGLE },
{ "RECORDING_TOGGLE", RARCH_RECORDING_TOGGLE },
{ "STREAMING_TOGGLE", RARCH_STREAMING_TOGGLE },
{ "RUNAHEAD_TOGGLE", RARCH_RUNAHEAD_TOGGLE },
{ "MENU_UP", RETRO_DEVICE_ID_JOYPAD_UP },
{ "MENU_DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN },
{ "MENU_LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT },
{ "MENU_RIGHT", RETRO_DEVICE_ID_JOYPAD_RIGHT },
{ "MENU_A", RETRO_DEVICE_ID_JOYPAD_A },
{ "MENU_B", RETRO_DEVICE_ID_JOYPAD_B },
{ "AI_SERVICE", RARCH_AI_SERVICE },
};
#endif
RETRO_END_DECLS
#endif
+42 -3
View File
@@ -37,11 +37,17 @@
#include "gfx/common/ctr_common.h"
#endif
/* Required for OpenDingux IPU filter setting */
/* Required for OpenDingux IPU filter + refresh
* rate settings */
#if defined(DINGUX)
#include "dingux/dingux_utils.h"
#endif
/* Required for menu screensaver animation */
#if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
#include "menu/menu_screensaver.h"
#endif
#if defined(HW_RVL)
#define MAX_GAMMA_SETTING 30
#elif defined(GEKKO)
@@ -62,6 +68,8 @@
#define DEFAULT_MOUSE_SCALE 1
#endif
#define DEFAULT_TOUCH_SCALE 1
#if defined(RARCH_MOBILE) || defined(HAVE_LIBNX) || defined(__WINRT__)
#define DEFAULT_POINTER_ENABLE true
#else
@@ -381,6 +389,11 @@
/* Sets image filtering method when using the
* IPU hardware scaler in Dingux devices */
#define DEFAULT_DINGUX_IPU_FILTER_TYPE DINGUX_IPU_FILTER_BICUBIC
#if defined(DINGUX_BETA)
/* Sets refresh rate of integral LCD panel
* in Dingux devices */
#define DEFAULT_DINGUX_REFRESH_RATE DINGUX_REFRESH_RATE_60HZ
#endif
#endif
/* Save configuration file on exit. */
@@ -574,6 +587,19 @@ static const bool menu_savestate_resume = false;
#define DEFAULT_QUIT_ON_CLOSE_CONTENT QUIT_ON_CLOSE_CONTENT_DISABLED
/* While the menu is active, supported drivers
* will display a screensaver after SCREENSAVER_TIMEOUT
* seconds of inactivity. A timeout of zero disables
* the screensaver */
#define DEFAULT_MENU_SCREENSAVER_TIMEOUT 0
#if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
/* When menu screensaver is enabled, specifies
* animation effect and animation speed */
#define DEFAULT_MENU_SCREENSAVER_ANIMATION MENU_SCREENSAVER_BLANK
#define DEFAULT_MENU_SCREENSAVER_ANIMATION_SPEED 1.0f
#endif
static const bool content_show_settings = true;
static const bool content_show_favorites = true;
#ifdef HAVE_IMAGEVIEWER
@@ -643,6 +669,7 @@ static const float menu_header_opacity = 1.000;
#define DEFAULT_SHOW_ADVANCED_SETTINGS false
#define DEFAULT_RGUI_COLOR_THEME RGUI_THEME_CLASSIC_GREEN
#define DEFAULT_RGUI_TRANSPARENCY true
static const bool rgui_inline_thumbnails = false;
static const bool rgui_swap_thumbnails = false;
@@ -655,6 +682,7 @@ static const unsigned rgui_aspect_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
static const bool rgui_shadows = false;
static const unsigned rgui_particle_effect = RGUI_PARTICLE_EFFECT_NONE;
#define DEFAULT_RGUI_PARTICLE_EFFECT_SPEED 1.0f
#define DEFAULT_RGUI_PARTICLE_EFFECT_SCREENSAVER true
static const bool rgui_extended_ascii = false;
#define DEFAULT_RGUI_SWITCH_ICONS true
#endif
@@ -838,6 +866,10 @@ static const bool audio_enable_menu_bgm = false;
* applied */
#define DEFAULT_NOTIFICATION_SHOW_CHEATS_APPLIED true
/* Display a notification when applying an
* IPS/BPS/UPS patch file */
#define DEFAULT_NOTIFICATION_SHOW_PATCH_APPLIED true
/* Display a notification when loading an
* input remap file */
#define DEFAULT_NOTIFICATION_SHOW_REMAP_LOAD true
@@ -866,8 +898,15 @@ static const bool audio_enable_menu_bgm = false;
#define DEFAULT_NOTIFICATION_SHOW_SCREENSHOT_FLASH 0
#endif
/*Display a notification when setting the refresh rate*/
/* Display a notification when setting the refresh rate*/
#if defined(_3DS) || (defined(DINGUX) && defined(DINGUX_BETA))
/* 3DS and OpenDingux Beta devices set refresh rate
* on gfx driver init - set default notification
* state to 'false' in order to avoid OSD log spam */
#define DEFAULT_NOTIFICATION_SHOW_REFRESH_RATE false
#else
#define DEFAULT_NOTIFICATION_SHOW_REFRESH_RATE true
#endif
/* Output samplerate. */
#ifdef GEKKO
@@ -975,7 +1014,7 @@ static const bool audio_enable_menu_bgm = false;
/* Saves non-volatile SRAM at a regular interval.
* It is measured in seconds. A value of 0 disables autosave. */
#if defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN32) || defined(OSX) || defined(ANDROID) || defined(IOS)
#if defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(__x86_64__) || defined(_M_X64) || defined(_WIN32) || defined(OSX) || defined(ANDROID) || defined(IOS) || defined(DINGUX)
/* Flush to file every 10 seconds on modern platforms by default */
#define DEFAULT_AUTOSAVE_INTERVAL 10
#else
+190 -179
View File
@@ -661,10 +661,6 @@ static void config_parse_file(global_t *global);
struct defaults g_defaults;
/* TODO/FIXME - static public global variables */
static unsigned old_analog_dpad_mode[MAX_USERS];
static unsigned old_libretro_device[MAX_USERS];
/**
* config_get_default_audio:
*
@@ -1189,6 +1185,47 @@ const char *config_get_midi_driver_options(void)
return char_list_new_special(STRING_LIST_MIDI_DRIVERS, NULL);
}
#ifdef HAVE_LAKKA
void config_set_timezone(char *timezone)
{
setenv("TZ", timezone, 1);
tzset();
}
const char *config_get_all_timezones(void)
{
return char_list_new_special(STRING_LIST_TIMEZONES, NULL);
}
static void load_timezone(char *setting)
{
char haystack[TIMEZONE_LENGTH+32];
static char *needle = "TIMEZONE=";
size_t needle_len = strlen(needle);
RFILE *tzfp = filestream_open(LAKKA_TIMEZONE_PATH,
RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
if (tzfp != NULL)
{
filestream_gets(tzfp, haystack, sizeof(haystack)-1);
filestream_close(tzfp);
char *start = strstr(haystack, needle);
if (start != NULL)
snprintf(setting, TIMEZONE_LENGTH, "%s", start + needle_len);
else
snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
}
else
snprintf(setting, TIMEZONE_LENGTH, "%s", DEFAULT_TIMEZONE);
config_set_timezone(setting);
}
#endif
bool config_overlay_enable_default(void)
{
if (g_defaults.overlay_set)
@@ -1506,6 +1543,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("menu_show_load_content_animation", &settings->bools.menu_show_load_content_animation, true, DEFAULT_MENU_SHOW_LOAD_CONTENT_ANIMATION, false);
SETTING_BOOL("notification_show_autoconfig", &settings->bools.notification_show_autoconfig, true, DEFAULT_NOTIFICATION_SHOW_AUTOCONFIG, false);
SETTING_BOOL("notification_show_cheats_applied", &settings->bools.notification_show_cheats_applied, true, DEFAULT_NOTIFICATION_SHOW_CHEATS_APPLIED, false);
SETTING_BOOL("notification_show_patch_applied", &settings->bools.notification_show_patch_applied, true, DEFAULT_NOTIFICATION_SHOW_PATCH_APPLIED, false);
SETTING_BOOL("notification_show_remap_load", &settings->bools.notification_show_remap_load, true, DEFAULT_NOTIFICATION_SHOW_REMAP_LOAD, false);
SETTING_BOOL("notification_show_config_override_load", &settings->bools.notification_show_config_override_load, true, DEFAULT_NOTIFICATION_SHOW_CONFIG_OVERRIDE_LOAD, false);
SETTING_BOOL("notification_show_set_initial_disk", &settings->bools.notification_show_set_initial_disk, true, DEFAULT_NOTIFICATION_SHOW_SET_INITIAL_DISK, false);
@@ -1670,12 +1708,14 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false);
SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false);
SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false);
SETTING_BOOL("menu_rgui_transparency", &settings->bools.menu_rgui_transparency, true, DEFAULT_RGUI_TRANSPARENCY, false);
SETTING_BOOL("menu_rgui_shadows", &settings->bools.menu_rgui_shadows, true, rgui_shadows, false);
SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false);
SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false);
SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false);
SETTING_BOOL("rgui_extended_ascii", &settings->bools.menu_rgui_extended_ascii, true, rgui_extended_ascii, false);
SETTING_BOOL("rgui_switch_icons", &settings->bools.menu_rgui_switch_icons, true, DEFAULT_RGUI_SWITCH_ICONS, false);
SETTING_BOOL("rgui_particle_effect_screensaver", &settings->bools.menu_rgui_particle_effect_screensaver, true, DEFAULT_RGUI_PARTICLE_EFFECT_SCREENSAVER, false);
#endif
#ifdef HAVE_XMB
SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, DEFAULT_XMB_SHADOWS_ENABLE, false);
@@ -1842,6 +1882,9 @@ static struct config_float_setting *populate_settings_float(
SETTING_FLOAT("menu_header_opacity", &settings->floats.menu_header_opacity, true, menu_header_opacity, false);
SETTING_FLOAT("menu_ticker_speed", &settings->floats.menu_ticker_speed, true, menu_ticker_speed, false);
SETTING_FLOAT("rgui_particle_effect_speed", &settings->floats.menu_rgui_particle_effect_speed, true, DEFAULT_RGUI_PARTICLE_EFFECT_SPEED, false);
#if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
SETTING_FLOAT("menu_screensaver_animation_speed", &settings->floats.menu_screensaver_animation_speed, true, DEFAULT_MENU_SCREENSAVER_ANIMATION_SPEED, false);
#endif
#endif
SETTING_FLOAT("video_message_pos_x", &settings->floats.video_msg_pos_x, true, message_pos_offset_x, false);
SETTING_FLOAT("video_message_pos_y", &settings->floats.video_msg_pos_y, true, message_pos_offset_y, false);
@@ -1887,6 +1930,7 @@ static struct config_uint_setting *populate_settings_uint(
#ifdef GEKKO
SETTING_UINT("input_mouse_scale", &settings->uints.input_mouse_scale, true, DEFAULT_MOUSE_SCALE, false);
#endif
SETTING_UINT("input_touch_scale", &settings->uints.input_touch_scale, true, DEFAULT_TOUCH_SCALE, false);
#if defined(DINGUX) && defined(HAVE_LIBSHAKE)
SETTING_UINT("input_dingux_rumble_gain", &settings->uints.input_dingux_rumble_gain, true, DEFAULT_DINGUX_RUMBLE_GAIN, false);
#endif
@@ -1933,6 +1977,10 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("menu_ticker_type", &settings->uints.menu_ticker_type, true, DEFAULT_MENU_TICKER_TYPE, false);
SETTING_UINT("menu_scroll_delay", &settings->uints.menu_scroll_delay, true, DEFAULT_MENU_SCROLL_DELAY, false);
SETTING_UINT("content_show_add_entry", &settings->uints.menu_content_show_add_entry, true, DEFAULT_MENU_CONTENT_SHOW_ADD_ENTRY, false);
SETTING_UINT("menu_screensaver_timeout", &settings->uints.menu_screensaver_timeout, true, DEFAULT_MENU_SCREENSAVER_TIMEOUT, false);
#if defined(HAVE_MATERIALUI) || defined(HAVE_XMB) || defined(HAVE_OZONE)
SETTING_UINT("menu_screensaver_animation", &settings->uints.menu_screensaver_animation, true, DEFAULT_MENU_SCREENSAVER_ANIMATION, false);
#endif
#ifdef HAVE_RGUI
SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, DEFAULT_RGUI_COLOR_THEME, false);
SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
@@ -2046,6 +2094,9 @@ static struct config_uint_setting *populate_settings_uint(
#if defined(DINGUX)
SETTING_UINT("video_dingux_ipu_filter_type", &settings->uints.video_dingux_ipu_filter_type, true, DEFAULT_DINGUX_IPU_FILTER_TYPE, false);
#if defined(DINGUX_BETA)
SETTING_UINT("video_dingux_refresh_rate", &settings->uints.video_dingux_refresh_rate, true, DEFAULT_DINGUX_REFRESH_RATE, false);
#endif
#endif
#ifdef HAVE_MENU
@@ -2120,10 +2171,8 @@ static struct config_int_setting *populate_settings_int(
return tmp;
}
static void video_driver_default_settings(void)
static void video_driver_default_settings(global_t *global)
{
global_t *global = global_get_ptr();
if (!global)
return;
@@ -2340,6 +2389,7 @@ void config_set_defaults(void *data)
configuration_set_bool(settings,
settings->bools.bluetooth_enable, filestream_exists(LAKKA_BLUETOOTH_PATH));
configuration_set_bool(settings, settings->bools.localap_enable, false);
load_timezone(settings->arrays.timezone);
#endif
#ifdef HAVE_MENU
@@ -2357,7 +2407,8 @@ void config_set_defaults(void *data)
input_config_reset();
#ifdef HAVE_CONFIGFILE
input_remapping_set_defaults(true);
input_remapping_deinit();
input_remapping_set_defaults();
#endif
/* Verify that binds are in proper order. */
@@ -2467,7 +2518,7 @@ void config_set_defaults(void *data)
*settings->paths.log_dir = '\0';
video_driver_default_settings();
video_driver_default_settings(global);
if (!string_is_empty(g_defaults.dirs[DEFAULT_DIR_WALLPAPERS]))
configuration_set_string(settings,
@@ -2927,13 +2978,10 @@ error:
}
#ifdef RARCH_CONSOLE
static void video_driver_load_settings(config_file_t *conf)
static void video_driver_load_settings(global_t *global,
config_file_t *conf)
{
bool tmp_bool = false;
global_t *global = global_get_ptr();
if (!conf)
return;
CONFIG_GET_INT_BASE(conf, global,
console.screen.gamma_correction, "gamma_correction");
@@ -3186,7 +3234,8 @@ static bool config_load_file(global_t *global,
settings->paths.directory_libretro, tmp_str);
#ifdef RARCH_CONSOLE
video_driver_load_settings(conf);
if (conf)
video_driver_load_settings(global, conf);
#endif
/* Post-settings load */
@@ -3717,7 +3766,7 @@ bool config_unload_override(void)
bool config_load_remap(const char *directory_input_remapping,
void *data)
{
char content_dir_name[PATH_MAX_LENGTH];
char content_dir_name[PATH_MAX_LENGTH] = { 0 };
/* path to the directory containing retroarch.cfg (prefix) */
char remap_directory[PATH_MAX_LENGTH];
/* final path for core-specific configuration (prefix+suffix) */
@@ -3773,14 +3822,17 @@ bool config_load_remap(const char *directory_input_remapping,
sizeof(game_path));
#ifdef HAVE_CONFIGFILE
input_remapping_set_defaults(false);
input_remapping_set_defaults();
#endif
/* If a game remap file exists, load it. */
if ((new_conf = config_file_new_from_path_to_string(game_path)))
{
bool ret = input_remapping_load_file(new_conf, game_path);
config_file_free(new_conf);
new_conf = NULL;
RARCH_LOG("[Remaps]: Game-specific remap found at \"%s\".\n", game_path);
if (input_remapping_load_file(new_conf, game_path))
if (ret)
{
rarch_ctl(RARCH_CTL_SET_REMAPS_GAME_ACTIVE, NULL);
/* msg_remap_loaded is set to MSG_GAME_REMAP_FILE_LOADED
@@ -3792,8 +3844,11 @@ bool config_load_remap(const char *directory_input_remapping,
/* If a content-dir remap file exists, load it. */
if ((new_conf = config_file_new_from_path_to_string(content_path)))
{
bool ret = input_remapping_load_file(new_conf, content_path);
config_file_free(new_conf);
new_conf = NULL;
RARCH_LOG("[Remaps]: Content-dir-specific remap found at \"%s\".\n", content_path);
if (input_remapping_load_file(new_conf, content_path))
if (ret)
{
rarch_ctl(RARCH_CTL_SET_REMAPS_CONTENT_DIR_ACTIVE, NULL);
msg_remap_loaded = MSG_DIRECTORY_REMAP_FILE_LOADED;
@@ -3804,8 +3859,11 @@ bool config_load_remap(const char *directory_input_remapping,
/* If a core remap file exists, load it. */
if ((new_conf = config_file_new_from_path_to_string(core_path)))
{
bool ret = input_remapping_load_file(new_conf, core_path);
config_file_free(new_conf);
new_conf = NULL;
RARCH_LOG("[Remaps]: Core-specific remap found at \"%s\".\n", core_path);
if (input_remapping_load_file(new_conf, core_path))
if (ret)
{
rarch_ctl(RARCH_CTL_SET_REMAPS_CORE_ACTIVE, NULL);
msg_remap_loaded = MSG_CORE_REMAP_FILE_LOADED;
@@ -3813,6 +3871,8 @@ bool config_load_remap(const char *directory_input_remapping,
}
}
if (new_conf)
config_file_free(new_conf);
new_conf = NULL;
return false;
@@ -3850,12 +3910,8 @@ static void config_parse_file(global_t *global)
}
}
static void video_driver_save_settings(config_file_t *conf)
static void video_driver_save_settings(global_t *global, config_file_t *conf)
{
global_t *global = global_get_ptr();
if (!conf)
return;
config_set_int(conf, "gamma_correction",
global->console.screen.gamma_correction);
config_set_bool(conf, "flicker_filter_enable",
@@ -3940,23 +3996,11 @@ bool config_save_autoconf_profile(const
fill_pathname_join(buf, autoconf_dir, joypad_driver, sizeof(buf));
if (path_is_directory(buf))
{
char buf_new[PATH_MAX_LENGTH];
buf_new[0] = '\0';
fill_pathname_join(buf_new, buf,
sanitised_name, sizeof(buf_new));
fill_pathname_noext(autoconf_file,
buf_new, ".cfg", sizeof(autoconf_file));
}
fill_pathname_join_concat(autoconf_file, buf,
sanitised_name, ".cfg", sizeof(autoconf_file));
else
{
fill_pathname_join(buf, autoconf_dir,
sanitised_name, sizeof(buf));
fill_pathname_noext(autoconf_file,
buf, ".cfg", sizeof(autoconf_file));
}
fill_pathname_join_concat(autoconf_file, autoconf_dir,
sanitised_name, ".cfg", sizeof(autoconf_file));
/* Open config file */
conf = config_file_new_from_path_to_string(autoconf_file);
@@ -4029,6 +4073,7 @@ bool config_save_file(const char *path)
struct config_path_setting *path_settings = NULL;
config_file_t *conf = config_file_new_from_path_to_string(path);
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
int bool_settings_size = sizeof(settings->bools) / sizeof(settings->bools.placeholder);
int float_settings_size = sizeof(settings->floats)/ sizeof(settings->floats.placeholder);
int int_settings_size = sizeof(settings->ints) / sizeof(settings->ints.placeholder);
@@ -4196,7 +4241,8 @@ bool config_save_file(const char *path)
/* Hexadecimal settings */
config_set_hex(conf, "video_message_color", msg_color);
video_driver_save_settings(conf);
if (conf)
video_driver_save_settings(global, conf);
#ifdef HAVE_LAKKA
if (settings->bools.ssh_enable)
@@ -4512,33 +4558,32 @@ bool config_replace(bool config_replace_save_on_exit, char *path)
**/
bool input_remapping_load_file(void *data, const char *path)
{
unsigned i, j, k;
config_file_t *conf = (config_file_t*)data;
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
unsigned i, j;
config_file_t *conf = (config_file_t*)data;
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][8] = {
"b", "y", "select", "start",
"up", "down", "left", "right",
"a", "x", "l", "r", "l2", "r2",
"l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
if (!conf || string_is_empty(path))
if (!conf || string_is_empty(path))
return false;
if (!string_is_empty(global->name.remapfile))
input_remapping_set_defaults(true);
{
input_remapping_deinit();
input_remapping_set_defaults();
}
global->name.remapfile = strdup(path);
for (i = 0; i < MAX_USERS; i++)
{
char s1[64], s2[64], s3[64];
char btn_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}};
char key_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}};
char stk_ident[8][4096] = {{0}};
char s1[32], s2[32], s3[32];
char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = {
"b", "y", "select", "start",
"up", "down", "left", "right",
"a", "x", "l", "r", "l2", "r2",
"l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
old_analog_dpad_mode[i] = settings->uints.input_analog_dpad_mode[i];
old_libretro_device[i] = settings->uints.input_libretro_device[i];
global->old_analog_dpad_mode[i] = settings->uints.input_analog_dpad_mode[i];
global->old_libretro_device[i] = settings->uints.input_libretro_device[i];
s1[0] = '\0';
s2[0] = '\0';
@@ -4550,49 +4595,57 @@ bool input_remapping_load_file(void *data, const char *path)
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
{
const char *key_string = key_strings[j];
if (j < RARCH_FIRST_CUSTOM_BIND)
{
int btn_remap = -1;
int key_remap = -1;
char btn_ident[128];
char key_ident[128];
btn_ident[0] = key_ident[0] = '\0';
fill_pathname_join_delim(btn_ident[j], s1,
key_strings[j], '_', sizeof(btn_ident[j]));
fill_pathname_join_delim(key_ident[j], s2,
key_strings[j], '_', sizeof(btn_ident[j]));
fill_pathname_join_delim(btn_ident, s1,
key_string, '_', sizeof(btn_ident));
fill_pathname_join_delim(key_ident, s2,
key_string, '_', sizeof(key_ident));
if (config_get_int(conf, btn_ident[j], &btn_remap))
if (config_get_int(conf, btn_ident, &btn_remap))
{
if (btn_remap == -1)
btn_remap = RARCH_UNMAPPED;
btn_remap = RARCH_UNMAPPED;
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], btn_remap);
}
if (!config_get_int(conf, key_ident[j], &key_remap))
key_remap = RETROK_UNKNOWN;
if (!config_get_int(conf, key_ident, &key_remap))
key_remap = RETROK_UNKNOWN;
configuration_set_uint(settings,
settings->uints.input_keymapper_ids[i][j], key_remap);
}
else
{
char stk_ident[128];
int stk_remap = -1;
k = j - RARCH_FIRST_CUSTOM_BIND;
stk_ident[0] = '\0';
fill_pathname_join_delim(stk_ident[k], s3,
key_strings[j], '$', sizeof(stk_ident[k]));
fill_pathname_join_delim(stk_ident, s3,
key_string, '$', sizeof(stk_ident));
snprintf(stk_ident[k],
sizeof(stk_ident[k]),
snprintf(stk_ident,
sizeof(stk_ident),
"%s_%s",
s3,
key_strings[j]);
key_string);
if (config_get_int(conf, stk_ident[k], &stk_remap))
if (config_get_int(conf, stk_ident, &stk_remap))
{
if (stk_remap == -1)
stk_remap = RARCH_UNMAPPED;
stk_remap = RARCH_UNMAPPED;
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], stk_remap);
@@ -4607,8 +4660,6 @@ bool input_remapping_load_file(void *data, const char *path)
CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], s1);
}
config_file_free(conf);
return true;
}
@@ -4623,19 +4674,23 @@ bool input_remapping_load_file(void *data, const char *path)
bool input_remapping_save_file(const char *path)
{
bool ret;
unsigned i, j, k;
char buf[PATH_MAX_LENGTH];
unsigned i, j;
char remap_file[PATH_MAX_LENGTH];
char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][8] = {
"b", "y", "select", "start",
"up", "down", "left", "right",
"a", "x", "l", "r", "l2", "r2",
"l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
config_file_t *conf = NULL;
unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS));
settings_t *settings = config_get_ptr();
const char *dir_input_remapping = settings->paths.directory_input_remapping;
buf[0] = remap_file[0] = '\0';
remap_file[0] = '\0';
fill_pathname_join(buf, dir_input_remapping, path, sizeof(buf));
fill_pathname_noext(remap_file, buf,
FILE_PATH_REMAP_EXTENSION, sizeof(remap_file));
fill_pathname_join_concat(remap_file, dir_input_remapping, path,
FILE_PATH_REMAP_EXTENSION,
sizeof(remap_file));
if (!(conf = config_file_new_from_path_to_string(remap_file)))
{
@@ -4645,62 +4700,68 @@ bool input_remapping_save_file(const char *path)
for (i = 0; i < max_users; i++)
{
char s1[64], s2[64], s3[64];
char btn_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}};
char key_ident[RARCH_FIRST_CUSTOM_BIND][128] = {{0}};
char stk_ident[8][128] = {{0}};
char key_strings[RARCH_FIRST_CUSTOM_BIND + 8][128] = {
"b", "y", "select", "start",
"up", "down", "left", "right",
"a", "x", "l", "r", "l2", "r2",
"l3", "r3", "l_x+", "l_x-", "l_y+", "l_y-", "r_x+", "r_x-", "r_y+", "r_y-" };
char s1[32], s2[32], s3[32];
s1[0] = '\0';
s2[0] = '\0';
s3[0] = '\0';
snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
snprintf(s3, sizeof(s1), "input_player%u_stk", i + 1);
snprintf(s3, sizeof(s3), "input_player%u_stk", i + 1);
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
{
unsigned remap_id = settings->uints.input_remap_ids[i][j];
unsigned keymap_id = settings->uints.input_keymapper_ids[i][j];
char btn_ident[128];
unsigned remap_id = settings->uints.input_remap_ids[i][j];
unsigned keymap_id = settings->uints.input_keymapper_ids[i][j];
const char *key_string = key_strings[j];
btn_ident[0] = '\0';
fill_pathname_join_delim(btn_ident, s1,
key_string, '_', sizeof(btn_ident));
if (j < RARCH_FIRST_CUSTOM_BIND)
{
fill_pathname_join_delim(btn_ident[j], s1,
key_strings[j], '_', sizeof(btn_ident[j]));
fill_pathname_join_delim(key_ident[j], s2,
key_strings[j], '_', sizeof(btn_ident[j]));
/* only save values that have been modified */
if (remap_id != j && remap_id != RARCH_UNMAPPED)
config_set_int(conf, btn_ident[j],
settings->uints.input_remap_ids[i][j]);
else if (remap_id != j && remap_id == RARCH_UNMAPPED)
config_set_int(conf, btn_ident[j], -1);
else
config_unset(conf, btn_ident[j]);
if (keymap_id != RETROK_UNKNOWN)
config_set_int(conf, key_ident[j],
settings->uints.input_keymapper_ids[i][j]);
}
/* only save values that have been modified */
if (remap_id == j)
config_unset(conf, btn_ident);
else
{
k = j - RARCH_FIRST_CUSTOM_BIND;
fill_pathname_join_delim(stk_ident[k], s3,
key_strings[j], '_', sizeof(stk_ident[k]));
if (remap_id != j && remap_id != RARCH_UNMAPPED)
config_set_int(conf, stk_ident[k],
settings->uints.input_remap_ids[i][j]);
else if (remap_id != j && remap_id == RARCH_UNMAPPED)
config_set_int(conf, stk_ident[k],
if (remap_id == RARCH_UNMAPPED)
config_set_int(conf, btn_ident, -1);
else
config_set_int(conf, btn_ident,
settings->uints.input_remap_ids[i][j]);
}
if (keymap_id != RETROK_UNKNOWN)
{
char key_ident[128];
key_ident[0] = '\0';
fill_pathname_join_delim(key_ident, s2,
key_string, '_', sizeof(key_ident));
config_set_int(conf, key_ident,
settings->uints.input_keymapper_ids[i][j]);
}
}
for (j = RARCH_FIRST_CUSTOM_BIND; j < (RARCH_FIRST_CUSTOM_BIND + 8); j++)
{
char stk_ident[128];
unsigned remap_id = settings->uints.input_remap_ids[i][j];
const char *key_string = key_strings[j];
stk_ident[0] = '\0';
fill_pathname_join_delim(stk_ident, s3,
key_string, '_', sizeof(stk_ident));
if (remap_id == j)
config_unset(conf, stk_ident);
else
{
if (remap_id == RARCH_UNMAPPED)
config_set_int(conf, stk_ident,
-1);
else
config_unset(conf, stk_ident[k]);
config_set_int(conf, stk_ident,
settings->uints.input_remap_ids[i][j]);
}
}
@@ -4719,63 +4780,13 @@ bool input_remapping_save_file(const char *path)
bool input_remapping_remove_file(const char *path,
const char *dir_input_remapping)
{
char buf[PATH_MAX_LENGTH];
char remap_file[PATH_MAX_LENGTH];
buf[0] = remap_file[0] = '\0';
fill_pathname_join(buf, dir_input_remapping, path, sizeof(buf));
fill_pathname_noext(remap_file, buf,
remap_file[0] = '\0';
fill_pathname_join_concat(remap_file, dir_input_remapping, path,
FILE_PATH_REMAP_EXTENSION,
sizeof(remap_file));
return filestream_delete(remap_file) == 0 ? true : false;
}
void input_remapping_set_defaults(bool deinit)
{
unsigned i, j;
settings_t *settings = config_get_ptr();
global_t *global = global_get_ptr();
if (!global)
return;
if (deinit)
{
if (!string_is_empty(global->name.remapfile))
free(global->name.remapfile);
global->name.remapfile = NULL;
rarch_ctl(RARCH_CTL_UNSET_REMAPS_CORE_ACTIVE, NULL);
rarch_ctl(RARCH_CTL_UNSET_REMAPS_CONTENT_DIR_ACTIVE, NULL);
rarch_ctl(RARCH_CTL_UNSET_REMAPS_GAME_ACTIVE, NULL);
}
for (i = 0; i < MAX_USERS; i++)
{
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND + 8; j++)
{
if (j < RARCH_FIRST_CUSTOM_BIND)
{
const struct retro_keybind *keybind = &input_config_binds[i][j];
if (keybind)
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], keybind->id);
configuration_set_uint(settings,
settings->uints.input_keymapper_ids[i][j], RETROK_UNKNOWN);
}
else
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], j);
}
if (old_analog_dpad_mode[i])
configuration_set_uint(settings,
settings->uints.input_analog_dpad_mode[i], old_analog_dpad_mode[i]);
if (old_libretro_device[i])
configuration_set_uint(settings,
settings->uints.input_libretro_device[i], old_libretro_device[i]);
}
}
#endif
#if !defined(HAVE_DYNAMIC)
+20
View File
@@ -29,6 +29,10 @@
#include "input/input_defines.h"
#include "led/led_defines.h"
#ifdef HAVE_LAKKA
#include "lakka.h"
#endif
#define configuration_set_float(settings, var, newvar) \
{ \
settings->modified = true; \
@@ -151,6 +155,7 @@ typedef struct settings
#ifdef GEKKO
unsigned input_mouse_scale;
#endif
unsigned input_touch_scale;
unsigned input_hotkey_block_delay;
unsigned input_menu_toggle_gamepad_combo;
unsigned input_keyboard_gamepad_mapping_type;
@@ -200,6 +205,7 @@ typedef struct settings
unsigned video_stream_scale_factor;
unsigned video_3ds_display_mode;
unsigned video_dingux_ipu_filter_type;
unsigned video_dingux_refresh_rate;
#ifdef HAVE_VIDEO_LAYOUT
unsigned video_layout_selected_view;
#endif
@@ -249,6 +255,8 @@ typedef struct settings
unsigned menu_ticker_type;
unsigned menu_scroll_delay;
unsigned menu_content_show_add_entry;
unsigned menu_screensaver_timeout;
unsigned menu_screensaver_animation;
unsigned playlist_entry_remove_enable;
unsigned playlist_show_inline_core_name;
@@ -306,6 +314,7 @@ typedef struct settings
float menu_header_opacity;
float menu_ticker_speed;
float menu_rgui_particle_effect_speed;
float menu_screensaver_animation_speed;
float audio_max_timing_skew;
float audio_volume; /* dB scale. */
@@ -376,6 +385,9 @@ typedef struct settings
char ai_service_url[PATH_MAX_LENGTH];
char crt_switch_timings[255];
#ifdef HAVE_LAKKA
char timezone[TIMEZONE_LENGTH];
#endif
} arrays;
struct
@@ -547,6 +559,7 @@ typedef struct settings
bool menu_show_load_content_animation;
bool notification_show_autoconfig;
bool notification_show_cheats_applied;
bool notification_show_patch_applied;
bool notification_show_remap_load;
bool notification_show_config_override_load;
bool notification_show_set_initial_disk;
@@ -605,11 +618,13 @@ typedef struct settings
bool menu_rgui_border_filler_thickness_enable;
bool menu_rgui_border_filler_enable;
bool menu_rgui_full_width_layout;
bool menu_rgui_transparency;
bool menu_rgui_shadows;
bool menu_rgui_inline_thumbnails;
bool menu_rgui_swap_thumbnails;
bool menu_rgui_extended_ascii;
bool menu_rgui_switch_icons;
bool menu_rgui_particle_effect_screensaver;
bool menu_xmb_shadows_enable;
bool menu_xmb_vertical_thumbnails;
bool menu_content_show_settings;
@@ -1004,6 +1019,11 @@ void config_save_file_salamander(void);
settings_t *config_get_ptr(void);
#ifdef HAVE_LAKKA
const char *config_get_all_timezones(void);
void config_set_timezone(char *timezone);
#endif
RETRO_END_DECLS
#endif
+438 -525
View File
File diff suppressed because it is too large. Load diff
+13 -35
View File
@@ -45,25 +45,19 @@ typedef struct
/* Simple container/convenience struct for
* holding the 'id' of a core file
* > 'id' is the filename without extension or
* > 'str' is the filename without extension or
* platform-specific suffix
* > 'id' is used for core info searches - enables
* matching regardless of core file base path,
* and is platform-independent (e.g. an Android
* core file will be correctly identified on Linux)
* > 'len' is used to cache the length of 'str', for
* improved performance when performing string
* comparisons */
* > 'hash' is a hash key used for efficient core
* list searches */
typedef struct
{
char *str;
size_t len;
uint32_t hash;
} core_file_id_t;
typedef struct
{
char *path;
void *config_data;
char *display_name;
char *display_version;
char *core_name;
@@ -89,8 +83,8 @@ typedef struct
struct string_list *required_hw_api_list;
core_info_firmware_t *firmware;
core_file_id_t core_file_id; /* ptr alignment */
void *userdata;
size_t firmware_count;
bool has_info;
bool supports_no_game;
bool database_match_archive_member;
bool is_experimental;
@@ -112,6 +106,7 @@ typedef struct
core_info_t *list;
char *all_ext;
size_t count;
size_t info_count;
} core_info_list_t;
typedef struct core_info_ctx_firmware
@@ -123,12 +118,6 @@ typedef struct core_info_ctx_firmware
} directory;
} core_info_ctx_firmware_t;
typedef struct core_info_ctx_find
{
core_info_t *inf;
const char *path;
} core_info_ctx_find_t;
struct core_info_state
{
#ifdef HAVE_COMPRESSION
@@ -141,30 +130,21 @@ struct core_info_state
typedef struct core_info_state core_info_state_t;
size_t core_info_list_num_info_files(core_info_list_t *list);
/* Non-reentrant, does not allocate. Returns pointer to internal state. */
void core_info_list_get_supported_cores(core_info_list_t *list,
const char *path, const core_info_t **infos, size_t *num_infos);
bool core_info_list_get_display_name(core_info_list_t *list,
const char *path, char *s, size_t len);
bool core_info_get_display_name(const char *path, char *s, size_t len);
const char *core_path, char *s, size_t len);
/* Returns core_info parameters required for
* core updater tasks, read from specified file.
* Returned core_updater_info_t object must be
* freed using core_info_free_core_updater_info().
* Returns NULL if 'path' is invalid. */
core_updater_info_t *core_info_get_core_updater_info(const char *path);
core_updater_info_t *core_info_get_core_updater_info(const char *info_path);
void core_info_free_core_updater_info(core_updater_info_t *info);
void core_info_get_name(const char *path, char *s, size_t len,
const char *path_info, const char *dir_cores,
const char *exts, bool show_hidden_files,
bool get_display_name);
core_info_t *core_info_get(core_info_list_t *list, size_t i);
void core_info_free_current_core(core_info_state_t *p_coreinfo);
@@ -186,22 +166,20 @@ size_t core_info_count(void);
bool core_info_list_update_missing_firmware(core_info_ctx_firmware_t *info,
bool *set_missing_bios);
bool core_info_find(core_info_ctx_find_t *info);
bool core_info_find(const char *core_path,
core_info_t **core_info);
bool core_info_load(
core_info_ctx_find_t *info,
bool core_info_load(const char *core_path,
core_info_state_t *p_coreinfo);
bool core_info_database_supports_content_path(const char *database_path, const char *path);
bool core_info_database_match_archive_member(const char *database_path);
bool core_info_unsupported_content_path(const char *path);
void core_info_qsort(core_info_list_t *core_info_list, enum core_info_list_qsort_type qsort_type);
bool core_info_list_get_info(core_info_list_t *core_info_list,
core_info_t *out_info, const char *path);
core_info_t *out_info, const char *core_path);
bool core_info_hw_api_supported(core_info_t *info);
@@ -223,7 +201,7 @@ bool core_info_get_core_lock(const char *core_path, bool validate_path);
core_info_state_t *coreinfo_get_ptr(void);
bool core_info_core_file_id_is_equal(const char* core_path_a, const char* core_path_b);
bool core_info_core_file_id_is_equal(const char *core_path_a, const char *core_path_b);
RETRO_END_DECLS
+3 -1
View File
@@ -37,7 +37,9 @@ int database_info_build_query_enum(char *s, size_t len,
bool add_quotes = true;
bool add_glob = false;
strcpy_literal(s, "{'");
s[0] = '{';
s[1] = '\'';
s[2] = '\0';
switch (type)
{
+128 -133
View File
@@ -1,132 +1,157 @@
/* 7z.h -- 7z interface
2010-03-11 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
#include "7zBuf.h"
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
extern uint8_t k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0
enum EIdEnum
{
k7zIdEnd,
k7zIdHeader,
k7zIdArchiveProperties,
k7zIdAdditionalStreamsInfo,
k7zIdMainStreamsInfo,
k7zIdFilesInfo,
k7zIdPackInfo,
k7zIdUnpackInfo,
k7zIdSubStreamsInfo,
k7zIdSize,
k7zIdCRC,
k7zIdFolder,
k7zIdCodersUnpackSize,
k7zIdNumUnpackStream,
k7zIdEmptyStream,
k7zIdEmptyFile,
k7zIdAnti,
k7zIdName,
k7zIdCTime,
k7zIdATime,
k7zIdMTime,
k7zIdWinAttributes,
k7zIdComment,
k7zIdEncodedHeader,
k7zIdStartPos,
k7zIdDummy
};
extern const Byte k7zSignature[k7zSignatureSize];
typedef struct
{
uint32_t NumInStreams;
uint32_t NumOutStreams;
uint64_t MethodID;
CBuf Props;
const Byte *Data;
size_t Size;
} CSzData;
/* CSzCoderInfo & CSzFolder support only default methods */
typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
void SzCoderInfo_Init(CSzCoderInfo *p);
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
} CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
uint32_t InIndex;
uint32_t OutIndex;
} CSzBindPair;
typedef struct
{
CSzCoderInfo *Coders;
CSzBindPair *BindPairs;
uint32_t *PackStreams;
uint64_t *UnpackSizes;
uint32_t NumCoders;
uint32_t NumBindPairs;
uint32_t NumPackStreams;
int UnpackCRCDefined;
uint32_t UnpackCRC;
uint32_t NumUnpackStreams;
UInt32 NumCoders;
UInt32 NumBonds;
UInt32 NumPackStreams;
UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
void SzFolder_Init(CSzFolder *p);
uint64_t SzFolder_GetUnpackSize(CSzFolder *p);
int SzFolder_FindBindPairForInStream(CSzFolder *p, uint32_t inStreamIndex);
uint32_t SzFolder_GetNumOutStreams(CSzFolder *p);
uint64_t SzFolder_GetUnpackSize(CSzFolder *p);
SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes,
ILookInStream *stream, uint64_t startPos,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain);
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct
{
uint32_t Low;
uint32_t High;
UInt32 Low;
UInt32 High;
} CNtfsFileTime;
typedef struct
{
CNtfsFileTime MTime;
uint64_t Size;
uint32_t Crc;
uint32_t Attrib;
uint8_t HasStream;
uint8_t IsDir;
uint8_t IsAnti;
uint8_t CrcDefined;
uint8_t MTimeDefined;
uint8_t AttribDefined;
} CSzFileItem;
void SzFile_Init(CSzFileItem *p);
Byte *Defs; /* MSB 0 bit numbering */
UInt32 *Vals;
} CSzBitUi32s;
typedef struct
{
uint64_t *PackSizes;
uint8_t *PackCRCsDefined;
uint32_t *PackCRCs;
CSzFolder *Folders;
CSzFileItem *Files;
uint32_t NumPackStreams;
uint32_t NumFolders;
uint32_t NumFiles;
Byte *Defs; /* MSB 0 bit numbering */
/* UInt64 *Vals; */
CNtfsFileTime *Vals;
} CSzBitUi64s;
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct
{
UInt32 NumPackStreams;
UInt32 NumFolders;
UInt64 *PackPositions; /* NumPackStreams + 1 */
CSzBitUi32s FolderCRCs; /* NumFolders */
size_t *FoCodersOffsets; /* NumFolders + 1 */
UInt32 *FoStartPackStreamIndex; /* NumFolders + 1 */
UInt32 *FoToCoderUnpackSizes; /* NumFolders + 1 */
Byte *FoToMainUnpackSizeIndex; /* NumFolders */
UInt64 *CoderUnpackSizes; /* for all coders in all folders */
Byte *CodersData;
} CSzAr;
void SzAr_Init(CSzAr *p);
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAllocPtr allocMain);
typedef struct
{
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt32 NumFiles;
UInt64 *UnpackPositions; /* NumFiles + 1 */
/* Byte *IsEmptyFiles; */
Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
/* CSzBitUi32s Parents; */
CSzBitUi64s MTime;
CSzBitUi64s CTime;
UInt32 *FolderToFile; /* NumFolders + 1 */
UInt32 *FileToFolder; /* NumFiles */
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
} CSzArEx;
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
/*
SzExtract extracts file from archive
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
@@ -138,53 +163,24 @@ void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
typedef struct
{
CSzAr db;
uint64_t startPosAfterHeader;
uint64_t dataPos;
uint32_t *FolderStartPackStreamIndex;
uint64_t *PackStreamStartPositions;
uint32_t *FolderStartFileIndex;
uint32_t *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */
CBuf FileNames; /* UTF-16-LE */
} CSzArEx;
void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
uint64_t SzArEx_GetFolderStreamPos(const CSzArEx *p, uint32_t folderIndex, uint32_t indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, uint32_t folderIndex, uint64_t *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, uint16_t *dest);
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStream *inStream,
uint32_t fileIndex, /* index of file */
uint32_t *blockIndex, /* index of solid block */
uint8_t **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
ISzAllocPtr allocMain,
ISzAllocPtr allocTemp);
/*
@@ -198,10 +194,9 @@ SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL
*/
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
+1771
View File
File diff suppressed because it is too large. Load diff
+23 -24
View File
@@ -1,37 +1,36 @@
/* 7zBuf.c -- Byte Buffer
2008-03-28
Igor Pavlov
Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include "7zBuf.h"
void Buf_Init(CBuf *p)
{
p->data = 0;
p->size = 0;
p->data = 0;
p->size = 0;
}
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
{
p->size = 0;
if (size == 0)
{
p->data = 0;
return 1;
}
p->data = (uint8_t *)alloc->Alloc(alloc, size);
if (p->data != 0)
{
p->size = size;
return 1;
}
return 0;
p->size = 0;
if (size == 0)
{
p->data = 0;
return 1;
}
p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
if (p->data)
{
p->size = size;
return 1;
}
return 0;
}
void Buf_Free(CBuf *p, ISzAlloc *alloc)
void Buf_Free(CBuf *p, ISzAllocPtr alloc)
{
alloc->Free(alloc, p->data);
p->data = 0;
p->size = 0;
ISzAlloc_Free(alloc, p->data);
p->data = 0;
p->size = 0;
}
+18 -10
View File
@@ -1,27 +1,35 @@
/* 7zBuf.h -- Byte Buffer
2009-02-07 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_BUF_H
#define __7Z_BUF_H
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
typedef struct
{
uint8_t *data;
Byte *data;
size_t size;
} CBuf;
void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
void Buf_Free(CBuf *p, ISzAlloc *alloc);
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
void Buf_Free(CBuf *p, ISzAllocPtr alloc);
#ifdef __cplusplus
}
#endif
typedef struct
{
Byte *data;
size_t size;
size_t pos;
} CDynBuf;
void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END
#endif
+106 -54
View File
@@ -1,76 +1,128 @@
/* 7zCrc.c -- CRC32 calculation
2009-11-23 : Igor Pavlov : Public domain */
/* 7zCrc.c -- CRC32 init
2017-06-06 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
#ifdef MSB_FIRST
#define CRC_NUM_TABLES 1
#ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8
#else
#define CRC_NUM_TABLES 8
#define CRC_NUM_TABLES 9
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef uint32_t (MY_FAST_CALL *CRC_FUNC)(uint32_t v, const void *data, size_t size, const uint32_t *table);
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
static CRC_FUNC g_CrcUpdate;
uint32_t g_CrcTable[256 * CRC_NUM_TABLES];
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
#if CRC_NUM_TABLES == 1
CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return g_CrcUpdate(v, data, size, g_CrcTable);
}
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
}
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
static uint32_t MY_FAST_CALL CrcUpdateT1(uint32_t v, const void *data, size_t size, const uint32_t *table)
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const uint8_t *p = (const uint8_t *)data;
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
const Byte *p = (const Byte *)data;
const Byte *pEnd = p + size;
for (; p != pEnd; p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#else
uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table);
uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table);
#endif
uint32_t MY_FAST_CALL CrcUpdate(uint32_t v, const void *data, size_t size)
void MY_FAST_CALL CrcGenerateTable()
{
return g_CrcUpdate(v, data, size, g_CrcTable);
}
UInt32 i;
for (i = 0; i < 256; i++)
{
UInt32 r = i;
unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
g_CrcTable[i] = r;
}
for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size)
{
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
}
#if CRC_NUM_TABLES < 4
g_CrcUpdate = CrcUpdateT1;
#else
#ifdef MY_CPU_LE
void MY_FAST_CALL CrcGenerateTable(void)
{
uint32_t i;
for (i = 0; i < 256; i++)
{
uint32_t r = i;
unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
#if CRC_NUM_TABLES == 1
g_CrcUpdate = CrcUpdateT1;
#else
for (; i < 256 * CRC_NUM_TABLES; i++)
{
uint32_t r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#ifdef MY_CPU_X86_OR_AMD64
g_CrcUpdate = CrcUpdateT8;
#else
g_CrcUpdate = CrcUpdateT4;
#endif
#endif
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
#ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder())
#endif
g_CrcUpdate = CrcUpdateT8;
#endif
#else
{
#ifndef MY_CPU_BE
UInt32 k = 0x01020304;
const Byte *p = (const Byte *)&k;
if (p[0] == 4 && p[1] == 3)
{
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
g_CrcUpdate = CrcUpdateT8;
#endif
}
else if (p[0] != 1 || p[1] != 2)
g_CrcUpdate = CrcUpdateT1;
else
#endif
{
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
{
UInt32 x = g_CrcTable[(size_t)i - 256];
g_CrcTable[i] = CRC_UINT32_SWAP(x);
}
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
g_CrcUpdate = CrcUpdateT1_BeT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
g_CrcUpdate = CrcUpdateT1_BeT8;
#endif
}
}
#endif
#endif
}
+6 -10
View File
@@ -1,16 +1,14 @@
/* 7zCrc.h -- CRC32 calculation
2009-11-21 : Igor Pavlov : Public domain */
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __7Z_CRC_H
#define __7Z_CRC_H
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
extern uint32_t g_CrcTable[];
extern UInt32 g_CrcTable[];
/* Call CrcGenerateTable one time before other CRC functions */
void MY_FAST_CALL CrcGenerateTable(void);
@@ -19,11 +17,9 @@ void MY_FAST_CALL CrcGenerateTable(void);
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
uint32_t MY_FAST_CALL CrcUpdate(uint32_t crc, const void *data, size_t size);
uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size);
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
+102 -25
View File
@@ -1,38 +1,115 @@
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
2009-11-23 : Igor Pavlov : Public domain */
/* 7zCrcOpt.c -- CRC32 calculation
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include "CpuArch.h"
#ifndef MSB_FIRST
#ifndef MY_CPU_BE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table);
uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table);
uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table)
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const uint8_t *p = (const uint8_t*)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const uint32_t *)p;
v =
table[0x300 + (v & 0xFF)] ^
table[0x200 + ((v >> 8) & 0xFF)] ^
table[0x100 + ((v >> 16) & 0xFF)] ^
table[0x000 + ((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
(table + 0x300)[((v ) & 0xFF)]
^ (table + 0x200)[((v >> 8) & 0xFF)]
^ (table + 0x100)[((v >> 16) & 0xFF)]
^ (table + 0x000)[((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table)
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
return CrcUpdateT4(v, data, size, table);
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
UInt32 d;
v ^= *(const UInt32 *)p;
v =
(table + 0x700)[((v ) & 0xFF)]
^ (table + 0x600)[((v >> 8) & 0xFF)]
^ (table + 0x500)[((v >> 16) & 0xFF)]
^ (table + 0x400)[((v >> 24))];
d = *((const UInt32 *)p + 1);
v ^=
(table + 0x300)[((d ) & 0xFF)]
^ (table + 0x200)[((d >> 8) & 0xFF)]
^ (table + 0x100)[((d >> 16) & 0xFF)]
^ (table + 0x000)[((d >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
#endif
#ifndef MY_CPU_LE
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
v ^= *(const UInt32 *)p;
v =
(table + 0x000)[((v ) & 0xFF)]
^ (table + 0x100)[((v >> 8) & 0xFF)]
^ (table + 0x200)[((v >> 16) & 0xFF)]
^ (table + 0x300)[((v >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v);
}
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
UInt32 d;
v ^= *(const UInt32 *)p;
v =
(table + 0x400)[((v ) & 0xFF)]
^ (table + 0x500)[((v >> 8) & 0xFF)]
^ (table + 0x600)[((v >> 16) & 0xFF)]
^ (table + 0x700)[((v >> 24))];
d = *((const UInt32 *)p + 1);
v ^=
(table + 0x000)[((d ) & 0xFF)]
^ (table + 0x100)[((d >> 8) & 0xFF)]
^ (table + 0x200)[((d >> 16) & 0xFF)]
^ (table + 0x300)[((d >> 24))];
}
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v);
}
#endif
+488 -340
View File
@@ -1,83 +1,184 @@
/* 7zDec.c -- Decoding from 7z folder
2010-11-02 : Igor Pavlov : Public domain */
2019-02-02 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include <string.h>
#include <boolean.h>
/* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT
#include "Ppmd7.h"
#endif
#define k_Copy 0
#define k_Delta 3
#define k_LZMA2 0x21
#define k_LZMA 0x30101
#define k_BCJ 0x03030103
#define k_PPC 0x03030205
#define k_ARM 0x03030501
#define k_ARMT 0x03030701
#define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B
#define k_BCJ 0x3030103
#define k_BCJ2 0x303011B
#define k_PPC 0x3030205
#define k_IA64 0x3030401
#define k_ARM 0x3030501
#define k_ARMT 0x3030701
#define k_SPARC 0x3030805
static SRes SzDecodeLzma(CSzCoderInfo *coder,
uint64_t inSize, ILookInStream *inStream,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
#ifdef _7ZIP_PPMD_SUPPPORT
#define k_PPMD 0x30401
typedef struct
{
IByteIn vt;
const Byte *cur;
const Byte *end;
const Byte *begin;
UInt64 processed;
BoolInt extra;
SRes res;
const ILookInStream *inStream;
} CByteInToLook;
static Byte ReadByte(const IByteIn *pp)
{
CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
if (p->cur != p->end)
return *p->cur++;
if (p->res == SZ_OK)
{
size_t size = p->cur - p->begin;
p->processed += size;
p->res = ILookInStream_Skip(p->inStream, size);
size = (1 << 25);
p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
p->cur = p->begin;
p->end = p->begin + size;
if (size != 0)
return *p->cur++;;
}
p->extra = True;
return 0;
}
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
CPpmd7 ppmd;
CByteInToLook s;
SRes res = SZ_OK;
s.vt.Read = ReadByte;
s.inStream = inStream;
s.begin = s.end = s.cur = NULL;
s.extra = False;
s.res = SZ_OK;
s.processed = 0;
if (propsSize != 5)
return SZ_ERROR_UNSUPPORTED;
{
unsigned order = props[0];
UInt32 memSize = GetUi32(props + 1);
if (order < PPMD7_MIN_ORDER ||
order > PPMD7_MAX_ORDER ||
memSize < PPMD7_MIN_MEM_SIZE ||
memSize > PPMD7_MAX_MEM_SIZE)
return SZ_ERROR_UNSUPPORTED;
Ppmd7_Construct(&ppmd);
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
return SZ_ERROR_MEM;
Ppmd7_Init(&ppmd, order);
}
{
CPpmd7z_RangeDec rc;
Ppmd7z_RangeDec_CreateVTable(&rc);
rc.Stream = &s.vt;
if (!Ppmd7z_RangeDec_Init(&rc))
res = SZ_ERROR_DATA;
else if (s.extra)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else
{
SizeT i;
for (i = 0; i < outSize; i++)
{
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
if (s.extra || sym < 0)
break;
outBuffer[i] = (Byte)sym;
}
if (i != outSize)
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
res = SZ_ERROR_DATA;
}
}
Ppmd7_Free(&ppmd, allocMain);
return res;
}
#endif
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
SRes result;
CLzmaDec state;
SRes res = SZ_OK;
SRes res = SZ_OK;
LzmaDec_Construct(&state);
result = LzmaDec_AllocateProbs(
&state, coder->Props.data,
(unsigned)coder->Props.size, allocMain);
if (result != 0)
return result;
state.dic = outBuffer;
RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
state.dic = outBuffer;
state.dicBufSize = outSize;
LzmaDec_Init(&state);
for (;;)
{
uint8_t *inBuf = NULL;
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look(
(void *)inStream, (const void **)&inBuf, &lookahead);
lookahead = (size_t)inSize;
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
ELzmaStatus status;
size_t inProcessed = (size_t)lookahead, dicPos = state.dicPos;
res = LzmaDec_DecodeToDic(
&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (
state.dicPos == state.dicBufSize ||
(inProcessed == 0 && dicPos == state.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
if (
state.dicBufSize != outSize ||
lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
if (outSize != state.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK)
break;
}
@@ -87,357 +188,404 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder,
return res;
}
static SRes SzDecodeLzma2(CSzCoderInfo *coder,
uint64_t inSize, ILookInStream *inStream,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
{
SRes result;
CLzma2Dec state;
SRes res = SZ_OK;
CLzma2Dec state;
SRes res = SZ_OK;
Lzma2Dec_Construct(&state);
if (coder->Props.size != 1)
return SZ_ERROR_DATA;
Lzma2Dec_Construct(&state);
if (propsSize != 1)
return SZ_ERROR_DATA;
RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
result = Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain);
if (result != 0)
return result;
for (;;)
{
const void *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
if (res != SZ_OK)
break;
state.decoder.dic = outBuffer;
state.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&state);
for (;;)
{
uint8_t *inBuf = NULL;
size_t lookahead = (1 << 18);
if (lookahead > inSize)
lookahead = (size_t)inSize;
res = inStream->Look(
(void *)inStream, (const void **)&inBuf, &lookahead);
{
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
ELzmaStatus status;
res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
break;
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{
ELzmaStatus status;
size_t inProcessed = (size_t)lookahead, dicPos = state.decoder.dicPos;
res = Lzma2Dec_DecodeToDic(
&state, outSize, inBuf, &inProcessed,
LZMA_FINISH_END, &status);
lookahead -= inProcessed;
inSize -= inProcessed;
if (res != SZ_OK)
break;
if (
state.decoder.dicPos == state.decoder.dicBufSize ||
(inProcessed == 0 && dicPos == state.decoder.dicPos))
{
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK)
break;
if (outSize != state.decoder.dicPos || inSize != 0)
res = SZ_ERROR_DATA;
break;
}
}
Lzma2Dec_FreeProbs(&state, allocMain);
return res;
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = ILookInStream_Skip(inStream, inProcessed);
if (res != SZ_OK)
break;
}
}
Lzma2Dec_FreeProbs(&state, allocMain);
return res;
}
static SRes SzDecodeCopy(uint64_t inSize,
ILookInStream *inStream, uint8_t *outBuffer)
#endif
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
SRes result;
void *inBuf = NULL;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
result = inStream->Look(
(void *)inStream, (const void **)&inBuf, &curSize);
if (result != 0)
return result;
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
result = inStream->Skip((void *)inStream, curSize);
if (result != 0)
return result;
}
return SZ_OK;
while (inSize > 0)
{
const void *inBuf;
size_t curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)inSize;
RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
if (curSize == 0)
return SZ_ERROR_INPUT_EOF;
memcpy(outBuffer, inBuf, curSize);
outBuffer += curSize;
inSize -= curSize;
RINOK(ILookInStream_Skip(inStream, curSize));
}
return SZ_OK;
}
static bool is_main_method(uint32_t m)
static BoolInt IS_MAIN_METHOD(UInt32 m)
{
switch(m)
{
case k_Copy:
case k_LZMA:
case k_LZMA2:
return true;
default:
break;
}
return false;
switch (m)
{
case k_Copy:
case k_LZMA:
#ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2:
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD:
#endif
return True;
}
return False;
}
static bool is_supported_coder(const CSzCoderInfo *c)
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{
return
c->NumInStreams == 1 &&
c->NumOutStreams == 1 &&
c->MethodID <= (uint32_t)0xFFFFFFFF &&
is_main_method((uint32_t)c->MethodID);
c->NumStreams == 1
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
&& IS_MAIN_METHOD((UInt32)c->MethodID);
}
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes check_supported_folder(const CSzFolder *f)
static SRes CheckSupportedFolder(const CSzFolder *f)
{
if (f->NumCoders < 1 || f->NumCoders > 4)
return SZ_ERROR_UNSUPPORTED;
if (!is_supported_coder(&f->Coders[0]))
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
return SZ_ERROR_UNSUPPORTED;
switch (f->NumCoders)
if (f->NumCoders == 1)
{
case 1:
if ( f->NumPackStreams != 1
|| f->PackStreams[0] != 0
|| f->NumBindPairs != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
case 2:
{
CSzCoderInfo *c = &f->Coders[1];
if (c->MethodID > (uint32_t)0xFFFFFFFF ||
c->NumInStreams != 1 ||
c->NumOutStreams != 1 ||
f->NumPackStreams != 1 ||
f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 ||
f->BindPairs[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((uint32_t)c->MethodID)
{
case k_BCJ:
case k_ARM:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
}
return SZ_OK;
case 4:
if (!is_supported_coder(&f->Coders[1]) ||
!is_supported_coder(&f->Coders[2]) ||
!IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4 ||
f->PackStreams[0] != 2 ||
f->PackStreams[1] != 6 ||
f->PackStreams[2] != 1 ||
f->PackStreams[3] != 0 ||
f->NumBindPairs != 3 ||
f->BindPairs[0].InIndex != 5 ||
f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 ||
f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 ||
f->BindPairs[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
#ifndef _7Z_NO_METHODS_FILTERS
if (f->NumCoders == 2)
{
const CSzCoderInfo *c = &f->Coders[1];
if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumStreams != 1
|| f->NumPackStreams != 1
|| f->PackStreams[0] != 0
|| f->NumBonds != 1
|| f->Bonds[0].InIndex != 1
|| f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
case k_Delta:
case k_BCJ:
case k_PPC:
case k_IA64:
case k_SPARC:
case k_ARM:
case k_ARMT:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
#endif
if (f->NumCoders == 4)
{
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|| !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4
|| f->PackStreams[0] != 2
|| f->PackStreams[1] != 6
|| f->PackStreams[2] != 1
|| f->PackStreams[3] != 0
|| f->NumBonds != 3
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
return SZ_ERROR_UNSUPPORTED;
}
static uint64_t get_sum(const uint64_t *values, uint32_t idx)
{
uint64_t sum = 0;
uint32_t i;
for (i = 0; i < idx; i++)
sum += values[i];
return sum;
}
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
static SRes SzFolder_Decode2(const CSzFolder *folder,
const uint64_t *packSizes,
ILookInStream *inStream, uint64_t startPos,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain,
uint8_t *tempBuf[])
const Byte *propsData,
const UInt64 *unpackSizes,
const UInt64 *packPositions,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
Byte *tempBuf[])
{
uint32_t ci;
size_t tempSizes[3] = { 0, 0, 0};
size_t tempSize3 = 0;
uint8_t *tempBuf3 = 0;
SRes result = check_supported_folder(folder);
UInt32 ci;
SizeT tempSizes[3] = { 0, 0, 0};
SizeT tempSize3 = 0;
Byte *tempBuf3 = 0;
if (result != 0)
return result;
RINOK(CheckSupportedFolder(folder));
for (ci = 0; ci < folder->NumCoders; ci++)
{
CSzCoderInfo *coder = &folder->Coders[ci];
for (ci = 0; ci < folder->NumCoders; ci++)
{
const CSzCoderInfo *coder = &folder->Coders[ci];
if (is_main_method((uint32_t)coder->MethodID))
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
{
UInt32 si = 0;
UInt64 offset;
UInt64 inSize;
Byte *outBufCur = outBuffer;
SizeT outSizeCur = outSize;
if (folder->NumCoders == 4)
{
SRes result;
uint64_t offset = 0;
uint64_t inSize = 0;
uint32_t si = 0;
uint8_t *outBufCur = outBuffer;
size_t outSizeCur = outSize;
if (folder->NumCoders == 4)
{
uint32_t indices[] = { 3, 2, 0 };
uint64_t unpackSize = folder->UnpackSizes[ci];
si = indices[ci];
if (ci < 2)
{
uint8_t *temp;
outSizeCur = (size_t)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (uint8_t *)IAlloc_Alloc(allocMain, outSizeCur);
if (temp == 0 && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = outBuffer
+ (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (size_t)unpackSize;
}
else
return SZ_ERROR_UNSUPPORTED;
}
offset = get_sum(packSizes, si);
inSize = packSizes[si];
result = LookInStream_SeekTo(inStream, startPos + offset);
if (result != 0)
return result;
switch (coder->MethodID)
{
case k_Copy:
if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA;
result = SzDecodeCopy(inSize, inStream, outBufCur);
if (result != 0)
return result;
break;
case k_LZMA:
result = SzDecodeLzma(
coder, inSize, inStream,
outBufCur, outSizeCur, allocMain);
if (result != 0)
return result;
break;
case k_LZMA2:
result = SzDecodeLzma2(
coder, inSize, inStream,
outBufCur, outSizeCur, allocMain);
if (result != 0)
return result;
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
UInt32 indices[] = { 3, 2, 0 };
UInt64 unpackSize = unpackSizes[ci];
si = indices[ci];
if (ci < 2)
{
Byte *temp;
outSizeCur = (SizeT)unpackSize;
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize) /* check it */
return SZ_ERROR_PARAM;
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (SizeT)unpackSize;
}
else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
offset = packPositions[si];
inSize = packPositions[(size_t)si + 1] - offset;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
if (coder->MethodID == k_Copy)
{
SRes res;
SRes result;
uint64_t offset = get_sum(packSizes, 1);
uint64_t s3Size = packSizes[1];
if (inSize != outSizeCur) /* check it */
return SZ_ERROR_DATA;
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
}
else if (coder->MethodID == k_LZMA)
{
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2)
{
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
else if (coder->MethodID == k_PPMD)
{
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = packPositions[1];
UInt64 s3Size = packPositions[2] - offset;
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
if ((tempSizes[0] & 3) != 0 ||
(tempSizes[1] & 3) != 0 ||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
return SZ_ERROR_DATA;
result = LookInStream_SeekTo(inStream, startPos + offset);
{
CBcj2Dec p;
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
p.dest = outBuffer;
p.destLim = outBuffer + outSize;
Bcj2Dec_Init(&p);
RINOK(Bcj2Dec_Decode(&p));
if (result != 0)
return result;
{
unsigned i;
for (i = 0; i < 4; i++)
if (p.bufs[i] != p.lims[i])
return SZ_ERROR_DATA;
if (!Bcj2Dec_IsFinished(&p))
return SZ_ERROR_DATA;
tempSizes[2] = (size_t)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (uint8_t *)IAlloc_Alloc(allocMain, tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0)
return SZ_ERROR_MEM;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
if (res != 0)
return res;
res = Bcj2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
tempBuf[2], tempSizes[2],
outBuffer, outSize);
if (res != 0)
return res;
if (p.dest != p.destLim
|| p.state != BCJ2_STREAM_MAIN)
return SZ_ERROR_DATA;
}
}
}
#ifndef _7Z_NO_METHODS_FILTERS
else if (ci == 1)
{
if (coder->MethodID == k_Delta)
{
if (coder->PropsSize != 1)
return SZ_ERROR_UNSUPPORTED;
{
Byte state[DELTA_STATE_SIZE];
Delta_Init(state);
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
}
else
{
if (ci != 1)
if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID)
{
case k_BCJ:
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
CASE_BRA_CONV(PPC)
CASE_BRA_CONV(IA64)
CASE_BRA_CONV(SPARC)
CASE_BRA_CONV(ARM)
CASE_BRA_CONV(ARMT)
default:
return SZ_ERROR_UNSUPPORTED;
switch(coder->MethodID)
{
case k_BCJ:
{
uint32_t state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
case k_ARM:
ARM_Convert(outBuffer, outSize, 0, 0);
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
}
}
}
return SZ_OK;
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes,
ILookInStream *inStream, uint64_t startPos,
uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain)
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAllocPtr allocMain)
{
int i;
uint8_t *tempBuf[3] = { 0, 0, 0};
SRes res = SzFolder_Decode2(folder,
packSizes, inStream, startPos,
outBuffer, (size_t)outSize, allocMain, tempBuf);
SRes res;
CSzFolder folder;
CSzData sd;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data;
sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd);
if (res != SZ_OK)
return res;
for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]);
return res;
if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL;
{
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
ISzAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res;
}
}
+216 -90
View File
@@ -1,160 +1,286 @@
/* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#define SKIP_STDIO_REDEFINES
#include <streams/file_stream_transforms.h>
#include "7zFile.h"
#ifndef USE_WINDOWS_FILE
#ifndef UNDER_CE
#include <errno.h>
#endif
#else
/*
ReadFile and WriteFile functions in Windows have BUG:
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
(Insufficient system resources exist to complete the requested service).
Probably in some version of Windows there are problems with other sizes:
for 32 MB (maybe also for 16 MB).
And message can be "Network connection was lost"
*/
#define kChunkSizeMax (1 << 22)
#endif
void File_Construct(CSzFile *p)
{
p->file = NULL;
#ifdef USE_WINDOWS_FILE
p->handle = INVALID_HANDLE_VALUE;
#else
p->file = NULL;
#endif
}
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
{
p->file = rfopen(name, writeMode ? "wb+" : "rb");
if (!p->file)
{
#ifdef UNDER_CE
return 2; /* ENOENT */
#else
return errno;
#ifdef USE_WINDOWS_FILE
p->handle = CreateFileA(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
#else
p->file = fopen(name, writeMode ? "wb+" : "rb");
return (p->file != 0) ? 0 :
#ifdef UNDER_CE
2; /* ENOENT */
#else
errno;
#endif
#endif
}
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
#endif
}
return 0;
}
WRes InFile_Open(CSzFile *p, const char *name)
#ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{
return File_Open(p, name, 0);
}
WRes OutFile_Open(CSzFile *p, const char *name)
{
return File_Open(p, name, 1);
p->handle = CreateFileW(name,
writeMode ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, NULL,
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
}
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endif
WRes File_Close(CSzFile *p)
{
if (p->file)
{
int res = rfclose((RFILE*)p->file);
if (res != 0)
return res;
p->file = NULL;
}
return 0;
#ifdef USE_WINDOWS_FILE
if (p->handle != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(p->handle))
return GetLastError();
p->handle = INVALID_HANDLE_VALUE;
}
#else
if (p->file != NULL)
{
int res = fclose(p->file);
if (res != 0)
return res;
p->file = NULL;
}
#endif
return 0;
}
WRes File_Read(CSzFile *p, void *data, size_t *size)
{
int64_t originalSize = *size;
if (originalSize == 0)
return 0;
size_t originalSize = *size;
if (originalSize == 0)
return 0;
*size = rfread(data, 1, originalSize, (RFILE*)p->file);
if (*size == originalSize)
return 0;
return rferror((RFILE*)p->file);
#ifdef USE_WINDOWS_FILE
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fread(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Write(CSzFile *p, const void *data, size_t *size)
{
int64_t originalSize = *size;
if (originalSize == 0)
return 0;
size_t originalSize = *size;
if (originalSize == 0)
return 0;
#ifdef USE_WINDOWS_FILE
*size = rfwrite(data, 1, originalSize, (RFILE*)p->file);
if (*size == originalSize)
return 0;
return rferror((RFILE*)p->file);
*size = 0;
do
{
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
DWORD processed = 0;
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
data = (void *)((Byte *)data + processed);
originalSize -= processed;
*size += processed;
if (!res)
return GetLastError();
if (processed == 0)
break;
}
while (originalSize > 0);
return 0;
#else
*size = fwrite(data, 1, originalSize, p->file);
if (*size == originalSize)
return 0;
return ferror(p->file);
#endif
}
WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin)
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
{
int whence;
int64_t res;
switch (origin)
{
case SZ_SEEK_SET:
whence = SEEK_SET;
break;
case SZ_SEEK_CUR:
whence = SEEK_CUR;
break;
case SZ_SEEK_END:
whence = SEEK_END;
break;
default:
return 1;
}
res = rfseek((RFILE*)p->file, (int64_t)*pos, whence);
*pos = rftell((RFILE*)p->file);
return res;
#ifdef USE_WINDOWS_FILE
LARGE_INTEGER value;
DWORD moveMethod;
value.LowPart = (DWORD)*pos;
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
switch (origin)
{
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
case SZ_SEEK_END: moveMethod = FILE_END; break;
default: return ERROR_INVALID_PARAMETER;
}
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
if (value.LowPart == 0xFFFFFFFF)
{
WRes res = GetLastError();
if (res != NO_ERROR)
return res;
}
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
return 0;
#else
int moveMethod;
int res;
switch (origin)
{
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
case SZ_SEEK_END: moveMethod = SEEK_END; break;
default: return 1;
}
res = fseek(p->file, (long)*pos, moveMethod);
*pos = ftell(p->file);
return res;
#endif
}
WRes File_GetLength(CSzFile *p, uint64_t *length)
WRes File_GetLength(CSzFile *p, UInt64 *length)
{
int64_t pos = rftell((RFILE*)p->file);
int64_t res = rfseek((RFILE*)p->file, 0, SEEK_END);
*length = rftell((RFILE*)p->file);
rfseek((RFILE*)p->file, pos, SEEK_SET);
return res;
#ifdef USE_WINDOWS_FILE
DWORD sizeHigh;
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
if (sizeLow == 0xFFFFFFFF)
{
DWORD res = GetLastError();
if (res != NO_ERROR)
return res;
}
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
return 0;
#else
long pos = ftell(p->file);
int res = fseek(p->file, 0, SEEK_END);
*length = ftell(p->file);
fseek(p->file, pos, SEEK_SET);
return res;
#endif
}
/* ---------- FileSeqInStream ---------- */
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
CFileSeqInStream *p = (CFileSeqInStream *)pp;
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
}
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
{
p->s.Read = FileSeqInStream_Read;
p->vt.Read = FileSeqInStream_Read;
}
/* ---------- FileInStream ---------- */
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
{
CFileInStream *p = (CFileInStream *)pp;
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
}
static SRes FileInStream_Seek(void *pp, int64_t *pos, ESzSeek origin)
static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
{
CFileInStream *p = (CFileInStream *)pp;
return File_Seek(&p->file, pos, origin);
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
return File_Seek(&p->file, pos, origin);
}
void FileInStream_CreateVTable(CFileInStream *p)
{
p->s.Read = FileInStream_Read;
p->s.Seek = FileInStream_Seek;
p->vt.Read = FileInStream_Read;
p->vt.Seek = FileInStream_Seek;
}
/* ---------- FileOutStream ---------- */
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
{
CFileOutStream *p = (CFileOutStream *)pp;
File_Write(&p->file, data, &size);
return size;
CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
File_Write(&p->file, data, &size);
return size;
}
void FileOutStream_CreateVTable(CFileOutStream *p)
{
p->s.Write = FileOutStream_Write;
p->vt.Write = FileOutStream_Write;
}
#undef SKIP_STDIO_REDEFINES
+27 -13
View File
@@ -1,27 +1,43 @@
/* 7zFile.h -- File IO
2009-11-24 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_FILE_H
#define __7Z_FILE_H
#ifdef _WIN32
#define USE_WINDOWS_FILE
#endif
#ifdef USE_WINDOWS_FILE
#include <windows.h>
#else
#include <stdio.h>
#endif
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
void *file;
#ifdef USE_WINDOWS_FILE
HANDLE handle;
#else
FILE *file;
#endif
} CSzFile;
void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name);
#endif
#ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif
WRes File_Close(CSzFile *p);
/* reads max(*size, remain file's size) bytes */
@@ -30,15 +46,15 @@ WRes File_Read(CSzFile *p, void *data, size_t *size);
/* writes *size bytes */
WRes File_Write(CSzFile *p, const void *data, size_t *size);
WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, uint64_t *length);
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, UInt64 *length);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeqInStream s;
ISeqInStream vt;
CSzFile file;
} CFileSeqInStream;
@@ -47,7 +63,7 @@ void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
ISeekInStream s;
ISeekInStream vt;
CSzFile file;
} CFileInStream;
@@ -56,14 +72,12 @@ void FileInStream_CreateVTable(CFileInStream *p);
typedef struct
{
ISeqOutStream s;
ISeqOutStream vt;
CSzFile file;
} CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
-1633
View File
File diff suppressed because it is too large. Load diff
+116 -124
View File
@@ -1,184 +1,176 @@
/* 7zStream.c -- 7z Stream functions
2010-03-11 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include <stdint.h>
#include <string.h>
#include "7zTypes.h"
SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf)
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
{
size_t processed = 1;
SRes result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed != 1)
return SZ_ERROR_INPUT_EOF;
return SZ_OK;
while (size != 0)
{
size_t processed = size;
RINOK(ISeqInStream_Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
size -= processed;
}
return SZ_OK;
}
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
{
while (size != 0)
{
size_t processed = size;
SRes result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed == 0)
return errorType;
buf = (void *)((uint8_t *)buf + processed);
size -= processed;
}
return SZ_OK;
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
{
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
size_t processed = 1;
RINOK(ISeqInStream_Read(stream, buf, &processed));
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
}
SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset)
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
{
int64_t t = offset;
return stream->Seek(stream, &t, SZ_SEEK_SET);
Int64 t = offset;
return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
}
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
{
SRes result;
const void *lookBuf;
if (*size == 0)
return SZ_OK;
result = stream->Look(stream, &lookBuf, size);
if (result != 0)
return result;
memcpy(buf, lookBuf, *size);
return stream->Skip(stream, *size);
const void *lookBuf;
if (*size == 0)
return SZ_OK;
RINOK(ILookInStream_Look(stream, &lookBuf, size));
memcpy(buf, lookBuf, *size);
return ILookInStream_Skip(stream, *size);
}
SRes LookInStream_Read2(ILookInStream *stream,
void *buf, size_t size, SRes errorType)
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
{
while (size != 0)
{
size_t processed = size;
SRes result = stream->Read(stream, buf, &processed);
if (result != 0)
return result;
if (processed == 0)
return errorType;
buf = (void *)((uint8_t *)buf + processed);
size -= processed;
}
return SZ_OK;
while (size != 0)
{
size_t processed = size;
RINOK(ILookInStream_Read(stream, buf, &processed));
if (processed == 0)
return errorType;
buf = (void *)((Byte *)buf + processed);
size -= processed;
}
return SZ_OK;
}
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
{
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
}
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0)
{
p->pos = 0;
size2 = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, &size2);
p->size = size2;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
SRes res = SZ_OK;
GET_LookToRead2
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size != 0)
{
p->pos = 0;
p->size = 0;
size2 = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, &size2);
p->size = size2;
}
if (*size > size2)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
{
SRes res = SZ_OK;
CLookToRead *p = (CLookToRead *)pp;
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size > 0)
{
p->pos = 0;
if (*size > LookToRead_BUF_SIZE)
*size = LookToRead_BUF_SIZE;
res = p->realStream->Read(p->realStream, p->buf, size);
size2 = p->size = *size;
}
if (size2 < *size)
*size = size2;
*buf = p->buf + p->pos;
return res;
SRes res = SZ_OK;
GET_LookToRead2
size_t size2 = p->size - p->pos;
if (size2 == 0 && *size != 0)
{
p->pos = 0;
p->size = 0;
if (*size > p->bufSize)
*size = p->bufSize;
res = ISeekInStream_Read(p->realStream, p->buf, size);
size2 = p->size = *size;
}
if (*size > size2)
*size = size2;
*buf = p->buf + p->pos;
return res;
}
static SRes LookToRead_Skip(void *pp, size_t offset)
static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
{
CLookToRead *p = (CLookToRead *)pp;
p->pos += offset;
return SZ_OK;
GET_LookToRead2
p->pos += offset;
return SZ_OK;
}
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
{
CLookToRead *p = (CLookToRead *)pp;
size_t rem = p->size - p->pos;
if (rem == 0)
return p->realStream->Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
p->pos += rem;
*size = rem;
return SZ_OK;
GET_LookToRead2
size_t rem = p->size - p->pos;
if (rem == 0)
return ISeekInStream_Read(p->realStream, buf, size);
if (rem > *size)
rem = *size;
memcpy(buf, p->buf + p->pos, rem);
p->pos += rem;
*size = rem;
return SZ_OK;
}
static SRes LookToRead_Seek(void *pp, int64_t *pos, ESzSeek origin)
static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
{
CLookToRead *p = (CLookToRead *)pp;
p->pos = p->size = 0;
return p->realStream->Seek(p->realStream, pos, origin);
GET_LookToRead2
p->pos = p->size = 0;
return ISeekInStream_Seek(p->realStream, pos, origin);
}
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
{
p->s.Look = lookahead ?
LookToRead_Look_Lookahead :
LookToRead_Look_Exact;
p->s.Skip = LookToRead_Skip;
p->s.Read = LookToRead_Read;
p->s.Seek = LookToRead_Seek;
p->vt.Look = lookahead ?
LookToRead2_Look_Lookahead :
LookToRead2_Look_Exact;
p->vt.Skip = LookToRead2_Skip;
p->vt.Read = LookToRead2_Read;
p->vt.Seek = LookToRead2_Seek;
}
void LookToRead_Init(CLookToRead *p)
{
p->pos = p->size = 0;
}
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
CSecToLook *p = (CSecToLook *)pp;
return LookInStream_LookRead(p->realStream, buf, size);
CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
return LookInStream_LookRead(p->realStream, buf, size);
}
void SecToLook_CreateVTable(CSecToLook *p)
{
p->s.Read = SecToLook_Read;
p->vt.Read = SecToLook_Read;
}
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
{
CSecToRead *p = (CSecToRead *)pp;
return p->realStream->Read(p->realStream, buf, size);
CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
return ILookInStream_Read(p->realStream, buf, size);
}
void SecToRead_CreateVTable(CSecToRead *p)
{
p->s.Read = SecToRead_Read;
p->vt.Read = SecToRead_Read;
}
+274 -66
View File
@@ -1,10 +1,13 @@
/* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */
2018-08-04 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stdint.h>
#ifdef _WIN32
/* #include <windows.h> */
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
@@ -19,10 +22,6 @@
EXTERN_C_BEGIN
#ifndef _7ZIP_ST
#define _7ZIP_ST
#endif
#define SZ_OK 0
#define SZ_ERROR_DATA 1
@@ -41,50 +40,157 @@ EXTERN_C_BEGIN
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int64_t SRes;
typedef int SRes;
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else
typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif
typedef int64_t WRes;
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
#ifdef _MSC_VER
#define MY_FAST_CALL __fastcall
#else
#define MY_FAST_CALL
#ifndef ZCONF_H
typedef unsigned char Byte;
#endif
typedef short Int16;
typedef unsigned short UInt16;
#if defined(_LZMA_UINT32_IS_ULONG) && !defined(__LP64__)
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#define UINT64_CONST(n) n
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#define UINT64_CONST(n) n ## ULL
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
typedef int BoolInt;
/* typedef BoolInt Bool; */
#define True 1
#define False 0
#ifdef _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall
#else
#define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL
#define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
typedef struct IByteIn IByteIn;
struct IByteIn
{
unsigned char (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn;
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)
typedef struct
{
void (*Write)(void *p, unsigned char b);
} IByteOut;
typedef struct
typedef struct IByteOut IByteOut;
struct IByteOut
{
SRes (*Read)(void *p, void *buf, size_t *size);
void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, unsigned char *buf);
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{
size_t (*Write)(void *p, const void *buf, size_t size);
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
@@ -93,76 +199,178 @@ typedef enum
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, int64_t *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{
SRes (*Look)(void *p, const void **buf, size_t *size);
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, int64_t *pos, ESzSeek origin);
} ILookInStream;
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
};
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset);
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
ILookInStream vt;
const ISeekInStream *realStream;
size_t pos;
size_t size;
unsigned char buf[LookToRead_BUF_SIZE];
} CLookToRead;
size_t size; /* it's data size */
/* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
ISeqInStream vt;
const ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, uint64_t inSize, uint64_t outSize);
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
typedef struct ICompressProgress ICompressProgress;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
struct ICompressProgress
{
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{
void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
};
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
EXTERN_C_END
+26 -6
View File
@@ -1,7 +1,27 @@
#define MY_VER_MAJOR 9
#define MY_VER_MINOR 20
#define MY_VER_MAJOR 19
#define MY_VER_MINOR 00
#define MY_VER_BUILD 0
#define MY_VERSION "9.20"
#define MY_DATE "2010-11-18"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_NUMBERS "19.00"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2019-02-21"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
#else
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
+233 -125
View File
@@ -1,149 +1,257 @@
/* Bcj2.c -- Converter for x86 code (BCJ2)
2008-10-04 : Igor Pavlov : Public domain */
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2018-04-28 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include "Bcj2.h"
#include "CpuArch.h"
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define CProb UInt16
#define kNumTopBits 24
#define kTopValue ((uint32_t)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++)
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
int Bcj2_Decode(
const uint8_t *buf0, size_t size0,
const uint8_t *buf1, size_t size1,
const uint8_t *buf2, size_t size2,
const uint8_t *buf3, size_t size3,
uint8_t *outBuf, size_t outSize)
void Bcj2Dec_Init(CBcj2Dec *p)
{
uint16_t p[256 + 2];
size_t inPos = 0, outPos = 0;
unsigned i;
const uint8_t *buffer, *bufferLim;
uint32_t range, codes = 0;
uint8_t prevuint8_t = 0;
p->state = BCJ2_DEC_STATE_OK;
p->ip = 0;
p->temp[3] = 0;
p->range = 0;
p->code = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1;
}
unsigned int i;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
p[i] = kBitModelTotal >> 1;
SRes Bcj2Dec_Decode(CBcj2Dec *p)
{
if (p->range <= 5)
{
p->state = BCJ2_DEC_STATE_OK;
for (; p->range != 5; p->range++)
{
if (p->range == 1 && p->code != 0)
return SZ_ERROR_DATA;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
buffer = buf3;
bufferLim = buffer + size3;
range = 0xFFFFFFFF;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
if (p->code == 0xFFFFFFFF)
return SZ_ERROR_DATA;
p->range = 0xFFFFFFFF;
}
else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
Byte *dest = p->dest;
if (dest == p->destLim)
return SZ_OK;
*dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
p->state++;
p->dest = dest + 1;
}
}
for (i = 0; i < 5; i++)
{
if (buffer == bufferLim)
return SZ_ERROR_DATA;
codes = (codes << 8) | RC_READ_BYTE;
}
/*
if (BCJ2_IS_32BIT_STREAM(p->state))
{
const Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state])
return SZ_OK;
p->bufs[p->state] = cur + 4;
{
UInt32 val;
Byte *dest;
SizeT rem;
p->ip += 4;
val = GetBe32(cur) - p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
return SZ_OK;
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
p->state = BCJ2_DEC_STATE_OK;
}
}
*/
if (outSize == 0)
return SZ_OK;
for (;;)
{
if (BCJ2_IS_32BIT_STREAM(p->state))
p->state = BCJ2_DEC_STATE_OK;
else
{
if (p->range < kTopValue)
{
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
for (;;)
{
uint8_t b;
uint16_t *prob;
uint32_t bound;
uint32_t ttt;
{
const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
const Byte *srcLim;
Byte *dest;
SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
if (num == 0)
{
p->state = BCJ2_STREAM_MAIN;
return SZ_OK;
}
dest = p->dest;
if (num > (SizeT)(p->destLim - dest))
{
num = p->destLim - dest;
if (num == 0)
{
p->state = BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
}
srcLim = src + num;
size_t limit = size0 - inPos;
if (outSize - outPos < limit)
limit = outSize - outPos;
while (limit != 0)
{
b = buf0[inPos];
outBuf[outPos++] = b;
if (IsJ(prevuint8_t, b))
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0];
else for (;;)
{
Byte b = *src;
*dest = b;
if (b != 0x0F)
{
if ((b & 0xFE) == 0xE8)
break;
dest++;
if (++src != srcLim)
continue;
break;
}
dest++;
if (++src == srcLim)
break;
inPos++;
prevuint8_t = b;
limit--;
if ((*src & 0xF0) != 0x80)
continue;
*dest = *src;
break;
}
num = src - p->bufs[BCJ2_STREAM_MAIN];
if (src == srcLim)
{
p->temp[3] = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = src;
p->ip += (UInt32)num;
p->dest += num;
p->state =
p->bufs[BCJ2_STREAM_MAIN] ==
p->lims[BCJ2_STREAM_MAIN] ?
(unsigned)BCJ2_STREAM_MAIN :
(unsigned)BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
{
UInt32 bound, ttt;
CProb *prob;
Byte b = src[0];
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
p->temp[3] = b;
p->bufs[BCJ2_STREAM_MAIN] = src + 1;
num++;
p->ip += (UInt32)num;
p->dest += num;
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
_IF_BIT_0
{
_UPDATE_0
continue;
}
_UPDATE_1
}
}
}
if (limit == 0 || outPos == outSize)
break;
{
UInt32 val;
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
const Byte *cur = p->bufs[cj];
Byte *dest;
SizeT rem;
if (cur == p->lims[cj])
{
p->state = cj;
break;
}
val = GetBe32(cur);
p->bufs[cj] = cur + 4;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevuint8_t;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
ttt = *(prob);
bound = (range >> kNumBitModelTotalBits) * ttt;
if (codes < bound)
p->ip += 4;
val -= p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
range = bound;
*(prob) = (uint16_t)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
if (range < kTopValue)
{
if (buffer == bufferLim)
return SZ_ERROR_DATA;
range <<= 8;
codes = (codes << 8) | RC_READ_BYTE;
}
prevuint8_t = b;
p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
p->temp[3] = (Byte)val;
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
}
else
{
uint32_t dest;
const uint8_t *v;
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
}
}
range -= bound;
codes -= bound;
*(prob) = (uint16_t)(ttt - (ttt >> kNumMoveBits));
if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
{
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
if (range < kTopValue)
{
if (buffer == bufferLim)
return SZ_ERROR_DATA;
range <<= 8;
codes = (codes << 8) | RC_READ_BYTE;
}
if (b == 0xE8)
{
v = buf1;
if (size1 < 4)
return SZ_ERROR_DATA;
buf1 += 4;
size1 -= 4;
}
else
{
v = buf2;
if (size2 < 4)
return SZ_ERROR_DATA;
buf2 += 4;
size2 -= 4;
}
dest = (((uint32_t)v[0] << 24) | ((uint32_t)v[1] << 16) |
((uint32_t)v[2] << 8) | ((uint32_t)v[3])) - ((uint32_t)outPos + 4);
outBuf[outPos++] = (uint8_t)dest;
if (outPos == outSize)
break;
outBuf[outPos++] = (uint8_t)(dest >> 8);
if (outPos == outSize)
break;
outBuf[outPos++] = (uint8_t)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevuint8_t = (uint8_t)(dest >> 24);
}
}
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
return SZ_OK;
}
+133 -25
View File
@@ -1,38 +1,146 @@
/* Bcj2.h -- Converter for x86 code (BCJ2)
2009-02-07 : Igor Pavlov : Public domain */
/* Bcj2.h -- BCJ2 Converter for x86 code
2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
#define BCJ2_NUM_STREAMS 4
enum
{
BCJ2_STREAM_MAIN,
BCJ2_STREAM_CALL,
BCJ2_STREAM_JUMP,
BCJ2_STREAM_RC
};
enum
{
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
BCJ2_DEC_STATE_ORIG_1,
BCJ2_DEC_STATE_ORIG_2,
BCJ2_DEC_STATE_ORIG_3,
BCJ2_DEC_STATE_ORIG,
BCJ2_DEC_STATE_OK
};
enum
{
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
BCJ2_ENC_STATE_OK
};
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
/*
Conditions:
outSize <= FullOutputSize,
where FullOutputSize is full size of output stream of x86_2 filter.
If buf0 overlaps outBuf, there are two required conditions:
1) (buf0 >= outBuf)
2) (buf0 + size0 >= outBuf + FullOutputSize).
Returns:
SZ_OK
SZ_ERROR_DATA - Data error
CBcj2Dec / CBcj2Enc
bufs sizes:
BUF_SIZE(n) = lims[n] - bufs[n]
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/
int Bcj2_Decode(
const uint8_t *buf0, size_t size0,
const uint8_t *buf1, size_t size1,
const uint8_t *buf2, size_t size2,
const uint8_t *buf3, size_t size3,
uint8_t *outBuf, size_t outSize);
/*
CBcj2Dec:
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
bufs[BCJ2_STREAM_MAIN] >= dest &&
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP)
tempReserv = 0 : for first call of Bcj2Dec_Decode
tempReserv = 4 : for any other calls of Bcj2Dec_Decode
overlap with offset = 1 is not allowed
*/
#ifdef __cplusplus
}
#endif
typedef struct
{
const Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
Byte *dest;
const Byte *destLim;
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
UInt32 ip;
Byte temp[4];
UInt32 range;
UInt32 code;
UInt16 probs[2 + 256];
} CBcj2Dec;
void Bcj2Dec_Init(CBcj2Dec *p);
/* Returns: SZ_OK or SZ_ERROR_DATA */
SRes Bcj2Dec_Decode(CBcj2Dec *p);
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
typedef enum
{
BCJ2_ENC_FINISH_MODE_CONTINUE,
BCJ2_ENC_FINISH_MODE_END_BLOCK,
BCJ2_ENC_FINISH_MODE_END_STREAM
} EBcj2Enc_FinishMode;
typedef struct
{
Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
const Byte *src;
const Byte *srcLim;
unsigned state;
EBcj2Enc_FinishMode finishMode;
Byte prevByte;
Byte cache;
UInt32 range;
UInt64 low;
UInt64 cacheSize;
UInt32 ip;
/* 32-bit ralative offset in JUMP/CALL commands is
- (mod 4 GB) in 32-bit mode
- signed Int32 in 64-bit mode
We use (mod 4 GB) check for fileSize.
Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
UInt32 fileIp;
UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
UInt32 tempTarget;
unsigned tempPos;
Byte temp[4 * 2];
unsigned flushPos;
UInt16 probs[2 + 256];
} CBcj2Enc;
void Bcj2Enc_Init(CBcj2Enc *p);
void Bcj2Enc_Encode(CBcj2Enc *p);
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
#define BCJ2_RELAT_LIMIT_NUM_BITS 26
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
/* limit for CBcj2Enc::fileSize variable */
#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
EXTERN_C_END
#endif
+212 -116
View File
@@ -1,134 +1,230 @@
/* Bra.c -- Converters for RISC code
2010-04-16 : Igor Pavlov : Public domain */
2017-04-04 : Igor Pavlov : Public domain */
#include <stdint.h>
#include "Precomp.h"
#include "CpuArch.h"
#include "Bra.h"
size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding)
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
size_t i;
if (size < 4)
return 0;
size -= 4;
ip += 8;
for (i = 0; i <= size; i += 4)
{
if (data[i + 3] == 0xEB)
{
uint32_t dest;
uint32_t src = ((uint32_t)data[i + 2] << 16) | ((uint32_t)data[i + 1] << 8) | (data[i + 0]);
src <<= 2;
if (encoding)
dest = ip + (uint32_t)i + src;
else
dest = src - (ip + (uint32_t)i);
dest >>= 2;
data[i + 2] = (uint8_t)(dest >> 16);
data[i + 1] = (uint8_t)(dest >> 8);
data[i + 0] = (uint8_t)dest;
}
}
return i;
Byte *p;
const Byte *lim;
size &= ~(size_t)3;
ip += 4;
p = data;
lim = data + size;
if (encoding)
for (;;)
{
for (;;)
{
if (p >= lim)
return p - data;
p += 4;
if (p[-1] == 0xEB)
break;
}
{
UInt32 v = GetUi32(p - 4);
v <<= 2;
v += ip + (UInt32)(p - data);
v >>= 2;
v &= 0x00FFFFFF;
v |= 0xEB000000;
SetUi32(p - 4, v);
}
}
for (;;)
{
for (;;)
{
if (p >= lim)
return p - data;
p += 4;
if (p[-1] == 0xEB)
break;
}
{
UInt32 v = GetUi32(p - 4);
v <<= 2;
v -= ip + (UInt32)(p - data);
v >>= 2;
v &= 0x00FFFFFF;
v |= 0xEB000000;
SetUi32(p - 4, v);
}
}
}
size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding)
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
size_t i;
if (size < 4)
return 0;
size -= 4;
ip += 4;
for (i = 0; i <= size; i += 2)
{
if ((data[i + 1] & 0xF8) == 0xF0 &&
(data[i + 3] & 0xF8) == 0xF8)
Byte *p;
const Byte *lim;
size &= ~(size_t)1;
p = data;
lim = data + size - 4;
if (encoding)
for (;;)
{
UInt32 b1;
for (;;)
{
UInt32 b3;
if (p > lim)
return p - data;
b1 = p[1];
b3 = p[3];
p += 2;
b1 ^= 8;
if ((b3 & b1) >= 0xF8)
break;
}
{
UInt32 v =
((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8)
+ (((UInt32)p[-2] << 11))
+ (p[0]);
p += 2;
{
uint32_t dest;
uint32_t src =
(((uint32_t)data[i + 1] & 0x7) << 19) |
((uint32_t)data[i + 0] << 11) |
(((uint32_t)data[i + 3] & 0x7) << 8) |
(data[i + 2]);
src <<= 1;
if (encoding)
dest = ip + (uint32_t)i + src;
else
dest = src - (ip + (uint32_t)i);
dest >>= 1;
data[i + 1] = (uint8_t)(0xF0 | ((dest >> 19) & 0x7));
data[i + 0] = (uint8_t)(dest >> 11);
data[i + 3] = (uint8_t)(0xF8 | ((dest >> 8) & 0x7));
data[i + 2] = (uint8_t)dest;
i += 2;
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v += cur;
}
}
return i;
p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8));
}
}
for (;;)
{
UInt32 b1;
for (;;)
{
UInt32 b3;
if (p > lim)
return p - data;
b1 = p[1];
b3 = p[3];
p += 2;
b1 ^= 8;
if ((b3 & b1) >= 0xF8)
break;
}
{
UInt32 v =
((UInt32)b1 << 19)
+ (((UInt32)p[1] & 0x7) << 8)
+ (((UInt32)p[-2] << 11))
+ (p[0]);
p += 2;
{
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
v -= cur;
}
/*
SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
SetUi16(p - 2, (UInt16)(v | 0xF800));
*/
p[-4] = (Byte)(v >> 11);
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
p[-2] = (Byte)v;
p[-1] = (Byte)(0xF8 | (v >> 8));
}
}
}
size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding)
{
size_t i;
if (size < 4)
return 0;
size -= 4;
for (i = 0; i <= size; i += 4)
{
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
{
uint32_t src = ((uint32_t)(data[i + 0] & 3) << 24) |
((uint32_t)data[i + 1] << 16) |
((uint32_t)data[i + 2] << 8) |
((uint32_t)data[i + 3] & (~3));
uint32_t dest;
if (encoding)
dest = ip + (uint32_t)i + src;
else
dest = src - (ip + (uint32_t)i);
data[i + 0] = (uint8_t)(0x48 | ((dest >> 24) & 0x3));
data[i + 1] = (uint8_t)(dest >> 16);
data[i + 2] = (uint8_t)(dest >> 8);
data[i + 3] &= 0x3;
data[i + 3] |= dest;
}
}
return i;
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
Byte *p;
const Byte *lim;
size &= ~(size_t)3;
ip -= 4;
p = data;
lim = data + size;
for (;;)
{
for (;;)
{
if (p >= lim)
return p - data;
p += 4;
/* if ((v & 0xFC000003) == 0x48000001) */
if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
break;
}
{
UInt32 v = GetBe32(p - 4);
if (encoding)
v += ip + (UInt32)(p - data);
else
v -= ip + (UInt32)(p - data);
v &= 0x03FFFFFF;
v |= 0x48000000;
SetBe32(p - 4, v);
}
}
}
size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding)
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
uint32_t i;
if (size < 4)
return 0;
size -= 4;
for (i = 0; i <= size; i += 4)
{
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
{
uint32_t src =
((uint32_t)data[i + 0] << 24) |
((uint32_t)data[i + 1] << 16) |
((uint32_t)data[i + 2] << 8) |
((uint32_t)data[i + 3]);
uint32_t dest;
Byte *p;
const Byte *lim;
size &= ~(size_t)3;
ip -= 4;
p = data;
lim = data + size;
src <<= 2;
if (encoding)
dest = ip + i + src;
else
dest = src - (ip + i);
dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
data[i + 0] = (uint8_t)(dest >> 24);
data[i + 1] = (uint8_t)(dest >> 16);
data[i + 2] = (uint8_t)(dest >> 8);
data[i + 3] = (uint8_t)dest;
}
}
return i;
for (;;)
{
for (;;)
{
if (p >= lim)
return p - data;
/*
v = GetBe32(p);
p += 4;
m = v + ((UInt32)5 << 29);
m ^= (UInt32)7 << 29;
m += (UInt32)1 << 22;
if ((m & ((UInt32)0x1FF << 23)) == 0)
break;
*/
p += 4;
if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
(p[-4] == 0x7F && (p[-3] >= 0xC0)))
break;
}
{
UInt32 v = GetBe32(p - 4);
v <<= 2;
if (encoding)
v += ip + (UInt32)(p - data);
else
v -= ip + (UInt32)(p - data);
v &= 0x01FFFFFF;
v -= (UInt32)1 << 24;
v ^= 0xFF000000;
v >>= 2;
v |= 0x40000000;
SetBe32(p - 4, v);
}
}
}
+46 -50
View File
@@ -1,68 +1,64 @@
/* Bra.h -- Branch converters for executables
2009-02-07 : Igor Pavlov : Public domain */
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __BRA_H
#define __BRA_H
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
/*
These functions convert relative addresses to absolute addresses
in CALL instructions to increase the compression ratio.
/*
These functions convert relative addresses to absolute addresses
in CALL instructions to increase the compression ratio.
In:
data - data buffer
size - size of data
ip - current virtual Instruction Pinter (IP) value
state - state variable for x86 converter
encoding - 0 (for decoding), 1 (for encoding)
Out:
state - state variable for x86 converter
In:
data - data buffer
size - size of data
ip - current virtual Instruction Pinter (IP) value
state - state variable for x86 converter
encoding - 0 (for decoding), 1 (for encoding)
Returns:
The number of processed bytes. If you call these functions with multiple calls,
you must start next call with first byte after block of processed bytes.
Type Endian Alignment LookAhead
x86 little 1 4
ARMT little 2 2
ARM little 4 0
PPC big 4 0
SPARC big 4 0
IA64 little 16 0
Out:
state - state variable for x86 converter
size must be >= Alignment + LookAhead, if it's not last block.
If (size < Alignment + LookAhead), converter returns 0.
Returns:
The number of processed bytes. If you call these functions with multiple calls,
you must start next call with first byte after block of processed bytes.
Example:
Type Endian Alignment LookAhead
x86 little 1 4
ARMT little 2 2
ARM little 4 0
PPC big 4 0
SPARC big 4 0
IA64 little 16 0
size must be >= Alignment + LookAhead, if it's not last block.
If (size < Alignment + LookAhead), converter returns 0.
Example:
uint32_t ip = 0;
for ()
{
; size must be >= Alignment + LookAhead, if it's not last block
size_t processed = Convert(data, size, ip, 1);
data += processed;
size -= processed;
ip += processed;
}
UInt32 ip = 0;
for ()
{
; size must be >= Alignment + LookAhead, if it's not last block
SizeT processed = Convert(data, size, ip, 1);
data += processed;
size -= processed;
ip += processed;
}
*/
#define x86_Convert_Init(state) { state = 0; }
size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding);
size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding);
size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding);
size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding);
size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding);
size_t IA64_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding);
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
+66 -70
View File
@@ -1,86 +1,82 @@
/* Bra86.c -- Converter for x86 code (BCJ)
2008-10-04 : Igor Pavlov : Public domain */
2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <stdint.h>
#include "Bra.h"
#define Test86MSuint8_t(b) ((b) == 0 || (b) == 0xFF)
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding)
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
{
size_t bufferPos = 0, prevPosT;
uint32_t prevMask = *state & 0x7;
if (size < 5)
return 0;
ip += 5;
prevPosT = (size_t)0 - 1;
SizeT pos = 0;
UInt32 mask = *state & 7;
if (size < 5)
return 0;
size -= 4;
ip += 5;
for (;;)
{
uint8_t *p = data + bufferPos;
uint8_t *limit = data + size - 4;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
bufferPos = (size_t)(p - data);
for (;;)
{
Byte *p = data + pos;
const Byte *limit = data + size;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
{
SizeT d = (SizeT)(p - data - pos);
pos = (SizeT)(p - data);
if (p >= limit)
break;
prevPosT = bufferPos - prevPosT;
if (prevPosT > 3)
prevMask = 0;
{
*state = (d > 2 ? 0 : mask >> (unsigned)d);
return pos;
}
if (d > 2)
mask = 0;
else
{
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
if (prevMask != 0)
{
uint8_t b = p[4 - kMaskToBitNumber[prevMask]];
if (!kMaskToAllowedStatus[prevMask] || Test86MSuint8_t(b))
{
prevPosT = bufferPos;
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
continue;
}
}
mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{
mask = (mask >> 1) | 4;
pos++;
continue;
}
}
prevPosT = bufferPos;
}
if (Test86MSuint8_t(p[4]))
{
uint32_t src = ((uint32_t)p[4] << 24) | ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) | ((uint32_t)p[1]);
uint32_t dest;
for (;;)
{
uint8_t b;
int idx;
if (encoding)
dest = (ip + (uint32_t)bufferPos) + src;
else
dest = src - (ip + (uint32_t)bufferPos);
if (prevMask == 0)
break;
idx = kMaskToBitNumber[prevMask] * 8;
b = (uint8_t)(dest >> (24 - idx));
if (!Test86MSuint8_t(b))
break;
src = dest ^ ((1 << (32 - idx)) - 1);
}
p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1));
p[3] = (uint8_t)(dest >> 16);
p[2] = (uint8_t)(dest >> 8);
p[1] = (uint8_t)dest;
bufferPos += 5;
}
if (Test86MSByte(p[4]))
{
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 cur = ip + (UInt32)pos;
pos += 5;
if (encoding)
v += cur;
else
v -= cur;
if (mask != 0)
{
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
unsigned sh = (mask & 6) << 2;
if (Test86MSByte((Byte)(v >> sh)))
{
v ^= (((UInt32)0x100 << sh) - 1);
if (encoding)
v += cur;
else
v -= cur;
}
mask = 0;
}
}
prevPosT = bufferPos - prevPosT;
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
p[1] = (Byte)v;
p[2] = (Byte)(v >> 8);
p[3] = (Byte)(v >> 16);
p[4] = (Byte)(0 - ((v >> 24) & 1));
}
else
{
mask = (mask >> 1) | 4;
pos++;
}
}
}
+53
View File
@@ -0,0 +1,53 @@
/* BraIA64.c -- Converter for IA-64 code
2017-01-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#include "Bra.h"
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
{
SizeT i;
if (size < 16)
return 0;
size -= 16;
i = 0;
do
{
unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
if (m)
{
m++;
do
{
Byte *p = data + (i + (size_t)m * 5 - 8);
if (((p[3] >> m) & 15) == 5
&& (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
{
unsigned raw = GetUi32(p);
unsigned v = raw >> m;
v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
v <<= 4;
if (encoding)
v += ip + (UInt32)i;
else
v -= ip + (UInt32)i;
v >>= 4;
v &= 0x1FFFFF;
v += 0x700000;
v &= 0x8FFFFF;
raw &= ~((UInt32)0x8FFFFF << m);
raw |= (v << m);
SetUi32(p, raw);
}
}
while (++m <= 4);
}
i += 16;
}
while (i <= size);
return i;
}
+33
View File
@@ -0,0 +1,33 @@
/* Compiler.h
2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) /* nonstandard extension used : nameless struct/union */
#pragma warning(disable : 4214) /* nonstandard extension used : bit field types other than int */
#endif
#if _MSC_VER >= 1300
#pragma warning(disable : 4996) /* This function or variable may be unsafe */
#else
#pragma warning(disable : 4511) /* copy constructor could not be generated */
#pragma warning(disable : 4512) /* assignment operator could not be generated */
#pragma warning(disable : 4514) /* unreferenced inline function has been removed */
#pragma warning(disable : 4702) /* unreachable code */
#pragma warning(disable : 4710) /* not inlined */
#pragma warning(disable : 4714) /* function marked as __forceinline not inlined */
#pragma warning(disable : 4786) /* identifier was truncated to '255' characters in the debug information */
#endif
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif
+218
View File
@@ -0,0 +1,218 @@
/* CpuArch.c -- CPU specific code
2018-02-18: Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#ifdef MY_CPU_X86_OR_AMD64
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
#define USE_ASM
#endif
#if !defined(USE_ASM) && _MSC_VER >= 1500
#include <intrin.h>
#endif
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
static UInt32 CheckFlag(UInt32 flag)
{
#ifdef _MSC_VER
__asm pushfd;
__asm pop EAX;
__asm mov EDX, EAX;
__asm xor EAX, flag;
__asm push EAX;
__asm popfd;
__asm pushfd;
__asm pop EAX;
__asm xor EAX, EDX;
__asm push EDX;
__asm popfd;
__asm and flag, EAX;
#else
__asm__ __volatile__ (
"pushf\n\t"
"pop %%EAX\n\t"
"movl %%EAX,%%EDX\n\t"
"xorl %0,%%EAX\n\t"
"push %%EAX\n\t"
"popf\n\t"
"pushf\n\t"
"pop %%EAX\n\t"
"xorl %%EDX,%%EAX\n\t"
"push %%EDX\n\t"
"popf\n\t"
"andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif
return flag;
}
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
#else
#define CHECK_CPUID_IS_SUPPORTED
#endif
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{
#ifdef USE_ASM
#ifdef _MSC_VER
UInt32 a2, b2, c2, d2;
__asm xor EBX, EBX;
__asm xor ECX, ECX;
__asm xor EDX, EDX;
__asm mov EAX, function;
__asm cpuid;
__asm mov a2, EAX;
__asm mov b2, EBX;
__asm mov c2, ECX;
__asm mov d2, EDX;
*a = a2;
*b = b2;
*c = c2;
*d = d2;
#else
__asm__ __volatile__ (
#if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;"
"cpuid;"
"xchgl %%ebx, %%edi;"
: "=a" (*a) ,
"=D" (*b) ,
#else
"cpuid"
: "=a" (*a) ,
"=b" (*b) ,
#endif
"=c" (*c) ,
"=d" (*d)
: "0" (function)) ;
#endif
#else
int CPUInfo[4];
__cpuid(CPUInfo, function);
*a = CPUInfo[0];
*b = CPUInfo[1];
*c = CPUInfo[2];
*d = CPUInfo[3];
#endif
}
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
{
CHECK_CPUID_IS_SUPPORTED
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
return True;
}
static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
{ 0x746E6543, 0x48727561, 0x736C7561}
};
int x86cpuid_GetFirm(const Cx86cpuid *p)
{
unsigned i;
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
{
const UInt32 *v = kVendors[i];
if (v[0] == p->vendor[0] &&
v[1] == p->vendor[1] &&
v[2] == p->vendor[2])
return (int)i;
}
return -1;
}
BoolInt CPU_Is_InOrder()
{
Cx86cpuid p;
int firm;
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
}
return True;
}
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
#include <windows.h>
static BoolInt CPU_Sys_Is_SSE_Supported()
{
OSVERSIONINFO vi;
vi.dwOSVersionInfoSize = sizeof(vi);
if (!GetVersionEx(&vi))
return False;
return (vi.dwMajorVersion >= 5);
}
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
#else
#define CHECK_SYS_SSE_SUPPORT
#endif
BoolInt CPU_Is_Aes_Supported()
{
Cx86cpuid p;
CHECK_SYS_SSE_SUPPORT
if (!x86cpuid_CheckAndRead(&p))
return False;
return (p.c >> 25) & 1;
}
BoolInt CPU_IsSupported_PageGB()
{
Cx86cpuid cpuid;
if (!x86cpuid_CheckAndRead(&cpuid))
return False;
{
UInt32 d[4] = { 0 };
MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
if (d[0] < 0x80000001)
return False;
}
{
UInt32 d[4] = { 0 };
MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
return (d[3] >> 26) & 1;
}
}
#endif
+309 -29
View File
@@ -1,56 +1,336 @@
/* CpuArch.h -- CPU specific code
2010-10-26: Igor Pavlov : Public domain */
2018-02-18 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
#include <retro_endianness.h>
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
/* MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and
CPU supports unaligned memory accesses.
If MY_CPU_LE_UNALIGN is not defined, we don't know
about these properties of platform.
/*
MY_CPU_LE means that CPU is LITTLE ENDIAN.
MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
#define MY_CPU_AMD64
#if defined(_M_X64) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#ifdef __ILP32__
#define MY_CPU_NAME "x32"
#else
#define MY_CPU_NAME "x64"
#endif
#define MY_CPU_64BIT
#endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
#define MY_CPU_32BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86
#if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#define MY_CPU_NAME "arm"
#define MY_CPU_32BIT
#endif
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#else
#define MY_CPU_NAME "ppc64"
#endif
#define MY_CPU_64BIT
#elif defined(__ppc__) \
|| defined(__powerpc__)
#define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
#if defined(__sparc64__)
#define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT
#elif defined(__sparc__)
#define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
#ifdef _WIN32
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#ifdef MY_CPU_ARM
#define MY_CPU_ARM_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64)
#define MY_CPU_LE_UNALIGN
#endif
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef __cplusplus
}
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#endif
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
#error Stop_Compiling_Bad_Endian
#endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
#else
#define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \
((UInt32)((const Byte *)(p))[3] << 24))
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
#ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
#define MY__has_builtin(x) 0
#endif
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
#include <stdlib.h>
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
#else
#define GetBe32(p) ( \
((UInt32)((const Byte *)(p))[0] << 24) | \
((UInt32)((const Byte *)(p))[1] << 16) | \
((UInt32)((const Byte *)(p))[2] << 8) | \
((const Byte *)(p))[3] )
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif
#ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#endif
#ifdef MY_CPU_X86_OR_AMD64
typedef struct
{
UInt32 maxFunc;
UInt32 vendor[3];
UInt32 ver;
UInt32 b;
UInt32 c;
UInt32 d;
} Cx86cpuid;
enum
{
CPU_FIRM_INTEL,
CPU_FIRM_AMD,
CPU_FIRM_VIA
};
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(ver) (ver & 0xF)
BoolInt CPU_Is_InOrder();
BoolInt CPU_Is_Aes_Supported();
BoolInt CPU_IsSupported_PageGB();
#endif
EXTERN_C_END
#endif
+64
View File
@@ -0,0 +1,64 @@
/* Delta.c -- Delta converter
2009-05-26 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Delta.h"
void Delta_Init(Byte *state)
{
unsigned i;
for (i = 0; i < DELTA_STATE_SIZE; i++)
state[i] = 0;
}
static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
{
unsigned i;
for (i = 0; i < size; i++)
dest[i] = src[i];
}
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size)
{
Byte buf[DELTA_STATE_SIZE];
unsigned j = 0;
MyMemCpy(buf, state, delta);
{
SizeT i;
for (i = 0; i < size;)
{
for (j = 0; j < delta && i < size; i++, j++)
{
Byte b = data[i];
data[i] = (Byte)(b - buf[j]);
buf[j] = b;
}
}
}
if (j == delta)
j = 0;
MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j);
}
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
{
Byte buf[DELTA_STATE_SIZE];
unsigned j = 0;
MyMemCpy(buf, state, delta);
{
SizeT i;
for (i = 0; i < size;)
{
for (j = 0; j < delta && i < size; i++, j++)
{
buf[j] = data[i] = (Byte)(buf[j] + data[i]);
}
}
}
if (j == delta)
j = 0;
MyMemCpy(state, buf + j, delta - j);
MyMemCpy(state + delta - j, buf, j);
}
+19
View File
@@ -0,0 +1,19 @@
/* Delta.h -- Delta converter
2013-01-18 : Igor Pavlov : Public domain */
#ifndef __DELTA_H
#define __DELTA_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256
void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
EXTERN_C_END
#endif
+478 -181
View File
File diff suppressed because it is too large. Load diff
+50 -46
View File
@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */
2017-06-10 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
@@ -8,45 +8,47 @@
EXTERN_C_BEGIN
typedef uint32_t CLzRef;
typedef UInt32 CLzRef;
typedef struct _CMatchFinder
{
unsigned char *buffer;
uint32_t pos;
uint32_t posLimit;
uint32_t streamPos;
uint32_t lenLimit;
Byte *buffer;
UInt32 pos;
UInt32 posLimit;
UInt32 streamPos;
UInt32 lenLimit;
uint32_t cyclicBufferPos;
uint32_t cyclicBufferSize; /* it must be = (historySize + 1) */
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
unsigned char streamEndWasReached;
unsigned char btMode;
unsigned char bigHash;
unsigned char directInput;
Byte streamEndWasReached;
Byte btMode;
Byte bigHash;
Byte directInput;
uint32_t matchMaxLen;
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
uint32_t hashMask;
uint32_t cutValue;
UInt32 hashMask;
UInt32 cutValue;
unsigned char *bufferBase;
Byte *bufferBase;
ISeqInStream *stream;
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
uint32_t blockSize;
uint32_t keepSizeBefore;
uint32_t keepSizeAfter;
uint32_t numHashBytes;
UInt32 numHashBytes;
size_t directInputRem;
uint32_t historySize;
uint32_t fixedHashSize;
uint32_t hashSizeSum;
UInt32 historySize;
UInt32 fixedHashSize;
UInt32 hashSizeSum;
SRes result;
uint32_t crc[256];
UInt32 crc[256];
size_t numRefs;
UInt64 expectedDataSize;
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
@@ -57,9 +59,9 @@ typedef struct _CMatchFinder
((p)->streamEndWasReached \
&& (p)->streamPos == (p)->pos \
&& (!(p)->directInput || (p)->directInputRem == 0))
int MatchFinder_NeedMove(CMatchFinder *p);
unsigned char *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p);
@@ -69,16 +71,16 @@ void MatchFinder_Construct(CMatchFinder *p);
historySize <= 3 GB
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
*/
int MatchFinder_Create(CMatchFinder *p, uint32_t historySize,
uint32_t keepAddBufferBefore, uint32_t matchMaxLen, uint32_t keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
void MatchFinder_Normalize3(uint32_t subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, uint32_t subValue);
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
uint32_t * GetMatchesSpec1(uint32_t lenLimit, uint32_t curMatch, uint32_t pos, const unsigned char *buffer, CLzRef *son,
uint32_t _cyclicBufferPos, uint32_t _cyclicBufferSize, uint32_t _cutValue,
uint32_t *distances, uint32_t maxLen);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen);
/*
Conditions:
@@ -87,10 +89,10 @@ Conditions:
*/
typedef void (*Mf_Init_Func)(void *object);
typedef uint32_t (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const unsigned char * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef uint32_t (*Mf_GetMatches_Func)(void *object, uint32_t *distances);
typedef void (*Mf_Skip_Func)(void *object, uint32_t);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder
{
@@ -103,14 +105,16 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_2(CMatchFinder *p, int readData);
void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p);
uint32_t Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances);
uint32_t Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, uint32_t num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, uint32_t num);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
EXTERN_C_END
+13 -12
View File
@@ -12,44 +12,45 @@
#define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
#define HASH2_CALC hv = cur[0] | ((uint32_t)cur[1] << 8);
#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
#define HASH3_CALC { \
uint32_t temp = p->crc[cur[0]] ^ cur[1]; \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \
hv = (temp ^ ((uint32_t)cur[2] << 8)) & p->hashMask; }
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
uint32_t temp = p->crc[cur[0]] ^ cur[1]; \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \
temp ^= ((uint32_t)cur[2] << 8); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
uint32_t temp = p->crc[cur[0]] ^ cur[1]; \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \
temp ^= ((uint32_t)cur[2] << 8); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
temp ^= (p->crc[cur[3]] << 5); \
h4 = temp & (kHash4Size - 1); \
hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
#define HASH_ZIP_CALC hv = ((cur[2] | ((uint32_t)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
uint32_t temp = p->crc[cur[0]] ^ cur[1]; \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \
h3 = (temp ^ ((uint32_t)cur[2] << 8)) & (kHash3Size - 1); }
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
uint32_t temp = p->crc[cur[0]] ^ cur[1]; \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
h2 = temp & (kHash2Size - 1); \
temp ^= ((uint32_t)cur[2] << 8); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+439 -308
View File
@@ -1,357 +1,488 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
2019-02-02 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
#include "Precomp.h"
#ifdef SHOW_DEBUG_INFO
#include <stdio.h>
#endif
#include <stdint.h>
#include <string.h>
#include "Lzma2Dec.h"
/*
00000000 - EOS
00000001 U U - Uncompressed Reset Dic
00000010 U U - Uncompressed No Reset
100uuuuu U U P P - LZMA no reset
101uuuuu U U P P - LZMA reset state
110uuuuu U U P P S - LZMA reset state + new prop
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
00000000 - End of data
00000001 U U - Uncompressed, reset dic, need reset state and set new prop
00000010 U U - Uncompressed, no reset
100uuuuu U U P P - LZMA, no reset
101uuuuu U U P P - LZMA, reset state
110uuuuu U U P P S - LZMA, reset state + set new prop
111uuuuu U U P P S - LZMA, reset state + set new prop, reset dic
u, U - Unpack Size
P - Pack Size
S - Props
*/
u, U - Unpack Size
P - Pack Size
S - Props
*/
#define LZMA2_CONTROL_LZMA (1 << 7)
#define LZMA2_CONTROL_COPY_NO_RESET 2
#define LZMA2_CONTROL_COPY_RESET_DIC 1
#define LZMA2_CONTROL_EOF 0
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
#define LZMA2_LCLP_MAX 4
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((uint32_t)2 | ((p) & 1)) << ((p) / 2 + 11))
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
typedef enum
{
LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK0,
LZMA2_STATE_PACK1,
LZMA2_STATE_PROP,
LZMA2_STATE_DATA,
LZMA2_STATE_DATA_CONT,
LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR
LZMA2_STATE_CONTROL,
LZMA2_STATE_UNPACK0,
LZMA2_STATE_UNPACK1,
LZMA2_STATE_PACK0,
LZMA2_STATE_PACK1,
LZMA2_STATE_PROP,
LZMA2_STATE_DATA,
LZMA2_STATE_DATA_CONT,
LZMA2_STATE_FINISHED,
LZMA2_STATE_ERROR
} ELzma2State;
static SRes Lzma2Dec_GetOldProps(uint8_t prop, uint8_t *props)
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
{
uint32_t dicSize;
if (prop > 40)
return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (uint8_t)LZMA2_LCLP_MAX;
props[1] = (uint8_t)(dicSize);
props[2] = (uint8_t)(dicSize >> 8);
props[3] = (uint8_t)(dicSize >> 16);
props[4] = (uint8_t)(dicSize >> 24);
return SZ_OK;
UInt32 dicSize;
if (prop > 40)
return SZ_ERROR_UNSUPPORTED;
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
props[0] = (Byte)LZMA2_LCLP_MAX;
props[1] = (Byte)(dicSize);
props[2] = (Byte)(dicSize >> 8);
props[3] = (Byte)(dicSize >> 16);
props[4] = (Byte)(dicSize >> 24);
return SZ_OK;
}
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{
uint8_t props[LZMA_PROPS_SIZE];
SRes result = Lzma2Dec_GetOldProps(prop, props);
if (result != 0)
return result;
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc)
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
{
uint8_t props[LZMA_PROPS_SIZE];
SRes result = Lzma2Dec_GetOldProps(prop, props);
if (result != 0)
return result;
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
Byte props[LZMA_PROPS_SIZE];
RINOK(Lzma2Dec_GetOldProps(prop, props));
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
}
void Lzma2Dec_Init(CLzma2Dec *p)
{
p->state = LZMA2_STATE_CONTROL;
p->needInitDic = true;
p->needInitState = true;
p->needInitProp = true;
LzmaDec_Init(&p->decoder);
p->state = LZMA2_STATE_CONTROL;
p->needInitLevel = 0xE0;
p->isExtraMode = False;
p->unpackSize = 0;
/* p->decoder.dicPos = 0; // we can use it instead of full init */
LzmaDec_Init(&p->decoder);
}
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, uint8_t b)
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
switch(p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos));
PRF(printf(" %2X", b));
if (p->control == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if ((p->control & 0x7F) > 2)
return LZMA2_STATE_ERROR;
p->unpackSize = 0;
}
else
p->unpackSize = (uint32_t)(p->control & 0x1F) << 16;
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (uint32_t)b << 8;
return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (uint32_t)b;
p->unpackSize++;
PRF(printf(" %8d", p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (uint32_t)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1:
p->packSize |= (uint32_t)b;
p->packSize++;
PRF(printf(" %8d", p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
case LZMA2_STATE_PROP:
{
int lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = b / 5;
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = lc;
p->decoder.prop.lp = lp;
p->needInitProp = false;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR;
}
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const uint8_t *src, size_t size)
{
memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize;
p->processedPos += (uint32_t)size;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit,
const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
size_t inSize = *srcLen;
*srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_FINISHED)
{
size_t dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->isExtraMode = False;
p->control = b;
PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
PRF(printf(" %02X", (unsigned)b));
if (b == 0)
return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
continue;
}
{
size_t destSizeCur = dicLimit - dicPos;
size_t srcSizeCur = inSize - *srcLen;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (p->unpackSize <= destSizeCur)
{
destSizeCur = (size_t)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->state == LZMA2_STATE_DATA)
{
bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
if (initDic)
p->needInitProp = p->needInitState = true;
else if (p->needInitDic)
return SZ_ERROR_DATA;
p->needInitDic = false;
LzmaDec_InitDicAndState(&p->decoder, initDic, false);
}
if (srcSizeCur > destSizeCur)
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
return SZ_ERROR_DATA;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->unpackSize -= (uint32_t)srcSizeCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
size_t outSizeProcessed;
SRes res;
if (p->state == LZMA2_STATE_DATA)
{
int mode = LZMA2_GET_LZMA_MODE(p);
bool initDic = (mode == 3);
bool initState = (mode > 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
return SZ_ERROR_DATA;
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->needInitDic = false;
p->needInitState = false;
p->state = LZMA2_STATE_DATA_CONT;
}
if (srcSizeCur > p->packSize)
srcSizeCur = (size_t)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
*srcLen += srcSizeCur;
p->packSize -= (uint32_t)srcSizeCur;
outSizeProcessed = p->decoder.dicPos - dicPos;
p->unpackSize -= (uint32_t)outSizeProcessed;
if (res != 0)
return res;
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
return res;
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
p->unpackSize != 0 || p->packSize != 0)
return SZ_ERROR_DATA;
p->state = LZMA2_STATE_CONTROL;
}
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
size_t outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
size_t srcSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
if (outSize > p->decoder.dicBufSize - dicPos)
{
outSizeCur = p->decoder.dicBufSize;
curFinishMode = LZMA_FINISH_ANY;
if (b == LZMA2_CONTROL_COPY_RESET_DIC)
p->needInitLevel = 0xC0;
else if (b > 2 || p->needInitLevel == 0xE0)
return LZMA2_STATE_ERROR;
}
else
{
outSizeCur = dicPos + outSize;
curFinishMode = finishMode;
if (b < p->needInitLevel)
return LZMA2_STATE_ERROR;
p->needInitLevel = 0;
p->unpackSize = (UInt32)(b & 0x1F) << 16;
}
return LZMA2_STATE_UNPACK0;
case LZMA2_STATE_UNPACK0:
p->unpackSize |= (UInt32)b << 8;
return LZMA2_STATE_UNPACK1;
case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b;
p->unpackSize++;
PRF(printf(" %7u", (unsigned)p->unpackSize));
return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0:
p->packSize = (UInt32)b << 8;
return LZMA2_STATE_PACK1;
case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b;
p->packSize++;
/* if (p->packSize < 5) return LZMA2_STATE_ERROR; */
PRF(printf(" %5u", (unsigned)p->packSize));
return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
case LZMA2_STATE_PROP:
{
unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
b /= 9;
p->decoder.prop.pb = (Byte)(b / 5);
lp = b % 5;
if (lc + lp > LZMA2_LCLP_MAX)
return LZMA2_STATE_ERROR;
p->decoder.prop.lc = (Byte)lc;
p->decoder.prop.lp = (Byte)lp;
return LZMA2_STATE_DATA;
}
}
return LZMA2_STATE_ERROR;
}
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
{
memcpy(p->dic + p->dicPos, src, size);
p->dicPos += size;
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
p->checkDicSize = p->prop.dicSize;
p->processedPos += (UInt32)size;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT inSize = *srcLen;
*srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
while (p->state != LZMA2_STATE_ERROR)
{
SizeT dicPos;
if (p->state == LZMA2_STATE_FINISHED)
{
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}
dicPos = p->decoder.dicPos;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
(*srcLen)++;
p->state = Lzma2Dec_UpdateState(p, *src++);
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
break;
continue;
}
{
SizeT inCur = inSize - *srcLen;
SizeT outCur = dicLimit - dicPos;
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
if (outCur >= p->unpackSize)
{
outCur = (SizeT)p->unpackSize;
curFinishMode = LZMA_FINISH_END;
}
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
src += srcSizeCur;
inSize -= srcSizeCur;
*srcLen += srcSizeCur;
outSizeCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
dest += outSizeCur;
outSize -= outSizeCur;
*destLen += outSizeCur;
if (res != 0)
return res;
if (outSizeCur == 0 || outSize == 0)
return SZ_OK;
}
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (inCur == 0)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->state == LZMA2_STATE_DATA)
{
BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
if (inCur > outCur)
inCur = outCur;
if (inCur == 0)
break;
LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
src += inCur;
*srcLen += inCur;
p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
SRes res;
if (p->state == LZMA2_STATE_DATA)
{
BoolInt initDic = (p->control >= 0xE0);
BoolInt initState = (p->control >= 0xA0);
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
p->state = LZMA2_STATE_DATA_CONT;
}
if (inCur > p->packSize)
inCur = (SizeT)p->packSize;
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
src += inCur;
*srcLen += inCur;
p->packSize -= (UInt32)inCur;
outCur = p->decoder.dicPos - dicPos;
p->unpackSize -= (UInt32)outCur;
if (res != 0)
break;
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
{
if (p->packSize == 0)
break;
return SZ_OK;
}
if (inCur == 0 && outCur == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
break;
p->state = LZMA2_STATE_CONTROL;
}
*status = LZMA_STATUS_NOT_SPECIFIED;
}
}
}
*status = LZMA_STATUS_NOT_SPECIFIED;
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen,
uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize,
const Byte *src, SizeT *srcLen,
int checkFinishBlock)
{
SRes res;
SRes result;
CLzma2Dec decoder;
size_t outSize = *destLen, inSize = *srcLen;
uint8_t props[LZMA_PROPS_SIZE];
SizeT inSize = *srcLen;
*srcLen = 0;
Lzma2Dec_Construct(&decoder);
while (p->state != LZMA2_STATE_ERROR)
{
if (p->state == LZMA2_STATE_FINISHED)
return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
decoder.decoder.dic = dest;
decoder.decoder.dicBufSize = outSize;
if (outSize == 0 && !checkFinishBlock)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
(*srcLen)++;
result = Lzma2Dec_GetOldProps(prop, props);
if (result != 0)
return result;
result = LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc);
if (result != 0)
return result;
p->state = Lzma2Dec_UpdateState(p, *src++);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
*destLen = decoder.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
if (p->state == LZMA2_STATE_UNPACK0)
{
/* if (p->decoder.dicPos != 0) */
if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
return LZMA2_PARSE_STATUS_NEW_BLOCK;
/* if (outSize == 0) return LZMA_STATUS_NOT_FINISHED; */
}
LzmaDec_FreeProbs(&decoder.decoder, alloc);
return res;
/* The following code can be commented.
* It's not big problem, if we read additional input bytes.
* It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state. */
if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
{
/* checkFinishBlock is true. So we expect that block must be finished,
* We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
* break; */
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
}
if (p->state == LZMA2_STATE_DATA)
return LZMA2_PARSE_STATUS_NEW_CHUNK;
continue;
}
if (outSize == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
{
SizeT inCur = inSize - *srcLen;
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
{
if (inCur == 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
if (inCur > p->unpackSize)
inCur = p->unpackSize;
if (inCur > outSize)
inCur = outSize;
p->decoder.dicPos += inCur;
src += inCur;
*srcLen += inCur;
outSize -= inCur;
p->unpackSize -= (UInt32)inCur;
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
}
else
{
p->isExtraMode = True;
if (inCur == 0)
{
if (p->packSize != 0)
return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
}
else if (p->state == LZMA2_STATE_DATA)
{
p->state = LZMA2_STATE_DATA_CONT;
if (*src != 0)
{
/* first byte of lzma chunk must be Zero */
*srcLen += 1;
p->packSize--;
break;
}
}
if (inCur > p->packSize)
inCur = (SizeT)p->packSize;
src += inCur;
*srcLen += inCur;
p->packSize -= (UInt32)inCur;
if (p->packSize == 0)
{
SizeT rem = outSize;
if (rem > p->unpackSize)
rem = p->unpackSize;
p->decoder.dicPos += rem;
p->unpackSize -= (UInt32)rem;
outSize -= rem;
if (p->unpackSize == 0)
p->state = LZMA2_STATE_CONTROL;
}
}
}
}
p->state = LZMA2_STATE_ERROR;
return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
}
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{
SizeT outSize = *destLen, inSize = *srcLen;
*srcLen = *destLen = 0;
for (;;)
{
SizeT inCur = inSize, outCur, dicPos;
ELzmaFinishMode curFinishMode;
SRes res;
if (p->decoder.dicPos == p->decoder.dicBufSize)
p->decoder.dicPos = 0;
dicPos = p->decoder.dicPos;
curFinishMode = LZMA_FINISH_ANY;
outCur = p->decoder.dicBufSize - dicPos;
if (outCur >= outSize)
{
outCur = outSize;
curFinishMode = finishMode;
}
res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
src += inCur;
inSize -= inCur;
*srcLen += inCur;
outCur = p->decoder.dicPos - dicPos;
memcpy(dest, p->decoder.dic + dicPos, outCur);
dest += outCur;
outSize -= outCur;
*destLen += outCur;
if (res != 0)
return res;
if (outCur == 0 || outSize == 0)
return SZ_OK;
}
}
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
{
CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
Lzma2Dec_Construct(&p);
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
p.decoder.dic = dest;
p.decoder.dicBufSize = outSize;
Lzma2Dec_Init(&p);
*srcLen = inSize;
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
*destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
Lzma2Dec_FreeProbs(&p, alloc);
return res;
}
+61 -26
View File
@@ -1,39 +1,35 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2009-05-03 : Igor Pavlov : Public domain */
2018-02-19 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
#include <boolean.h>
#include "LzmaDec.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
typedef struct
{
unsigned state;
Byte control;
Byte needInitLevel;
Byte isExtraMode;
Byte _pad_;
UInt32 packSize;
UInt32 unpackSize;
CLzmaDec decoder;
uint32_t packSize;
uint32_t unpackSize;
int state;
uint8_t control;
bool needInitDic;
bool needInitState;
bool needInitProp;
} CLzma2Dec;
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc);
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
@@ -49,11 +45,52 @@ Returns:
SZ_ERROR_DATA - Data error
*/
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit,
const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen,
const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- LZMA2 block and chunk parsing ---------- */
/*
Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
CLzma2Dec::unpackSize contains unpack size of that chunk
*/
typedef enum
{
/*
LZMA_STATUS_NOT_SPECIFIED // data error
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED //
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
*/
LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
LZMA2_PARSE_STATUS_NEW_CHUNK
} ELzma2ParseStatus;
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, /* output size */
const Byte *src, SizeT *srcLen,
int checkFinishBlock /* set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position. */
);
/*
LZMA2 parser doesn't decode LZMA chunks, so we must read
full input LZMA chunk to decode some part of LZMA chunk.
Lzma2Dec_GetUnpackExtra() returns the value that shows
max possible number of output bytes that can be output by decoder
at current input positon.
*/
#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0);
/* ---------- One Call Interface ---------- */
@@ -75,11 +112,9 @@ Returns:
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen,
uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
+998 -882
View File
File diff suppressed because it is too large. Load diff
+175 -161
View File
@@ -1,174 +1,190 @@
/* LzmaDec.h -- LZMA Decoder
2009-02-07 : Igor Pavlov : Public domain */
2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
EXTERN_C_BEGIN
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef _LZMA_PROB32
UInt32
#else
UInt16
#endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
uint32_t dicSize;
} CLzmaProps;
typedef struct _CLzmaProps
{
Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size);
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
CLzmaProps prop;
uint16_t *probs;
uint8_t *dic;
const uint8_t *buf;
uint32_t range, code;
size_t dicPos;
size_t dicBufSize;
uint32_t processedPos;
uint32_t checkDicSize;
unsigned state;
uint32_t reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
uint32_t numProbs;
unsigned tempBufSize;
uint8_t tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const uint8_t *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
typedef struct
{
LzmaDec_Init()
while (it needs more decompression)
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop;
CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic;
SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos;
UInt32 checkDicSize;
UInt32 reps[4];
UInt32 state;
UInt32 remainLen;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
- Stream with end mark. That end mark adds about 6 bytes to compressed size.
- Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Construct()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit,
const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
@@ -179,13 +195,13 @@ SZ_ERROR_DATA - Data error
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen,
const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
@@ -193,28 +209,26 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen,
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen,
const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAllocPtr alloc);
#ifdef __cplusplus
}
#endif
EXTERN_C_END
#endif
+2164 -1500
View File
File diff suppressed because it is too large. Load diff
+29 -33
View File
@@ -1,11 +1,9 @@
/* LzmaEnc.h -- LZMA Encoder
2013-01-18 : Igor Pavlov : Public domain */
2017-07-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
#include <stdint.h>
#include <stddef.h>
#include "7zTypes.h"
EXTERN_C_BEGIN
@@ -14,12 +12,10 @@ EXTERN_C_BEGIN
typedef struct _CLzmaEncProps
{
int level; /* 0 <= level <= 9 */
uint32_t dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
uint64_t reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
Encoder uses this value to reduce dictionary size */
int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (3 << 29) for 64-bit version
default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
@@ -27,53 +23,53 @@ typedef struct _CLzmaEncProps
int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */
uint32_t mc; /* 1 <= mc <= (1 << 30), default = 32 */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
Encoder uses this value to reduce dictionary size */
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p);
uint32_t LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc_* functions can return the following exit codes:
Returns:
/* LzmaEnc* functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error.
SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, unsigned char *properties, size_t *size);
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */
/* LzmaEncode
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
SRes LzmaEncode(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
const CLzmaEncProps *props, unsigned char *propsEncoded, size_t *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END
+10
View File
@@ -0,0 +1,10 @@
/* Precomp.h -- StdAfx
2013-11-12 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "Compiler.h"
/* #include "7zTypes.h" */
#endif
+2
View File
@@ -57,7 +57,9 @@ void Discord_RunCallbacks(void);
/* If you disable the lib starting its own I/O thread,
* you'll need to call this from your own */
#ifdef DISCORD_DISABLE_IO_THREAD
void Discord_UpdateConnection(void);
#endif
void Discord_UpdatePresence(const DiscordRichPresence* presence);
void Discord_ClearPresence(void);
+134 -58
View File
@@ -10,10 +10,22 @@
#include <chrono>
#include <mutex>
#ifndef DISCORD_DISABLE_IO_THREAD
#include <condition_variable>
#include <thread>
#endif
struct QueuedMessage
{
size_t length;
char buffer[16384];
void Copy(const QueuedMessage& other)
{
length = other.length;
if (length)
memcpy(buffer, other.buffer, length);
}
};
struct User
@@ -68,13 +80,66 @@ static User connectedUser;
static Backoff ReconnectTimeMs(500, 60 * 1000);
static auto NextConnect = std::chrono::system_clock::now();
static void update_reconnect_time(void)
#ifndef DISCORD_DISABLE_IO_THREAD
static void Discord_UpdateConnection(void);
class IoThreadHolder
{
private:
std::atomic_bool keepRunning{true};
std::mutex waitForIOMutex;
std::condition_variable waitForIOActivity;
std::thread ioThread;
public:
void Start()
{
keepRunning.store(true);
ioThread = std::thread([&]() {
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
Discord_UpdateConnection();
while (keepRunning.load()) {
std::unique_lock<std::mutex> lock(waitForIOMutex);
waitForIOActivity.wait_for(lock, maxWait);
Discord_UpdateConnection();
}
});
}
void Notify() { waitForIOActivity.notify_all(); }
void Stop()
{
keepRunning.exchange(false);
Notify();
if (ioThread.joinable())
ioThread.join();
}
~IoThreadHolder() { Stop(); }
};
#else
class IoThreadHolder
{
public:
void Start() {}
void Stop() {}
void Notify() {}
};
#endif /* DISCORD_DISABLE_IO_THREAD */
static IoThreadHolder* IoThread{nullptr};
static void UpdateReconnectTime(void)
{
NextConnect = std::chrono::system_clock::now() +
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
}
#ifdef DISCORD_DISABLE_IO_THREAD
extern "C" void Discord_UpdateConnection(void)
#else
static void Discord_UpdateConnection(void)
#endif
{
if (!Connection)
return;
@@ -83,7 +148,7 @@ extern "C" void Discord_UpdateConnection(void)
{
if (std::chrono::system_clock::now() >= NextConnect)
{
update_reconnect_time();
UpdateReconnectTime();
Connection->Open();
}
}
@@ -203,19 +268,16 @@ extern "C" void Discord_UpdateConnection(void)
if (QueuedPresence.length)
{
QueuedMessage local;
std::lock_guard<std::mutex> guard(PresenceMutex);
local.length = QueuedPresence.length;
if (local.length)
memcpy(local.buffer, QueuedPresence.buffer, local.length);
QueuedPresence.length = 0;
{
std::lock_guard<std::mutex> guard(PresenceMutex);
local.Copy(QueuedPresence);
QueuedPresence.length = 0;
}
if (!Connection->Write(local.buffer, local.length))
{
/* if we fail to send, requeue */
std::lock_guard<std::mutex> guard(PresenceMutex);
QueuedPresence.length = local.length;
if (QueuedPresence.length)
memcpy(QueuedPresence.buffer, local.buffer, QueuedPresence.length);
QueuedPresence.Copy(local);
}
}
@@ -236,6 +298,8 @@ static bool RegisterForEvent(const char* evtName)
qmessage->length =
JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
SendQueue.CommitAdd();
if (IoThread)
IoThread->Notify();
return true;
}
return false;
@@ -249,6 +313,8 @@ static bool DeregisterForEvent(const char* evtName)
qmessage->length =
JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName);
SendQueue.CommitAdd();
if (IoThread)
IoThread->Notify();
return true;
}
return false;
@@ -260,6 +326,10 @@ extern "C" void Discord_Initialize(
int autoRegister,
const char* optionalSteamId)
{
IoThread = new (std::nothrow) IoThreadHolder();
if (!IoThread)
return;
if (autoRegister)
{
if (optionalSteamId && optionalSteamId[0])
@@ -284,38 +354,34 @@ extern "C" void Discord_Initialize(
if (Connection)
return;
Connection = RpcConnection::Create(applicationId);
Connection = RpcConnection::Create(applicationId);
Connection->onConnect = [](JsonDocument& readyMessage)
{
Discord_UpdateHandlers(&QueuedHandlers);
char *userId = NULL;
char *username = NULL;
char *avatar = NULL;
char *discriminator = NULL;
bool in_data = false;
bool in_user = false;
Discord_UpdateHandlers(&QueuedHandlers);
bool in_data = false, in_user = false;
for (JsonReader r(readyMessage); r.NextKey();)
{
if (r.depth == 1)
{
in_data = !strcmp(r.key,"data");
in_user = false;
}
else if (r.depth == 2 && in_data)
in_user = !strcmp(r.key, "user");
else if (r.depth == 3 && in_user)
{
if (!strcmp(r.key, "id" ))
r.NextStrDup(&userId);
else if (!strcmp(r.key, "username" ))
r.NextStrDup(&username);
else if (!strcmp(r.key, "avatar" ))
r.NextStrDup(&avatar);
else if (!strcmp(r.key, "discriminator"))
r.NextStrDup(&discriminator);
}
if (r.depth == 1)
{
in_data = !strcmp(r.key,"data");
in_user = false;
}
else if (r.depth == 2 && in_data)
{
in_user = !strcmp(r.key, "user");
}
else if (r.depth == 3 && in_user)
{
if (!strcmp(r.key, "id" )) r.NextStrDup(&userId);
else if (!strcmp(r.key, "username" )) r.NextStrDup(&username);
else if (!strcmp(r.key, "avatar" )) r.NextStrDup(&avatar);
else if (!strcmp(r.key, "discriminator")) r.NextStrDup(&discriminator);
}
}
if (userId && username)
@@ -332,14 +398,10 @@ extern "C" void Discord_Initialize(
WasJustConnected.exchange(true);
ReconnectTimeMs.reset();
if (userId)
free(userId);
if (username)
free(username);
if (avatar)
free(avatar);
if (discriminator)
free(discriminator);
if (userId ) free(userId );
if (username ) free(username );
if (avatar ) free(avatar );
if (discriminator) free(discriminator);
};
Connection->onDisconnect = [](int err, const char* message)
{
@@ -350,8 +412,10 @@ extern "C" void Discord_Initialize(
Handlers = {};
}
WasJustDisconnected.exchange(true);
update_reconnect_time();
UpdateReconnectTime();
};
IoThread->Start();
}
extern "C" void Discord_Shutdown(void)
@@ -360,17 +424,26 @@ extern "C" void Discord_Shutdown(void)
return;
Connection->onConnect = nullptr;
Connection->onDisconnect = nullptr;
Handlers = {};
Handlers = {};
if (IoThread)
{
IoThread->Stop();
delete IoThread;
IoThread = nullptr;
}
RpcConnection::Destroy(Connection);
}
extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence)
{
std::lock_guard<std::mutex> guard(PresenceMutex);
QueuedPresence.length = JsonWriteRichPresenceObj(
QueuedPresence.buffer, sizeof(QueuedPresence.buffer),
Nonce++, Pid, presence);
{
std::lock_guard<std::mutex> guard(PresenceMutex);
QueuedPresence.length = JsonWriteRichPresenceObj(
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
}
if (IoThread)
IoThread->Notify();
}
extern "C" void Discord_ClearPresence(void)
@@ -378,8 +451,7 @@ extern "C" void Discord_ClearPresence(void)
Discord_UpdatePresence(nullptr);
}
extern "C" void Discord_Respond(const char* userId,
/* DISCORD_REPLY_ */ int reply)
extern "C" void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply)
{
/* if we are not connected, let's not batch up stale messages for later */
if (!Connection || !Connection->IsOpen())
@@ -390,6 +462,8 @@ extern "C" void Discord_Respond(const char* userId,
qmessage->length =
JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++);
SendQueue.CommitAdd();
if (IoThread)
IoThread->Notify();
}
}
@@ -456,14 +530,16 @@ extern "C" void Discord_RunCallbacks(void)
*/
while (JoinAskQueue.HavePendingSends())
{
auto req = JoinAskQueue.GetNextSendMessage();
std::lock_guard<std::mutex> guard(HandlerMutex);
if (Handlers.joinRequest)
{
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
Handlers.joinRequest(&du);
}
JoinAskQueue.CommitSend();
auto req = JoinAskQueue.GetNextSendMessage();
{
std::lock_guard<std::mutex> guard(HandlerMutex);
if (Handlers.joinRequest)
{
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
Handlers.joinRequest(&du);
}
}
JoinAskQueue.CommitSend();
}
if (!isConnected)
@@ -1,5 +1,5 @@
#ifndef RCONSOLES_H
#define RCONSOLES_H
#ifndef RC_CONSOLES_H
#define RC_CONSOLES_H
#ifdef __cplusplus
extern "C" {
@@ -32,7 +32,7 @@ enum {
RC_CONSOLE_WII_U = 20,
RC_CONSOLE_PLAYSTATION_2 = 21,
RC_CONSOLE_XBOX = 22,
/* 23 used to be EVENTS */
RC_CONSOLE_MAGNAVOX_ODYSSEY2 = 23,
RC_CONSOLE_POKEMON_MINI = 24,
RC_CONSOLE_ATARI_2600 = 25,
RC_CONSOLE_MS_DOS = 26,
@@ -45,7 +45,7 @@ enum {
RC_CONSOLE_SG1000 = 33,
RC_CONSOLE_VIC20 = 34,
RC_CONSOLE_AMIGA = 35,
RC_CONSOLE_AMIGA_ST = 36,
RC_CONSOLE_ATARI_ST = 36,
RC_CONSOLE_AMSTRAD_PC = 37,
RC_CONSOLE_APPLE_II = 38,
RC_CONSOLE_SATURN = 39,
@@ -65,6 +65,17 @@ enum {
RC_CONSOLE_WONDERSWAN = 53,
RC_CONSOLE_CASSETTEVISION = 54,
RC_CONSOLE_SUPER_CASSETTEVISION = 55,
RC_CONSOLE_NEO_GEO_CD = 56,
RC_CONSOLE_FAIRCHILD_CHANNEL_F = 57,
RC_CONSOLE_FM_TOWNS = 58,
RC_CONSOLE_ZX_SPECTRUM = 59,
RC_CONSOLE_GAME_AND_WATCH = 60,
RC_CONSOLE_NOKIA_NGAGE = 61,
RC_CONSOLE_NINTENDO_3DS = 62,
RC_CONSOLE_SUPERVISION = 63,
RC_CONSOLE_SHARPX1 = 64,
RC_CONSOLE_TIC80 = 65,
RC_CONSOLE_THOMSONTO8 = 66,
RC_CONSOLE_HUBS = 100,
RC_CONSOLE_EVENTS = 101
@@ -76,4 +87,4 @@ const char* rc_console_name(int console_id);
}
#endif
#endif /* RCONSOLES_H */
#endif /* RC_CONSOLES_H */
+1 -1
View File
@@ -5,7 +5,7 @@
#include <stdio.h>
#include <stdint.h>
#include "rconsoles.h"
#include "rc_consoles.h"
#ifdef __cplusplus
extern "C" {
+135 -17
View File
@@ -1,5 +1,5 @@
#include "rcheevos.h"
#include "rconsoles.h"
#include "rc_consoles.h"
#include <ctype.h>
@@ -13,9 +13,6 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_AMIGA:
return "Amiga";
case RC_CONSOLE_AMIGA_ST:
return "Amiga ST";
case RC_CONSOLE_AMSTRAD_PC:
return "Amstrad CPC";
@@ -40,6 +37,9 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_ATARI_LYNX:
return "Atari Lynx";
case RC_CONSOLE_ATARI_ST:
return "Atari ST";
case RC_CONSOLE_CASSETTEVISION:
return "CassetteVision";
@@ -58,6 +58,15 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_EVENTS:
return "Events";
case RC_CONSOLE_FAIRCHILD_CHANNEL_F:
return "Fairchild Channel F";
case RC_CONSOLE_FM_TOWNS:
return "FM Towns";
case RC_CONSOLE_GAME_AND_WATCH:
return "Game & Watch";
case RC_CONSOLE_GAMEBOY:
return "GameBoy";
@@ -79,6 +88,9 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_INTELLIVISION:
return "Intellivision";
case RC_CONSOLE_MAGNAVOX_ODYSSEY2:
return "Magnavox Odyssey 2";
case RC_CONSOLE_MASTER_SYSTEM:
return "Master System";
@@ -91,6 +103,12 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_MSX:
return "MSX";
case RC_CONSOLE_NEO_GEO_CD:
return "Neo Geo CD";
case RC_CONSOLE_NEOGEO_POCKET:
return "Neo Geo Pocket";
case RC_CONSOLE_NINTENDO:
return "Nintendo Entertainment System";
@@ -100,8 +118,11 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_NINTENDO_DS:
return "Nintendo DS";
case RC_CONSOLE_NEOGEO_POCKET:
return "Neo Geo Pocket";
case RC_CONSOLE_NINTENDO_3DS:
return "Nintendo 3DS";
case RC_CONSOLE_NOKIA_NGAGE:
return "Nokia N-Gage";
case RC_CONSOLE_ORIC:
return "Oric";
@@ -142,14 +163,23 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_SG1000:
return "SG-1000";
case RC_CONSOLE_SHARPX1:
return "Sharp X1";
case RC_CONSOLE_SUPER_NINTENDO:
return "Super Nintendo Entertainment System";
case RC_CONSOLE_SUPER_CASSETTEVISION:
return "Super CassetteVision";
case RC_CONSOLE_WONDERSWAN:
return "WonderSwan";
case RC_CONSOLE_SUPERVISION:
return "Watara Supervision";
case RC_CONSOLE_THOMSONTO8:
return "Thomson TO8";
case RC_CONSOLE_TIC80:
return "TIC-80";
case RC_CONSOLE_VECTREX:
return "Vectrex";
@@ -166,6 +196,9 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_WII_U:
return "Wii-U";
case RC_CONSOLE_WONDERSWAN:
return "WonderSwan";
case RC_CONSOLE_X68K:
return "X68K";
@@ -175,6 +208,9 @@ const char* rc_console_name(int console_id)
case RC_CONSOLE_ZX81:
return "ZX-81";
case RC_CONSOLE_ZX_SPECTRUM:
return "ZX Spectrum";
default:
return "Unknown";
}
@@ -302,6 +338,12 @@ static const rc_memory_region_t _rc_memory_regions_intellivision[] = {
};
static const rc_memory_regions_t rc_memory_regions_intellivision = { _rc_memory_regions_intellivision, 9 };
/* ===== Magnavox Odyssey 2 ===== */
static const rc_memory_region_t _rc_memory_regions_magnavox_odyssey_2[] = {
{ 0x000000U, 0x00003FU, 0x000040U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_magnavox_odyssey_2 = { _rc_memory_regions_magnavox_odyssey_2, 1 };
/* ===== Master System ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_master_system[] = {
@@ -349,9 +391,23 @@ static const rc_memory_region_t _rc_memory_regions_nes[] = {
{ 0x2008U, 0x3FFFU, 0x2008U, RC_MEMORY_TYPE_VIRTUAL_RAM, "Mirrored PPU Register" }, /* repeats every 8 bytes */
{ 0x4000U, 0x4017U, 0x4000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O register" },
{ 0x4018U, 0x401FU, 0x4018U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "APU and I/O test register" },
/* NOTE: these are for the original NES/Famicom */
{ 0x4020U, 0x5FFFU, 0x4020U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, /* varies by mapper */
{ 0x6000U, 0x7FFFU, 0x6000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM"},
{ 0x8000U, 0xFFFFU, 0x8000U, RC_MEMORY_TYPE_READONLY, "Cartridge ROM"},
/* NOTE: these are the correct mappings for FDS: https://fms.komkon.org/EMUL8/NES.html
* 0x6000-0xDFFF is RAM on the FDS system and 0xE000-0xFFFF is FDS BIOS.
* If the core implements a memory map, we should still be able to translate the addresses
* correctly as we only use the classifications when a memory map is not provided
{ 0x4020U, 0x40FFU, 0x4020U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "FDS I/O registers"},
{ 0x4100U, 0x5FFFU, 0x4100U, RC_MEMORY_TYPE_READONLY, "Cartridge data"}, // varies by mapper
{ 0x6000U, 0xDFFFU, 0x6000U, RC_MEMORY_TYPE_SYSTEM_RAM, "FDS RAM"},
{ 0xE000U, 0xFFFFU, 0xE000U, RC_MEMORY_TYPE_READONLY, "FDS BIOS ROM"},
*/
};
static const rc_memory_regions_t rc_memory_regions_nes = { _rc_memory_regions_nes, 11 };
@@ -359,7 +415,7 @@ static const rc_memory_regions_t rc_memory_regions_nes = { _rc_memory_regions_ne
/* https://raw.githubusercontent.com/mikeryan/n64dev/master/docs/n64ops/n64ops%23h.txt */
static const rc_memory_region_t _rc_memory_regions_n64[] = {
{ 0x000000U, 0x1FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 1 */
{ 0x200000U, 0x3FFFFFU, 0x00020000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 2 */
{ 0x200000U, 0x3FFFFFU, 0x00200000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }, /* RDRAM 2 */
{ 0x400000U, 0x7FFFFFU, 0x80000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" } /* expansion pak - cannot find any details for real address */
};
static const rc_memory_regions_t rc_memory_regions_n64 = { _rc_memory_regions_n64, 3 };
@@ -386,6 +442,7 @@ static const rc_memory_region_t _rc_memory_regions_pc8800[] = {
static const rc_memory_regions_t rc_memory_regions_pc8800 = { _rc_memory_regions_pc8800, 2 };
/* ===== PC Engine ===== */
/* http://www.archaicpixels.com/Memory_Map */
static const rc_memory_region_t _rc_memory_regions_pcengine[] = {
{ 0x000000U, 0x001FFFU, 0x1F0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x002000U, 0x011FFFU, 0x100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "CD RAM" },
@@ -411,6 +468,14 @@ static const rc_memory_region_t _rc_memory_regions_playstation[] = {
};
static const rc_memory_regions_t rc_memory_regions_playstation = { _rc_memory_regions_playstation, 2 };
/* ===== PlayStation 2 ===== */
/* https://psi-rockin.github.io/ps2tek/ */
static const rc_memory_region_t _rc_memory_regions_playstation2[] = {
{ 0x00000000U, 0x000FFFFFU, 0x00000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Kernel RAM" },
{ 0x00100000U, 0x01FFFFFFU, 0x00100000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_playstation2 = { _rc_memory_regions_playstation2, 2 };
/* ===== Pokemon Mini ===== */
/* https://www.pokemon-mini.net/documentation/memory-map/ */
static const rc_memory_region_t _rc_memory_regions_pokemini[] = {
@@ -420,6 +485,7 @@ static const rc_memory_region_t _rc_memory_regions_pokemini[] = {
static const rc_memory_regions_t rc_memory_regions_pokemini = { _rc_memory_regions_pokemini, 2 };
/* ===== Sega CD ===== */
/* https://en.wikibooks.org/wiki/Genesis_Programming#MegaCD_Changes */
static const rc_memory_region_t _rc_memory_regions_segacd[] = {
{ 0x000000U, 0x00FFFFU, 0x00FF0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "68000 RAM" },
{ 0x010000U, 0x08FFFFU, 0x80020000U, RC_MEMORY_TYPE_SAVE_RAM, "CD PRG RAM" } /* normally banked into $020000-$03FFFF */
@@ -437,12 +503,17 @@ static const rc_memory_regions_t rc_memory_regions_saturn = { _rc_memory_regions
/* ===== SG-1000 ===== */
/* http://www.smspower.org/Development/MemoryMap */
static const rc_memory_region_t _rc_memory_regions_sg1000[] = {
{ 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
/* TODO: should cartridge memory be exposed ($0000-$BFFF)? it's usually just ROM data, but may contain on-cartridge RAM
* This not is also concerning: http://www.smspower.org/Development/MemoryMap
* Cartridges may disable the system RAM and thus take over the full 64KB address space. */
{ 0x000000U, 0x0003FFU, 0xC000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
/* https://github.com/libretro/FBNeo/blob/697801c6262be6ca91615cf905444d3e039bc06f/src/burn/drv/sg1000/d_sg1000.cpp#L210-L237 */
/* Expansion mode B exposes 8KB at $C000. The first 2KB hides the System RAM, but since the address matches,
we'll leverage that definition and expand it another 6KB */
{ 0x000400U, 0x001FFFU, 0xC400U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" },
/* Expansion mode A exposes 8KB at $2000 */
{ 0x002000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" },
/* Othello exposes 2KB at $8000, and The Castle exposes 8KB at $8000 */
{ 0x004000U, 0x005FFFU, 0x8000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Extended RAM" }
};
static const rc_memory_regions_t rc_memory_regions_sg1000 = { _rc_memory_regions_sg1000, 1 };
static const rc_memory_regions_t rc_memory_regions_sg1000 = { _rc_memory_regions_sg1000, 4 };
/* ===== Super Cassette Vision ===== */
static const rc_memory_region_t _rc_memory_regions_scv[] = {
@@ -457,13 +528,36 @@ static const rc_memory_region_t _rc_memory_regions_scv[] = {
static const rc_memory_regions_t rc_memory_regions_scv = { _rc_memory_regions_scv, 7 };
/* ===== Super Nintendo ===== */
/* https://segaretro.org/Sega_Saturn_hardware_notes_(2004-04-27) */
/* https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_memory_map#LoROM */
static const rc_memory_region_t _rc_memory_regions_snes[] = {
{ 0x000000U, 0x01FFFFU, 0x7E0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x020000U, 0x03FFFFU, 0xFE0000U, RC_MEMORY_TYPE_SAVE_RAM, "Cartridge RAM" }
};
static const rc_memory_regions_t rc_memory_regions_snes = { _rc_memory_regions_snes, 2 };
/* ===== Thomson TO8 ===== */
/* https://github.com/mamedev/mame/blob/master/src/mame/drivers/thomson.cpp#L1617 */
static const rc_memory_region_t _rc_memory_regions_thomson_to8[] = {
{ 0x000000U, 0x07FFFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" }
};
static const rc_memory_regions_t rc_memory_regions_thomson_to8 = { _rc_memory_regions_thomson_to8, 1 };
/* ===== TIC-80 ===== */
/* https://github.com/nesbox/TIC-80/wiki/RAM */
static const rc_memory_region_t _rc_memory_regions_tic80[] = {
{ 0x000000U, 0x003FFFU, 0x000000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Video RAM" }, /* have to classify this as system RAM because the core exposes it as part of the RETRO_MEMORY_SYSTEM_RAM */
{ 0x004000U, 0x005FFFU, 0x004000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Tile RAM" },
{ 0x006000U, 0x007FFFU, 0x006000U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite RAM" },
{ 0x008000U, 0x00FF7FU, 0x008000U, RC_MEMORY_TYPE_SYSTEM_RAM, "MAP RAM" },
{ 0x00FF80U, 0x00FF8BU, 0x00FF80U, RC_MEMORY_TYPE_SYSTEM_RAM, "Input State" },
{ 0x00FF8CU, 0x014003U, 0x00FF8CU, RC_MEMORY_TYPE_SYSTEM_RAM, "Sound RAM" },
{ 0x014004U, 0x014403U, 0x014004U, RC_MEMORY_TYPE_SAVE_RAM, "Persistent Memory" }, /* this is also returned as part of RETRO_MEMORY_SYSTEM_RAM, but can be extrapolated correctly because the pointer starts at the first SYSTEM_RAM region */
{ 0x014404U, 0x014603U, 0x014404U, RC_MEMORY_TYPE_SYSTEM_RAM, "Sprite Flags" },
{ 0x014604U, 0x014E03U, 0x014604U, RC_MEMORY_TYPE_SYSTEM_RAM, "System Font" },
{ 0x014E04U, 0x017FFFU, 0x014E04U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM"}
};
static const rc_memory_regions_t rc_memory_regions_tic80 = { _rc_memory_regions_tic80, 10 };
/* ===== Vectrex ===== */
/* https://roadsidethoughts.com/vectrex/vectrex-memory-map.htm */
static const rc_memory_region_t _rc_memory_regions_vectrex[] = {
@@ -478,6 +572,15 @@ static const rc_memory_region_t _rc_memory_regions_virtualboy[] = {
};
static const rc_memory_regions_t rc_memory_regions_virtualboy = { _rc_memory_regions_virtualboy, 2 };
/* ===== Watara Supervision ===== */
/* https://github.com/libretro/potator/blob/b5e5ba02914fcdf4a8128072dbc709da28e08832/common/memorymap.c#L231-L259 */
static const rc_memory_region_t _rc_memory_regions_watara_supervision[] = {
{ 0x0000U, 0x001FFFU, 0x0000U, RC_MEMORY_TYPE_SYSTEM_RAM, "System RAM" },
{ 0x2000U, 0x003FFFU, 0x2000U, RC_MEMORY_TYPE_HARDWARE_CONTROLLER, "Registers" },
{ 0x4000U, 0x005FFFU, 0x4000U, RC_MEMORY_TYPE_VIDEO_RAM, "Video RAM" }
};
static const rc_memory_regions_t rc_memory_regions_watara_supervision = { _rc_memory_regions_watara_supervision, 3 };
/* ===== WonderSwan ===== */
/* http://daifukkat.su/docs/wsman/#ovr_memmap */
static const rc_memory_region_t _rc_memory_regions_wonderswan[] = {
@@ -538,6 +641,9 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
case RC_CONSOLE_INTELLIVISION:
return &rc_memory_regions_intellivision;
case RC_CONSOLE_MAGNAVOX_ODYSSEY2:
return &rc_memory_regions_magnavox_odyssey_2;
case RC_CONSOLE_MASTER_SYSTEM:
return &rc_memory_regions_master_system;
@@ -572,11 +678,14 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
return &rc_memory_regions_pcengine;
case RC_CONSOLE_PCFX:
return &rc_memory_regions_pcfx;
return &rc_memory_regions_pcfx;
case RC_CONSOLE_PLAYSTATION:
return &rc_memory_regions_playstation;
case RC_CONSOLE_PLAYSTATION_2:
return &rc_memory_regions_playstation2;
case RC_CONSOLE_POKEMON_MINI:
return &rc_memory_regions_pokemini;
@@ -595,6 +704,15 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
case RC_CONSOLE_SUPER_NINTENDO:
return &rc_memory_regions_snes;
case RC_CONSOLE_SUPERVISION:
return &rc_memory_regions_watara_supervision;
case RC_CONSOLE_THOMSONTO8:
return &rc_memory_regions_thomson_to8;
case RC_CONSOLE_TIC80:
return &rc_memory_regions_tic80;
case RC_CONSOLE_VECTREX:
return &rc_memory_regions_vectrex;
@@ -602,7 +720,7 @@ const rc_memory_regions_t* rc_console_memory_regions(int console_id)
return &rc_memory_regions_virtualboy;
case RC_CONSOLE_WONDERSWAN:
return &rc_memory_regions_wonderswan;
return &rc_memory_regions_wonderswan;
default:
return &rc_memory_regions_none;
+5 -1
View File
@@ -151,6 +151,10 @@ int rc_lboard_size(const char* memaddr) {
rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
rc_lboard_t* self;
rc_parse_state_t parse;
if (!buffer || !memaddr)
return 0;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
self = RC_ALLOC(rc_lboard_t, &parse);
@@ -159,7 +163,7 @@ rc_lboard_t* rc_parse_lboard(void* buffer, const char* memaddr, lua_State* L, in
rc_parse_lboard_internal(self, memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
return (parse.offset >= 0) ? self : 0;
}
int rc_evaluate_lboard(rc_lboard_t* self, int* value, rc_peek_t peek, void* peek_ud, lua_State* L) {
+5 -1
View File
@@ -394,6 +394,10 @@ int rc_richpresence_size(const char* script) {
rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_State* L, int funcs_ndx) {
rc_richpresence_t* self;
rc_parse_state_t parse;
if (!buffer || !script)
return 0;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
self = RC_ALLOC(rc_richpresence_t, &parse);
@@ -402,7 +406,7 @@ rc_richpresence_t* rc_parse_richpresence(void* buffer, const char* script, lua_S
rc_parse_richpresence_internal(self, script, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
return (parse.offset >= 0) ? self : 0;
}
int rc_evaluate_richpresence(rc_richpresence_t* richpresence, char* buffer, unsigned buffersize, rc_peek_t peek, void* peek_ud, lua_State* L) {
+5 -1
View File
@@ -58,6 +58,10 @@ int rc_trigger_size(const char* memaddr) {
rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
rc_trigger_t* self;
rc_parse_state_t parse;
if (!buffer || !memaddr)
return 0;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
self = RC_ALLOC(rc_trigger_t, &parse);
@@ -66,7 +70,7 @@ rc_trigger_t* rc_parse_trigger(void* buffer, const char* memaddr, lua_State* L,
rc_parse_trigger_internal(self, &memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
return (parse.offset >= 0) ? self : 0;
}
static void rc_reset_trigger_hitcounts(rc_trigger_t* self) {
+5 -1
View File
@@ -201,6 +201,10 @@ int rc_value_size(const char* memaddr) {
rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int funcs_ndx) {
rc_value_t* self;
rc_parse_state_t parse;
if (!buffer || !memaddr)
return 0;
rc_init_parse_state(&parse, buffer, L, funcs_ndx);
self = RC_ALLOC(rc_value_t, &parse);
@@ -209,7 +213,7 @@ rc_value_t* rc_parse_value(void* buffer, const char* memaddr, lua_State* L, int
rc_parse_value_internal(self, &memaddr, &parse);
rc_destroy_parse_state(&parse);
return parse.offset >= 0 ? self : 0;
return (parse.offset >= 0) ? self : 0;
}
int rc_evaluate_value(rc_value_t* self, rc_peek_t peek, void* ud, lua_State* L) {
+60
View File
@@ -19,6 +19,7 @@
#include <streams/file_stream.h>
#if defined(DINGUX_BETA)
#include <string/stdstring.h>
#include <stdlib.h>
#endif
@@ -37,6 +38,7 @@
#define DINGUX_BATTERY_VOLTAGE_NOW "/sys/class/power_supply/jz-battery/voltage_now"
#define DINGUX_SCALING_MODE_ENVAR "SDL_VIDEO_KMSDRM_SCALING_MODE"
#define DINGUX_SCALING_SHARPNESS_ENVAR "SDL_VIDEO_KMSDRM_SCALING_SHARPNESS"
#define DINGUX_VIDEO_REFRESHRATE_ENVAR "SDL_VIDEO_REFRESHRATE"
/* Enables/disables downscaling when using
* the IPU hardware scaler */
@@ -162,6 +164,63 @@ bool dingux_ipu_set_filter_type(enum dingux_ipu_filter_type filter_type)
#endif
}
#if defined(DINGUX_BETA)
/* Sets the refresh rate of the integral LCD panel.
* If specified value is invalid, will set refresh
* rate to 60 Hz.
* Returns a floating point representation of the
* resultant hardware refresh rate. In the event
* that a refresh rate cannot be set (i.e. hardware
* error), returns 0.0 */
float dingux_set_video_refresh_rate(enum dingux_refresh_rate refresh_rate)
{
float refresh_rate_float = 60.0f;
const char *refresh_rate_str = "60";
/* Check filter type */
switch (refresh_rate)
{
case DINGUX_REFRESH_RATE_50HZ:
refresh_rate_float = 50.0f;
refresh_rate_str = "50";
break;
default:
/* Refresh rate is already set to 60 Hz
* by default */
break;
}
if (setenv(DINGUX_VIDEO_REFRESHRATE_ENVAR, refresh_rate_str, 1) != 0)
refresh_rate_float = 0.0f;
return refresh_rate_float;
}
/* Gets the currently set refresh rate of the
* integral LCD panel. */
bool dingux_get_video_refresh_rate(enum dingux_refresh_rate *refresh_rate)
{
const char *refresh_rate_str = getenv(DINGUX_VIDEO_REFRESHRATE_ENVAR);
/* If environment variable is unset, refresh
* rate defaults to 60 Hz */
if (!refresh_rate_str)
{
*refresh_rate = DINGUX_REFRESH_RATE_60HZ;
return true;
}
if (string_is_equal(refresh_rate_str, "60"))
*refresh_rate = DINGUX_REFRESH_RATE_60HZ;
else if (string_is_equal(refresh_rate_str, "50"))
*refresh_rate = DINGUX_REFRESH_RATE_50HZ;
else
return false;
return true;
}
#endif
/* Resets the IPU hardware scaler to the
* default configuration */
bool dingux_ipu_reset(void)
@@ -169,6 +228,7 @@ bool dingux_ipu_reset(void)
#if defined(DINGUX_BETA)
unsetenv(DINGUX_SCALING_MODE_ENVAR);
unsetenv(DINGUX_SCALING_SHARPNESS_ENVAR);
unsetenv(DINGUX_VIDEO_REFRESHRATE_ENVAR);
return true;
#else
return dingux_ipu_set_scaling_mode(true, false) &&
+28
View File
@@ -38,6 +38,17 @@ enum dingux_ipu_filter_type
DINGUX_IPU_FILTER_LAST
};
#if defined(DINGUX_BETA)
/* Specifies all video refresh rates supported
* by OpenDingux Beta */
enum dingux_refresh_rate
{
DINGUX_REFRESH_RATE_60HZ = 0,
DINGUX_REFRESH_RATE_50HZ,
DINGUX_REFRESH_RATE_LAST
};
#endif
/* Enables/disables downscaling when using
* the IPU hardware scaler */
bool dingux_ipu_set_downscaling_enable(bool enable);
@@ -66,6 +77,23 @@ bool dingux_ipu_set_scaling_mode(bool keep_aspect, bool integer_scale);
* using the IPU hardware scaler */
bool dingux_ipu_set_filter_type(enum dingux_ipu_filter_type filter_type);
#if defined(DINGUX_BETA)
/* Sets the refresh rate of the integral LCD panel.
* If specified value is invalid, will set refresh
* rate to 60 Hz.
* Returns a floating point representation of the
* resultant hardware refresh rate. In the event
* that a refresh rate cannot be set (i.e. hardware
* error), returns 0.0 */
float dingux_set_video_refresh_rate(enum dingux_refresh_rate refresh_rate);
/* Gets the currently set refresh rate of the
* integral LCD panel.
* Returns false if hardware is in an undefined
* state. */
bool dingux_get_video_refresh_rate(enum dingux_refresh_rate *refresh_rate);
#endif
/* Resets the IPU hardware scaler to the
* default configuration */
bool dingux_ipu_reset(void);
+3 -1
View File
@@ -100,7 +100,7 @@ static void frontend_ctr_get_env(int* argc, char* argv[],
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], g_defaults.dirs[DEFAULT_DIR_PORT],
"downloads", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_ASSETS], g_defaults.dirs[DEFAULT_DIR_PORT],
"media", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
"assets", sizeof(g_defaults.dirs[DEFAULT_DIR_ASSETS]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], g_defaults.dirs[DEFAULT_DIR_PORT],
"cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], g_defaults.dirs[DEFAULT_DIR_CORE],
@@ -123,6 +123,8 @@ static void frontend_ctr_get_env(int* argc, char* argv[],
"filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], g_defaults.dirs[DEFAULT_DIR_PORT],
"filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_OVERLAY], g_defaults.dirs[DEFAULT_DIR_PORT],
"overlays/ctr", sizeof(g_defaults.dirs[DEFAULT_DIR_OVERLAY]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_DATABASE], g_defaults.dirs[DEFAULT_DIR_PORT],
"database/rdb", sizeof(g_defaults.dirs[DEFAULT_DIR_DATABASE]));
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CURSOR], g_defaults.dirs[DEFAULT_DIR_PORT],
+1 -2
View File
@@ -221,9 +221,8 @@ static void frontend_orbis_deinit(void *data)
#ifndef IS_SALAMANDER
verbosity_disable();
#ifdef HAVE_FILE_LOGGER
command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL);
retro_main_log_file_deinit();
#endif
#endif
ps4LinkFinish();
}
+17
View File
@@ -109,6 +109,13 @@ typedef struct ctr_video
bool supports_parallax_disable;
bool enable_3d;
#ifdef HAVE_OVERLAY
struct ctr_overlay_data *overlay;
unsigned overlays;
bool overlay_enabled;
bool overlay_full_screen;
#endif
void* empty_framebuffer;
aptHookCookie lcd_aptHook;
@@ -139,6 +146,16 @@ typedef struct ctr_texture
void* data;
} ctr_texture_t;
#ifdef HAVE_OVERLAY
struct ctr_overlay_data
{
ctr_texture_t texture;
ctr_vertex_t* frame_coords;
ctr_scale_vector_t scale_vector;
float alpha_mod;
};
#endif
static INLINE void ctr_set_scale_vector(ctr_scale_vector_t* vec,
int viewport_width, int viewport_height,
int texture_width, int texture_height)
+9 -3
View File
@@ -121,6 +121,12 @@ bool drm_get_connector(int fd, unsigned monitor_index)
return true;
}
float drm_calc_refresh_rate(drmModeModeInfo *mode)
{
float refresh_rate = (mode->clock * 1000.0f) / (mode->htotal * mode->vtotal);
return refresh_rate;
}
bool drm_get_encoder(int fd)
{
unsigned i;
@@ -147,12 +153,12 @@ bool drm_get_encoder(int fd)
for (i = 0; (int)i < g_drm_connector->count_modes; i++)
{
RARCH_LOG("[DRM]: Mode %d: (%s) %d x %d, %u Hz\n",
RARCH_LOG("[DRM]: Mode %d: (%s) %d x %d, %f Hz\n",
i,
g_drm_connector->modes[i].name,
g_drm_connector->modes[i].hdisplay,
g_drm_connector->modes[i].vdisplay,
g_drm_connector->modes[i].vrefresh);
drm_calc_refresh_rate(&g_drm_connector->modes[i]));
}
return true;
@@ -173,7 +179,7 @@ float drm_get_refresh_rate(void *data)
if (g_drm_mode)
{
refresh_rate = g_drm_mode->clock * 1000.0f / g_drm_mode->htotal / g_drm_mode->vtotal;
refresh_rate = drm_calc_refresh_rate(g_drm_mode);
}
return refresh_rate;
+2
View File
@@ -43,6 +43,8 @@ extern drmModeCrtc *g_orig_crtc;
extern drmEventContext g_drm_evctx;
float drm_calc_refresh_rate(drmModeModeInfo *mode);
bool drm_get_encoder(int fd);
/* Restore the original CRTC. */
+11 -1
View File
@@ -232,6 +232,12 @@ typedef LONG (WINAPI *GETDISPLAYCONFIGBUFFERSIZES)(UINT32, UINT32*, UINT32*);
HACCEL window_accelerators;
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined(__MINGW32__)
#ifndef _XBOX
#define HAVE_CLIP_WINDOW
#endif
#endif
/* Power Request APIs */
#if !defined(_XBOX) && (_MSC_VER == 1310)
@@ -1030,6 +1036,7 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd,
taskbar_is_created = true;
#endif
break;
#ifdef HAVE_CLIP_WINDOW
case WM_SETFOCUS:
if (input_mouse_grabbed())
win32_clip_window(true);
@@ -1038,6 +1045,7 @@ static LRESULT CALLBACK wnd_proc_common_internal(HWND hwnd,
if (input_mouse_grabbed())
win32_clip_window(false);
break;
#endif
}
return DefWindowProc(hwnd, message, wparam, lparam);
@@ -1144,6 +1152,7 @@ static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd,
taskbar_is_created = true;
#endif
break;
#ifdef HAVE_CLIP_WINDOW
case WM_SETFOCUS:
if (input_mouse_grabbed())
win32_clip_window(true);
@@ -1152,6 +1161,7 @@ static LRESULT CALLBACK wnd_proc_common_dinput_internal(HWND hwnd,
if (input_mouse_grabbed())
win32_clip_window(false);
break;
#endif
}
return DefWindowProc(hwnd, message, wparam, lparam);
@@ -1561,7 +1571,7 @@ void win32_check_window(void *data,
void win32_clip_window(bool state)
{
#if !defined(_XBOX)
#ifdef HAVE_CLIP_WINDOW
RECT clip_rect;
if (state && main_window.hwnd)
+35 -8
View File
@@ -261,11 +261,14 @@ static bool x11_display_server_set_resolution(void *data,
XRRSetCrtcConfig(dpy, res,res->crtcs[i], CurrentTime,
0, 0, None, RR_Rotate_0, NULL, 0);
XSync(dpy, False);
XRRSetScreenSize(dpy, window, width, height, (int) ((25.4 * width) / 96.0), (int) ((25.4 * height) / 96.0));
XSync(dpy, False);
XRRSetCrtcConfig(dpy, res, res->crtcs[i], CurrentTime,
crtc->x, crtc->y, crtc->mode, crtc->rotation,
crtc->outputs, crtc->noutput);
XSync(dpy, False);
XRRFreeCrtcInfo(crtc);
}
@@ -292,13 +295,13 @@ static bool x11_display_server_set_resolution(void *data,
XRRSetCrtcConfig(dpy, res,res->crtcs[monitor_index], CurrentTime,
0, 0, None, RR_Rotate_0, NULL, 0);
XSync(dpy, False);
XRRSetScreenSize(dpy, window, width, height, (int) ((25.4 * width) / 96.0), (int) ((25.4 * height) / 96.0));
XSync(dpy, False);
XRRSetCrtcConfig(dpy, res, res->crtcs[monitor_index], CurrentTime,
crtc->x, crtc->y, crtc->mode, crtc->rotation,
crtc->outputs, crtc->noutput);
XSync(dpy, False);
XRRFreeCrtcInfo(crtc);
}
XRRFreeOutputInfo(outputs);
@@ -579,6 +582,29 @@ static void x11_display_server_destroy(void *data)
}
XRRFreeOutputInfo(outputs);
}
for (m = 0; m < resources->nmode; m++)
{
for (j = 0; j < res->noutput; j++)
{
for (i = 1 ; i <= dispserv->crt_name_id; i++ )
{
XRROutputInfo *outputs = XRRGetOutputInfo(dpy, res, res->outputs[j]);
if (outputs->connection == RR_Connected)
{
snprintf(dispserv->old_mode, sizeof(dispserv->old_mode),
"CRT%d", i);
if (string_is_equal(resources->modes[m].name,
dispserv->old_mode))
{
swoldmode = &resources->modes[m];
XRRDeleteOutputMode(dpy, res->outputs[j], swoldmode->id);
XRRDestroyMode(dpy, swoldmode->id);
XSync(dpy, False);
}
}
}
}
}
}
else
{
@@ -611,15 +637,13 @@ static void x11_display_server_destroy(void *data)
XRRFreeCrtcInfo(crtc);
}
XRRFreeOutputInfo(outputs);
}
for (m = 0; m < resources->nmode; m++)
{
for (j = 0; j < res->noutput; j++)
for (m = 0; m < resources->nmode; m++)
{
for (i = 1 ; i <= dispserv->crt_name_id; i++ )
{
XRROutputInfo *outputs = XRRGetOutputInfo(dpy, res, res->outputs[j]);
XRROutputInfo *outputs = XRRGetOutputInfo(dpy, res, res->outputs[dispserv->monitor_index]);
if (outputs->connection == RR_Connected)
{
snprintf(dispserv->old_mode, sizeof(dispserv->old_mode),
@@ -628,14 +652,17 @@ static void x11_display_server_destroy(void *data)
dispserv->old_mode))
{
swoldmode = &resources->modes[m];
XRRDeleteOutputMode(dpy, res->outputs[j], swoldmode->id);
XRRDeleteOutputMode(dpy, res->outputs[dispserv->monitor_index], swoldmode->id);
XRRDestroyMode(dpy, swoldmode->id);
XSync(dpy, False);
}
}
}
}
}
XRRFreeScreenResources(resources);
XRRFreeScreenResources(res);
XCloseDisplay(dpy);
+242 -9
View File
@@ -144,6 +144,24 @@ static INLINE void ctr_set_screen_coords(ctr_video_t * ctr)
}
}
#ifdef HAVE_OVERLAY
static void ctr_render_overlay(void *data);
static void ctr_free_overlay(ctr_video_t *ctr)
{
unsigned i;
for (i = 0; i < ctr->overlays; i++)
{
linearFree(ctr->overlay[i].frame_coords);
linearFree(ctr->overlay[i].texture.data);
}
free(ctr->overlay);
ctr->overlay = NULL;
ctr->overlays = 0;
}
#endif
static void ctr_update_viewport(
ctr_video_t* ctr,
settings_t *settings,
@@ -895,6 +913,11 @@ static bool ctr_frame(void* data, const void* frame,
}
#endif
#ifdef HAVE_OVERLAY
if (ctr->overlay_enabled)
ctr_render_overlay(ctr);
#endif
#ifdef HAVE_GFX_WIDGETS
if (widgets_active)
gfx_widgets_frame(video_info);
@@ -1191,10 +1214,10 @@ static uintptr_t ctr_load_texture(void *video_data, void *data,
{
((uint32_t*)texture->data)[ctrgu_swizzle_coords(i, j,
texture->width)] =
((*src >> 8) & 0x00FF00)
| ((*src >> 24) & 0xFF)
| ((*src << 8) & 0xFF0000)
| ((*src << 24) & 0xFF000000);
((*src << 8) & 0xFF000000)
| ((*src << 8) & 0x00FF0000)
| ((*src << 8) & 0x0000FF00)
| ((*src >> 24) & 0x000000FF);
src++;
}
GSPGPU_FlushDataCache(texture->data, texture->width
@@ -1221,10 +1244,10 @@ static uintptr_t ctr_load_texture(void *video_data, void *data,
for (i = 0; i < image->width * image->height; i++)
{
*dst =
((*src >> 8) & 0x00FF00)
| ((*src >> 24) & 0xFF)
| ((*src << 8) & 0xFF0000)
| ((*src << 24) & 0xFF000000);
((*src << 8) & 0xFF000000)
| ((*src << 8) & 0x00FF0000)
| ((*src << 8) & 0x0000FF00)
| ((*src >> 24) & 0x000000FF);
dst++;
src++;
}
@@ -1264,6 +1287,216 @@ static void ctr_unload_texture(void *data, bool threaded,
free(texture);
}
#ifdef HAVE_OVERLAY
static void ctr_overlay_tex_geom(void *data,
unsigned image, float x, float y, float w, float h)
{
ctr_video_t *ctr = (ctr_video_t *)data;
struct ctr_overlay_data *o = NULL;
if (ctr)
o = (struct ctr_overlay_data *)&ctr->overlay[image];
if (!o)
return;
// printf("tex_geom[%i]: %i, %i, %.6f, %.6f\n%.6f, %.6f, ", image, o->texture.width, o->texture.height,x,y,w,h);
o->frame_coords->u0 = x*o->texture.width;
o->frame_coords->v0 = y*o->texture.height;
o->frame_coords->u1 = w*o->texture.width;
o->frame_coords->v1 = h*o->texture.height;
// printf("tex_geom[%i]: %i, %i, %i, %i\n", image, o->frame_coords->u0,o->frame_coords->v0,o->frame_coords->u1,o->frame_coords->v1);
GSPGPU_FlushDataCache(o->frame_coords, sizeof(ctr_vertex_t));
}
static void ctr_overlay_vertex_geom(void *data,
unsigned image, float x, float y, float w, float h)
{
ctr_video_t *ctr = (ctr_video_t *)data;
struct ctr_overlay_data *o = NULL;
if (ctr)
o = (struct ctr_overlay_data *)&ctr->overlay[image];
if (!o)
return;
// printf("vertex_geom[%i]: %.6f, %.6f, %.6f, %.6f, ", image, x,y,w,h);
o->frame_coords->x0 = x * CTR_TOP_FRAMEBUFFER_WIDTH;
o->frame_coords->y0 = y * CTR_TOP_FRAMEBUFFER_HEIGHT;
o->frame_coords->x1 = w * (o->frame_coords->x0 + o->texture.width);
o->frame_coords->y1 = h * (o->frame_coords->y0 + o->texture.height);
// printf("vertex_geom[%i]: %i, %i, %i, %i\n", image, o->frame_coords->x0,o->frame_coords->y0,o->frame_coords->x1,o->frame_coords->y1);
GSPGPU_FlushDataCache(o->frame_coords, sizeof(ctr_vertex_t));
}
static bool ctr_overlay_load(void *data,
const void *image_data, unsigned num_images)
{
void* tmpdata;
unsigned i, j;
ctr_texture_t *texture = NULL;
ctr_video_t *ctr = (ctr_video_t *)data;
struct texture_image *images = (struct texture_image *)image_data;
ctr_free_overlay(ctr);
ctr->overlay = (struct ctr_overlay_data *)calloc(num_images, sizeof(*ctr->overlay));
if (!ctr)
return false;
ctr->overlays = num_images;
for (i = 0; i < num_images; i++)
{
struct ctr_overlay_data *o = (struct ctr_overlay_data *)&ctr->overlay[i];
o->frame_coords = linearAlloc(sizeof(ctr_vertex_t));
if (!ctr || !images || images[i].width > 1024 || images[i].height > 1024)
return 0;
memset(&o->texture, 0, sizeof(ctr_texture_t));
o->texture.width = next_pow2(images[i].width);
o->texture.height = next_pow2(images[i].height);
o->texture.data = linearAlloc(
o->texture.width * o->texture.height * sizeof(uint32_t));
if (!o->texture.data)
{
free(o);
return 0;
}
uint32_t *src = NULL;
uint32_t *dst = NULL;
tmpdata = linearAlloc(images[i].width
* images[i].height * sizeof(uint32_t));
if (!tmpdata)
{
linearFree(o->texture.data);
free(o);
return 0;
}
src = (uint32_t*)images[i].pixels;
dst = (uint32_t*)tmpdata;
for (j = 0; j < images[i].width * images[i].height; j++)
{
*dst =
((*src << 8) & 0xFF000000)
| ((*src << 8) & 0x00FF0000)
| ((*src << 8) & 0x0000FF00)
| ((*src >> 24) & 0x000000FF);
dst++;
src++;
}
GSPGPU_FlushDataCache(tmpdata,
images[i].width * images[i].height * sizeof(uint32_t));
ctrGuCopyImage(true, tmpdata,
images[i].width, images[i].height, CTRGU_RGBA8, false,
o->texture.data, o->texture.width, CTRGU_RGBA8, true);
ctr->ppf_event_pending = true;
linearFree(tmpdata);
ctr_overlay_tex_geom(ctr, i, 0, 0, 1, 1);
ctr_overlay_vertex_geom(ctr, i, 0, 0, 1, 1);
ctr_set_scale_vector(&o->scale_vector,
CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT,
o->texture.width, o->texture.height);
ctr->overlay[i].alpha_mod = 1.0f;
}
return true;
}
static void ctr_overlay_enable(void *data, bool state)
{
ctr_video_t *ctr = (ctr_video_t *)data;
if (!ctr)
return;
ctr->overlay_enabled = state;
}
static void ctr_overlay_full_screen(void *data, bool enable)
{
ctr_video_t *ctr = (ctr_video_t *)data;
ctr->overlay_full_screen = enable;
}
static void ctr_overlay_set_alpha(void *data, unsigned image, float mod){ }
static void ctr_render_overlay(void *data)
{
unsigned i;
ctr_video_t *ctr = (ctr_video_t*)data;
for (i = 0; i < ctr->overlays; i++)
{
ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->overlay[i].texture.data), ctr->overlay[i].texture.width, ctr->overlay[i].texture.height,
GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
GPU_RGBA8);
GPUCMD_AddWrite(GPUREG_GSH_BOOLUNIFORM, 0);
ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->overlay[i].scale_vector, 1);
ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->overlay[i].frame_coords));
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_2D_800X240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
{
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.right),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
}
}
}
static const video_overlay_interface_t ctr_overlay = {
ctr_overlay_enable,
ctr_overlay_load,
ctr_overlay_tex_geom,
ctr_overlay_vertex_geom,
ctr_overlay_full_screen,
ctr_overlay_set_alpha,
};
void ctr_overlay_interface(void *data, const video_overlay_interface_t **iface)
{
ctr_video_t *ctr = (ctr_video_t *)data;
if (!ctr)
return;
*iface = &ctr_overlay;
}
#endif
static void ctr_set_osd_msg(void *data,
const char *msg,
const void *params, void *font)
@@ -1348,7 +1581,7 @@ video_driver_t video_ctr =
NULL, /* read_viewport */
NULL, /* read_frame_raw */
#ifdef HAVE_OVERLAY
NULL,
ctr_overlay_interface,
#endif
#ifdef HAVE_VIDEO_LAYOUT
NULL,
+122 -24
View File
@@ -42,6 +42,9 @@
#include "../../gfx/drivers_font_renderer/bitmap.h"
#include "../../configuration.h"
#include "../../retroarch.h"
#if defined(DINGUX_BETA)
#include "../../driver.h"
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
@@ -51,11 +54,10 @@
#define SDL_DINGUX_NUM_FONT_GLYPHS 256
#define SDL_DINGUX_FF_FRAME_TIME_MIN 16667
typedef struct sdl_dingux_video
{
retro_time_t last_frame_time;
retro_time_t ff_frame_time_min;
SDL_Surface *screen;
bitmapfont_lut_t *osd_font;
unsigned frame_width;
@@ -63,6 +65,9 @@ typedef struct sdl_dingux_video
unsigned frame_padding_x;
unsigned frame_padding_y;
enum dingux_ipu_filter_type filter_type;
#if defined(DINGUX_BETA)
enum dingux_refresh_rate refresh_rate;
#endif
uint32_t font_colour32;
uint16_t font_colour16;
uint16_t menu_texture[SDL_DINGUX_MENU_WIDTH * SDL_DINGUX_MENU_HEIGHT];
@@ -402,16 +407,23 @@ static void sdl_dingux_input_driver_init(
static void *sdl_dingux_gfx_init(const video_info_t *video,
input_driver_t **input, void **input_data)
{
sdl_dingux_video_t *vid = NULL;
uint32_t sdl_subsystem_flags = SDL_WasInit(0);
settings_t *settings = config_get_ptr();
bool ipu_keep_aspect = settings->bools.video_dingux_ipu_keep_aspect;
bool ipu_integer_scaling = settings->bools.video_scale_integer;
enum dingux_ipu_filter_type ipu_filter_type = (enum dingux_ipu_filter_type)
sdl_dingux_video_t *vid = NULL;
uint32_t sdl_subsystem_flags = SDL_WasInit(0);
settings_t *settings = config_get_ptr();
bool ipu_keep_aspect = settings->bools.video_dingux_ipu_keep_aspect;
bool ipu_integer_scaling = settings->bools.video_scale_integer;
#if defined(DINGUX_BETA)
enum dingux_refresh_rate current_refresh_rate = DINGUX_REFRESH_RATE_60HZ;
enum dingux_refresh_rate target_refresh_rate = (enum dingux_refresh_rate)
settings->uints.video_dingux_refresh_rate;
bool refresh_rate_valid = false;
float hw_refresh_rate = 0.0f;
#endif
enum dingux_ipu_filter_type ipu_filter_type = (enum dingux_ipu_filter_type)
settings->uints.video_dingux_ipu_filter_type;
const char *input_driver_name = settings->arrays.input_driver;
const char *joypad_driver_name = settings->arrays.input_joypad_driver;
uint32_t surface_flags = (video->vsync) ?
const char *input_driver_name = settings->arrays.input_driver;
const char *joypad_driver_name = settings->arrays.input_joypad_driver;
uint32_t surface_flags = (video->vsync) ?
(SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) :
(SDL_HWSURFACE | SDL_FULLSCREEN);
@@ -434,6 +446,50 @@ static void *sdl_dingux_gfx_init(const video_info_t *video,
dingux_ipu_set_downscaling_enable(true);
dingux_ipu_set_scaling_mode(ipu_keep_aspect, ipu_integer_scaling);
dingux_ipu_set_filter_type(ipu_filter_type);
#if defined(DINGUX_BETA)
/* Get current refresh rate */
refresh_rate_valid = dingux_get_video_refresh_rate(&current_refresh_rate);
/* Check if refresh rate needs to be updated */
if (!refresh_rate_valid ||
(current_refresh_rate != target_refresh_rate))
hw_refresh_rate = dingux_set_video_refresh_rate(target_refresh_rate);
else
{
/* Correct refresh rate is already set,
* just convert to float */
switch (current_refresh_rate)
{
case DINGUX_REFRESH_RATE_50HZ:
hw_refresh_rate = 50.0f;
break;
default:
hw_refresh_rate = 60.0f;
break;
}
}
if (hw_refresh_rate == 0.0f)
{
RARCH_ERR("[SDL1]: Failed to set video refresh rate\n");
goto error;
}
vid->refresh_rate = target_refresh_rate;
switch (target_refresh_rate)
{
case DINGUX_REFRESH_RATE_50HZ:
vid->ff_frame_time_min = 20000;
break;
default:
vid->ff_frame_time_min = 16667;
break;
}
driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &hw_refresh_rate);
#else
vid->ff_frame_time_min = 16667;
#endif
vid->screen = SDL_SetVideoMode(
SDL_DINGUX_MENU_WIDTH, SDL_DINGUX_MENU_HEIGHT,
@@ -505,12 +561,27 @@ static void sdl_dingux_sanitize_frame_dimensions(
*sanitized_width = (width + 0xF) & ~0xF;
/* Blacklist */
if (!vid->integer_scaling)
/* Neo Geo @ 304x224 */
if (!vid->integer_scaling && (width == 304) && (height == 224))
*sanitized_width = 320;
#if defined(DINGUX_BETA)
else if (vid->keep_aspect && !vid->integer_scaling)
{
/* Neo Geo @ 304x224 */
if ((width == 304) && (height == 224))
*sanitized_width = 320;
/* Neo Geo Pocket (x2) @ 320x304 */
if ((width == 320) && (height == 304))
*sanitized_width = 336;
/* GB/GBC/GG @ 160x144 */
else if ((width == 160) && (height == 144))
*sanitized_width = 176;
/* GB/GBC/GG (x2) @ 320x288 */
else if ((width == 320) && (height == 288))
*sanitized_width = 336;
/* GB/GBC/GG (x3) @ 480x432 */
else if ((width == 480) && (height == 432))
*sanitized_width = 496;
}
#endif
/*** HEIGHT ***/
*sanitized_height = height;
@@ -521,15 +592,21 @@ static void sdl_dingux_sanitize_frame_dimensions(
if ((width == 160) && (height == 152))
*sanitized_height = 154;
/* TIC-80 @ 240x136 */
if ((width == 240) && (height == 136))
else if ((width == 240) && (height == 136))
*sanitized_height = 144;
#else
if (!vid->integer_scaling)
else if (vid->keep_aspect && !vid->integer_scaling)
{
/* Neo Geo Pocket @ 160x152 */
if ((width == 160) && (height == 152))
*sanitized_height = 160;
/* GBA @ 240x160 */
if ((width == 240) && (height == 160))
*sanitized_height = 162;
/* GBA (x2) @ 480x320 */
else if ((width == 480) && (height == 320))
*sanitized_height = 324;
}
#else
/* Neo Geo Pocket @ 160x152 */
if (!vid->integer_scaling && (width == 160) && (height == 152))
*sanitized_height = 160;
#endif
}
@@ -689,7 +766,8 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame,
/* If fast forward is currently active, we may
* push frames at an 'unlimited' rate. Since the
* display has a fixed refresh rate of 60 Hz, this
* display has a fixed refresh rate of 60 Hz (or
* potentially 50 Hz on OpenDingux Beta), this
* represents wasted effort. We therefore drop any
* 'excess' frames in this case.
* (Note that we *only* do this when fast forwarding.
@@ -700,7 +778,7 @@ static bool sdl_dingux_gfx_frame(void *data, const void *frame,
retro_time_t current_time = cpu_features_get_time_usec();
if ((current_time - vid->last_frame_time) <
SDL_DINGUX_FF_FRAME_TIME_MIN)
vid->ff_frame_time_min)
return true;
vid->last_frame_time = current_time;
@@ -911,6 +989,26 @@ static void sdl_dingux_gfx_viewport_info(void *data, struct video_viewport *vp)
vp->height = vp->full_height = vid->frame_height;
}
static float sdl_dingux_get_refresh_rate(void *data)
{
#if defined(DINGUX_BETA)
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
if (!vid)
return 0.0f;
switch (vid->refresh_rate)
{
case DINGUX_REFRESH_RATE_50HZ:
return 50.0f;
default:
break;
}
#endif
return 60.0f;
}
static void sdl_dingux_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
@@ -979,7 +1077,7 @@ static const video_poke_interface_t sdl_dingux_poke_interface = {
NULL,
NULL,
NULL,
NULL, /* get_refresh_rate */
sdl_dingux_get_refresh_rate,
sdl_dingux_set_filtering,
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
+6
View File
@@ -54,6 +54,8 @@ typedef struct cocoa_ctx_data
/* TODO/FIXME - static globals */
static unsigned g_vk_minor = 0;
static unsigned g_vk_major = 0;
/* Forward declaration */
CocoaView *cocoaview_get(void);
static uint32_t cocoa_vk_gfx_ctx_get_flags(void *data)
{
@@ -179,9 +181,13 @@ static void cocoa_vk_gfx_ctx_swap_buffers(void *data)
{
cocoa_ctx->vk.context.has_acquired_swapchain = false;
if (cocoa_ctx->vk.swapchain == VK_NULL_HANDLE)
{
retro_sleep(10);
}
else
{
vulkan_present(&cocoa_ctx->vk, cocoa_ctx->vk.context.current_swapchain_index);
}
}
vulkan_acquire_next_image(&cocoa_ctx->vk);
}
+28 -23
View File
@@ -96,23 +96,23 @@ struct drm_fb
*/
typedef struct hdmi_timings
{
int h_active_pixels; // horizontal pixels (width)
int h_sync_polarity; // invert hsync polarity
int h_front_porch; // horizontal forward padding from DE acitve edge
int h_sync_pulse; // hsync pulse width in pixel clocks
int h_back_porch; // vertical back padding from DE active edge
int v_active_lines; // vertical pixels height (lines)
int v_sync_polarity; // invert vsync polarity
int v_front_porch; // vertical forward padding from DE active edge
int v_sync_pulse; // vsync pulse width in pixel clocks
int v_back_porch; // vertical back padding from DE active edge
int v_sync_offset_a; // leave at zero
int v_sync_offset_b; // leave at zero
int pixel_rep; // leave at zero
int frame_rate; // screen refresh rate in Hz
int interlaced; // leave at zero
int pixel_freq; // clock frequency (width*height*framerate)
int aspect_ratio; // *
int h_active_pixels; /* horizontal pixels (width) */
int h_sync_polarity; /* invert hsync polarity */
int h_front_porch; /* horizontal forward padding from DE acitve edge */
int h_sync_pulse; /* hsync pulse width in pixel clocks */
int h_back_porch; /* vertical back padding from DE active edge */
int v_active_lines; /* vertical pixels height (lines) */
int v_sync_polarity; /* invert vsync polarity */
int v_front_porch; /* vertical forward padding from DE active edge */
int v_sync_pulse; /* vsync pulse width in pixel clocks */
int v_back_porch; /* vertical back padding from DE active edge */
int v_sync_offset_a; /* leave at zero */
int v_sync_offset_b; /* leave at zero */
int pixel_rep; /* leave at zero */
int frame_rate; /* screen refresh rate in Hz */
int interlaced; /* leave at zero */
int pixel_freq; /* clock frequency (width*height*framerate) */
int aspect_ratio;
} hdmi_timings_t;
static enum gfx_ctx_api drm_api = GFX_CTX_NONE;
@@ -150,7 +150,7 @@ bool gfx_ctx_drm_load_mode(drmModeModeInfoPtr modeInfo)
modeInfo->vsync_start = modeInfo->vdisplay + (timings.v_front_porch * (timings.interlaced ? 2 : 1));
modeInfo->vsync_end = modeInfo->vsync_start + (timings.v_sync_pulse * (timings.interlaced ? 2 : 1));
modeInfo->vtotal = modeInfo->vsync_end + (timings.v_back_porch * (timings.interlaced ? 2 : 1));
modeInfo->vscan = 0; // TODO: ??
modeInfo->vscan = 0; /* TODO: ?? */
modeInfo->vrefresh = timings.frame_rate;
modeInfo->flags = timings.interlaced ? DRM_MODE_FLAG_INTERLACE : 0;
modeInfo->flags |= timings.v_sync_polarity ? DRM_MODE_FLAG_NVSYNC : DRM_MODE_FLAG_PVSYNC;
@@ -733,19 +733,24 @@ static bool gfx_ctx_drm_set_video_mode(void *data,
* refresh rates as well.
*/
float minimum_fps_diff = 0.0f;
float mode_vrefresh = 0.0f;
drmModeModeInfo *mode;
/* Find best match. */
for (i = 0; i < g_drm_connector->count_modes; i++) {
float diff;
if (width != g_drm_connector->modes[i].hdisplay ||
height != g_drm_connector->modes[i].vdisplay)
mode = &g_drm_connector->modes[i];
if (width != mode->hdisplay ||
height != mode->vdisplay)
continue;
diff = fabsf(refresh_mod * g_drm_connector->modes[i].vrefresh
- video_refresh_rate);
mode_vrefresh = drm_calc_refresh_rate(mode);
diff = fabsf(refresh_mod * mode_vrefresh - video_refresh_rate);
if (!g_drm_mode || diff < minimum_fps_diff) {
g_drm_mode = &g_drm_connector->modes[i];
g_drm_mode = mode;
minimum_fps_diff = diff;
}
}
-4
View File
@@ -249,10 +249,6 @@ static bool gfx_ctx_w_vk_set_video_mode(void *data,
RARCH_ERR("[WGL]: win32_set_video_mode failed.\n");
goto error;
}
else
/* This is required for fullscreen mailbox
* not to crash after refresh rate change */
vulkan_create_swapchain(&win32_vk, width, height, win32_vk_interval);
gfx_ctx_w_vk_swap_interval(data, win32_vk_interval);
return true;
+2 -1
View File
@@ -300,7 +300,8 @@ static bool gfx_ctx_xegl_set_video_mode(void *data,
g_x11_dpy, RootWindow(g_x11_dpy, vi->screen),
vi->visual, AllocNone);
swa.event_mask = StructureNotifyMask | KeyPressMask |
ButtonPressMask | ButtonReleaseMask | KeyReleaseMask;
ButtonPressMask | ButtonReleaseMask | KeyReleaseMask |
EnterWindowMask | LeaveWindowMask;
swa.override_redirect = False;
if (fullscreen && !windowed_fullscreen)
+1 -1
View File
@@ -163,6 +163,7 @@ static void gfx_display_d3d10_draw(gfx_display_ctx_draw_t *draw,
}
static void gfx_display_d3d10_draw_pipeline(gfx_display_ctx_draw_t* draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
d3d10_video_t* d3d10 = (d3d10_video_t*)data;
@@ -175,7 +176,6 @@ static void gfx_display_d3d10_draw_pipeline(gfx_display_ctx_draw_t* draw,
case VIDEO_SHADER_MENU:
case VIDEO_SHADER_MENU_2:
{
gfx_display_t *p_disp = disp_get_ptr();
video_coord_array_t* ca = &p_disp->dispca;
if (!d3d10->menu_pipeline_vbo)
+1 -1
View File
@@ -162,6 +162,7 @@ static void gfx_display_d3d11_draw(gfx_display_ctx_draw_t *draw,
}
static void gfx_display_d3d11_draw_pipeline(gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
d3d11_video_t *d3d11 = (d3d11_video_t*)data;
@@ -174,7 +175,6 @@ static void gfx_display_d3d11_draw_pipeline(gfx_display_ctx_draw_t *draw,
case VIDEO_SHADER_MENU:
case VIDEO_SHADER_MENU_2:
{
gfx_display_t *p_disp = disp_get_ptr();
video_coord_array_t* ca = &p_disp->dispca;
if (!d3d11->menu_pipeline_vbo)
+1 -1
View File
@@ -179,6 +179,7 @@ static void gfx_display_d3d12_draw(gfx_display_ctx_draw_t *draw,
}
static void gfx_display_d3d12_draw_pipeline(gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
d3d12_video_t *d3d12 = (d3d12_video_t*)data;
@@ -191,7 +192,6 @@ static void gfx_display_d3d12_draw_pipeline(gfx_display_ctx_draw_t *draw,
case VIDEO_SHADER_MENU:
case VIDEO_SHADER_MENU_2:
{
gfx_display_t *p_disp = disp_get_ptr();
video_coord_array_t* ca = &p_disp->dispca;
if (!d3d12->menu_pipeline_vbo)
+1 -1
View File
@@ -212,12 +212,12 @@ static void gfx_display_d3d9_draw(gfx_display_ctx_draw_t *draw,
}
static void gfx_display_d3d9_draw_pipeline(gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
#if defined(HAVE_HLSL) || defined(HAVE_CG)
static float t = 0;
video_coord_array_t *ca = NULL;
gfx_display_t *p_disp = disp_get_ptr();
if (!draw)
return;
+1 -1
View File
@@ -253,6 +253,7 @@ static void gfx_display_gl_draw(gfx_display_ctx_draw_t *draw,
static void gfx_display_gl_draw_pipeline(
gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data,
unsigned video_width,
unsigned video_height)
@@ -261,7 +262,6 @@ static void gfx_display_gl_draw_pipeline(
struct uniform_info uniform_param;
gl_t *gl = (gl_t*)data;
static float t = 0;
gfx_display_t *p_disp = disp_get_ptr();
video_coord_array_t *ca = &p_disp->dispca;
draw->x = 0;
+1 -1
View File
@@ -202,7 +202,7 @@ static void gfx_display_gl1_scissor_end(
gfx_display_ctx_driver_t gfx_display_ctx_gl1 = {
gfx_display_gl1_draw,
NULL,
NULL, /* draw_pipeline */
gfx_display_gl1_blend_begin,
gfx_display_gl1_blend_end,
gfx_display_gl1_get_default_mvp,
+3 -2
View File
@@ -66,7 +66,9 @@ static const float *gfx_display_gl_core_get_default_tex_coords(void)
return &gl_core_tex_coords[0];
}
static void gfx_display_gl_core_draw_pipeline(gfx_display_ctx_draw_t *draw,
static void gfx_display_gl_core_draw_pipeline(
gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data,
unsigned video_width,
unsigned video_height)
@@ -78,7 +80,6 @@ static void gfx_display_gl_core_draw_pipeline(gfx_display_ctx_draw_t *draw,
static float t = 0.0f;
float yflip = 0.0f;
video_coord_array_t *ca = NULL;
gfx_display_t *p_disp = disp_get_ptr();
gl_core_t *gl = (gl_core_t*)data;
if (!gl || !draw)
+1
View File
@@ -76,6 +76,7 @@ static void gfx_display_metal_draw(gfx_display_ctx_draw_t *draw,
static void gfx_display_metal_draw_pipeline(
gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data,
unsigned video_width,
unsigned video_height)
+5 -4
View File
@@ -88,15 +88,16 @@ static unsigned to_menu_pipeline(
return 0;
}
static void gfx_display_vk_draw_pipeline(gfx_display_ctx_draw_t *draw,
static void gfx_display_vk_draw_pipeline(
gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
static uint8_t ubo_scratch_data[768];
static float t = 0.0f;
gfx_display_t *p_disp = disp_get_ptr();
float yflip = 1.0f;
static struct video_coords blank_coords;
static float t = 0.0f;
float output_size[2];
float yflip = 1.0f;
video_coord_array_t *ca = NULL;
vk_t *vk = (vk_t*)data;
+3 -2
View File
@@ -207,11 +207,12 @@ static void gfx_display_wiiu_draw(gfx_display_ctx_draw_t *draw,
sizeof(*wiiu->vertex_cache.v), wiiu->vertex_cache.v);
}
static void gfx_display_wiiu_draw_pipeline(gfx_display_ctx_draw_t *draw,
static void gfx_display_wiiu_draw_pipeline(
gfx_display_ctx_draw_t *draw,
gfx_display_t *p_disp,
void *data, unsigned video_width, unsigned video_height)
{
video_coord_array_t *ca = NULL;
gfx_display_t *p_disp = disp_get_ptr();
wiiu_video_t *wiiu = (wiiu_video_t*)data;
if (!wiiu || !draw)
+8 -5
View File
@@ -142,9 +142,11 @@ static void gdi_render_msg(
blue = video_msg_color_b * 255.0f;
}
msg_strlen = strlen(msg);
char* msg_local = utf8_to_local_string_alloc(msg);
GetTextExtentPoint32(font->gdi->memDC, msg, msg_strlen, &textSize);
msg_strlen = strlen(msg_local);
GetTextExtentPoint32(font->gdi->memDC, msg_local, msg_strlen, &textSize);
switch (align)
{
@@ -174,7 +176,7 @@ static void gdi_render_msg(
SetBkMode(font->gdi->memDC, TRANSPARENT);
string_list_initialize(&msg_list);
string_split_noalloc(&msg_list, msg, "\n");
string_split_noalloc(&msg_list, msg_local, "\n");
if (drop_x || drop_y)
{
@@ -188,7 +190,7 @@ static void gdi_render_msg(
for (i = 0; i < msg_list.size; i++)
TextOut(font->gdi->memDC, newDropX, newDropY + (textSize.cy * i),
msg_list.elems[i].data,
utf8len(msg_list.elems[i].data));
strlen(msg_list.elems[i].data));
}
SetTextColor(font->gdi->memDC, RGB(red, green, blue));
@@ -196,9 +198,10 @@ static void gdi_render_msg(
for (i = 0; i < msg_list.size; i++)
TextOut(font->gdi->memDC, newX, newY + (textSize.cy * i),
msg_list.elems[i].data,
utf8len(msg_list.elems[i].data));
strlen(msg_list.elems[i].data));
string_list_deinitialize(&msg_list);
free(msg_local);
SelectObject(font->gdi->memDC, font->gdi->bmp_old);
}
+9 -4
View File
@@ -28,6 +28,11 @@
#define BMP_ATLAS_ROWS 16
#define BMP_ATLAS_SIZE (BMP_ATLAS_COLS * BMP_ATLAS_ROWS)
/* Padding is required between each glyph in
* the atlas to prevent texture bleed when
* drawing with linear filtering enabled */
#define BMP_ATLAS_PADDING 1
typedef struct bm_renderer
{
unsigned scale_factor;
@@ -96,16 +101,16 @@ static void *font_renderer_bmp_init(const char *font_path, float font_size)
if (!handle->scale_factor)
handle->scale_factor = 1;
handle->atlas.width = FONT_WIDTH * handle->scale_factor * BMP_ATLAS_COLS;
handle->atlas.height = FONT_HEIGHT * handle->scale_factor * BMP_ATLAS_ROWS;
handle->atlas.width = (BMP_ATLAS_PADDING + (FONT_WIDTH * handle->scale_factor)) * BMP_ATLAS_COLS;
handle->atlas.height = (BMP_ATLAS_PADDING + (FONT_HEIGHT * handle->scale_factor)) * BMP_ATLAS_ROWS;
handle->atlas.buffer = (uint8_t*)calloc(handle->atlas.width * handle->atlas.height, 1);
for (i = 0; i < BMP_ATLAS_SIZE; i++)
{
unsigned x = (i % BMP_ATLAS_COLS) *
handle->scale_factor * FONT_WIDTH;
(BMP_ATLAS_PADDING + (handle->scale_factor * FONT_WIDTH));
unsigned y = (i / BMP_ATLAS_COLS) *
handle->scale_factor * FONT_HEIGHT;
(BMP_ATLAS_PADDING + (handle->scale_factor * FONT_HEIGHT));
char_to_texture(handle, i, x, y);
+41 -12
View File
@@ -48,6 +48,10 @@
#define FT_ATLAS_ROWS 16
#define FT_ATLAS_COLS 16
#define FT_ATLAS_SIZE (FT_ATLAS_ROWS * FT_ATLAS_COLS)
/* Padding is required between each glyph in
* the atlas to prevent texture bleed when
* drawing with linear filtering enabled */
#define FT_ATLAS_PADDING 1
typedef struct freetype_atlas_slot
{
@@ -64,6 +68,8 @@ typedef struct freetype_renderer
struct font_atlas atlas; /* ptr alignment */
freetype_atlas_slot_t atlas_slots[FT_ATLAS_SIZE]; /* ptr alignment */
freetype_atlas_slot_t* uc_map[0x100]; /* ptr alignment */
unsigned max_glyph_width;
unsigned max_glyph_height;
unsigned usage_counter;
struct font_line_metrics line_metrics; /* float alignment */
} ft_font_renderer_t;
@@ -165,13 +171,35 @@ static const struct font_glyph *font_renderer_ft_get_glyph(
if (slot->bitmap.buffer)
{
unsigned r, c;
const uint8_t *src = (const uint8_t*)slot->bitmap.buffer;
const uint8_t *src = (const uint8_t*)slot->bitmap.buffer;
unsigned delta_width = (handle->max_glyph_width > atlas_slot->glyph.width) ?
(handle->max_glyph_width - atlas_slot->glyph.width) : 0;
unsigned x, y;
for (r = 0; r < atlas_slot->glyph.height;
r++, dst += handle->atlas.width, src += slot->bitmap.pitch)
for (c = 0; c < atlas_slot->glyph.width; c++)
dst[c] = src[c];
/* When copying the glyph bitmap, it is
* necessary to clear any unused regions of
* the atlas texture, otherwise garbage
* (due to texture bleeding) may be drawn at
* the edges of the glyph when rendering with
* filtering enabled */
for (y = 0; y < atlas_slot->glyph.height; y++)
{
/* Copy bitmap row */
memcpy(dst, src, atlas_slot->glyph.width * sizeof(uint8_t));
/* Zero out remaining atlas row */
memset(dst + atlas_slot->glyph.width, 0, delta_width * sizeof(uint8_t));
dst += handle->atlas.width;
src += slot->bitmap.pitch;
}
/* Zero out unused atlas rows */
for (y = atlas_slot->glyph.height; y < handle->max_glyph_height; y++)
{
memset(dst, 0, handle->max_glyph_width * sizeof(uint8_t));
dst += handle->atlas.width;
}
}
handle->atlas.dirty = true;
@@ -184,12 +212,11 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle, float font_si
unsigned i, x, y;
freetype_atlas_slot_t* slot = NULL;
unsigned max_width = round((handle->face->bbox.xMax - handle->face->bbox.xMin) * font_size / handle->face->units_per_EM);
unsigned max_width = round((handle->face->bbox.xMax - handle->face->bbox.xMin) * font_size / handle->face->units_per_EM);
unsigned max_height = round((handle->face->bbox.yMax - handle->face->bbox.yMin) * font_size / handle->face->units_per_EM);
unsigned atlas_width = max_width * FT_ATLAS_COLS;
unsigned atlas_height = max_height * FT_ATLAS_ROWS;
unsigned atlas_width = (max_width + FT_ATLAS_PADDING) * FT_ATLAS_COLS;
unsigned atlas_height = (max_height + FT_ATLAS_PADDING) * FT_ATLAS_ROWS;
uint8_t *atlas_buffer = (uint8_t*)
calloc(atlas_width * atlas_height, 1);
@@ -197,6 +224,8 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle, float font_si
if (!atlas_buffer)
return false;
handle->max_glyph_width = max_width;
handle->max_glyph_height = max_height;
handle->atlas.buffer = atlas_buffer;
handle->atlas.width = atlas_width;
handle->atlas.height = atlas_height;
@@ -206,8 +235,8 @@ static bool font_renderer_create_atlas(ft_font_renderer_t *handle, float font_si
{
for (x = 0; x < FT_ATLAS_COLS; x++)
{
slot->glyph.atlas_offset_x = x * max_width;
slot->glyph.atlas_offset_y = y * max_height;
slot->glyph.atlas_offset_x = x * (max_width + FT_ATLAS_PADDING);
slot->glyph.atlas_offset_y = y * (max_height + FT_ATLAS_PADDING);
slot++;
}
}
+3
View File
@@ -86,6 +86,9 @@ static bool font_renderer_stb_create_atlas(stb_font_renderer_t *self,
if (!self->atlas.buffer)
goto error;
/* Note: 1 pixel of padding is added to
* prevent texture bleed when drawing with
* linear filtering enabled */
stbtt_PackBegin(&pc, self->atlas.buffer,
self->atlas.width, self->atlas.height,
self->atlas.width, 1, NULL);
+8 -4
View File
@@ -42,6 +42,10 @@
#define STB_UNICODE_ATLAS_ROWS 16
#define STB_UNICODE_ATLAS_COLS 16
#define STB_UNICODE_ATLAS_SIZE (STB_UNICODE_ATLAS_ROWS * STB_UNICODE_ATLAS_COLS)
/* Padding is required between each glyph in
* the atlas to prevent texture bleed when
* drawing with linear filtering enabled */
#define STB_UNICODE_ATLAS_PADDING 1
typedef struct stb_unicode_atlas_slot
{
@@ -195,8 +199,8 @@ static bool font_renderer_stb_unicode_create_atlas(
self->max_glyph_width = font_size < 0 ? -font_size : font_size;
self->max_glyph_height = font_size < 0 ? -font_size : font_size;
self->atlas.width = self->max_glyph_width * STB_UNICODE_ATLAS_COLS;
self->atlas.height = self->max_glyph_height * STB_UNICODE_ATLAS_ROWS;
self->atlas.width = (self->max_glyph_width + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_COLS;
self->atlas.height = (self->max_glyph_height + STB_UNICODE_ATLAS_PADDING) * STB_UNICODE_ATLAS_ROWS;
self->atlas.buffer = (uint8_t*)
calloc(self->atlas.width * self->atlas.height, sizeof(uint8_t));
@@ -210,8 +214,8 @@ static bool font_renderer_stb_unicode_create_atlas(
{
for (x = 0; x < STB_UNICODE_ATLAS_COLS; x++)
{
slot->glyph.atlas_offset_x = x * self->max_glyph_width;
slot->glyph.atlas_offset_y = y * self->max_glyph_height;
slot->glyph.atlas_offset_x = x * (self->max_glyph_width + STB_UNICODE_ATLAS_PADDING);
slot->glyph.atlas_offset_y = y * (self->max_glyph_height + STB_UNICODE_ATLAS_PADDING);
slot++;
}
}
+1 -1
View File
@@ -116,7 +116,7 @@ bool glslang_read_shader_file(const char *path,
if (string_is_empty(path) || !output)
return false;
basename = path_basename(path);
basename = path_basename_nocompression(path);
if (string_is_empty(basename))
return false;
+6 -5
View File
@@ -47,10 +47,11 @@ static std::string build_stage_source(
if (lines->size < 1)
return "";
str.reserve(lines->size);
/* Version header. */
str += lines->elems[0].data;
str += '\n';
str.append(lines->elems[0].data);
str.append("\n");
for (i = 1; i < lines->size; i++)
{
@@ -82,12 +83,12 @@ static std::string build_stage_source(
/* Ignore */
}
else if (active)
str += line;
str.append(line);
}
else if (active)
str += line;
str.append(line);
str += '\n';
str.append("\n");
}
return str;
+79 -74
View File
@@ -37,8 +37,6 @@
#include "../../verbosity.h"
#include "../../msg_hash.h"
using namespace std;
GLuint gl_core_cross_compile_program(
const uint32_t *vertex, size_t vertex_size,
const uint32_t *fragment, size_t fragment_size,
@@ -189,9 +187,9 @@ GLuint gl_core_cross_compile_program(
for (auto &res : vertex_resources.stage_inputs)
{
char loc_buf[64];
uint32_t loc = vertex_compiler.get_decoration(res.id, spv::DecorationLocation);
snprintf(loc_buf, sizeof(loc_buf), "RARCH_ATTRIBUTE_%d", loc);
glBindAttribLocation(program, loc, loc_buf);
uint32_t _loc = vertex_compiler.get_decoration(res.id, spv::DecorationLocation);
snprintf(loc_buf, sizeof(loc_buf), "RARCH_ATTRIBUTE_%d", _loc);
glBindAttribLocation(program, _loc, loc_buf);
}
glLinkProgram(program);
glDeleteShader(vertex_shader);
@@ -255,7 +253,7 @@ GLuint gl_core_cross_compile_program(
glUseProgram(0);
}
catch (const exception &e)
catch (const std::exception &e)
{
RARCH_ERR("[GLCore]: Failed to cross compile program: %s\n", e.what());
if (program != 0)
@@ -387,7 +385,7 @@ static GLenum convert_glslang_format(glslang_format fmt)
class StaticTexture
{
public:
StaticTexture(string id,
StaticTexture(std::string id,
GLuint image,
unsigned width, unsigned height,
bool linear,
@@ -398,17 +396,17 @@ public:
StaticTexture(StaticTexture&&) = delete;
void operator=(StaticTexture&&) = delete;
void set_id(string name) { id = move(name); }
const string &get_id() const { return id; }
void set_id(std::string name) { id = std::move(name); }
const std::string &get_id() const { return id; }
const Texture &get_texture() const { return texture; }
private:
string id;
std::string id;
GLuint image;
Texture texture;
};
StaticTexture::StaticTexture(string id_, GLuint image_,
StaticTexture::StaticTexture(std::string id_, GLuint image_,
unsigned width, unsigned height, bool linear, bool mipmap,
glslang_filter_chain_address address)
: id(std::move(id_)), image(image_)
@@ -464,14 +462,14 @@ struct CommonResources
CommonResources();
~CommonResources();
vector<Texture> original_history;
vector<Texture> framebuffer_feedback;
vector<Texture> pass_outputs;
vector<unique_ptr<StaticTexture>> luts;
std::vector<Texture> original_history;
std::vector<Texture> framebuffer_feedback;
std::vector<Texture> pass_outputs;
std::vector<std::unique_ptr<StaticTexture>> luts;
unordered_map<string, slang_texture_semantic_map> texture_semantic_map;
unordered_map<string, slang_texture_semantic_map> texture_semantic_uniform_map;
unique_ptr<video_shader> shader_preset;
std::unordered_map<std::string, slang_texture_semantic_map> texture_semantic_map;
std::unordered_map<std::string, slang_texture_semantic_map> texture_semantic_uniform_map;
std::unique_ptr<video_shader> shader_preset;
GLuint quad_program = 0;
GLuint quad_vbo = 0;
@@ -716,7 +714,7 @@ public:
pass_name = name;
}
const string &get_name() const
const std::string &get_name() const
{
return pass_name;
}
@@ -769,10 +767,10 @@ private:
gl_core_viewport current_viewport;
gl_core_filter_chain_pass_info pass_info;
vector<uint32_t> vertex_shader;
vector<uint32_t> fragment_shader;
unique_ptr<Framebuffer> framebuffer;
unique_ptr<Framebuffer> framebuffer_feedback;
std::vector<uint32_t> vertex_shader;
std::vector<uint32_t> fragment_shader;
std::unique_ptr<Framebuffer> framebuffer;
std::unique_ptr<Framebuffer> framebuffer_feedback;
bool init_pipeline();
@@ -811,29 +809,29 @@ private:
unsigned pass_number = 0;
size_t ubo_offset = 0;
string pass_name;
std::string pass_name;
struct Parameter
{
string id;
std::string id;
unsigned index;
unsigned semantic_index;
};
vector<Parameter> parameters;
vector<Parameter> filtered_parameters;
vector<uint8_t> push_constant_buffer;
std::vector<Parameter> parameters;
std::vector<Parameter> filtered_parameters;
std::vector<uint8_t> push_constant_buffer;
gl_core_buffer_locations locations = {};
UBORing ubo_ring;
void reflect_parameter(const std::string &name, slang_semantic_meta &meta);
void reflect_parameter(const std::string &name, slang_texture_semantic_meta &meta);
void reflect_parameter_array(const std::string &name, std::vector<slang_texture_semantic_meta> &meta);
void reflect_parameter_array(const char *name, std::vector<slang_texture_semantic_meta> &meta);
};
bool Pass::build()
{
unordered_map<string, slang_semantic_map> semantic_map;
std::unordered_map<std::string, slang_semantic_map> semantic_map;
unsigned i;
unsigned j = 0;
@@ -841,7 +839,7 @@ bool Pass::build()
framebuffer_feedback.reset();
if (!final_pass)
framebuffer = unique_ptr<Framebuffer>(
framebuffer = std::unique_ptr<Framebuffer>(
new Framebuffer(pass_info.rt_format, pass_info.max_levels));
for (i = 0; i < parameters.size(); i++)
@@ -927,20 +925,24 @@ void Pass::reflect_parameter(const std::string &name, slang_texture_semantic_met
}
}
void Pass::reflect_parameter_array(const std::string &name, std::vector<slang_texture_semantic_meta> &meta)
void Pass::reflect_parameter_array(const char *name, std::vector<slang_texture_semantic_meta> &meta)
{
size_t i;
for (i = 0; i < meta.size(); i++)
{
std::string n = name + std::to_string(i);
char n[128];
snprintf(n, sizeof(n), "%s%u", name, (unsigned)i);
slang_texture_semantic_meta *m = (slang_texture_semantic_meta*)&meta[i];
if (m->uniform)
{
int vert = glGetUniformLocation(pipeline,
(std::string("RARCH_UBO_VERTEX_INSTANCE.") + n).c_str());
int frag = glGetUniformLocation(pipeline,
(std::string("RARCH_UBO_FRAGMENT_INSTANCE.") + n).c_str());
int vert, frag;
char vert_n[256];
char frag_n[256];
snprintf(vert_n, sizeof(vert_n), "RARCH_UBO_VERTEX_INSTANCE.%s", n);
snprintf(frag_n, sizeof(frag_n), "RARCH_UBO_FRAGMENT_INSTANCE.%s", n);
vert = glGetUniformLocation(pipeline, vert_n);
frag = glGetUniformLocation(pipeline, frag_n);
if (vert >= 0)
m->location.ubo_vertex = vert;
@@ -950,10 +952,13 @@ void Pass::reflect_parameter_array(const std::string &name, std::vector<slang_te
if (m->push_constant)
{
int vert = glGetUniformLocation(pipeline,
(std::string("RARCH_PUSH_VERTEX_INSTANCE.") + n).c_str());
int frag = glGetUniformLocation(pipeline,
(std::string("RARCH_PUSH_FRAGMENT_INSTANCE.") + n).c_str());
int vert, frag;
char vert_n[256];
char frag_n[256];
snprintf(vert_n, sizeof(vert_n), "RARCH_PUSH_VERTEX_INSTANCE.%s", n);
snprintf(frag_n, sizeof(frag_n), "RARCH_PUSH_FRAGMENT_INSTANCE.%s", n);
vert = glGetUniformLocation(pipeline, vert_n);
frag = glGetUniformLocation(pipeline, frag_n);
if (vert >= 0)
m->location.push_vertex = vert;
@@ -1128,12 +1133,12 @@ void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
}
else
{
float *data = reinterpret_cast<float *>
float *_data = reinterpret_cast<float *>
(push_constant_buffer.data() + refl->push_constant_offset);
data[0] = (float)(width);
data[1] = (float)(height);
data[2] = 1.0f / (float)(width);
data[3] = 1.0f / (float)(height);
_data[0] = (float)(width);
_data[1] = (float)(height);
_data[2] = 1.0f / (float)(width);
_data[3] = 1.0f / (float)(height);
}
}
}
@@ -1290,11 +1295,11 @@ void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semant
}
else
{
float *data = reinterpret_cast<float *>(push_constant_buffer.data() + refl[index].push_constant_offset);
data[0] = (float)(width);
data[1] = (float)(height);
data[2] = 1.0f / (float)(width);
data[3] = 1.0f / (float)(height);
float *_data = reinterpret_cast<float *>(push_constant_buffer.data() + refl[index].push_constant_offset);
_data[0] = (float)(width);
_data[1] = (float)(height);
_data[2] = 1.0f / (float)(width);
_data[3] = 1.0f / (float)(height);
}
}
}
@@ -1310,7 +1315,7 @@ bool Pass::init_feedback()
if (final_pass)
return false;
framebuffer_feedback = unique_ptr<Framebuffer>(
framebuffer_feedback = std::unique_ptr<Framebuffer>(
new Framebuffer(pass_info.rt_format, pass_info.max_levels));
return true;
}
@@ -1597,9 +1602,9 @@ struct gl_core_filter_chain
public:
gl_core_filter_chain(unsigned num_passes) { set_num_passes(num_passes); }
inline void set_shader_preset(unique_ptr<video_shader> shader)
inline void set_shader_preset(std::unique_ptr<video_shader> shader)
{
common.shader_preset = move(shader);
common.shader_preset = std::move(shader);
}
inline video_shader *get_shader_preset()
@@ -1624,14 +1629,14 @@ public:
void set_frame_direction(int32_t direction);
void set_pass_name(unsigned pass, const char *name);
void add_static_texture(unique_ptr<gl_core_shader::StaticTexture> texture);
void add_static_texture(std::unique_ptr<gl_core_shader::StaticTexture> texture);
void add_parameter(unsigned pass, unsigned parameter_index, const std::string &id);
void set_num_passes(unsigned passes);
private:
vector<unique_ptr<gl_core_shader::Pass>> passes;
vector<gl_core_filter_chain_pass_info> pass_info;
vector<vector<function<void ()>>> deferred_calls;
std::vector<std::unique_ptr<gl_core_shader::Pass>> passes;
std::vector<gl_core_filter_chain_pass_info> pass_info;
std::vector<std::vector<std::function<void ()>>> deferred_calls;
std::unique_ptr<gl_core_shader::Framebuffer> copy_framebuffer;
gl_core_shader::CommonResources common;
@@ -1640,7 +1645,7 @@ private:
bool init_history();
bool init_feedback();
bool init_alias();
vector<unique_ptr<gl_core_shader::Framebuffer>> original_history;
std::vector<std::unique_ptr<gl_core_shader::Framebuffer>> original_history;
bool require_clear = false;
void clear_history_and_feedback();
void update_feedback_info();
@@ -1744,8 +1749,8 @@ void gl_core_filter_chain::end_frame()
if (!original_history.empty())
{
/* Update history */
unique_ptr<gl_core_shader::Framebuffer> tmp;
unique_ptr<gl_core_shader::Framebuffer> &back = original_history.back();
std::unique_ptr<gl_core_shader::Framebuffer> tmp;
std::unique_ptr<gl_core_shader::Framebuffer> &back = original_history.back();
swap(back, tmp);
if (input_texture.width != tmp->get_size().width ||
@@ -1831,7 +1836,7 @@ bool gl_core_filter_chain::init_history()
for (i = 0; i < passes.size(); i++)
required_images =
max(required_images,
std::max(required_images,
passes[i]->get_reflection().semantic_textures[
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY].size());
@@ -1910,7 +1915,7 @@ bool gl_core_filter_chain::init_alias()
for (i = 0; i < passes.size(); i++)
{
const string name = passes[i]->get_name();
const std::string name = passes[i]->get_name();
if (name.empty())
continue;
@@ -2064,9 +2069,9 @@ void gl_core_filter_chain::set_input_texture(
}
}
void gl_core_filter_chain::add_static_texture(unique_ptr<gl_core_shader::StaticTexture> texture)
void gl_core_filter_chain::add_static_texture(std::unique_ptr<gl_core_shader::StaticTexture> texture)
{
common.luts.push_back(move(texture));
common.luts.push_back(std::move(texture));
}
void gl_core_filter_chain::set_frame_count(uint64_t count)
@@ -2093,7 +2098,7 @@ void gl_core_filter_chain::set_pass_name(unsigned pass, const char *name)
passes[pass]->set_name(name);
}
static unique_ptr<gl_core_shader::StaticTexture> gl_core_filter_chain_load_lut(
static std::unique_ptr<gl_core_shader::StaticTexture> gl_core_filter_chain_load_lut(
gl_core_filter_chain *chain,
const video_shader_lut *shader)
{
@@ -2129,7 +2134,7 @@ static unique_ptr<gl_core_shader::StaticTexture> gl_core_filter_chain_load_lut(
if (image.pixels)
image_texture_free(&image);
return unique_ptr<gl_core_shader::StaticTexture>(new gl_core_shader::StaticTexture(shader->id,
return std::unique_ptr<gl_core_shader::StaticTexture>(new gl_core_shader::StaticTexture(shader->id,
tex, image.width, image.height,
shader->filter != RARCH_FILTER_NEAREST,
levels > 1,
@@ -2143,14 +2148,14 @@ static bool gl_core_filter_chain_load_luts(
unsigned i;
for (i = 0; i < shader->luts; i++)
{
unique_ptr<gl_core_shader::StaticTexture> image = gl_core_filter_chain_load_lut(chain, &shader->lut[i]);
std::unique_ptr<gl_core_shader::StaticTexture> image = gl_core_filter_chain_load_lut(chain, &shader->lut[i]);
if (!image)
{
RARCH_ERR("[GLCore]: Failed to load LUT \"%s\".\n", shader->lut[i].path);
return false;
}
chain->add_static_texture(move(image));
chain->add_static_texture(std::move(image));
}
return true;
@@ -2161,7 +2166,7 @@ gl_core_filter_chain_t *gl_core_filter_chain_create_default(
{
struct gl_core_filter_chain_pass_info pass_info;
unique_ptr<gl_core_filter_chain> chain{ new gl_core_filter_chain(1) };
std::unique_ptr<gl_core_filter_chain> chain{ new gl_core_filter_chain(1) };
if (!chain)
return nullptr;
@@ -2194,7 +2199,7 @@ gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
const char *path, glslang_filter_chain_filter filter)
{
unsigned i;
unique_ptr<video_shader> shader{ new video_shader() };
std::unique_ptr<video_shader> shader{ new video_shader() };
if (!shader)
return nullptr;
@@ -2203,7 +2208,7 @@ gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
bool last_pass_is_fbo = shader->pass[shader->passes - 1].fbo.valid;
unique_ptr<gl_core_filter_chain> chain{ new gl_core_filter_chain(shader->passes + (last_pass_is_fbo ? 1 : 0)) };
std::unique_ptr<gl_core_filter_chain> chain{ new gl_core_filter_chain(shader->passes + (last_pass_is_fbo ? 1 : 0)) };
if (!chain)
return nullptr;
@@ -2246,7 +2251,7 @@ gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
return nullptr;
}
auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters,
auto itr = std::find_if(shader->parameters, shader->parameters + shader->num_parameters,
[&](const video_shader_parameter &param)
{
return meta_param.id == param.id;
@@ -2444,7 +2449,7 @@ gl_core_filter_chain_t *gl_core_filter_chain_create_from_preset(
sizeof(gl_core_shader::opaque_frag) / sizeof(uint32_t));
}
chain->set_shader_preset(move(shader));
chain->set_shader_preset(std::move(shader));
if (!chain->init())
return nullptr;
+82 -84
View File
@@ -14,6 +14,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../include/vulkan/vk_sdk_platform.h"
#include "shader_vulkan.h"
#include "glslang_util.h"
#include "glslang_util_cxx.h"
@@ -35,8 +36,6 @@
#include "../../verbosity.h"
#include "../../msg_hash.h"
using namespace std;
static const uint32_t opaque_vert[] =
#include "../drivers/vulkan_shaders/opaque.vert.inc"
;
@@ -56,15 +55,15 @@ struct Texture
class DeferredDisposer
{
public:
DeferredDisposer(vector<function<void ()>> &calls) : calls(calls) {}
DeferredDisposer(std::vector<std::function<void ()>> &calls) : calls(calls) {}
void defer(function<void ()> func)
void defer(std::function<void ()> func)
{
calls.push_back(move(func));
calls.push_back(std::move(func));
}
private:
vector<function<void ()>> &calls;
std::vector<std::function<void ()>> &calls;
};
class Buffer
@@ -95,12 +94,12 @@ class Buffer
class StaticTexture
{
public:
StaticTexture(string id,
StaticTexture(std::string id,
VkDevice device,
VkImage image,
VkImageView view,
VkDeviceMemory memory,
unique_ptr<Buffer> buffer,
std::unique_ptr<Buffer> buffer,
unsigned width, unsigned height,
bool linear,
bool mipmap,
@@ -111,8 +110,8 @@ class StaticTexture
void operator=(StaticTexture&&) = delete;
void release_staging_buffer() { buffer.reset(); }
void set_id(string name) { id = move(name); }
const string &get_id() const { return id; }
void set_id(std::string name) { id = std::move(name); }
const std::string &get_id() const { return id; }
const Texture &get_texture() const { return texture; }
private:
@@ -120,8 +119,8 @@ class StaticTexture
VkImage image;
VkImageView view;
VkDeviceMemory memory;
unique_ptr<Buffer> buffer;
string id;
std::unique_ptr<Buffer> buffer;
std::string id;
Texture texture;
};
@@ -177,8 +176,8 @@ struct CommonResources
const VkPhysicalDeviceMemoryProperties &memory_properties);
~CommonResources();
unique_ptr<Buffer> vbo;
unique_ptr<Buffer> ubo;
std::unique_ptr<Buffer> vbo;
std::unique_ptr<Buffer> ubo;
uint8_t *ubo_mapped = nullptr;
size_t ubo_sync_index_stride = 0;
size_t ubo_offset = 0;
@@ -186,14 +185,14 @@ struct CommonResources
VkSampler samplers[GLSLANG_FILTER_CHAIN_COUNT][GLSLANG_FILTER_CHAIN_COUNT][GLSLANG_FILTER_CHAIN_ADDRESS_COUNT];
vector<Texture> original_history;
vector<Texture> fb_feedback;
vector<Texture> pass_outputs;
vector<unique_ptr<StaticTexture>> luts;
std::vector<Texture> original_history;
std::vector<Texture> fb_feedback;
std::vector<Texture> pass_outputs;
std::vector<std::unique_ptr<StaticTexture>> luts;
unordered_map<string, slang_texture_semantic_map> texture_semantic_map;
unordered_map<string, slang_texture_semantic_map> texture_semantic_uniform_map;
unique_ptr<video_shader> shader_preset;
std::unordered_map<std::string, slang_texture_semantic_map> texture_semantic_map;
std::unordered_map<std::string, slang_texture_semantic_map> texture_semantic_uniform_map;
std::unique_ptr<video_shader> shader_preset;
VkDevice device;
};
@@ -245,7 +244,7 @@ class Pass
void set_frame_count_period(unsigned p) { frame_count_period = p; }
void set_frame_direction(int32_t dir) { frame_direction = dir; }
void set_name(const char *name) { pass_name = name; }
const string &get_name() const { return pass_name; }
const std::string &get_name() const { return pass_name; }
glslang_filter_chain_filter get_source_filter() const {
return pass_info.source_filter; }
@@ -284,17 +283,17 @@ class Pass
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
VkDescriptorPool pool = VK_NULL_HANDLE;
vector<VkDescriptorSet> sets;
std::vector<VkDescriptorSet> sets;
CommonResources *common = nullptr;
Size2D current_framebuffer_size;
VkViewport current_viewport;
vulkan_filter_chain_pass_info pass_info;
vector<uint32_t> vertex_shader;
vector<uint32_t> fragment_shader;
unique_ptr<Framebuffer> framebuffer;
unique_ptr<Framebuffer> fb_feedback;
std::vector<uint32_t> vertex_shader;
std::vector<uint32_t> fragment_shader;
std::unique_ptr<Framebuffer> framebuffer;
std::unique_ptr<Framebuffer> fb_feedback;
VkRenderPass swapchain_render_pass;
void clear_vk();
@@ -333,22 +332,22 @@ class Pass
unsigned pass_number = 0;
size_t ubo_offset = 0;
string pass_name;
std::string pass_name;
struct Parameter
{
string id;
std::string id;
unsigned index;
unsigned semantic_index;
};
vector<Parameter> parameters;
vector<Parameter> filtered_parameters;
std::vector<Parameter> parameters;
std::vector<Parameter> filtered_parameters;
struct PushConstant
{
VkShaderStageFlags stages = 0;
vector<uint32_t> buffer; /* uint32_t to have correct alignment. */
std::vector<uint32_t> buffer; /* uint32_t to have correct alignment. */
};
PushConstant push;
};
@@ -360,9 +359,9 @@ struct vulkan_filter_chain
vulkan_filter_chain(const vulkan_filter_chain_create_info &info);
~vulkan_filter_chain();
inline void set_shader_preset(unique_ptr<video_shader> shader)
inline void set_shader_preset(std::unique_ptr<video_shader> shader)
{
common.shader_preset = move(shader);
common.shader_preset = std::move(shader);
}
inline video_shader *get_shader_preset()
@@ -391,7 +390,7 @@ struct vulkan_filter_chain
void set_frame_direction(int32_t direction);
void set_pass_name(unsigned pass, const char *name);
void add_static_texture(unique_ptr<StaticTexture> texture);
void add_static_texture(std::unique_ptr<StaticTexture> texture);
void add_parameter(unsigned pass, unsigned parameter_index, const std::string &id);
void release_staging_buffers();
@@ -400,9 +399,9 @@ struct vulkan_filter_chain
VkPhysicalDevice gpu;
const VkPhysicalDeviceMemoryProperties &memory_properties;
VkPipelineCache cache;
vector<unique_ptr<Pass>> passes;
vector<vulkan_filter_chain_pass_info> pass_info;
vector<vector<function<void ()>>> deferred_calls;
std::vector<std::unique_ptr<Pass>> passes;
std::vector<vulkan_filter_chain_pass_info> pass_info;
std::vector<std::vector<std::function<void ()>>> deferred_calls;
CommonResources common;
VkFormat original_format;
@@ -424,7 +423,7 @@ struct vulkan_filter_chain
bool init_feedback();
bool init_alias();
void update_history(DeferredDisposer &disposer, VkCommandBuffer cmd);
vector<unique_ptr<Framebuffer>> original_history;
std::vector<std::unique_ptr<Framebuffer>> original_history;
bool require_clear = false;
void clear_history_and_feedback(VkCommandBuffer cmd);
void update_feedback_info();
@@ -512,7 +511,7 @@ static VkFormat glslang_format_to_vk(glslang_format fmt)
return VK_FORMAT_UNDEFINED;
}
static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
static std::unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
VkCommandBuffer cmd,
const struct vulkan_filter_chain_create_info *info,
vulkan_filter_chain *chain,
@@ -520,7 +519,7 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
{
unsigned i;
texture_image image;
unique_ptr<Buffer> buffer;
std::unique_ptr<Buffer> buffer;
VkMemoryRequirements mem_reqs;
VkImageCreateInfo image_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
@@ -581,7 +580,7 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
vkCreateImageView(info->device, &view_info, nullptr, &view);
buffer =
unique_ptr<Buffer>(new Buffer(info->device, *info->memory_properties,
std::unique_ptr<Buffer>(new Buffer(info->device, *info->memory_properties,
image.width * image.height * sizeof(uint32_t), VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
ptr = buffer->map();
memcpy(ptr, image.pixels, image.width * image.height * sizeof(uint32_t));
@@ -682,8 +681,8 @@ static unique_ptr<StaticTexture> vulkan_filter_chain_load_lut(
image_texture_free(&image);
image.pixels = nullptr;
return unique_ptr<StaticTexture>(new StaticTexture(shader->id, info->device,
tex, view, memory, move(buffer), image.width, image.height,
return std::unique_ptr<StaticTexture>(new StaticTexture(shader->id, info->device,
tex, view, memory, std::move(buffer), image.width, image.height,
shader->filter != RARCH_FILTER_NEAREST,
image_info.mipLevels > 1,
rarch_wrap_to_address(shader->wrap)));
@@ -726,7 +725,7 @@ static bool vulkan_filter_chain_load_luts(
for (i = 0; i < shader->luts; i++)
{
unique_ptr<StaticTexture> image =
std::unique_ptr<StaticTexture> image =
vulkan_filter_chain_load_lut(cmd, info, chain, &shader->lut[i]);
if (!image)
{
@@ -734,7 +733,7 @@ static bool vulkan_filter_chain_load_luts(
goto error;
}
chain->add_static_texture(move(image));
chain->add_static_texture(std::move(image));
}
vkEndCommandBuffer(cmd);
@@ -931,7 +930,7 @@ void vulkan_filter_chain::build_offscreen_passes(VkCommandBuffer cmd,
void vulkan_filter_chain::update_history(DeferredDisposer &disposer,
VkCommandBuffer cmd)
{
unique_ptr<Framebuffer> tmp;
std::unique_ptr<Framebuffer> tmp;
VkImageLayout src_layout = input_texture.layout;
/* Transition input texture to something appropriate. */
@@ -951,7 +950,7 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer,
src_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
}
unique_ptr<Framebuffer> &back = original_history.back();
std::unique_ptr<Framebuffer> &back = original_history.back();
swap(back, tmp);
if (input_texture.width != tmp->get_size().width ||
@@ -1057,7 +1056,7 @@ bool vulkan_filter_chain::init_history()
for (i = 0; i < passes.size(); i++)
required_images =
max(required_images,
std::max(required_images,
passes[i]->get_reflection().semantic_textures[
SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY].size());
@@ -1144,7 +1143,7 @@ bool vulkan_filter_chain::init_alias()
for (i = 0; i < passes.size(); i++)
{
const string name = passes[i]->get_name();
const std::string name = passes[i]->get_name();
if (name.empty())
continue;
@@ -1251,7 +1250,7 @@ bool vulkan_filter_chain::init_ubo()
common.ubo_sync_index_stride = common.ubo_offset;
if (common.ubo_offset != 0)
common.ubo = unique_ptr<Buffer>(new Buffer(device,
common.ubo = std::unique_ptr<Buffer>(new Buffer(device,
memory_properties, common.ubo_offset * deferred_calls.size(),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT));
@@ -1269,14 +1268,13 @@ bool vulkan_filter_chain::init()
for (i = 0; i < passes.size(); i++)
{
const string name = passes[i]->get_name();
#ifdef VULKAN_DEBUG
const char *name = passes[i]->get_name().c_str();
RARCH_LOG("[slang]: Building pass #%u (%s)\n", i,
name.empty() ?
string_is_empty(name) ?
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE) :
name.c_str());
name);
#endif
source = passes[i]->set_pass_info(max_input_size,
source, swapchain_info, pass_info[i]);
if (!passes[i]->build())
@@ -1314,9 +1312,9 @@ void vulkan_filter_chain::set_input_texture(
}
void vulkan_filter_chain::add_static_texture(
unique_ptr<StaticTexture> texture)
std::unique_ptr<StaticTexture> texture)
{
common.luts.push_back(move(texture));
common.luts.push_back(std::move(texture));
}
void vulkan_filter_chain::set_frame_count(uint64_t count)
@@ -1344,12 +1342,12 @@ void vulkan_filter_chain::set_pass_name(unsigned pass, const char *name)
passes[pass]->set_name(name);
}
StaticTexture::StaticTexture(string id,
StaticTexture::StaticTexture(std::string id,
VkDevice device,
VkImage image,
VkImageView view,
VkDeviceMemory memory,
unique_ptr<Buffer> buffer,
std::unique_ptr<Buffer> buffer,
unsigned width, unsigned height,
bool linear,
bool mipmap,
@@ -1358,8 +1356,8 @@ StaticTexture::StaticTexture(string id,
image(image),
view(view),
memory(memory),
buffer(move(buffer)),
id(move(id))
buffer(std::move(buffer)),
id(std::move(id))
{
texture.filter = GLSLANG_FILTER_CHAIN_NEAREST;
texture.mip_filter = GLSLANG_FILTER_CHAIN_NEAREST;
@@ -1561,8 +1559,8 @@ void Pass::clear_vk()
bool Pass::init_pipeline_layout()
{
unsigned i;
vector<VkDescriptorSetLayoutBinding> bindings;
vector<VkDescriptorPoolSize> desc_counts;
std::vector<VkDescriptorSetLayoutBinding> bindings;
std::vector<VkDescriptorPoolSize> desc_counts;
VkPushConstantRange push_range = {};
VkDescriptorSetLayoutCreateInfo set_layout_info = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
@@ -1821,7 +1819,7 @@ CommonResources::CommonResources(VkDevice device,
};
vbo =
unique_ptr<Buffer>(new Buffer(device,
std::unique_ptr<Buffer>(new Buffer(device,
memory_properties, sizeof(vbo_data), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
void *ptr = vbo->map();
@@ -1947,7 +1945,7 @@ bool Pass::init_feedback()
if (final_pass)
return false;
fb_feedback = unique_ptr<Framebuffer>(
fb_feedback = std::unique_ptr<Framebuffer>(
new Framebuffer(device, memory_properties,
current_framebuffer_size,
pass_info.rt_format, pass_info.max_levels));
@@ -1958,13 +1956,13 @@ bool Pass::build()
{
unsigned i;
unsigned j = 0;
unordered_map<string, slang_semantic_map> semantic_map;
std::unordered_map<std::string, slang_semantic_map> semantic_map;
framebuffer.reset();
fb_feedback.reset();
if (!final_pass)
framebuffer = unique_ptr<Framebuffer>(
framebuffer = std::unique_ptr<Framebuffer>(
new Framebuffer(device, memory_properties,
current_framebuffer_size,
pass_info.rt_format, pass_info.max_levels));
@@ -2039,11 +2037,11 @@ void Pass::build_semantic_texture_array_vec4(uint8_t *data, slang_texture_semant
if (refl[index].push_constant)
{
float *data = reinterpret_cast<float *>(push.buffer.data() + (refl[index].push_constant_offset >> 2));
data[0] = (float)(width);
data[1] = (float)(height);
data[2] = 1.0f / (float)(width);
data[3] = 1.0f / (float)(height);
float *_data = reinterpret_cast<float *>(push.buffer.data() + (refl[index].push_constant_offset >> 2));
_data[0] = (float)(width);
_data[1] = (float)(height);
_data[2] = 1.0f / (float)(width);
_data[3] = 1.0f / (float)(height);
}
}
@@ -2069,12 +2067,12 @@ void Pass::build_semantic_vec4(uint8_t *data, slang_semantic semantic,
if (refl.push_constant)
{
float *data = reinterpret_cast<float *>
float *_data = reinterpret_cast<float *>
(push.buffer.data() + (refl.push_constant_offset >> 2));
data[0] = (float)(width);
data[1] = (float)(height);
data[2] = 1.0f / (float)(width);
data[3] = 1.0f / (float)(height);
_data[0] = (float)(width);
_data[1] = (float)(height);
_data[2] = 1.0f / (float)(width);
_data[3] = 1.0f / (float)(height);
}
}
@@ -2374,7 +2372,7 @@ Framebuffer::Framebuffer(
unsigned max_levels) :
size(max_size),
format(format),
max_levels(max(max_levels, 1u)),
max_levels(std::max(max_levels, 1u)),
memory_properties(mem_props),
device(device)
{
@@ -2397,7 +2395,7 @@ void Framebuffer::init(DeferredDisposer *disposer)
info.extent.width = size.width;
info.extent.height = size.height;
info.extent.depth = 1;
info.mipLevels = min(max_levels,
info.mipLevels = std::min(max_levels,
glslang_num_miplevels(size.width, size.height));
info.arrayLayers = 1;
info.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -2543,7 +2541,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_default(
tmpinfo.num_passes = 1;
unique_ptr<vulkan_filter_chain> chain{ new vulkan_filter_chain(tmpinfo) };
std::unique_ptr<vulkan_filter_chain> chain{ new vulkan_filter_chain(tmpinfo) };
if (!chain)
return nullptr;
@@ -2577,7 +2575,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
const char *path, glslang_filter_chain_filter filter)
{
unsigned i;
unique_ptr<video_shader> shader{ new video_shader() };
std::unique_ptr<video_shader> shader{ new video_shader() };
if (!shader)
return nullptr;
@@ -2589,7 +2587,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
auto tmpinfo = *info;
tmpinfo.num_passes = shader->passes + (last_pass_is_fbo ? 1 : 0);
unique_ptr<vulkan_filter_chain> chain{ new vulkan_filter_chain(tmpinfo) };
std::unique_ptr<vulkan_filter_chain> chain{ new vulkan_filter_chain(tmpinfo) };
if (!chain)
goto error;
@@ -2631,7 +2629,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
goto error;
}
auto itr = find_if(shader->parameters, shader->parameters + shader->num_parameters,
auto itr = std::find_if(shader->parameters, shader->parameters + shader->num_parameters,
[&](const video_shader_parameter &param)
{
return meta_param.id == param.id;
@@ -2825,7 +2823,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
sizeof(opaque_frag) / sizeof(uint32_t));
}
chain->set_shader_preset(move(shader));
chain->set_shader_preset(std::move(shader));
if (!chain->init())
goto error;
Loaded 100 of 232 files, more files were not shown because too many files have changed in this diff. Show more