mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-10 03:21:30 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc23d070de | ||
|
|
951ea6baaf | ||
|
|
84ab14cb83 | ||
|
|
019130298a | ||
|
|
99917368b4 | ||
|
|
5f12edaae4 | ||
|
|
8eb8b44e83 | ||
|
|
9c534c3550 | ||
|
|
10c1361751 | ||
|
|
2153cd8e2c | ||
|
|
95cea8cc5d | ||
|
|
02630d998e | ||
|
|
77d04af845 | ||
|
|
42e01acfa1 | ||
|
|
b2faff6bf9 | ||
|
|
a58236d69d | ||
|
|
3bc2758d51 | ||
|
|
40f6f7b803 | ||
|
|
b1a7d3e995 | ||
|
|
7fc636c623 | ||
|
|
2c5c4647e3 | ||
|
|
2702ce693b | ||
|
|
71836cacdb | ||
|
|
a501dfd680 | ||
|
|
7e7615c97c | ||
|
|
a4d955357d | ||
|
|
9c0aec1d19 | ||
|
|
28541fe826 | ||
|
|
8466a213e8 | ||
|
|
0cd0ce87f5 | ||
|
|
c7f3fa2b5d | ||
|
|
f601f4ce70 | ||
|
|
56a0300db5 | ||
|
|
d7075296e3 | ||
|
|
a904b1665f | ||
|
|
f4511f6fa4 | ||
|
|
1d81841091 | ||
|
|
d339d5eab5 | ||
|
|
9d13b090d8 | ||
|
|
6f898e611c | ||
|
|
1235a7435e | ||
|
|
2ebf46e241 | ||
|
|
d2af1e905c | ||
|
|
be255ff269 | ||
|
|
0211e7749e | ||
|
|
d24f808d79 | ||
|
|
6d42481c37 | ||
|
|
80753ac741 | ||
|
|
93e467913e | ||
|
|
fc283123bb | ||
|
|
5998c561ee | ||
|
|
4e8a71d034 | ||
|
|
d458729f6c | ||
|
|
3191fec54c | ||
|
|
7a5559aba0 | ||
|
|
29d5963cad | ||
|
|
90529c62b2 | ||
|
|
ae21979b7c | ||
|
|
09c3ef0f6a | ||
|
|
ba791b7de8 | ||
|
|
0ddfbd976c | ||
|
|
d4ba7579d1 | ||
|
|
220bc434be | ||
|
|
2932a835fc | ||
|
|
e88fad00a5 | ||
|
|
36d274d460 | ||
|
|
4c4d5e5837 | ||
|
|
769fb7cd02 | ||
|
|
0cc5b29558 | ||
|
|
191171802b | ||
|
|
32b626704e | ||
|
|
b193fd0ba9 | ||
|
|
7317b6b98e | ||
|
|
799fcdb5e0 | ||
|
|
6b021f8d14 | ||
|
|
a56fcfb24a | ||
|
|
1811bd6885 | ||
|
|
46a37b9bd9 | ||
|
|
3fcd645a73 | ||
|
|
7cbee3dc8f | ||
|
|
9812f368e7 | ||
|
|
0f4dbcfc53 | ||
|
|
fb79927c05 | ||
|
|
fc05c0805b | ||
|
|
b69e023736 | ||
|
|
54c45bd54e | ||
|
|
67c06d17bb | ||
|
|
b91a1f4788 | ||
|
|
9f902c8bd4 | ||
|
|
52454591aa | ||
|
|
cfe9d60f51 | ||
|
|
36bf1ad112 | ||
|
|
6f29c1ff94 | ||
|
|
58080d6157 | ||
|
|
45bf867d38 | ||
|
|
eb578557c0 | ||
|
|
299a471af2 | ||
|
|
4ec8b82388 | ||
|
|
5ae5463f52 | ||
|
|
9a994eb777 | ||
|
|
bdfbc86ecb | ||
|
|
b5d983cddf | ||
|
|
65c01b35ec | ||
|
|
a6cffc0e29 | ||
|
|
5658ea7047 | ||
|
|
7f3b9e8a89 | ||
|
|
7fe2ad81a0 | ||
|
|
dcc266df12 | ||
|
|
d07043fe26 | ||
|
|
2f0f724813 | ||
|
|
fc5b557a10 | ||
|
|
116bf8058a | ||
|
|
050f44382b | ||
|
|
1392eebfa0 | ||
|
|
544a17926b | ||
|
|
637cff628f | ||
|
|
3841fecc59 | ||
|
|
f1cf5ceb82 | ||
|
|
40c39de5e3 | ||
|
|
0087be2a53 | ||
|
|
d9cacc0b8c | ||
|
|
370751551f | ||
|
|
ac8e1b88e4 | ||
|
|
aa0a9f18d5 | ||
|
|
05a2623875 | ||
|
|
1f506615d3 | ||
|
|
bc08e325ce | ||
|
|
a8f410ed40 | ||
|
|
f29a4b51cc | ||
|
|
924b5830ba | ||
|
|
ab877c429f | ||
|
|
97e5e6beee | ||
|
|
5530b7022f | ||
|
|
0aa266a6ca | ||
|
|
0b52823f2c | ||
|
|
1273536752 | ||
|
|
59449600ad | ||
|
|
c392a475ee | ||
|
|
d024ff553f | ||
|
|
b5d49b9e79 | ||
|
|
f0fa3c5861 | ||
|
|
966dd62551 | ||
|
|
ca5ce839ce | ||
|
|
760fc6b3f7 | ||
|
|
372f939cc9 | ||
|
|
5df321fcaa | ||
|
|
10c9d485c4 | ||
|
|
8f3e02e49c | ||
|
|
8b197e49bb | ||
|
|
200983f938 | ||
|
|
dd7fe2e7e0 | ||
|
|
1e94070dca | ||
|
|
40ab6f839a | ||
|
|
43cb646870 | ||
|
|
d1d9f96ab3 | ||
|
|
d910f520d9 | ||
|
|
5ca666acee | ||
|
|
338c2eb2f0 | ||
|
|
deccc4d8c6 | ||
|
|
204eaf0e76 | ||
|
|
421dbb19c2 | ||
|
|
808f326209 | ||
|
|
9c5f365b2b | ||
|
|
f7a5833cb0 | ||
|
|
0d549fd42b | ||
|
|
2a2f77f0dc | ||
|
|
42bd709f67 | ||
|
|
2c7226de20 | ||
|
|
d6c243143d | ||
|
|
9ab6b9b308 | ||
|
|
d80833d892 | ||
|
|
b7bc1fc51d | ||
|
|
9f6a5e35de | ||
|
|
f8ec815467 | ||
|
|
fb1258b817 | ||
|
|
5334ddd199 | ||
|
|
e5e8e9b5d8 | ||
|
|
2e6393f082 | ||
|
|
95527fb566 | ||
|
|
03849b3e87 | ||
|
|
3a4c19f82d | ||
|
|
c23e32a047 | ||
|
|
5e432a6586 | ||
|
|
ea9f3f13ca | ||
|
|
412a1885b2 | ||
|
|
886a692f1a | ||
|
|
d5ebf9039c | ||
|
|
789cf29d28 | ||
|
|
7cb5de7df4 | ||
|
|
c68c71f7b2 | ||
|
|
09f1404c45 | ||
|
|
f8a88fcb94 | ||
|
|
29a358ee3a | ||
|
|
29513919ca | ||
|
|
45beb1bcdd | ||
|
|
166333a2cd | ||
|
|
ebc567d03c | ||
|
|
529c0f24da | ||
|
|
4855f371f1 | ||
|
|
76f000e4c8 | ||
|
|
2aea7a375d | ||
|
|
5cf2a7abd1 | ||
|
|
d11c7cbbb1 | ||
|
|
5c6cd1b48a | ||
|
|
cbec423413 | ||
|
|
9910dfbee2 | ||
|
|
e2b084b715 | ||
|
|
5f9197bcc2 | ||
|
|
0b9bc85ddd | ||
|
|
66ad300515 | ||
|
|
4ce66f0764 | ||
|
|
0fc6116082 | ||
|
|
48af4fc704 | ||
|
|
8c08b531d6 | ||
|
|
966e0640af | ||
|
|
0e26077a64 | ||
|
|
b830b33cf1 | ||
|
|
a989cfb987 | ||
|
|
5a0c0a26e3 | ||
|
|
cd016824f8 | ||
|
|
af00dca08b | ||
|
|
115b08e0e1 | ||
|
|
daa6152868 | ||
|
|
a81280939e | ||
|
|
8df97a0c75 | ||
|
|
2fbcc99b24 | ||
|
|
77f48c8c8e | ||
|
|
aaf7e1fb0d | ||
|
|
9577f1a46f | ||
|
|
63e5a8b1b5 | ||
|
|
be8dd0dba1 | ||
|
|
9f17cb7a86 | ||
|
|
70acb573d5 | ||
|
|
45047732a7 | ||
|
|
f7d0908ff1 | ||
|
|
9f90833d2b | ||
|
|
93174dcd19 | ||
|
|
72f08bb1b4 | ||
|
|
371d0b7395 | ||
|
|
21b2ec6bd5 | ||
|
|
311c5c133c | ||
|
|
551a671cc6 | ||
|
|
f54098618e | ||
|
|
fc69e73dcf | ||
|
|
41855bb6d4 | ||
|
|
e3ee0ac22b | ||
|
|
e65a891274 | ||
|
|
01944dd80e | ||
|
|
ed6dd6d6d1 | ||
|
|
6d13ace83a | ||
|
|
32bdb49496 | ||
|
|
cc8160d044 | ||
|
|
ba7900a3fb | ||
|
|
b9ff6cb1d9 |
No files matched your search
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
+13
-35
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
Vendored
+128
-133
@@ -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
|
||||
Vendored
+1771
File diff suppressed because it is too large.
Load diff
Vendored
+23
-24
@@ -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;
|
||||
}
|
||||
Vendored
+18
-10
@@ -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
|
||||
Vendored
+106
-54
@@ -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
|
||||
}
|
||||
Vendored
+6
-10
@@ -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
|
||||
Vendored
+102
-25
@@ -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
|
||||
Vendored
+488
-340
@@ -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;
|
||||
}
|
||||
}
|
||||
Vendored
+216
-90
@@ -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
|
||||
Vendored
+27
-13
@@ -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
|
||||
Vendored
-1633
File diff suppressed because it is too large.
Load diff
Vendored
+116
-124
@@ -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;
|
||||
}
|
||||
Vendored
+274
-66
@@ -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
|
||||
|
||||
|
||||
Vendored
+26
-6
@@ -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
|
||||
Vendored
+233
-125
@@ -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;
|
||||
}
|
||||
Vendored
+133
-25
@@ -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
|
||||
Vendored
+212
-116
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+46
-50
@@ -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
|
||||
Vendored
+66
-70
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+53
@@ -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;
|
||||
}
|
||||
Vendored
+33
@@ -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
|
||||
Vendored
+218
@@ -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
|
||||
Vendored
+309
-29
@@ -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
|
||||
Vendored
+64
@@ -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);
|
||||
}
|
||||
Vendored
+19
@@ -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
|
||||
Vendored
+478
-181
File diff suppressed because it is too large.
Load diff
Vendored
+50
-46
@@ -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
|
||||
|
||||
|
||||
Vendored
+13
-12
@@ -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); }
|
||||
|
||||
|
||||
Vendored
+439
-308
@@ -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;
|
||||
}
|
||||
Vendored
+61
-26
@@ -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
|
||||
Vendored
+998
-882
File diff suppressed because it is too large.
Load diff
Vendored
+175
-161
@@ -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
|
||||
Vendored
+2164
-1500
File diff suppressed because it is too large.
Load diff
Vendored
+29
-33
@@ -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
|
||||
|
||||
|
||||
Vendored
+10
@@ -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
@@ -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);
|
||||
|
||||
Vendored
+134
-58
@@ -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 */
|
||||
Vendored
+1
-1
@@ -5,7 +5,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rconsoles.h"
|
||||
#include "rc_consoles.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
+135
-17
@@ -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;
|
||||
|
||||
Vendored
+5
-1
@@ -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
@@ -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) {
|
||||
|
||||
Vendored
+5
-1
@@ -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) {
|
||||
|
||||
Vendored
+5
-1
@@ -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) {
|
||||
|
||||
@@ -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) &&
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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(¤t_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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ¶m)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -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 ¶m)
|
||||
{
|
||||
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
Reference in new issue
Block a user