mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 13:20:30 +00:00
Merge remote-tracking branch 'upstream/master' into patch-7
This commit is contained in:
commit
512e280c68
3
.gitignore
vendored
3
.gitignore
vendored
@ -55,7 +55,6 @@ DerivedData
|
||||
apple/tmp
|
||||
apple/*.mobileprovision
|
||||
apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
|
||||
menu/driverspzarch.c
|
||||
/Cg/
|
||||
/GL/
|
||||
/SDL/
|
||||
@ -76,6 +75,7 @@ libretro-super
|
||||
run.sh
|
||||
convert_rumble.awk
|
||||
*~
|
||||
assets
|
||||
|
||||
# Wii U
|
||||
*.depend
|
||||
@ -121,7 +121,6 @@ wiiu/wut/elf2rpl/elf2rpl
|
||||
/media/libretrodb/
|
||||
|
||||
pkg/apple/iOS/build/
|
||||
pkg/apple/iOS/modules/
|
||||
pkg/apple/build/
|
||||
ui/drivers/qt/moc_*
|
||||
ui/drivers/moc_*
|
||||
|
@ -39,9 +39,8 @@ matrix:
|
||||
script:
|
||||
- xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
|
||||
- os: osx
|
||||
osx_image: xcode9.3
|
||||
osx_image: xcode10.1
|
||||
script:
|
||||
- brew update
|
||||
- brew install --force-bottle qt5
|
||||
- xcodebuild -target RetroArchQt -configuration Release -project pkg/apple/RetroArch_Metal.xcodeproj
|
||||
deploy:
|
||||
|
50
CHANGES.md
50
CHANGES.md
@ -1,14 +1,27 @@
|
||||
# 1.7.6 (future)
|
||||
- ANDROID: Fix Xperia Play input binding
|
||||
- CHEEVOS: Reset when hardcore mode is toggled
|
||||
- COMMON: Add new JSON playlist format
|
||||
- CORE UPDATER: Allow sideloading cores from the menu
|
||||
# 1.7.7 (future)
|
||||
|
||||
# 1.7.6
|
||||
- ANDROID: Fix Xperia Play input binding.
|
||||
- CHEEVOS: Reset when hardcore mode is toggled.
|
||||
- CHEEVOS: Update the hashing methods to identify NES, SNES and Lynx games (more accurate and accepting headerless ROMs).
|
||||
- COMMON: Add new JSON playlist format.
|
||||
- COMMON: Fix playlist corruption when deleting items.
|
||||
- COMMON: Fix archive progress display calculation.
|
||||
- COMMON: Fix playlist entries appearing with previously used names.
|
||||
- COMMON: Fix screenshot filename with no core or content.
|
||||
- COMMON: Allow compiling without menu support.
|
||||
- CORE UPDATER: Allow sideloading cores from the menu.
|
||||
- CPU FILTERS: Add Normal2x filter.
|
||||
- CRT/LINUX: New Linux switching method partially implemented.
|
||||
- CRT/LINUX: Linux restore desktop resolution fixed.
|
||||
- CRT/LINUX: Monitor index switching and auto enumerate for output detection in Linux (still working on the windows method).
|
||||
- CRT/RASPBERRY PI: Initial support.
|
||||
- DATE: Add Date / Time style options.
|
||||
- DEBUGGING: Add an integrated crash handler for debug builds (see https://docs.libretro.com/tech/debugging)
|
||||
- DISCORD: Register the application name properly.
|
||||
- DISK CONTROL: Remember the last used folder / current active folder to make disk-swapping faster.
|
||||
- INPUT: Add new menu toggle (hold start button for 2 seconds)
|
||||
- INPUT: Fix arrow keys being incorrectly bound as numpad keys
|
||||
- INPUT/SDL: Flush the joypad events. Decreases cpu usage over time with the SDL joypad driver.
|
||||
- LOCALIZATION: Add Greek translation.
|
||||
- LOCALIZATION: Update German translation.
|
||||
@ -16,11 +29,24 @@
|
||||
- LOCALIZATION: Update Japanese translation.
|
||||
- LOCALIZATION: Update Simplified Chinese translation.
|
||||
- LOCALIZATION: Update Spanish translation.
|
||||
- MENU: New "ozone" menu driver.
|
||||
- MENU: Only show CRT SwitchRes if video display server is implemented (Windows/Linux for now)
|
||||
- MENU: User Interface -> Appearance -> 'Menu Font Green/Blue Color' settings now work properly.
|
||||
- MENU: Add option to enable in-menu sound effects.
|
||||
- MENU/D3D: Scissoring support (will be used for Ozone and menu widgets).
|
||||
- MENU/QT/WIMP: Allow building with MSVC2017.
|
||||
- MENU/QT/WIMP: Add detailed file browser table.
|
||||
- MENU/QT/WIMP: New grid view implementation that is faster and loads thumbnails on-demand.
|
||||
- MENU/QT/WIMP: Thumbnail drag and drop support.
|
||||
- MENU/RGUI: Overhaul custom theme interface + add wallpaper support.
|
||||
- MENU/RGUI: Thumbnail support and thumbnail downscaling.
|
||||
- MENU: Hide password values.
|
||||
- MENU/SOUNDS: Implement in-menu sound effects (not enabled by default for now, still experimental).
|
||||
- MIDI: Add a Linux ALSA driver for MIDI.
|
||||
- NETPLAY: Force fast-save-states when netlay is enabled
|
||||
- NETPLAY: Allow quick joining subsystem lobbies
|
||||
- NETPLAY: Force fast-save-states when netplay is enabled.
|
||||
- NETPLAY: Allow quick joining subsystem lobbies.
|
||||
- OSX: Initial CoreAudio V3 audio driver (not yet used in release builds).
|
||||
- OSX: OpenGL 3.2 Core support for cores.
|
||||
- PS2: Initial PlayStation2 port.
|
||||
- PS4: Initial PlayStation4 port.
|
||||
- RECORDING: Implement recording options in the menu complete with quality profiles, streaming, and proper file naming
|
||||
@ -31,17 +57,23 @@
|
||||
- SUBSYSTEM: Remember the last used folder to make loading subsystem type content faster
|
||||
- SWITCH/LIBNX: Improve touch scaling calculation.
|
||||
- SWITCH: Proper button labels.
|
||||
- TVOS: Initial tvOS port.
|
||||
- VULKAN: Fix RGUI crashing at startup.
|
||||
- VULKAN/RGUI: Enable 'Menu Linear Filter' option.
|
||||
- VULKAN: Fix secondary screens in overlays not working.
|
||||
- WAYLAND: Implement idle-inhibit support (needed for screensaver suspend).
|
||||
- WAYLAND: Fix fullscreen toggle.
|
||||
- WIIU: Initial netplay peer-to-peer support. Network information working.
|
||||
- WINDOWS/WSA: Network Information info is blank until first network operation.
|
||||
- WINDOWS: Fix an ancient bug that caused wrong mappings for keyboard arrows
|
||||
- WINDOWS: Remember window size and position if so desired
|
||||
- WINDOWS: Fix an ancient bug that caused wrong mappings for keyboard arrows.
|
||||
- WINDOWS: Remember window size and position if so desired.
|
||||
- WINDOWS: SSL/TLS connections now work properly.
|
||||
- WINDOWS: Fall back to GDI driver if no accelerated graphics driver is found.
|
||||
- UWP: Initial UWP port.
|
||||
- VFS: Update to version 3.
|
||||
- XBONE: Initial Xbox One port.
|
||||
- XMB/OZONE: Add more icons
|
||||
- XMB: Add Automatic Inverted theme
|
||||
- ???: Easter Egg
|
||||
|
||||
# 1.7.5
|
||||
|
7
Makefile
7
Makefile
@ -19,6 +19,7 @@ TARGET = retroarch
|
||||
OBJ :=
|
||||
LIBS :=
|
||||
DEF_FLAGS :=
|
||||
ASFLAGS :=
|
||||
DEFINES := -DHAVE_CONFIG_H -DRARCH_INTERNAL -D_FILE_OFFSET_BITS=64
|
||||
DEFINES += -DGLOBAL_CONFIG_DIR='"$(GLOBAL_CONFIG_DIR)"'
|
||||
|
||||
@ -253,15 +254,9 @@ install: $(TARGET)
|
||||
@if test -d media/assets && test $(HAVE_ASSETS); then \
|
||||
echo "Installing media assets..."; \
|
||||
mkdir -p $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
if test $(HAVE_ZARCH) = 1; then \
|
||||
cp -r media/assets/zarch/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_MATERIALUI) = 1; then \
|
||||
cp -r media/assets/glui/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_NUKLEAR) = 1; then \
|
||||
cp -r media/assets/nuklear/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
if test $(HAVE_XMB) = 1; then \
|
||||
cp -r media/assets/xmb/ $(DESTDIR)$(ASSETS_DIR)/assets; \
|
||||
fi; \
|
||||
|
231
Makefile.common
231
Makefile.common
@ -27,10 +27,6 @@ ifeq ($(HAVE_LIBRETRODB),)
|
||||
HAVE_LIBRETRODB = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_VIDEO_PROCESSOR), 1)
|
||||
DEFINES += -DHAVE_VIDEO_PROCESSOR
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SOCKET_LEGACY), 1)
|
||||
DEFINES += -DHAVE_SOCKET_LEGACY
|
||||
endif
|
||||
@ -67,8 +63,14 @@ ifeq ($(VULKAN_DEBUG), 1)
|
||||
DEF_FLAGS += -DVULKAN_DEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_HARD_FLOAT), 1)
|
||||
DEFINES += -mfloat-abi=hard
|
||||
ifeq ($(HAVE_FLOATHARD), 1)
|
||||
DEF_FLAGS += $(FLOATHARD_CFLAGS)
|
||||
ASFLAGS += $(FLOATHARD_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_FLOATSOFTFP), 1)
|
||||
DEF_FLAGS += $(FLOATSOFTFP_CFLAGS)
|
||||
ASFLAGS += $(FLOATSOFTFP_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(TDM_GCC),)
|
||||
@ -374,6 +376,10 @@ ifeq ($(HAVE_SSA),1)
|
||||
LIBS += $(SSA_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SSE),1)
|
||||
DEF_FLAGS += $(SSE_LIBS)
|
||||
endif
|
||||
|
||||
# LibretroDB
|
||||
|
||||
ifeq ($(HAVE_LIBRETRODB), 1)
|
||||
@ -504,9 +510,19 @@ endif
|
||||
|
||||
# Audio
|
||||
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO), 1)
|
||||
OBJ += audio/drivers/coreaudio.o
|
||||
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
|
||||
HAVE_COREAUDIO_LIBS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO3), 1)
|
||||
OBJ += audio/drivers/coreaudio3.o
|
||||
HAVE_COREAUDIO_LIBS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_COREAUDIO_LIBS), 1)
|
||||
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CORETEXT), 1)
|
||||
@ -625,7 +641,10 @@ ifeq ($(HAVE_NEON),1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/audio/resampler/drivers/sinc_resampler_neon.o \
|
||||
audio/drivers_resampler/cc_resampler_neon.o \
|
||||
memory/neon/memcpy-neon.o
|
||||
DEFINES += -DHAVE_NEON
|
||||
|
||||
DEFINES += -DHAVE_NEON
|
||||
ASFLAGS += $(NEON_ASFLAGS)
|
||||
DEF_FLAGS += $(NEON_CFLAGS)
|
||||
endif
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/audio/conversion/s16_to_float.o \
|
||||
@ -651,10 +670,6 @@ endif
|
||||
|
||||
# XMB and MaterialUI are always enabled if supported and not explicitly disabled
|
||||
ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
ifeq ($(HAVE_ZARCH),)
|
||||
HAVE_ZARCH = 0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RGUI),)
|
||||
HAVE_RGUI = 1
|
||||
endif
|
||||
@ -663,10 +678,6 @@ ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
HAVE_MATERIALUI = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NUKLEAR),)
|
||||
HAVE_NUKLEAR = 0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XMB),)
|
||||
HAVE_XMB = 1
|
||||
endif
|
||||
@ -679,10 +690,8 @@ ifeq ($(HW_CONTEXT_MENU_DRIVERS), 1)
|
||||
HAVE_OZONE = 1
|
||||
endif
|
||||
else
|
||||
HAVE_ZARCH ?= 0
|
||||
HAVE_RGUI ?= 0
|
||||
HAVE_MATERIALUI ?= 0
|
||||
HAVE_NUKLEAR ?= 0
|
||||
HAVE_XMB ?= 0
|
||||
HAVE_STRIPES ?= 0
|
||||
HAVE_OZONE ?= 0
|
||||
@ -703,21 +712,6 @@ ifeq ($(HAVE_MENU), 1)
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_NUKLEAR), 1)
|
||||
OBJ += menu/drivers/nuklear/nk_common.o \
|
||||
menu/drivers/nuklear/nk_menu.o \
|
||||
menu/drivers/nuklear/nk_wnd_debug.o \
|
||||
menu/drivers/nuklear.o
|
||||
DEFINES += -DHAVE_NUKLEAR
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZARCH), 1)
|
||||
OBJ += menu/drivers/zarch.o
|
||||
DEFINES += -DHAVE_ZARCH
|
||||
HAVE_ASSETS = 1
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XMB), 1)
|
||||
OBJ += menu/drivers/xmb.o
|
||||
DEFINES += -DHAVE_XMB
|
||||
@ -1061,9 +1055,7 @@ endif
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_GLSL
|
||||
OBJ += gfx/drivers/gl.o \
|
||||
gfx/drivers_renderchain/gl2_renderchain.o \
|
||||
$(LIBRETRO_COMM_DIR)/gfx/gl_capabilities.o \
|
||||
gfx/common/gl_common.o \
|
||||
gfx/drivers_font/gl_raster_font.o \
|
||||
$(LIBRETRO_COMM_DIR)/glsym/rglgen.o
|
||||
|
||||
@ -1160,7 +1152,6 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
endif
|
||||
|
||||
OBJ += gfx/drivers_shader/shader_glsl.o
|
||||
DEFINES += -DHAVE_GLSL
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
@ -1170,36 +1161,27 @@ ifeq ($(HAVE_EGL), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
HAVE_SDL=0
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL), 1)
|
||||
OBJ += gfx/drivers/sdl_gfx.o \
|
||||
input/drivers/sdl_input.o \
|
||||
input/drivers_joypad/sdl_joypad.o \
|
||||
audio/drivers/sdl_audio.o
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
endif
|
||||
|
||||
DEFINES += $(SDL_CFLAGS) $(BSD_LOCAL_INC)
|
||||
HAVE_SDL_COMMON = 1
|
||||
OBJ += gfx/drivers/sdl2_gfx.o
|
||||
DEFINES += $(SDL2_CFLAGS)
|
||||
LIBS += $(SDL2_LIBS)
|
||||
else ifeq ($(HAVE_SDL), 1)
|
||||
HAVE_SDL_COMMON = 1
|
||||
OBJ += gfx/drivers/sdl_gfx.o
|
||||
DEFINES += $(SDL_CFLAGS)
|
||||
LIBS += $(SDL_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
OBJ += gfx/drivers/sdl2_gfx.o \
|
||||
input/drivers/sdl_input.o \
|
||||
ifeq ($(HAVE_SDL_COMMON), 1)
|
||||
OBJ += input/drivers/sdl_input.o \
|
||||
input/drivers_joypad/sdl_joypad.o \
|
||||
audio/drivers/sdl_audio.o
|
||||
|
||||
ifeq ($(HAVE_GL_CONTEXT), 1)
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
OBJ += gfx/drivers_context/sdl_gl_ctx.o
|
||||
endif
|
||||
|
||||
DEFINES += $(SDL2_CFLAGS) $(BSD_LOCAL_INC)
|
||||
LIBS += $(SDL2_LIBS)
|
||||
HAVE_SDL = 0
|
||||
DEFINES += $(BSD_LOCAL_INC)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XSHM), 1)
|
||||
@ -1254,8 +1236,6 @@ endif
|
||||
ifeq ($(HAVE_DISPMANX), 1)
|
||||
OBJ += gfx/drivers/dispmanx_gfx.o
|
||||
HAVE_VIDEOCORE = 1
|
||||
LIBS += $(DISPMANX_LIBS)
|
||||
DEFINES += $(DISPMANX_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SUNXI), 1)
|
||||
@ -1547,8 +1527,6 @@ ifeq ($(HAVE_ZLIB), 1)
|
||||
else
|
||||
LIBS += $(ZLIB_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CHD), 1)
|
||||
DEF_FLAGS += -I$(LIBRETRO_COMM_DIR)/formats/libchdr
|
||||
DEFINES += -DHAVE_CHD -DWANT_SUBCODE -DWANT_RAW_DATA_SECTOR
|
||||
@ -1558,18 +1536,17 @@ ifeq ($(HAVE_CHD), 1)
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_huffman.o \
|
||||
$(LIBRETRO_COMM_DIR)/streams/chd_stream.o
|
||||
|
||||
ifeq ($(HAVE_FLAC), 1)
|
||||
|
||||
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zlib.o
|
||||
ifeq ($(HAVE_FLAC),1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac.o \
|
||||
$(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_flac_codec.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_7ZIP), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_lzma.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_ZLIB), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/formats/libchdr/libchdr_zlib.o
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RTGA), 1)
|
||||
@ -1612,7 +1589,8 @@ endif
|
||||
|
||||
ifeq ($(HAVE_V4L2),1)
|
||||
OBJ += camera/drivers/video4linux2.o
|
||||
ifeq ($(HAVE_VIDEO_PROCESSOR),1)
|
||||
ifeq ($(HAVE_VIDEOPROCESSOR),1)
|
||||
DEFINES += -DHAVE_VIDEOPROCESSOR
|
||||
OBJ += cores/libretro-video-processor/video_processor_v4l2.o
|
||||
endif
|
||||
DEFINES += -DHAVE_V4L2
|
||||
@ -1665,54 +1643,78 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
network/netplay/netplay_buf.o \
|
||||
network/netplay/netplay_room_parse.o
|
||||
|
||||
# Retro Achievements
|
||||
# RetroAchievements
|
||||
ifeq ($(HAVE_CHEEVOS), 1)
|
||||
DEFINES += -DHAVE_CHEEVOS
|
||||
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/badges.o \
|
||||
cheevos/var.o \
|
||||
cheevos/cond.o
|
||||
|
||||
ifeq ($(HAVE_LUA), 1)
|
||||
DEFINES += -DHAVE_LUA \
|
||||
-DLUA_32BITS \
|
||||
-Ideps/lua/src
|
||||
OBJ += deps/lua/src/lapi.o \
|
||||
deps/lua/src/lcode.o \
|
||||
deps/lua/src/lctype.o \
|
||||
deps/lua/src/ldebug.o \
|
||||
deps/lua/src/ldo.o \
|
||||
deps/lua/src/ldump.o \
|
||||
deps/lua/src/lfunc.o \
|
||||
deps/lua/src/lgc.o \
|
||||
deps/lua/src/llex.o \
|
||||
deps/lua/src/lmem.o \
|
||||
deps/lua/src/lobject.o \
|
||||
deps/lua/src/lopcodes.o \
|
||||
deps/lua/src/lparser.o \
|
||||
deps/lua/src/lstate.o \
|
||||
deps/lua/src/lstring.o \
|
||||
deps/lua/src/ltable.o \
|
||||
deps/lua/src/ltm.o \
|
||||
deps/lua/src/lundump.o \
|
||||
deps/lua/src/lvm.o \
|
||||
deps/lua/src/lzio.o \
|
||||
deps/lua/src/lauxlib.o \
|
||||
deps/lua/src/lbaselib.o \
|
||||
deps/lua/src/lbitlib.o \
|
||||
deps/lua/src/lcorolib.o \
|
||||
deps/lua/src/ldblib.o \
|
||||
deps/lua/src/liolib.o \
|
||||
deps/lua/src/lmathlib.o \
|
||||
deps/lua/src/loslib.o \
|
||||
deps/lua/src/lstrlib.o \
|
||||
deps/lua/src/ltablib.o \
|
||||
deps/lua/src/lutf8lib.o \
|
||||
deps/lua/src/loadlib.o \
|
||||
deps/lua/src/linit.o
|
||||
ifeq ($(HAVE_NEW_CHEEVOS), 1)
|
||||
DEFINES += -DHAVE_NEW_CHEEVOS \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ideps/lua/src
|
||||
OBJ += cheevos-new/cheevos.o \
|
||||
cheevos-new/badges.o \
|
||||
cheevos-new/fixup.o \
|
||||
cheevos-new/parser.o \
|
||||
cheevos-new/hash.o \
|
||||
deps/rcheevos/src/rcheevos/trigger.o \
|
||||
deps/rcheevos/src/rcheevos/condset.o \
|
||||
deps/rcheevos/src/rcheevos/condition.o \
|
||||
deps/rcheevos/src/rcheevos/operand.o \
|
||||
deps/rcheevos/src/rcheevos/term.o \
|
||||
deps/rcheevos/src/rcheevos/expression.o \
|
||||
deps/rcheevos/src/rcheevos/value.o \
|
||||
deps/rcheevos/src/rcheevos/lboard.o \
|
||||
deps/rcheevos/src/rcheevos/alloc.o \
|
||||
deps/rcheevos/src/rcheevos/format.o \
|
||||
deps/rcheevos/src/rurl/url.o
|
||||
|
||||
ifeq ($(HAVE_LUA), 1)
|
||||
DEFINES += -DHAVE_LUA \
|
||||
-DLUA_32BITS \
|
||||
-Ideps/lua/src
|
||||
OBJ += deps/lua/src/lapi.o \
|
||||
deps/lua/src/lcode.o \
|
||||
deps/lua/src/lctype.o \
|
||||
deps/lua/src/ldebug.o \
|
||||
deps/lua/src/ldo.o \
|
||||
deps/lua/src/ldump.o \
|
||||
deps/lua/src/lfunc.o \
|
||||
deps/lua/src/lgc.o \
|
||||
deps/lua/src/llex.o \
|
||||
deps/lua/src/lmem.o \
|
||||
deps/lua/src/lobject.o \
|
||||
deps/lua/src/lopcodes.o \
|
||||
deps/lua/src/lparser.o \
|
||||
deps/lua/src/lstate.o \
|
||||
deps/lua/src/lstring.o \
|
||||
deps/lua/src/ltable.o \
|
||||
deps/lua/src/ltm.o \
|
||||
deps/lua/src/lundump.o \
|
||||
deps/lua/src/lvm.o \
|
||||
deps/lua/src/lzio.o \
|
||||
deps/lua/src/lauxlib.o \
|
||||
deps/lua/src/lbaselib.o \
|
||||
deps/lua/src/lbitlib.o \
|
||||
deps/lua/src/lcorolib.o \
|
||||
deps/lua/src/ldblib.o \
|
||||
deps/lua/src/liolib.o \
|
||||
deps/lua/src/lmathlib.o \
|
||||
deps/lua/src/loslib.o \
|
||||
deps/lua/src/lstrlib.o \
|
||||
deps/lua/src/ltablib.o \
|
||||
deps/lua/src/lutf8lib.o \
|
||||
deps/lua/src/loadlib.o \
|
||||
deps/lua/src/linit.o
|
||||
else
|
||||
DEFINES += -DRC_DISABLE_LUA
|
||||
endif
|
||||
|
||||
# if not HAVE_NEW_CHEEVOS
|
||||
else
|
||||
DEFINES += -DRC_DISABLE_LUA
|
||||
OBJ += cheevos/cheevos.o \
|
||||
cheevos/badges.o \
|
||||
cheevos/var.o \
|
||||
cheevos/cond.o
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1720,6 +1722,11 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
NEED_CXX_LINKER = 1
|
||||
DEFINES += -DHAVE_DISCORD
|
||||
DEFINES += -Ideps/discord-rpc/include/ -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/
|
||||
|
||||
ifneq ($(HAVE_THREADS), 1)
|
||||
DEFINES += -DDISCORD_DISABLE_IO_THREAD
|
||||
endif
|
||||
|
||||
OBJ += deps/discord-rpc/src/discord_rpc.o \
|
||||
deps/discord-rpc/src/rpc_connection.o \
|
||||
deps/discord-rpc/src/serialization.o \
|
||||
|
@ -68,7 +68,6 @@ else
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
@ -137,7 +136,6 @@ CFLAGS += -I. \
|
||||
-Ideps/libz \
|
||||
-Ideps/7zip \
|
||||
-Ideps/stb \
|
||||
-Ideps/rcheevos/include \
|
||||
-Ilibretro-common/include
|
||||
|
||||
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE
|
||||
|
@ -41,7 +41,7 @@ HAVE_NETWORKING = 1
|
||||
HAVE_NETPLAYDISCOVERY = 1
|
||||
HAVE_STB_FONT = 1
|
||||
HAVE_CHEEVOS = 1
|
||||
HAVE_CHD = 1
|
||||
HAVE_CHD = 0 # disabled due to static libretro-common and libchdr conflicts between different cores
|
||||
HAVE_STB_VORBIS = 1
|
||||
|
||||
# RetroArch libnx useful flags
|
||||
@ -56,18 +56,13 @@ HAVE_LANGEXTRA = 1
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
HAVE_EGL = 1
|
||||
HAVE_SHADERPIPELINE = 1
|
||||
|
||||
HAVE_RGUI = 1
|
||||
HAVE_MATERIALUI = 1
|
||||
|
||||
HAVE_XMB = 1
|
||||
HAVE_OZONE = 1
|
||||
|
||||
HAVE_OVERLAY = 1
|
||||
else
|
||||
HAVE_RGUI = 1
|
||||
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 0
|
||||
HAVE_XMB = 0
|
||||
HAVE_OZONE = 0
|
||||
|
@ -30,18 +30,17 @@ else
|
||||
HAVE_RBMP := 1
|
||||
HAVE_RTGA := 1
|
||||
HAVE_ZLIB := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_7ZIP := 1
|
||||
HAVE_EGL := 1
|
||||
HAVE_OPENGLES := 1
|
||||
HAVE_OPENGLES := 1
|
||||
HAVE_NETWORKING := 0
|
||||
HAVE_SOCKET_LEGACY := 0
|
||||
HAVE_MENU := 1
|
||||
HAVE_MENU_COMMON := 1
|
||||
HAVE_RGUI := 0
|
||||
HAVE_MATERIALUI := 0
|
||||
HAVE_XMB := 1
|
||||
HAVE_ZARCH := 0
|
||||
HAVE_MATERIALUI := 0
|
||||
HAVE_XMB := 1
|
||||
HAVE_THREADS := 1
|
||||
HAVE_LIBRETRODB := 1
|
||||
HAVE_CC_RESAMPLER := 1
|
||||
|
@ -24,7 +24,6 @@ else
|
||||
HAVE_ZLIB = 1
|
||||
HAVE_BUILTINZLIB = 1
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 0 # enable later?
|
||||
HAVE_XMB = 0
|
||||
HAVE_STATIC_VIDEO_FILTERS = 1
|
||||
|
@ -122,7 +122,6 @@ endif
|
||||
HAVE_7ZIP = 1
|
||||
HAVE_BUILTINZLIB = 0
|
||||
HAVE_LIBRETRODB = 1
|
||||
HAVE_ZARCH = 0
|
||||
HAVE_MATERIALUI = 1
|
||||
HAVE_XMB = 1
|
||||
HAVE_STB_FONT = 1
|
||||
|
88
audio/audio_defines.h
Normal file
88
audio/audio_defines.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __AUDIO_DEFINES__H
|
||||
#define __AUDIO_DEFINES__H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 512
|
||||
|
||||
/* So we don't get complete line-noise when fast-forwarding audio. */
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
|
||||
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_STREAMS 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS + 4)
|
||||
|
||||
/* do not define more than (MAX_SYSTEM_STREAMS - MAX_STREAMS) */
|
||||
enum audio_mixer_system_slot
|
||||
{
|
||||
AUDIO_MIXER_SYSTEM_SLOT_OK = AUDIO_MIXER_MAX_STREAMS,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_CANCEL,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_NOTICE,
|
||||
AUDIO_MIXER_SYSTEM_SLOT_BGM
|
||||
};
|
||||
|
||||
enum audio_action
|
||||
{
|
||||
AUDIO_ACTION_NONE = 0,
|
||||
AUDIO_ACTION_RATE_CONTROL_DELTA,
|
||||
AUDIO_ACTION_MIXER_MUTE_ENABLE,
|
||||
AUDIO_ACTION_MUTE_ENABLE,
|
||||
AUDIO_ACTION_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER
|
||||
};
|
||||
|
||||
enum audio_mixer_slot_selection_type
|
||||
{
|
||||
AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC = 0,
|
||||
AUDIO_MIXER_SLOT_SELECTION_MANUAL
|
||||
};
|
||||
|
||||
enum audio_mixer_stream_type
|
||||
{
|
||||
AUDIO_STREAM_TYPE_NONE = 0,
|
||||
AUDIO_STREAM_TYPE_USER,
|
||||
AUDIO_STREAM_TYPE_SYSTEM
|
||||
};
|
||||
|
||||
enum audio_mixer_state
|
||||
{
|
||||
AUDIO_STREAM_STATE_NONE = 0,
|
||||
AUDIO_STREAM_STATE_STOPPED,
|
||||
AUDIO_STREAM_STATE_PLAYING,
|
||||
AUDIO_STREAM_STATE_PLAYING_LOOPED,
|
||||
AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL
|
||||
};
|
||||
|
||||
typedef struct audio_statistics
|
||||
{
|
||||
float average_buffer_saturation;
|
||||
float std_deviation_percentage;
|
||||
float close_to_underrun;
|
||||
float close_to_blocking;
|
||||
unsigned samples;
|
||||
} audio_statistics_t;
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
@ -21,10 +21,12 @@
|
||||
#include <lists/string_list.h>
|
||||
#include <audio/conversion/float_to_s16.h>
|
||||
#include <audio/conversion/s16_to_float.h>
|
||||
#include <audio/audio_resampler.h>
|
||||
#include <audio/dsp_filter.h>
|
||||
#include <file/file_path.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -35,6 +37,8 @@
|
||||
#include "../gfx/video_driver.h"
|
||||
#include "../record/record_driver.h"
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "../tasks/task_audio_mixer.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
|
||||
#include "../command.h"
|
||||
#include "../driver.h"
|
||||
@ -42,9 +46,17 @@
|
||||
#include "../retroarch.h"
|
||||
#include "../verbosity.h"
|
||||
#include "../list_special.h"
|
||||
#include "../file_path_special.h"
|
||||
#include "../content.h"
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#include <rthreads/rthreads.h>
|
||||
#endif
|
||||
|
||||
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
|
||||
|
||||
#define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac"
|
||||
|
||||
/**
|
||||
* db_to_gain:
|
||||
* @db : Decibels.
|
||||
@ -77,6 +89,9 @@ static const audio_driver_t *audio_drivers[] = {
|
||||
#ifdef HAVE_COREAUDIO
|
||||
&audio_coreaudio,
|
||||
#endif
|
||||
#ifdef HAVE_COREAUDIO3
|
||||
&audio_coreaudio3,
|
||||
#endif
|
||||
#ifdef HAVE_AL
|
||||
&audio_openal,
|
||||
#endif
|
||||
@ -185,13 +200,36 @@ static const audio_driver_t *current_audio = NULL;
|
||||
static void *audio_driver_context_audio_data = NULL;
|
||||
|
||||
static bool audio_suspended = false;
|
||||
static bool audio_is_threaded = false;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static slock_t* s_audio_driver_lock = NULL;
|
||||
#endif
|
||||
|
||||
static void audio_mixer_play_stop_sequential_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
static void audio_mixer_play_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
static void audio_mixer_menu_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason);
|
||||
|
||||
enum resampler_quality audio_driver_get_resampler_quality(void)
|
||||
#ifdef HAVE_THREADS
|
||||
#define audio_driver_lock() \
|
||||
if (s_audio_driver_lock) \
|
||||
slock_lock(s_audio_driver_lock)
|
||||
#else
|
||||
#define audio_driver_lock()
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#define audio_driver_unlock() \
|
||||
if (s_audio_driver_lock) \
|
||||
slock_unlock(s_audio_driver_lock)
|
||||
#else
|
||||
#define audio_driver_unlock()
|
||||
#endif
|
||||
|
||||
static enum resampler_quality audio_driver_get_resampler_quality(void)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
@ -447,6 +485,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
#ifdef HAVE_THREADS
|
||||
if (audio_cb_inited)
|
||||
{
|
||||
audio_is_threaded = true;
|
||||
RARCH_LOG("[Audio]: Starting threaded audio driver ...\n");
|
||||
if (!audio_init_thread(
|
||||
¤t_audio,
|
||||
@ -465,6 +504,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
audio_is_threaded = false;
|
||||
audio_driver_context_audio_data =
|
||||
current_audio->init(*settings->arrays.audio_device ?
|
||||
settings->arrays.audio_device : NULL,
|
||||
@ -507,6 +547,15 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
audio_source_ratio_original = audio_source_ratio_current =
|
||||
(double)settings->uints.audio_out_rate / audio_driver_input;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
if (s_audio_driver_lock)
|
||||
slock_free(s_audio_driver_lock);
|
||||
s_audio_driver_lock = slock_new();
|
||||
#endif
|
||||
|
||||
audio_resampler_lock_init();
|
||||
audio_resampler_lock();
|
||||
|
||||
if (!retro_resampler_realloc(
|
||||
&audio_driver_resampler_data,
|
||||
&audio_driver_resampler,
|
||||
@ -519,6 +568,8 @@ static bool audio_driver_init_internal(bool audio_cb_inited)
|
||||
audio_driver_active = false;
|
||||
}
|
||||
|
||||
audio_resampler_unlock();
|
||||
|
||||
aud_inp_data = (float*)malloc(max_bufsamples * sizeof(float));
|
||||
retro_assert(aud_inp_data != NULL);
|
||||
|
||||
@ -589,9 +640,13 @@ void audio_driver_set_nonblocking_state(bool enable)
|
||||
audio_driver_context_audio_data,
|
||||
settings->bools.audio_sync ? enable : true);
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
audio_driver_chunk_size = enable ?
|
||||
audio_driver_chunk_nonblock_size :
|
||||
audio_driver_chunk_block_size;
|
||||
|
||||
audio_driver_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -609,6 +664,7 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
bool is_paused = false;
|
||||
bool is_idle = false;
|
||||
bool is_slowmotion = false;
|
||||
bool is_active = false;
|
||||
const void *output_data = NULL;
|
||||
unsigned output_frames = 0;
|
||||
float audio_volume_gain = !audio_driver_mute_enable ?
|
||||
@ -617,9 +673,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.data_out = NULL;
|
||||
src_data.output_frames = 0;
|
||||
|
||||
recording_driver_lock();
|
||||
|
||||
if (recording_data)
|
||||
recording_push_audio(data, samples);
|
||||
|
||||
recording_driver_unlock();
|
||||
|
||||
runloop_get_status(&is_paused, &is_idle, &is_slowmotion,
|
||||
&is_perfcnt_enable);
|
||||
|
||||
@ -629,9 +689,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
!audio_driver_output_samples_buf)
|
||||
return;
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
convert_s16_to_float(audio_driver_input_data, data, samples,
|
||||
audio_volume_gain);
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
src_data.data_in = audio_driver_input_data;
|
||||
src_data.input_frames = samples >> 1;
|
||||
|
||||
@ -695,9 +759,15 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.ratio *= settings->floats.slowmotion_ratio;
|
||||
}
|
||||
|
||||
audio_driver_resampler->process(audio_driver_resampler_data, &src_data);
|
||||
audio_driver_lock();
|
||||
|
||||
if (audio_mixer_active)
|
||||
audio_resampler_lock();
|
||||
audio_driver_resampler->process(audio_driver_resampler_data, &src_data);
|
||||
audio_resampler_unlock();
|
||||
|
||||
is_active = audio_mixer_active;
|
||||
|
||||
if (is_active)
|
||||
{
|
||||
bool override = audio_driver_mixer_mute_enable ? true :
|
||||
(audio_driver_mixer_volume_gain != 1.0f) ? true : false;
|
||||
@ -707,6 +777,8 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
src_data.output_frames, mixer_gain, override);
|
||||
}
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
output_data = audio_driver_output_samples_buf;
|
||||
output_frames = (unsigned)src_data.output_frames;
|
||||
|
||||
@ -721,9 +793,13 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
output_frames *= sizeof(int16_t);
|
||||
}
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
if (current_audio->write(audio_driver_context_audio_data,
|
||||
output_data, output_frames * 2) < 0)
|
||||
audio_driver_active = false;
|
||||
|
||||
audio_driver_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -735,14 +811,24 @@ static void audio_driver_flush(const int16_t *data, size_t samples)
|
||||
**/
|
||||
void audio_driver_sample(int16_t left, int16_t right)
|
||||
{
|
||||
audio_driver_lock();
|
||||
|
||||
if (audio_suspended)
|
||||
{
|
||||
audio_driver_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
audio_driver_output_samples_conv_buf[audio_driver_data_ptr++] = left;
|
||||
audio_driver_output_samples_conv_buf[audio_driver_data_ptr++] = right;
|
||||
|
||||
if (audio_driver_data_ptr < audio_driver_chunk_size)
|
||||
{
|
||||
audio_driver_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
audio_driver_flush(audio_driver_output_samples_conv_buf,
|
||||
audio_driver_data_ptr);
|
||||
@ -753,9 +839,8 @@ void audio_driver_sample(int16_t left, int16_t right)
|
||||
void audio_driver_menu_sample(void)
|
||||
{
|
||||
static int16_t samples_buf[1024] = {0};
|
||||
struct retro_system_av_info
|
||||
*av_info = video_viewport_get_system_av_info();
|
||||
const struct retro_system_timing *info =
|
||||
struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
|
||||
const struct retro_system_timing *info =
|
||||
(const struct retro_system_timing*)&av_info->timing;
|
||||
unsigned sample_count = (info->sample_rate / info->fps) * 2;
|
||||
while (sample_count > 1024)
|
||||
@ -966,10 +1051,13 @@ bool audio_driver_find_driver(void)
|
||||
|
||||
void audio_driver_deinit_resampler(void)
|
||||
{
|
||||
audio_resampler_lock();
|
||||
if (audio_driver_resampler && audio_driver_resampler_data)
|
||||
audio_driver_resampler->free(audio_driver_resampler_data);
|
||||
audio_driver_resampler = NULL;
|
||||
audio_driver_resampler_data = NULL;
|
||||
audio_resampler_unlock();
|
||||
audio_resampler_lock_free();
|
||||
}
|
||||
|
||||
bool audio_driver_free_devices_list(void)
|
||||
@ -1095,6 +1183,28 @@ static void audio_mixer_play_stop_cb(
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_mixer_menu_stop_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason)
|
||||
{
|
||||
int idx = audio_mixer_find_index(sound);
|
||||
|
||||
switch (reason)
|
||||
{
|
||||
case AUDIO_MIXER_SOUND_FINISHED:
|
||||
if (idx >= 0)
|
||||
{
|
||||
unsigned i = (unsigned)idx;
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_STOPPED;
|
||||
audio_mixer_streams[i].volume = 0.0f;
|
||||
}
|
||||
break;
|
||||
case AUDIO_MIXER_SOUND_STOPPED:
|
||||
break;
|
||||
case AUDIO_MIXER_SOUND_REPEATED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_mixer_play_stop_sequential_cb(
|
||||
audio_mixer_sound_t *sound, unsigned reason)
|
||||
{
|
||||
@ -1113,9 +1223,9 @@ static void audio_mixer_play_stop_sequential_cb(
|
||||
free(audio_mixer_streams[i].name);
|
||||
|
||||
if (i < AUDIO_MIXER_MAX_STREAMS)
|
||||
audio_mixer_streams[i].type = AUDIO_STREAM_TYPE_USER;
|
||||
audio_mixer_streams[i].stream_type = AUDIO_STREAM_TYPE_USER;
|
||||
else
|
||||
audio_mixer_streams[i].type = AUDIO_STREAM_TYPE_SYSTEM;
|
||||
audio_mixer_streams[i].stream_type = AUDIO_STREAM_TYPE_SYSTEM;
|
||||
|
||||
audio_mixer_streams[i].name = NULL;
|
||||
audio_mixer_streams[i].state = AUDIO_STREAM_STATE_NONE;
|
||||
@ -1243,17 +1353,22 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params)
|
||||
break;
|
||||
}
|
||||
|
||||
audio_driver_lock();
|
||||
|
||||
audio_mixer_active = true;
|
||||
|
||||
audio_mixer_streams[free_slot].name = !string_is_empty(params->basename) ? strdup(params->basename) : NULL;
|
||||
audio_mixer_streams[free_slot].name = !string_is_empty(params->basename) ? strdup(params->basename) : NULL;
|
||||
audio_mixer_streams[free_slot].buf = buf;
|
||||
audio_mixer_streams[free_slot].handle = handle;
|
||||
audio_mixer_streams[free_slot].voice = voice;
|
||||
audio_mixer_streams[free_slot].type = params->stream_type;
|
||||
audio_mixer_streams[free_slot].stream_type = params->stream_type;
|
||||
audio_mixer_streams[free_slot].type = params->type;
|
||||
audio_mixer_streams[free_slot].state = params->state;
|
||||
audio_mixer_streams[free_slot].volume = params->volume;
|
||||
audio_mixer_streams[free_slot].stop_cb = stop_cb;
|
||||
|
||||
audio_driver_unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1291,12 +1406,128 @@ static void audio_driver_mixer_play_stream_internal(unsigned i, unsigned type)
|
||||
audio_mixer_streams[i].state = (enum audio_mixer_state)type;
|
||||
}
|
||||
|
||||
static void audio_driver_load_menu_bgm_callback(void *task_data, void *user_data, const char *error)
|
||||
{
|
||||
bool contentless = false;
|
||||
bool is_inited = false;
|
||||
|
||||
content_get_status(&contentless, &is_inited);
|
||||
|
||||
if (!is_inited)
|
||||
audio_driver_mixer_play_menu_sound_looped(AUDIO_MIXER_SYSTEM_SLOT_BGM);
|
||||
}
|
||||
|
||||
void audio_driver_load_menu_sounds(void)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
char *sounds_path = NULL;
|
||||
char *sounds_fallback_path = NULL;
|
||||
const char *path_ok = NULL;
|
||||
const char *path_cancel = NULL;
|
||||
const char *path_notice = NULL;
|
||||
const char *path_bgm = NULL;
|
||||
struct string_list *list = NULL;
|
||||
struct string_list *list_fallback = NULL;
|
||||
int i = 0;
|
||||
|
||||
sounds_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
sounds_fallback_path = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
sounds_path[0] = sounds_fallback_path[0] = '\0';
|
||||
|
||||
fill_pathname_join(
|
||||
sounds_fallback_path,
|
||||
settings->paths.directory_assets,
|
||||
"sounds",
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
|
||||
fill_pathname_application_special(sounds_path, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_SOUNDS);
|
||||
|
||||
list = dir_list_new(sounds_path, MENU_SOUND_FORMATS, false, false, false, false);
|
||||
list_fallback = dir_list_new(sounds_fallback_path, MENU_SOUND_FORMATS, false, false, false, false);
|
||||
|
||||
if (!list)
|
||||
{
|
||||
list = list_fallback;
|
||||
list_fallback = NULL;
|
||||
}
|
||||
|
||||
if (!list || list->size == 0)
|
||||
goto end;
|
||||
|
||||
if (list_fallback && list_fallback->size > 0)
|
||||
{
|
||||
for (i = 0; i < list_fallback->size; i++)
|
||||
{
|
||||
if (list->size == 0 || !string_list_find_elem(list, list_fallback->elems[i].data))
|
||||
{
|
||||
union string_list_elem_attr attr = {0};
|
||||
string_list_append(list, list_fallback->elems[i].data, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < list->size; i++)
|
||||
{
|
||||
const char *path = list->elems[i].data;
|
||||
const char *ext = path_get_extension(path);
|
||||
char basename_noext[PATH_MAX_LENGTH];
|
||||
|
||||
basename_noext[0] = '\0';
|
||||
|
||||
fill_pathname_base_noext(basename_noext, path, sizeof(basename_noext));
|
||||
|
||||
if (audio_driver_mixer_extension_supported(ext))
|
||||
{
|
||||
if (string_is_equal_noncase(basename_noext, "ok"))
|
||||
path_ok = path;
|
||||
if (string_is_equal_noncase(basename_noext, "cancel"))
|
||||
path_cancel = path;
|
||||
if (string_is_equal_noncase(basename_noext, "notice"))
|
||||
path_notice = path;
|
||||
if (string_is_equal_noncase(basename_noext, "bgm"))
|
||||
path_bgm = path;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_ok && settings->bools.audio_enable_menu_ok)
|
||||
task_push_audio_mixer_load(path_ok, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_OK);
|
||||
if (path_cancel && settings->bools.audio_enable_menu_cancel)
|
||||
task_push_audio_mixer_load(path_cancel, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_CANCEL);
|
||||
if (path_notice && settings->bools.audio_enable_menu_notice)
|
||||
task_push_audio_mixer_load(path_notice, NULL, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_NOTICE);
|
||||
if (path_bgm && settings->bools.audio_enable_menu_bgm)
|
||||
task_push_audio_mixer_load(path_bgm, audio_driver_load_menu_bgm_callback, NULL, true, AUDIO_MIXER_SLOT_SELECTION_MANUAL, AUDIO_MIXER_SYSTEM_SLOT_BGM);
|
||||
|
||||
end:
|
||||
if (list)
|
||||
string_list_free(list);
|
||||
if (list_fallback)
|
||||
string_list_free(list_fallback);
|
||||
if (sounds_path)
|
||||
free(sounds_path);
|
||||
if (sounds_fallback_path)
|
||||
free(sounds_fallback_path);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_stream(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_menu_sound_looped(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_menu_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING_LOOPED);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_menu_sound(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_menu_stop_cb;
|
||||
audio_driver_mixer_play_stream_internal(i, AUDIO_STREAM_STATE_PLAYING);
|
||||
}
|
||||
|
||||
void audio_driver_mixer_play_stream_looped(unsigned i)
|
||||
{
|
||||
audio_mixer_streams[i].stop_cb = audio_mixer_play_stop_cb;
|
||||
@ -1421,6 +1652,11 @@ bool audio_driver_deinit(void)
|
||||
{
|
||||
audio_driver_mixer_deinit();
|
||||
audio_driver_free_devices_list();
|
||||
#ifdef HAVE_THREADS
|
||||
slock_free(s_audio_driver_lock);
|
||||
s_audio_driver_lock = NULL;
|
||||
#endif
|
||||
|
||||
if (!audio_driver_deinit_internal())
|
||||
return false;
|
||||
return true;
|
||||
|
@ -22,56 +22,14 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <audio/audio_mixer.h>
|
||||
#include <audio/audio_resampler.h>
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <audio/audio_mixer.h>
|
||||
|
||||
#include "audio_defines.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define AUDIO_CHUNK_SIZE_BLOCKING 512
|
||||
|
||||
/* So we don't get complete line-noise when fast-forwarding audio. */
|
||||
#define AUDIO_CHUNK_SIZE_NONBLOCKING 2048
|
||||
|
||||
#define AUDIO_MAX_RATIO 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_STREAMS 16
|
||||
|
||||
#define AUDIO_MIXER_MAX_SYSTEM_STREAMS (AUDIO_MIXER_MAX_STREAMS+4)
|
||||
|
||||
enum audio_action
|
||||
{
|
||||
AUDIO_ACTION_NONE = 0,
|
||||
AUDIO_ACTION_RATE_CONTROL_DELTA,
|
||||
AUDIO_ACTION_MIXER_MUTE_ENABLE,
|
||||
AUDIO_ACTION_MUTE_ENABLE,
|
||||
AUDIO_ACTION_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER_VOLUME_GAIN,
|
||||
AUDIO_ACTION_MIXER
|
||||
};
|
||||
|
||||
enum audio_mixer_slot_selection_type
|
||||
{
|
||||
AUDIO_MIXER_SLOT_SELECTION_AUTOMATIC = 0,
|
||||
AUDIO_MIXER_SLOT_SELECTION_MANUAL
|
||||
};
|
||||
|
||||
enum audio_mixer_stream_type
|
||||
{
|
||||
AUDIO_STREAM_TYPE_NONE = 0,
|
||||
AUDIO_STREAM_TYPE_USER,
|
||||
AUDIO_STREAM_TYPE_SYSTEM
|
||||
};
|
||||
|
||||
enum audio_mixer_state
|
||||
{
|
||||
AUDIO_STREAM_STATE_NONE = 0,
|
||||
AUDIO_STREAM_STATE_STOPPED,
|
||||
AUDIO_STREAM_STATE_PLAYING,
|
||||
AUDIO_STREAM_STATE_PLAYING_LOOPED,
|
||||
AUDIO_STREAM_STATE_PLAYING_SEQUENTIAL
|
||||
};
|
||||
|
||||
typedef struct audio_mixer_stream
|
||||
{
|
||||
audio_mixer_sound_t *handle;
|
||||
@ -86,14 +44,19 @@ typedef struct audio_mixer_stream
|
||||
size_t bufsize;
|
||||
} audio_mixer_stream_t;
|
||||
|
||||
typedef struct audio_statistics
|
||||
typedef struct audio_mixer_stream_params
|
||||
{
|
||||
float average_buffer_saturation;
|
||||
float std_deviation_percentage;
|
||||
float close_to_underrun;
|
||||
float close_to_blocking;
|
||||
unsigned samples;
|
||||
} audio_statistics_t;
|
||||
float volume;
|
||||
enum audio_mixer_slot_selection_type slot_selection_type;
|
||||
unsigned slot_selection_idx;
|
||||
enum audio_mixer_stream_type stream_type;
|
||||
enum audio_mixer_type type;
|
||||
enum audio_mixer_state state;
|
||||
void *buf;
|
||||
char *basename;
|
||||
size_t bufsize;
|
||||
audio_mixer_stop_cb_t cb;
|
||||
} audio_mixer_stream_params_t;
|
||||
|
||||
typedef struct audio_driver
|
||||
{
|
||||
@ -177,20 +140,6 @@ typedef struct audio_driver
|
||||
size_t (*buffer_size)(void *data);
|
||||
} audio_driver_t;
|
||||
|
||||
typedef struct audio_mixer_stream_params
|
||||
{
|
||||
float volume;
|
||||
enum audio_mixer_slot_selection_type slot_selection_type;
|
||||
unsigned slot_selection_idx;
|
||||
enum audio_mixer_stream_type stream_type;
|
||||
enum audio_mixer_type type;
|
||||
enum audio_mixer_state state;
|
||||
void *buf;
|
||||
char *basename;
|
||||
size_t bufsize;
|
||||
audio_mixer_stop_cb_t cb;
|
||||
} audio_mixer_stream_params_t;
|
||||
|
||||
void audio_driver_destroy_data(void);
|
||||
|
||||
void audio_driver_set_own_driver(void);
|
||||
@ -315,6 +264,10 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params);
|
||||
|
||||
void audio_driver_mixer_play_stream(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_menu_sound(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_menu_sound_looped(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_sequential(unsigned i);
|
||||
|
||||
void audio_driver_mixer_play_stream_looped(unsigned i);
|
||||
@ -327,14 +280,14 @@ void audio_driver_mixer_set_stream_volume(unsigned i, float vol);
|
||||
|
||||
void audio_driver_mixer_remove_stream(unsigned i);
|
||||
|
||||
enum resampler_quality audio_driver_get_resampler_quality(void);
|
||||
|
||||
enum audio_mixer_state audio_driver_mixer_get_stream_state(unsigned i);
|
||||
|
||||
const char *audio_driver_mixer_get_stream_name(unsigned i);
|
||||
|
||||
bool compute_audio_buffer_statistics(audio_statistics_t *stats);
|
||||
|
||||
void audio_driver_load_menu_sounds(void);
|
||||
|
||||
extern audio_driver_t audio_rsound;
|
||||
extern audio_driver_t audio_audioio;
|
||||
extern audio_driver_t audio_oss;
|
||||
@ -351,6 +304,7 @@ extern audio_driver_t audio_pulse;
|
||||
extern audio_driver_t audio_dsound;
|
||||
extern audio_driver_t audio_wasapi;
|
||||
extern audio_driver_t audio_coreaudio;
|
||||
extern audio_driver_t audio_coreaudio3;
|
||||
extern audio_driver_t audio_xenon360;
|
||||
extern audio_driver_t audio_ps3;
|
||||
extern audio_driver_t audio_gx;
|
||||
|
@ -125,7 +125,9 @@ static OSStatus audio_write_cb(void *userdata,
|
||||
static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state)
|
||||
{
|
||||
(void)data;
|
||||
#if TARGET_OS_IOS
|
||||
g_interrupted = (interrupt_state == kAudioSessionBeginInterruption);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||
@ -218,7 +220,7 @@ static void *coreaudio_init(const char *device,
|
||||
dev->lock = slock_new();
|
||||
dev->cond = scond_new();
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_OS_IOS
|
||||
if (!session_initialized)
|
||||
{
|
||||
session_initialized = true;
|
||||
|
382
audio/drivers/coreaudio3.m
Normal file
382
audio/drivers/coreaudio3.m
Normal file
@ -0,0 +1,382 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2019 - Stuart Carnie
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "../audio_driver.h"
|
||||
|
||||
#pragma mark - ringbuffer
|
||||
|
||||
typedef struct ringbuffer
|
||||
{
|
||||
float *buffer;
|
||||
size_t cap;
|
||||
atomic_int len;
|
||||
size_t writePtr;
|
||||
size_t readPtr;
|
||||
} ringbuffer_t;
|
||||
|
||||
typedef ringbuffer_t * ringbuffer_h;
|
||||
|
||||
static inline size_t rb_len(ringbuffer_h r)
|
||||
{
|
||||
return atomic_load_explicit(&r->len, memory_order_relaxed);
|
||||
}
|
||||
|
||||
static inline size_t rb_cap(ringbuffer_h r)
|
||||
{
|
||||
return (r->readPtr + r->cap - r->writePtr) % r->cap;
|
||||
}
|
||||
|
||||
static inline size_t rb_avail(ringbuffer_h r)
|
||||
{
|
||||
return r->cap - rb_len(r);
|
||||
}
|
||||
|
||||
static inline void rb_advance_write(ringbuffer_h r)
|
||||
{
|
||||
r->writePtr = (r->writePtr + 1) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_advance_write_n(ringbuffer_h r, size_t n)
|
||||
{
|
||||
r->writePtr = (r->writePtr + n) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_advance_read(ringbuffer_h r)
|
||||
{
|
||||
r->readPtr = (r->readPtr + 1) % r->cap;
|
||||
}
|
||||
|
||||
static inline void rb_len_add(ringbuffer_h r, int n)
|
||||
{
|
||||
atomic_fetch_add(&r->len, n);
|
||||
}
|
||||
|
||||
static inline void rb_len_sub(ringbuffer_h r, int n)
|
||||
{
|
||||
atomic_fetch_sub(&r->len, n);
|
||||
}
|
||||
|
||||
static void rb_init(ringbuffer_h r, size_t cap)
|
||||
{
|
||||
r->buffer = malloc(cap * sizeof(float));
|
||||
r->cap = cap;
|
||||
atomic_init(&r->len, 0);
|
||||
r->writePtr = 0;
|
||||
r->readPtr = 0;
|
||||
}
|
||||
|
||||
static void rb_free(ringbuffer_h r)
|
||||
{
|
||||
free(r->buffer);
|
||||
bzero(r, sizeof(*r));
|
||||
}
|
||||
|
||||
#define UNLIKELY(x) __builtin_expect((x), 0)
|
||||
#define LIKELY(x) __builtin_expect((x), 1)
|
||||
|
||||
static void rb_write_data(ringbuffer_h r, const float *data, size_t len)
|
||||
{
|
||||
size_t avail = rb_avail(r);
|
||||
size_t n = MIN(len, avail);
|
||||
size_t first_write = n;
|
||||
size_t rest_write = 0;
|
||||
|
||||
if (r->writePtr + n > r->cap)
|
||||
{
|
||||
first_write = r->cap - r->writePtr;
|
||||
rest_write = n - first_write;
|
||||
}
|
||||
|
||||
memcpy(r->buffer + r->writePtr, data, first_write*sizeof(float));
|
||||
memcpy(r->buffer, data + first_write, rest_write*sizeof(float));
|
||||
|
||||
rb_advance_write_n(r, n);
|
||||
rb_len_add(r, (int)n);
|
||||
}
|
||||
|
||||
static void rb_read_data(ringbuffer_h r, float *d0, float *d1, size_t len)
|
||||
{
|
||||
size_t need = len*2;
|
||||
|
||||
do {
|
||||
size_t have = rb_len(r);
|
||||
size_t n = MIN(have, need);
|
||||
int i = 0;
|
||||
for (; i < n/2; i++)
|
||||
{
|
||||
d0[i] = r->buffer[r->readPtr];
|
||||
rb_advance_read(r);
|
||||
d1[i] = r->buffer[r->readPtr];
|
||||
rb_advance_read(r);
|
||||
}
|
||||
|
||||
need -= n;
|
||||
rb_len_sub(r, (int)n);
|
||||
|
||||
if (UNLIKELY(need > 0))
|
||||
{
|
||||
/* we got more data */
|
||||
if (rb_len(r) > 0)
|
||||
continue;
|
||||
|
||||
// underflow
|
||||
const float quiet = 0.0f;
|
||||
size_t fill = (need/2)*sizeof(float);
|
||||
memset_pattern4(&d0[i], &quiet, fill);
|
||||
memset_pattern4(&d1[i], &quiet, fill);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
#pragma mark - CoreAudio3
|
||||
|
||||
static bool g_interrupted;
|
||||
|
||||
@interface CoreAudio3 : NSObject {
|
||||
ringbuffer_t _rb;
|
||||
dispatch_semaphore_t _sema;
|
||||
AUAudioUnit *_au;
|
||||
size_t _bufferSize;
|
||||
BOOL _nonBlock;
|
||||
}
|
||||
|
||||
@property (nonatomic, readwrite) BOOL nonBlock;
|
||||
@property (nonatomic, readonly) BOOL paused;
|
||||
@property (nonatomic, readonly) size_t writeAvailableInBytes;
|
||||
@property (nonatomic, readonly) size_t bufferSizeInBytes;
|
||||
|
||||
- (instancetype)initWithRate:(NSUInteger)rate
|
||||
latency:(NSUInteger)latency;
|
||||
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples;
|
||||
- (void)start;
|
||||
- (void)stop;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CoreAudio3
|
||||
|
||||
- (instancetype)initWithRate:(NSUInteger)rate
|
||||
latency:(NSUInteger)latency {
|
||||
if (self = [super init])
|
||||
{
|
||||
_sema = dispatch_semaphore_create(0);
|
||||
|
||||
_bufferSize = (latency * rate) / 1000;
|
||||
_bufferSize *= 2; // stereo
|
||||
rb_init(&_rb, _bufferSize);
|
||||
|
||||
AudioComponentDescription desc = {
|
||||
.componentType = kAudioUnitType_Output,
|
||||
.componentSubType = kAudioUnitSubType_DefaultOutput,
|
||||
.componentManufacturer = kAudioUnitManufacturer_Apple,
|
||||
};
|
||||
|
||||
NSError *err;
|
||||
AUAudioUnit *au = [[AUAudioUnit alloc] initWithComponentDescription:desc error:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
AVAudioFormat *format = au.outputBusses[0].format;
|
||||
if (format.channelCount != 2)
|
||||
return nil;
|
||||
|
||||
AVAudioFormat *renderFormat = [[AVAudioFormat alloc] initStandardFormatWithSampleRate:rate channels:2];
|
||||
[au.inputBusses[0] setFormat:renderFormat error:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
ringbuffer_h rb = &_rb;
|
||||
__block dispatch_semaphore_t sema = _sema;
|
||||
au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags * actionFlags, const AudioTimeStamp * timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList * inputData) {
|
||||
rb_read_data(rb, inputData->mBuffers[0].mData, inputData->mBuffers[1].mData, frameCount);
|
||||
dispatch_semaphore_signal(sema);
|
||||
return 0;
|
||||
};
|
||||
|
||||
[au allocateRenderResourcesAndReturnError:&err];
|
||||
if (err != nil)
|
||||
return nil;
|
||||
|
||||
_au = au;
|
||||
|
||||
RARCH_LOG("[CoreAudio3]: Using buffer size of %u bytes: (latency = %u ms)\n", (unsigned)self.bufferSizeInBytes, latency);
|
||||
|
||||
[self start];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
rb_free(&_rb);
|
||||
}
|
||||
|
||||
- (BOOL)paused {
|
||||
return !_au.running;
|
||||
}
|
||||
|
||||
- (size_t)bufferSizeInBytes {
|
||||
return _bufferSize * sizeof(float);
|
||||
}
|
||||
|
||||
- (size_t)writeAvailableInBytes {
|
||||
return rb_avail(&_rb) * sizeof(float);
|
||||
}
|
||||
|
||||
- (void)start {
|
||||
NSError *err;
|
||||
[_au startHardwareAndReturnError:&err];
|
||||
}
|
||||
|
||||
- (void)stop {
|
||||
[_au stopHardware];
|
||||
}
|
||||
|
||||
- (ssize_t)writeFloat:(const float *)data samples:(size_t)samples {
|
||||
size_t written = 0;
|
||||
while (!g_interrupted && samples > 0)
|
||||
{
|
||||
size_t write_avail = rb_avail(&_rb);
|
||||
if (write_avail > samples)
|
||||
write_avail = samples;
|
||||
|
||||
rb_write_data(&_rb, data, write_avail);
|
||||
data += write_avail;
|
||||
written += write_avail;
|
||||
samples -= write_avail;
|
||||
|
||||
if (_nonBlock)
|
||||
break;
|
||||
|
||||
if (write_avail == 0)
|
||||
dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void coreaudio3_free(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge_transfer CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return;
|
||||
|
||||
[dev stop];
|
||||
dev = nil;
|
||||
}
|
||||
|
||||
static void *coreaudio3_init(const char *device,
|
||||
unsigned rate, unsigned latency,
|
||||
unsigned block_frames,
|
||||
unsigned *new_rate)
|
||||
{
|
||||
CoreAudio3 *dev = [[CoreAudio3 alloc] initWithRate:rate
|
||||
latency:latency];
|
||||
|
||||
*new_rate = rate;
|
||||
|
||||
return (__bridge_retained void *)dev;
|
||||
}
|
||||
|
||||
static ssize_t coreaudio3_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
return [dev writeFloat:(const float *)buf_ samples:size/sizeof(float)] * sizeof(float);
|
||||
}
|
||||
|
||||
static void coreaudio3_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return;
|
||||
|
||||
dev.nonBlock = state;
|
||||
}
|
||||
|
||||
static bool coreaudio3_alive(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_stop(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
[dev stop];
|
||||
return dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_start(void *data, bool is_shutdown)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return NO;
|
||||
|
||||
[dev start];
|
||||
return !dev.paused;
|
||||
}
|
||||
|
||||
static bool coreaudio3_use_float(void *data)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
static size_t coreaudio3_write_avail(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return 0;
|
||||
|
||||
return dev.writeAvailableInBytes;
|
||||
}
|
||||
|
||||
static size_t coreaudio3_buffer_size(void *data)
|
||||
{
|
||||
CoreAudio3 *dev = (__bridge CoreAudio3 *)data;
|
||||
if (dev == nil)
|
||||
return 0;
|
||||
|
||||
return dev.bufferSizeInBytes;
|
||||
}
|
||||
|
||||
audio_driver_t audio_coreaudio3 = {
|
||||
coreaudio3_init,
|
||||
coreaudio3_write,
|
||||
coreaudio3_stop,
|
||||
coreaudio3_start,
|
||||
coreaudio3_alive,
|
||||
coreaudio3_set_nonblock_state,
|
||||
coreaudio3_free,
|
||||
coreaudio3_use_float,
|
||||
"coreaudio3",
|
||||
coreaudio3_write_avail,
|
||||
coreaudio3_buffer_size,
|
||||
};
|
@ -84,22 +84,21 @@ static void audioCreateThread(ps2_audio_t *ps2)
|
||||
ps2->running = true;
|
||||
ps2->worker_thread = CreateThread(&thread);
|
||||
|
||||
if (ps2->worker_thread >= 0) {
|
||||
if (ps2->worker_thread >= 0)
|
||||
{
|
||||
ret = StartThread(ps2->worker_thread, NULL);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
printf("sound_init: StartThread returned %d\n", ret);
|
||||
}
|
||||
} else {
|
||||
printf("CreateThread failed: %d\n", ps2->worker_thread);
|
||||
}
|
||||
else
|
||||
printf("CreateThread failed: %d\n", ps2->worker_thread);
|
||||
}
|
||||
|
||||
static void audioStopNDeleteThread(ps2_audio_t *ps2)
|
||||
{
|
||||
ps2->running = false;
|
||||
if (ps2->worker_thread) {
|
||||
if (ps2->worker_thread)
|
||||
ps2->worker_thread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void audioConfigure(ps2_audio_t *ps2, unsigned rate)
|
||||
@ -187,14 +186,14 @@ static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
|
||||
if (!ps2->running)
|
||||
return -1;
|
||||
|
||||
if (ps2->nonblocking){
|
||||
if (ps2->nonblocking)
|
||||
{
|
||||
if (fifo_write_avail(ps2->buffer) < size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fifo_write_avail(ps2->buffer) < size) {
|
||||
while (fifo_write_avail(ps2->buffer) < size)
|
||||
WaitSema(ps2->cond_lock);
|
||||
}
|
||||
|
||||
WaitSema(ps2->lock);
|
||||
fifo_write(ps2->buffer, buf, size);
|
||||
@ -205,22 +204,22 @@ static ssize_t ps2_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool ps2_audio_alive(void *data)
|
||||
{
|
||||
bool alive = false;
|
||||
|
||||
bool alive = false;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
if (ps2) {
|
||||
|
||||
if (ps2)
|
||||
alive = ps2->running;
|
||||
}
|
||||
|
||||
return alive;
|
||||
}
|
||||
|
||||
static bool ps2_audio_stop(void *data)
|
||||
{
|
||||
bool stop = true;
|
||||
bool stop = true;
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2) {
|
||||
if (ps2)
|
||||
{
|
||||
audioStopNDeleteThread(ps2);
|
||||
audsrv_stop_audio();
|
||||
}
|
||||
@ -231,12 +230,12 @@ static bool ps2_audio_stop(void *data)
|
||||
static bool ps2_audio_start(void *data, bool is_shutdown)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
bool start = true;
|
||||
bool start = true;
|
||||
|
||||
if (ps2) {
|
||||
if (!ps2->running && !ps2->worker_thread) {
|
||||
if (ps2)
|
||||
{
|
||||
if (!ps2->running && !ps2->worker_thread)
|
||||
audioCreateThread(ps2);
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
@ -246,9 +245,8 @@ static void ps2_audio_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2) {
|
||||
if (ps2)
|
||||
ps2->nonblocking = toggle;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ps2_audio_use_float(void *data)
|
||||
@ -260,7 +258,8 @@ static size_t ps2_audio_write_avail(void *data)
|
||||
{
|
||||
ps2_audio_t* ps2 = (ps2_audio_t*)data;
|
||||
|
||||
if (ps2 && ps2->running) {
|
||||
if (ps2 && ps2->running)
|
||||
{
|
||||
size_t size;
|
||||
WaitSema(ps2->lock);
|
||||
size = AUDIO_BUFFER - fifo_read_avail(ps2->buffer);
|
||||
|
@ -52,7 +52,11 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef __CELLOS_LV2__
|
||||
#include <sys/poll.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
|
@ -1118,6 +1118,8 @@ enum
|
||||
|
||||
static int cheevos_iterate(coro_t* coro)
|
||||
{
|
||||
const int snes_header_len = 0x200;
|
||||
const int lynx_header_len = 0x40;
|
||||
ssize_t num_read = 0;
|
||||
size_t to_read = 4096;
|
||||
uint8_t *buffer = NULL;
|
||||
@ -1159,10 +1161,10 @@ static int cheevos_iterate(coro_t* coro)
|
||||
|
||||
static cheevos_finder_t finders[] =
|
||||
{
|
||||
{SNES_MD5, "SNES (8Mb padding)", snes_exts},
|
||||
{SNES_MD5, "SNES (discards header)", snes_exts},
|
||||
{GENESIS_MD5, "Genesis (6Mb padding)", genesis_exts},
|
||||
{LYNX_MD5, "Atari Lynx (only first 512 bytes)", lynx_exts},
|
||||
{NES_MD5, "NES (discards VROM)", NULL},
|
||||
{LYNX_MD5, "Atari Lynx (discards header)", lynx_exts},
|
||||
{NES_MD5, "NES (discards header)", NULL},
|
||||
{GENERIC_MD5, "Generic (plain content)", NULL},
|
||||
{FILENAME_MD5, "Generic (filename)", NULL}
|
||||
};
|
||||
@ -1403,33 +1405,22 @@ found:
|
||||
* Output CHEEVOS_VAR_GAMEID the Retro Achievements game ID, or 0 if not found
|
||||
*************************************************************************/
|
||||
CORO_SUB(SNES_MD5)
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0;
|
||||
coro->count = 0;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count == 0)
|
||||
/* Checks for the existence of a headered SNES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != snes_header_len)
|
||||
{
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
if (coro->count < CHEEVOS_MB(8))
|
||||
{
|
||||
/*
|
||||
* Inputs: CHEEVOS_VAR_MD5, CHEEVOS_VAR_OFFSET, CHEEVOS_VAR_COUNT
|
||||
* Outputs: CHEEVOS_VAR_MD5
|
||||
*/
|
||||
coro->offset = 0;
|
||||
coro->count = CHEEVOS_MB(8) - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
coro->offset = snes_header_len;
|
||||
coro->count = 0;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
|
||||
/**************************************************************************
|
||||
@ -1469,16 +1460,18 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(LYNX_MD5)
|
||||
|
||||
if (coro->len < 0x0240)
|
||||
/* Checks for the existence of a headered Lynx file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len <= lynx_header_len ||
|
||||
memcmp("LYNX", (void *)coro->data, 5) != 0)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0x0040;
|
||||
coro->count = 0x0200;
|
||||
coro->offset = lynx_header_len;
|
||||
coro->count = coro->len - lynx_header_len;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
@ -1491,13 +1484,8 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(NES_MD5)
|
||||
|
||||
/* Note about the references to the FCEU emulator below. There is no
|
||||
* core-specific code in this function, it's rather Retro Achievements
|
||||
* specific code that must be followed to the letter so we compute
|
||||
* the correct ROM hash. Retro Achievements does indeed use some
|
||||
* FCEU related method to compute the hash, since its NES emulator
|
||||
* is based on it. */
|
||||
|
||||
/* Checks for the existence of a headered NES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
if (coro->len < sizeof(coro->header))
|
||||
{
|
||||
coro->gameid = 0;
|
||||
@ -1506,84 +1494,23 @@ found:
|
||||
|
||||
memcpy((void*)&coro->header, coro->data,
|
||||
sizeof(coro->header));
|
||||
|
||||
if (coro->header.id[0] == 'N'
|
||||
&& coro->header.id[1] == 'E'
|
||||
&& coro->header.id[2] == 'S'
|
||||
&& coro->header.id[3] == 0x1a)
|
||||
|
||||
if ( coro->header.id[0] != 'N'
|
||||
|| coro->header.id[1] != 'E'
|
||||
|| coro->header.id[2] != 'S'
|
||||
|| coro->header.id[3] != 0x1a)
|
||||
{
|
||||
size_t romsize = 256;
|
||||
/* from FCEU core - compute size using the cart mapper */
|
||||
int mapper = (coro->header.rom_type >> 4) | (coro->header.rom_type2 & 0xF0);
|
||||
|
||||
if (coro->header.rom_size)
|
||||
romsize = next_pow2(coro->header.rom_size);
|
||||
|
||||
/* for games not to the power of 2, so we just read enough
|
||||
* PRG rom from it, but we have to keep ROM_size to the power of 2
|
||||
* since PRGCartMapping wants ROM_size to be to the power of 2
|
||||
* so instead if not to power of 2, we just use head.ROM_size when
|
||||
* we use FCEU_read. */
|
||||
coro->round = mapper != 53 && mapper != 198 && mapper != 228;
|
||||
coro->bytes = coro->round ? romsize : coro->header.rom_size;
|
||||
|
||||
coro->offset = sizeof(coro->header) + (coro->header.rom_type & 4
|
||||
? sizeof(coro->header) : 0);
|
||||
|
||||
/* from FCEU core - check if Trainer included in ROM data */
|
||||
MD5_Init(&coro->md5);
|
||||
coro->count = 0x4000 * coro->bytes;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count < 0x4000 * coro->bytes)
|
||||
{
|
||||
coro->offset = 0xff;
|
||||
coro->count = 0x4000 * coro->bytes - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned i;
|
||||
size_t chunks = coro->len >> 14;
|
||||
size_t chunk_size = 0x4000;
|
||||
|
||||
/* Fall back to headerless hashing
|
||||
* PRG ROM size is unknown, so test by 16KB chunks */
|
||||
MD5_Init(&coro->md5);
|
||||
coro->offset = sizeof(coro->header);
|
||||
coro->count = coro->len - coro->offset;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
coro->round = 0;
|
||||
coro->offset = 0;
|
||||
|
||||
for (i = 0; i < chunks; i++)
|
||||
{
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->bytes = i + 1;
|
||||
coro->count = coro->bytes * chunk_size;
|
||||
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
if (coro->count < 0x4000 * coro->bytes)
|
||||
{
|
||||
coro->offset = 0xff;
|
||||
coro->count = 0x4000 * coro->bytes - coro->count;
|
||||
CORO_GOSUB(FILL_MD5);
|
||||
}
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOSUB(GET_GAMEID);
|
||||
|
||||
if (coro->gameid > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CORO_RET();
|
||||
}
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
CORO_GOTO(GET_GAMEID);
|
||||
|
||||
/**************************************************************************
|
||||
* Info Tries to identify a "generic" game
|
||||
|
@ -2571,7 +2571,8 @@ enum
|
||||
|
||||
static int cheevos_iterate(coro_t *coro)
|
||||
{
|
||||
const int SNES_HEADER_LEN = 0x200;
|
||||
const int snes_header_len = 0x200;
|
||||
const int lynx_header_len = 0x40;
|
||||
ssize_t num_read = 0;
|
||||
size_t to_read = 4096;
|
||||
uint8_t *buffer = NULL;
|
||||
@ -2615,7 +2616,7 @@ static int cheevos_iterate(coro_t *coro)
|
||||
{
|
||||
{SNES_MD5, "SNES (discards header)", snes_exts},
|
||||
{GENESIS_MD5, "Genesis (6Mb padding)", genesis_exts},
|
||||
{LYNX_MD5, "Atari Lynx (only first 512 bytes)", lynx_exts},
|
||||
{LYNX_MD5, "Atari Lynx (discards header)", lynx_exts},
|
||||
{NES_MD5, "NES (discards header)", NULL},
|
||||
{GENERIC_MD5, "Generic (plain content)", NULL},
|
||||
{FILENAME_MD5, "Generic (filename)", NULL}
|
||||
@ -2904,7 +2905,7 @@ found:
|
||||
/* Checks for the existence of a headered SNES file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != SNES_HEADER_LEN)
|
||||
if (coro->len < 0x2000 || coro->len % 0x2000 != snes_header_len)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
@ -2955,16 +2956,19 @@ found:
|
||||
*************************************************************************/
|
||||
CORO_SUB(LYNX_MD5)
|
||||
|
||||
if (coro->len < 0x0240)
|
||||
/* Checks for the existence of a headered Lynx file.
|
||||
Unheadered files fall back to GENERIC_MD5. */
|
||||
|
||||
if (coro->len <= lynx_header_len ||
|
||||
memcmp("LYNX", (void *)coro->data, 5) != 0)
|
||||
{
|
||||
coro->gameid = 0;
|
||||
CORO_RET();
|
||||
}
|
||||
|
||||
MD5_Init(&coro->md5);
|
||||
|
||||
coro->offset = 0x0040;
|
||||
coro->count = 0x0200;
|
||||
coro->offset = lynx_header_len;
|
||||
coro->count = coro->len - lynx_header_len;
|
||||
CORO_GOSUB(EVAL_MD5);
|
||||
|
||||
MD5_Final(coro->hash, &coro->md5);
|
||||
|
59
command.c
59
command.c
@ -89,6 +89,7 @@
|
||||
#include "managers/cheat_manager.h"
|
||||
#include "managers/state_manager.h"
|
||||
#include "ui/ui_companion_driver.h"
|
||||
#include "tasks/task_content.h"
|
||||
#include "tasks/tasks_internal.h"
|
||||
#include "list_special.h"
|
||||
|
||||
@ -174,7 +175,7 @@ static bool command_version(const char* arg)
|
||||
{
|
||||
char reply[256] = {0};
|
||||
|
||||
sprintf(reply, "%s\n", PACKAGE_VERSION);
|
||||
snprintf(reply, sizeof(reply), "%s\n", PACKAGE_VERSION);
|
||||
#if defined(HAVE_CHEEVOS) && (defined(HAVE_STDIN_CMD) || defined(HAVE_NETWORK_CMD) && defined(HAVE_NETWORKING))
|
||||
command_reply(reply, strlen(reply));
|
||||
#endif
|
||||
@ -291,7 +292,7 @@ static bool command_read_ram(const char *arg)
|
||||
|
||||
if (data)
|
||||
{
|
||||
for (i=0;i<nbytes;i++)
|
||||
for (i = 0; i < nbytes; i++)
|
||||
sprintf(reply_at+3*i, " %.2X", data[i]);
|
||||
reply_at[3*nbytes] = '\n';
|
||||
command_reply(reply, reply_at+3*nbytes+1 - reply);
|
||||
@ -303,7 +304,7 @@ static bool command_read_ram(const char *arg)
|
||||
}
|
||||
free(reply);
|
||||
#else
|
||||
cheevos_var_t var;
|
||||
cheevos_var_t var;
|
||||
unsigned i;
|
||||
char reply[256] = {0};
|
||||
const uint8_t * data = NULL;
|
||||
@ -323,7 +324,7 @@ static bool command_read_ram(const char *arg)
|
||||
{
|
||||
unsigned nbytes = strtol(reply_at, NULL, 10);
|
||||
|
||||
for (i=0;i<nbytes;i++)
|
||||
for (i = 0; i < nbytes; i++)
|
||||
sprintf(reply_at+3*i, " %.2X", data[i]);
|
||||
reply_at[3*nbytes] = '\n';
|
||||
command_reply(reply, reply_at+3*nbytes+1 - reply);
|
||||
@ -1766,56 +1767,6 @@ static bool command_event_resize_windowed_scale(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
void command_playlist_push_write(
|
||||
playlist_t *playlist,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name)
|
||||
{
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
if (playlist_push(
|
||||
playlist,
|
||||
path,
|
||||
label,
|
||||
core_path,
|
||||
core_name,
|
||||
NULL,
|
||||
NULL
|
||||
))
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
void command_playlist_update_write(
|
||||
playlist_t *plist,
|
||||
size_t idx,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_display_name,
|
||||
const char *crc32,
|
||||
const char *db_name)
|
||||
{
|
||||
playlist_t *playlist = plist ? plist : playlist_get_cached();
|
||||
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
playlist_update(
|
||||
playlist,
|
||||
idx,
|
||||
path,
|
||||
label,
|
||||
core_path,
|
||||
core_display_name,
|
||||
crc32,
|
||||
db_name);
|
||||
|
||||
playlist_write_file(playlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* command_event:
|
||||
* @cmd : Event command index.
|
||||
|
19
command.h
19
command.h
@ -27,8 +27,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "playlist.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
typedef struct command command_t;
|
||||
@ -272,23 +270,6 @@ bool command_free(command_t *handle);
|
||||
**/
|
||||
bool command_event(enum event_command action, void *data);
|
||||
|
||||
void command_playlist_push_write(
|
||||
playlist_t *playlist,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_name);
|
||||
|
||||
void command_playlist_update_write(
|
||||
playlist_t *playlist,
|
||||
size_t idx,
|
||||
const char *path,
|
||||
const char *label,
|
||||
const char *core_path,
|
||||
const char *core_display_name,
|
||||
const char *crc32,
|
||||
const char *db_name);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
22
config.def.h
22
config.def.h
@ -373,14 +373,7 @@ static unsigned menu_shader_pipeline = 2;
|
||||
#endif
|
||||
|
||||
static bool show_advanced_settings = false;
|
||||
static const uint32_t menu_entry_normal_color = 0xffffffff;
|
||||
static const uint32_t menu_entry_hover_color = 0xff64ff64;
|
||||
static const uint32_t menu_title_color = 0xff64ff64;
|
||||
static const uint32_t menu_bg_dark_color = 0xc0202020;
|
||||
static const uint32_t menu_bg_light_color = 0xc0404040;
|
||||
static const uint32_t menu_border_dark_color = 0xc0204020;
|
||||
static const uint32_t menu_border_light_color = 0xc0408040;
|
||||
static unsigned rgui_color_theme = RGUI_THEME_CUSTOM;
|
||||
static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN;
|
||||
|
||||
#else
|
||||
static bool default_block_config_read = false;
|
||||
@ -402,12 +395,14 @@ static bool default_screenshots_in_content_dir = false;
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX1) || defined(_XBOX360)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L3_R3;
|
||||
#elif defined(PS2)
|
||||
#elif defined(PS2) || defined(PSP)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_HOLD_START;
|
||||
#elif defined(VITA)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L1_R1_START_SELECT;
|
||||
#elif defined(SWITCH) || defined(ORBIS)
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_START_SELECT;
|
||||
#elif TARGET_OS_TV
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_DOWN_Y_L_R;
|
||||
#else
|
||||
static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_NONE;
|
||||
#endif
|
||||
@ -508,6 +503,13 @@ static const bool video_3ds_lcd_bottom = true;
|
||||
/* Will enable audio or not. */
|
||||
static const bool audio_enable = true;
|
||||
|
||||
/* Enable menu audio sounds. */
|
||||
static const bool audio_enable_menu = false;
|
||||
static const bool audio_enable_menu_ok = false;
|
||||
static const bool audio_enable_menu_cancel = false;
|
||||
static const bool audio_enable_menu_notice = false;
|
||||
static const bool audio_enable_menu_bgm = false;
|
||||
|
||||
/* Output samplerate. */
|
||||
#ifdef GEKKO
|
||||
static const unsigned out_rate = 32000;
|
||||
@ -752,6 +754,8 @@ static const unsigned menu_timedate_style = 5;
|
||||
|
||||
static const bool xmb_vertical_thumbnails = false;
|
||||
|
||||
static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT;
|
||||
|
||||
#ifdef IOS
|
||||
static const bool ui_companion_start_on_boot = false;
|
||||
#else
|
||||
|
@ -152,6 +152,12 @@ static const bool _coreaudio_supp = true;
|
||||
static const bool _coreaudio_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COREAUDIO3
|
||||
static const bool _coreaudio3_supp = true;
|
||||
#else
|
||||
static const bool _coreaudio3_supp = false;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OSS) || defined(HAVE_OSS_BSD)
|
||||
static const bool _oss_supp = true;
|
||||
#else
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "verbosity.h"
|
||||
#include "lakka.h"
|
||||
|
||||
#include "tasks/task_content.h"
|
||||
#include "tasks/tasks_internal.h"
|
||||
|
||||
#include "../list_special.h"
|
||||
@ -190,6 +191,7 @@ enum audio_driver_enum
|
||||
AUDIO_DSOUND,
|
||||
AUDIO_WASAPI,
|
||||
AUDIO_COREAUDIO,
|
||||
AUDIO_COREAUDIO3,
|
||||
AUDIO_PS3,
|
||||
AUDIO_XENON360,
|
||||
AUDIO_WII,
|
||||
@ -298,7 +300,6 @@ enum menu_driver_enum
|
||||
MENU_MATERIALUI,
|
||||
MENU_XMB,
|
||||
MENU_STRIPES,
|
||||
MENU_NUKLEAR,
|
||||
MENU_OZONE,
|
||||
MENU_NULL
|
||||
};
|
||||
@ -393,6 +394,8 @@ static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_TINYALSA;
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_OSS;
|
||||
#elif defined(HAVE_JACK)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_JACK;
|
||||
#elif defined(HAVE_COREAUDIO3)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO3;
|
||||
#elif defined(HAVE_COREAUDIO)
|
||||
static enum audio_driver_enum AUDIO_DEFAULT_DRIVER = AUDIO_COREAUDIO;
|
||||
#elif defined(HAVE_XAUDIO)
|
||||
@ -525,14 +528,14 @@ static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_ANDROID;
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_SDL;
|
||||
#elif defined(DJGPP)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_DOS;
|
||||
#elif defined(IOS)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI;
|
||||
#elif defined(HAVE_HID)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_HID;
|
||||
#elif defined(__QNX__)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_QNX;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_RWEBPAD;
|
||||
#elif defined(IOS)
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_MFI;
|
||||
#else
|
||||
static enum joypad_driver_enum JOYPAD_DEFAULT_DRIVER = JOYPAD_NULL;
|
||||
#endif
|
||||
@ -570,7 +573,7 @@ static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_RGUI;
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XUI;
|
||||
#elif defined(HAVE_MATERIALUI) && defined(RARCH_MOBILE)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_MATERIALUI;
|
||||
#elif defined(HAVE_OZONE) && defined(HAVE_LIBNX)
|
||||
#elif defined(HAVE_OZONE) && (defined(HAVE_LIBNX) || TARGET_OS_TV)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_OZONE;
|
||||
#elif defined(HAVE_XMB) && !defined(_XBOX)
|
||||
static enum menu_driver_enum MENU_DEFAULT_DRIVER = MENU_XMB;
|
||||
@ -666,6 +669,8 @@ const char *config_get_default_audio(void)
|
||||
return "roar";
|
||||
case AUDIO_COREAUDIO:
|
||||
return "coreaudio";
|
||||
case AUDIO_COREAUDIO3:
|
||||
return "coreaudio3";
|
||||
case AUDIO_AL:
|
||||
return "openal";
|
||||
case AUDIO_SL:
|
||||
@ -1089,8 +1094,6 @@ const char *config_get_default_menu(void)
|
||||
return "xmb";
|
||||
case MENU_STRIPES:
|
||||
return "stripes";
|
||||
case MENU_NUKLEAR:
|
||||
return "nuklear";
|
||||
case MENU_NULL:
|
||||
break;
|
||||
}
|
||||
@ -1215,6 +1218,8 @@ static struct config_path_setting *populate_settings_path(settings_t *settings,
|
||||
#ifdef HAVE_MENU
|
||||
SETTING_PATH("menu_wallpaper",
|
||||
settings->paths.path_menu_wallpaper, false, NULL, true);
|
||||
SETTING_PATH("rgui_menu_theme_preset",
|
||||
settings->paths.path_rgui_theme_preset, false, NULL, true);
|
||||
#endif
|
||||
SETTING_PATH("content_history_path",
|
||||
settings->paths.path_content_history, false, NULL, true);
|
||||
@ -1394,7 +1399,11 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
SETTING_BOOL("keyboard_gamepad_enable", &settings->bools.input_keyboard_gamepad_enable, true, true, false);
|
||||
SETTING_BOOL("core_set_supports_no_game_enable", &settings->bools.set_supports_no_game_enable, true, true, false);
|
||||
SETTING_BOOL("audio_enable", &settings->bools.audio_enable, true, audio_enable, false);
|
||||
SETTING_BOOL("audio_enable_menu", &settings->bools.audio_enable_menu, true, false, false);
|
||||
SETTING_BOOL("audio_enable_menu", &settings->bools.audio_enable_menu, true, audio_enable_menu, false);
|
||||
SETTING_BOOL("audio_enable_menu_ok", &settings->bools.audio_enable_menu_ok, true, audio_enable_menu_ok, false);
|
||||
SETTING_BOOL("audio_enable_menu_cancel", &settings->bools.audio_enable_menu_cancel, true, audio_enable_menu_cancel, false);
|
||||
SETTING_BOOL("audio_enable_menu_notice", &settings->bools.audio_enable_menu_notice, true, audio_enable_menu_notice, false);
|
||||
SETTING_BOOL("audio_enable_menu_bgm", &settings->bools.audio_enable_menu_bgm, true, audio_enable_menu_bgm, false);
|
||||
SETTING_BOOL("audio_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MUTE_ENABLE), true, false, false);
|
||||
SETTING_BOOL("audio_mixer_mute_enable", audio_get_bool_ptr(AUDIO_ACTION_MIXER_MUTE_ENABLE), true, false, false);
|
||||
SETTING_BOOL("location_allow", &settings->bools.location_allow, true, false, false);
|
||||
@ -1653,6 +1662,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
SETTING_UINT("menu_thumbnails", &settings->uints.menu_thumbnails, true, menu_thumbnails_default, false);
|
||||
SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, menu_timedate_style, false);
|
||||
SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false);
|
||||
SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
|
||||
#ifdef HAVE_LIBNX
|
||||
SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false);
|
||||
SETTING_UINT("split_joycon_p2", &settings->uints.input_split_joycon[1], true, 0, false);
|
||||
@ -1677,7 +1687,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
SETTING_UINT("materialui_menu_color_theme", &settings->uints.menu_materialui_color_theme, true, MATERIALUI_THEME_BLUE, false);
|
||||
SETTING_UINT("menu_shader_pipeline", &settings->uints.menu_xmb_shader_pipeline, true, menu_shader_pipeline, false);
|
||||
#ifdef HAVE_OZONE
|
||||
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 0, false);
|
||||
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 1, false);
|
||||
#endif
|
||||
#endif
|
||||
SETTING_UINT("audio_out_rate", &settings->uints.audio_out_rate, true, out_rate, false);
|
||||
@ -1959,13 +1969,6 @@ void config_set_defaults(void)
|
||||
#ifdef HAVE_MENU
|
||||
if (first_initialized)
|
||||
settings->bools.menu_show_start_screen = default_menu_show_start_screen;
|
||||
settings->uints.menu_entry_normal_color = menu_entry_normal_color;
|
||||
settings->uints.menu_entry_hover_color = menu_entry_hover_color;
|
||||
settings->uints.menu_title_color = menu_title_color;
|
||||
settings->uints.menu_bg_dark_color = menu_bg_dark_color;
|
||||
settings->uints.menu_bg_light_color = menu_bg_light_color;
|
||||
settings->uints.menu_border_dark_color = menu_border_dark_color;
|
||||
settings->uints.menu_border_light_color = menu_border_light_color;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
@ -2068,6 +2071,7 @@ void config_set_defaults(void)
|
||||
#endif
|
||||
*settings->paths.path_cheat_database = '\0';
|
||||
*settings->paths.path_menu_wallpaper = '\0';
|
||||
*settings->paths.path_rgui_theme_preset = '\0';
|
||||
*settings->paths.path_content_database = '\0';
|
||||
*settings->paths.path_overlay = '\0';
|
||||
*settings->paths.path_record_config = '\0';
|
||||
@ -2652,6 +2656,8 @@ static void config_file_dump_all(config_file_t *conf)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is no longer used, so comment out to silence warnings...
|
||||
#ifdef HAVE_MENU
|
||||
static void config_get_hex_base(config_file_t *conf,
|
||||
const char *key, unsigned *base)
|
||||
@ -2663,6 +2669,7 @@ static void config_get_hex_base(config_file_t *conf,
|
||||
*base = tmp;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
/**
|
||||
* config_load:
|
||||
@ -2878,22 +2885,6 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
settings->floats.video_msg_color_g = ((msg_color >> 8) & 0xff) / 255.0f;
|
||||
settings->floats.video_msg_color_b = ((msg_color >> 0) & 0xff) / 255.0f;
|
||||
}
|
||||
#ifdef HAVE_MENU
|
||||
config_get_hex_base(conf, "menu_entry_normal_color",
|
||||
&settings->uints.menu_entry_normal_color);
|
||||
config_get_hex_base(conf, "menu_entry_hover_color",
|
||||
&settings->uints.menu_entry_hover_color);
|
||||
config_get_hex_base(conf, "menu_title_color",
|
||||
&settings->uints.menu_title_color);
|
||||
config_get_hex_base(conf, "menu_bg_dark_color",
|
||||
&settings->uints.menu_bg_dark_color);
|
||||
config_get_hex_base(conf, "menu_bg_light_color",
|
||||
&settings->uints.menu_bg_light_color);
|
||||
config_get_hex_base(conf, "menu_border_dark_color",
|
||||
&settings->uints.menu_border_dark_color);
|
||||
config_get_hex_base(conf, "menu_border_light_color",
|
||||
&settings->uints.menu_border_light_color);
|
||||
#endif
|
||||
|
||||
/* Float settings */
|
||||
for (i = 0; i < (unsigned)float_settings_size; i++)
|
||||
@ -3082,6 +3073,8 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
|
||||
if (string_is_equal(settings->paths.path_menu_wallpaper, "default"))
|
||||
*settings->paths.path_menu_wallpaper = '\0';
|
||||
if (string_is_equal(settings->paths.path_rgui_theme_preset, "default"))
|
||||
*settings->paths.path_rgui_theme_preset = '\0';
|
||||
if (string_is_equal(settings->paths.directory_video_shader, "default"))
|
||||
*settings->paths.directory_video_shader = '\0';
|
||||
if (string_is_equal(settings->paths.directory_video_filter, "default"))
|
||||
@ -4381,22 +4374,6 @@ bool config_save_file(const char *path)
|
||||
|
||||
/* Hexadecimal settings */
|
||||
config_set_hex(conf, "video_message_color", msg_color);
|
||||
#ifdef HAVE_MENU
|
||||
config_set_hex(conf, "menu_entry_normal_color",
|
||||
settings->uints.menu_entry_normal_color);
|
||||
config_set_hex(conf, "menu_entry_hover_color",
|
||||
settings->uints.menu_entry_hover_color);
|
||||
config_set_hex(conf, "menu_title_color",
|
||||
settings->uints.menu_title_color);
|
||||
config_set_hex(conf, "menu_bg_dark_color",
|
||||
settings->uints.menu_bg_dark_color);
|
||||
config_set_hex(conf, "menu_bg_light_color",
|
||||
settings->uints.menu_bg_light_color);
|
||||
config_set_hex(conf, "menu_border_dark_color",
|
||||
settings->uints.menu_border_dark_color);
|
||||
config_set_hex(conf, "menu_border_light_color",
|
||||
settings->uints.menu_border_light_color);
|
||||
#endif
|
||||
|
||||
video_driver_save_settings(conf);
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <retro_common_api.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "gfx/video_driver.h"
|
||||
#include "gfx/video_defines.h"
|
||||
#include "input/input_defines.h"
|
||||
#include "led/led_defines.h"
|
||||
|
||||
@ -110,6 +110,10 @@ typedef struct settings
|
||||
/* Audio */
|
||||
bool audio_enable;
|
||||
bool audio_enable_menu;
|
||||
bool audio_enable_menu_ok;
|
||||
bool audio_enable_menu_cancel;
|
||||
bool audio_enable_menu_notice;
|
||||
bool audio_enable_menu_bgm;
|
||||
bool audio_sync;
|
||||
bool audio_rate_control;
|
||||
bool audio_wasapi_exclusive_mode;
|
||||
@ -403,14 +407,8 @@ typedef struct settings
|
||||
unsigned menu_timedate_style;
|
||||
unsigned menu_thumbnails;
|
||||
unsigned menu_left_thumbnails;
|
||||
unsigned menu_rgui_thumbnail_downscaler;
|
||||
unsigned menu_dpi_override_value;
|
||||
unsigned menu_entry_normal_color;
|
||||
unsigned menu_entry_hover_color;
|
||||
unsigned menu_title_color;
|
||||
unsigned menu_bg_dark_color;
|
||||
unsigned menu_bg_light_color;
|
||||
unsigned menu_border_dark_color;
|
||||
unsigned menu_border_light_color;
|
||||
unsigned menu_rgui_color_theme;
|
||||
unsigned menu_xmb_layout;
|
||||
unsigned menu_xmb_shader_pipeline;
|
||||
@ -542,6 +540,7 @@ typedef struct settings
|
||||
char path_cheat_settings[PATH_MAX_LENGTH];
|
||||
char path_shader[PATH_MAX_LENGTH];
|
||||
char path_font[PATH_MAX_LENGTH];
|
||||
char path_rgui_theme_preset[PATH_MAX_LENGTH];
|
||||
|
||||
char directory_audio_filter[PATH_MAX_LENGTH];
|
||||
char directory_autoconfig[PATH_MAX_LENGTH];
|
||||
|
2
configure
vendored
2
configure
vendored
@ -4,6 +4,8 @@ PACKAGE_NAME=retroarch
|
||||
|
||||
cat /dev/null > config.log
|
||||
|
||||
. qb/qb.init.sh
|
||||
|
||||
. qb/qb.system.sh
|
||||
|
||||
. qb/qb.params.sh
|
||||
|
2
core.h
2
core.h
@ -65,6 +65,8 @@ typedef struct rarch_system_info
|
||||
const char *input_desc_btn[MAX_USERS][RARCH_FIRST_META_KEY];
|
||||
char valid_extensions[255];
|
||||
|
||||
bool supports_vfs;
|
||||
|
||||
struct retro_disk_control_callback disk_control_cb;
|
||||
struct retro_location_callback location_cb;
|
||||
|
||||
|
23656
deps/nuklear/nuklear.h
vendored
23656
deps/nuklear/nuklear.h
vendored
File diff suppressed because it is too large
Load Diff
@ -14,18 +14,24 @@
|
||||
*/
|
||||
|
||||
#include <file/file_path.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include "discord.h"
|
||||
#include "discord_register.h"
|
||||
|
||||
#include "../deps/discord-rpc/include/discord_rpc.h"
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../configuration.h"
|
||||
#include "../core.h"
|
||||
#include "../core_info.h"
|
||||
#include "../paths.h"
|
||||
#include "../playlist.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
#include "../msg_hash.h"
|
||||
#include "../tasks/task_file_transfer.h"
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
#include "../../network/netplay/netplay.h"
|
||||
@ -70,12 +76,16 @@ DiscordRichPresence discord_presence;
|
||||
|
||||
char* discord_get_own_username(void)
|
||||
{
|
||||
return user_name;
|
||||
if (discord_is_ready())
|
||||
return user_name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* discord_get_own_avatar(void)
|
||||
{
|
||||
return user_avatar;
|
||||
if (discord_is_ready())
|
||||
return user_avatar;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool discord_avatar_is_ready(void)
|
||||
@ -305,11 +315,13 @@ void discord_update(enum discord_presence presence)
|
||||
discord_presence.instance = 0;
|
||||
break;
|
||||
case DISCORD_PRESENCE_GAME_PAUSED:
|
||||
discord_presence.smallImageKey = "paused";
|
||||
discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED);
|
||||
discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED);
|
||||
pause_time = time(0);
|
||||
ellapsed_time = difftime(time(0), start_time);
|
||||
discord_presence.smallImageKey = "paused";
|
||||
discord_presence.smallImageText = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PAUSED);
|
||||
discord_presence.details = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME_PAUSED);
|
||||
pause_time = time(0);
|
||||
ellapsed_time = difftime(time(0), start_time);
|
||||
discord_presence.startTimestamp = pause_time;
|
||||
break;
|
||||
case DISCORD_PRESENCE_GAME:
|
||||
@ -339,13 +351,15 @@ void discord_update(enum discord_presence presence)
|
||||
if (pause_time != 0)
|
||||
start_time = time(0) - ellapsed_time;
|
||||
|
||||
pause_time = 0;
|
||||
pause_time = 0;
|
||||
ellapsed_time = 0;
|
||||
|
||||
discord_presence.smallImageKey = "playing";
|
||||
discord_presence.smallImageText = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING);
|
||||
discord_presence.smallImageText = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_DISCORD_STATUS_PLAYING);
|
||||
discord_presence.startTimestamp = start_time;
|
||||
discord_presence.details = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME);
|
||||
discord_presence.details = msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_DISCORD_IN_GAME);
|
||||
|
||||
discord_presence.state = label;
|
||||
discord_presence.instance = 0;
|
||||
@ -366,9 +380,9 @@ void discord_update(enum discord_presence presence)
|
||||
snprintf(join_secret, sizeof(join_secret), "%d|%s", room->id, room->nickname);
|
||||
discord_presence.joinSecret = strdup(join_secret);
|
||||
/* discord_presence.spectateSecret = "SPECSPECSPEC"; */
|
||||
discord_presence.partyId = strdup(party_name);
|
||||
discord_presence.partyMax = 0;
|
||||
discord_presence.partySize = 0;
|
||||
discord_presence.partyId = strdup(party_name);
|
||||
discord_presence.partyMax = 0;
|
||||
discord_presence.partySize = 0;
|
||||
|
||||
RARCH_LOG("[Discord] join secret: %s\n", join_secret);
|
||||
RARCH_LOG("[Discord] party id: %s\n", party_name);
|
||||
|
@ -20,15 +20,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include "../deps/discord-rpc/include/discord_rpc.h"
|
||||
#include "verbosity.h"
|
||||
|
||||
enum discord_presence
|
||||
{
|
||||
@ -53,13 +46,13 @@ void discord_shutdown(void);
|
||||
|
||||
void discord_update(enum discord_presence presence);
|
||||
|
||||
void discord_run_callbacks();
|
||||
void discord_run_callbacks(void);
|
||||
|
||||
bool discord_is_ready();
|
||||
bool discord_is_ready(void);
|
||||
|
||||
void discord_avatar_set_ready(bool ready);
|
||||
|
||||
bool discord_avatar_is_ready();
|
||||
bool discord_avatar_is_ready(void);
|
||||
|
||||
char* discord_get_own_username(void);
|
||||
|
||||
|
2
driver.c
2
driver.c
@ -22,6 +22,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <audio/audio_resampler.h>
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
#include "menu/menu_driver.h"
|
||||
#endif
|
||||
|
20
dynamic.c
20
dynamic.c
@ -104,7 +104,7 @@ static dylib_t lib_handle;
|
||||
#define SYMBOL_NETRETROPAD(x) current_core->x = libretro_netretropad_##x
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_VIDEO_PROCESSOR)
|
||||
#if defined(HAVE_VIDEOPROCESSOR)
|
||||
#define SYMBOL_VIDEOPROCESSOR(x) current_core->x = libretro_videoprocessor_##x
|
||||
#endif
|
||||
|
||||
@ -191,9 +191,7 @@ static bool environ_cb_get_system_info(unsigned cmd, void *data)
|
||||
break;
|
||||
case RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO:
|
||||
{
|
||||
unsigned i = 0;
|
||||
unsigned j = 0;
|
||||
unsigned size = i;
|
||||
unsigned i, j, size;
|
||||
const struct retro_subsystem_info *info =
|
||||
(const struct retro_subsystem_info*)data;
|
||||
subsystem_current_count = 0;
|
||||
@ -496,8 +494,9 @@ bool libretro_get_system_info(const char *path,
|
||||
* Setup libretro callback symbols. Returns true on success,
|
||||
* or false if symbols could not be loaded.
|
||||
**/
|
||||
bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, dylib_t *lib_handle_p)
|
||||
bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, void *_lib_handle_p)
|
||||
{
|
||||
dylib_t *lib_handle_p = (dylib_t*)_lib_handle_p;
|
||||
#ifdef HAVE_DYNAMIC
|
||||
/* the library handle for use with the SYMBOL macro */
|
||||
dylib_t lib_handle_local;
|
||||
@ -749,7 +748,7 @@ bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *cu
|
||||
#endif
|
||||
break;
|
||||
case CORE_TYPE_VIDEO_PROCESSOR:
|
||||
#if defined(HAVE_VIDEO_PROCESSOR)
|
||||
#if defined(HAVE_VIDEOPROCESSOR)
|
||||
SYMBOL_VIDEOPROCESSOR(retro_init);
|
||||
SYMBOL_VIDEOPROCESSOR(retro_deinit);
|
||||
|
||||
@ -1515,7 +1514,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
{
|
||||
memcpy(hwr,
|
||||
cb, offsetof(struct retro_hw_render_callback, stencil));
|
||||
memset((uint8_t*)hwr + offsetof(struct retro_hw_render_callback, stencil),
|
||||
memset((uint8_t*)hwr + offsetof(struct retro_hw_render_callback, stencil),
|
||||
0, sizeof(*cb) - offsetof(struct retro_hw_render_callback, stencil));
|
||||
}
|
||||
else
|
||||
@ -1929,7 +1928,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
{
|
||||
const uint32_t supported_vfs_version = 3;
|
||||
static struct retro_vfs_interface vfs_iface =
|
||||
{
|
||||
{
|
||||
/* VFS API v1 */
|
||||
retro_vfs_file_get_path_impl,
|
||||
retro_vfs_file_open_impl,
|
||||
@ -1941,9 +1940,9 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
retro_vfs_file_write_impl,
|
||||
retro_vfs_file_flush_impl,
|
||||
retro_vfs_file_remove_impl,
|
||||
retro_vfs_file_rename_impl,
|
||||
retro_vfs_file_rename_impl,
|
||||
/* VFS API v2 */
|
||||
retro_vfs_file_truncate_impl,
|
||||
retro_vfs_file_truncate_impl,
|
||||
/* VFS API v3 */
|
||||
retro_vfs_stat_impl,
|
||||
retro_vfs_mkdir_impl,
|
||||
@ -1960,6 +1959,7 @@ bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
RARCH_LOG("Core requested VFS version >= v%d, providing v%d\n", vfs_iface_info->required_interface_version, supported_vfs_version);
|
||||
vfs_iface_info->required_interface_version = supported_vfs_version;
|
||||
vfs_iface_info->iface = &vfs_iface;
|
||||
system->supports_vfs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <boolean.h>
|
||||
#include <retro_common_api.h>
|
||||
#include <libretro.h>
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
#include "core_type.h"
|
||||
|
||||
@ -133,7 +132,7 @@ bool libretro_get_shared_context(void);
|
||||
bool init_libretro_sym(enum rarch_core_type type,
|
||||
struct retro_core_t *core);
|
||||
|
||||
bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, dylib_t *lib_handle_p);
|
||||
bool init_libretro_sym_custom(enum rarch_core_type type, struct retro_core_t *current_core, const char *lib_path, void *lib_handle_p);
|
||||
|
||||
/**
|
||||
* uninit_libretro_sym:
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <encodings/utf.h>
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
#include "menu/menu_driver.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
@ -160,39 +164,6 @@ void fill_pathname_application_special(char *s,
|
||||
fill_pathname_basedir(s, path_get(RARCH_PATH_CONFIG), len);
|
||||
}
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS:
|
||||
#ifdef HAVE_ZARCH
|
||||
{
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_FONT:
|
||||
#ifdef HAVE_ZARCH
|
||||
{
|
||||
char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
s1[0] = '\0';
|
||||
|
||||
fill_pathname_application_special(s1,
|
||||
PATH_MAX_LENGTH * sizeof(char),
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH);
|
||||
fill_pathname_join(s,
|
||||
s1, "Roboto-Condensed.ttf", len);
|
||||
|
||||
free(s1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH:
|
||||
#ifdef HAVE_ZARCH
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
fill_pathname_join(s,
|
||||
settings->paths.directory_assets,
|
||||
"zarch",
|
||||
len);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_ICONS:
|
||||
#ifdef HAVE_XMB
|
||||
{
|
||||
@ -238,6 +209,70 @@ void fill_pathname_application_special(char *s,
|
||||
free(s1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_SOUNDS:
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *menu_ident = settings->arrays.menu_driver;
|
||||
char *s1 = (char*)calloc(1, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (string_is_equal(menu_ident, "xmb"))
|
||||
{
|
||||
fill_pathname_application_special(s1, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB);
|
||||
|
||||
if (!string_is_empty(s1))
|
||||
strlcat(s1, "/sounds", PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
else if (string_is_equal(menu_ident, "glui"))
|
||||
{
|
||||
fill_pathname_application_special(s1, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI);
|
||||
|
||||
if (!string_is_empty(s1))
|
||||
strlcat(s1, "/sounds", PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
else if (string_is_equal(menu_ident, "ozone"))
|
||||
{
|
||||
fill_pathname_application_special(s1, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_OZONE);
|
||||
|
||||
if (!string_is_empty(s1))
|
||||
strlcat(s1, "/sounds", PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
|
||||
if (string_is_empty(s1))
|
||||
{
|
||||
fill_pathname_join(
|
||||
s1,
|
||||
settings->paths.directory_assets,
|
||||
"sounds",
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
}
|
||||
|
||||
strlcpy(s, s1, len);
|
||||
free(s1);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_OZONE:
|
||||
#ifdef HAVE_OZONE
|
||||
{
|
||||
char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
s1[0] = '\0';
|
||||
|
||||
fill_pathname_join(
|
||||
s1,
|
||||
settings->paths.directory_assets,
|
||||
"ozone",
|
||||
PATH_MAX_LENGTH * sizeof(char)
|
||||
);
|
||||
strlcpy(s, s1, len);
|
||||
free(s1);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB:
|
||||
|
@ -108,9 +108,8 @@ enum application_special_type
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_BG,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_ICONS,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_FONT,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_FONT,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_OZONE,
|
||||
APPLICATION_SPECIAL_DIRECTORY_ASSETS_SOUNDS,
|
||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES,
|
||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_DISCORD_AVATARS
|
||||
};
|
||||
|
@ -115,7 +115,11 @@ static NSSearchPathDirectory NSConvertFlagsCF(unsigned flags)
|
||||
switch (flags)
|
||||
{
|
||||
case CFDocumentDirectory:
|
||||
return NSDocumentDirectory;
|
||||
#if TARGET_OS_TV
|
||||
return NSCachesDirectory;
|
||||
#else
|
||||
return NSDocumentDirectory;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -363,7 +367,7 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[],
|
||||
home_dir_buf, "shaders_glsl",
|
||||
sizeof(g_defaults.dirs[DEFAULT_DIR_SHADER]));
|
||||
#endif
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_OS_IOS
|
||||
int major, minor;
|
||||
get_ios_version(&major, &minor);
|
||||
if (major >= 10 )
|
||||
@ -372,6 +376,9 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[],
|
||||
else
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
home_dir_buf, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
#elif TARGET_OS_TV
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE],
|
||||
bundle_path_buf, "modules", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
#else
|
||||
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE], home_dir_buf, "cores", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE]));
|
||||
#endif
|
||||
@ -423,7 +430,7 @@ static void frontend_darwin_get_environment_settings(int *argc, char *argv[],
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_OS_IOS
|
||||
char assets_zip_path[PATH_MAX_LENGTH];
|
||||
if (major > 8)
|
||||
strlcpy(g_defaults.path.buildbot_server_url, "http://buildbot.libretro.com/nightly/apple/ios9/latest/", sizeof(g_defaults.path.buildbot_server_url));
|
||||
@ -582,7 +589,7 @@ static enum frontend_powerstate frontend_darwin_get_powerstate(int *seconds, int
|
||||
end:
|
||||
if (blob)
|
||||
CFRelease(blob);
|
||||
#elif defined(IOS)
|
||||
#elif TARGET_OS_IOS
|
||||
float level;
|
||||
UIDevice *uidev = [UIDevice currentDevice];
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "../frontend.h"
|
||||
#include "../frontend_driver.h"
|
||||
#include "../../gfx/video_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../defaults.h"
|
||||
#include "../../content.h"
|
||||
|
@ -510,6 +510,11 @@ static int frontend_ps2_parse_drive_list(void *data, bool load_content)
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
menu_entries_append_enum(list,
|
||||
"cdfs:/",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
menu_entries_append_enum(list,
|
||||
"hdd0:/",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
|
@ -271,18 +271,48 @@ static int frontend_uwp_parse_drive_list(void *data, bool load_content)
|
||||
enum msg_hash_enums enum_idx = load_content ?
|
||||
MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR :
|
||||
MSG_UNKNOWN;
|
||||
/* TODO (krzys_h): UWP storage sandboxing */
|
||||
char *home_dir = (char*)malloc(
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
char drive[] = " :\\";
|
||||
char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
bool have_any_drives = false;
|
||||
|
||||
fill_pathname_home_dir(home_dir,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_home_dir(home_dir, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
|
||||
{
|
||||
if (uwp_drive_exists(drive))
|
||||
{
|
||||
menu_entries_append_enum(list,
|
||||
drive,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
have_any_drives = true;
|
||||
}
|
||||
}
|
||||
|
||||
menu_entries_append_enum(list,
|
||||
home_dir,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
home_dir,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_DETECT_CORE_LIST_PUSH_DIR),
|
||||
enum_idx,
|
||||
FILE_TYPE_DIRECTORY, 0, 0);
|
||||
|
||||
if (!have_any_drives)
|
||||
{
|
||||
menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILE_BROWSER_OPEN_PICKER),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER),
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_OPEN_PICKER,
|
||||
MENU_SETTING_ACTION, 0, 0);
|
||||
|
||||
if (string_is_equal(uwp_device_family, "Windows.Desktop"))
|
||||
{
|
||||
menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_FILE_BROWSER_OPEN_UWP_PERMISSIONS),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_FILE_BROWSER_OPEN_UWP_PERMISSIONS),
|
||||
MENU_ENUM_LABEL_FILE_BROWSER_OPEN_UWP_PERMISSIONS,
|
||||
MENU_SETTING_ACTION, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
free(home_dir);
|
||||
#endif
|
||||
|
@ -29,14 +29,16 @@
|
||||
#endif
|
||||
|
||||
#include "frontend.h"
|
||||
#include "frontend_driver.h"
|
||||
#include "../configuration.h"
|
||||
#include "../ui/ui_companion_driver.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
#include "../tasks/task_content.h"
|
||||
|
||||
#include "../driver.h"
|
||||
#include "../paths.h"
|
||||
#include "../retroarch.h"
|
||||
#include "../verbosity.h"
|
||||
#include "../record/record_driver.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
|
||||
#include <objbase.h>
|
||||
@ -90,6 +92,7 @@ void main_exit(void *args)
|
||||
driver_ctl(RARCH_DRIVER_CTL_DEINIT, NULL);
|
||||
ui_companion_driver_free();
|
||||
frontend_driver_free();
|
||||
recording_driver_lock_free();
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
|
||||
CoUninitialize();
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include "d3d_common.h"
|
||||
#include "d3d12_common.h"
|
||||
#include "dxgi_common.h"
|
||||
#include "d3dcompiler_common.h"
|
||||
@ -219,6 +220,7 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
int width, int height, void* corewindow)
|
||||
{
|
||||
unsigned i;
|
||||
HRESULT hr;
|
||||
#ifdef __WINRT__
|
||||
DXGI_SWAP_CHAIN_DESC1 desc;
|
||||
memset(&desc, 0, sizeof(DXGI_SWAP_CHAIN_DESC1));
|
||||
@ -256,10 +258,15 @@ bool d3d12_init_swapchain(d3d12_video_t* d3d12,
|
||||
#endif
|
||||
|
||||
#ifdef __WINRT__
|
||||
DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle);
|
||||
hr = DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle);
|
||||
#else
|
||||
DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle);
|
||||
hr = DXGICreateSwapChain(d3d12->factory, d3d12->queue.handle, &desc, &d3d12->chain.handle);
|
||||
#endif
|
||||
if (FAILED(hr))
|
||||
{
|
||||
RARCH_ERR("[D3D12]: Failed to create the swap chain (0x%08X)\n", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WINDOW
|
||||
DXGIMakeWindowAssociation(d3d12->factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
@ -457,6 +457,12 @@ static INLINE void d3d9_set_viewports(LPDIRECT3DDEVICE9 dev,
|
||||
IDirect3DDevice9_SetViewport(dev, (D3DVIEWPORT9*)vp);
|
||||
}
|
||||
|
||||
static INLINE void d3d9_set_scissor_rect(
|
||||
LPDIRECT3DDEVICE9 dev, RECT *rect)
|
||||
{
|
||||
IDirect3DDevice9_SetScissorRect(dev, rect);
|
||||
}
|
||||
|
||||
static INLINE void d3d9_set_render_state(
|
||||
LPDIRECT3DDEVICE9 dev, D3DRENDERSTATETYPE state, DWORD value)
|
||||
{
|
||||
|
@ -1,80 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
*
|
||||
* 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 <gfx/gl_capabilities.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "gl_common.h"
|
||||
|
||||
static void gl_size_format(GLint* internalFormat)
|
||||
{
|
||||
#ifndef HAVE_PSGL
|
||||
switch (*internalFormat)
|
||||
{
|
||||
case GL_RGB:
|
||||
/* FIXME: PS3 does not support this, neither does it have GL_RGB565_OES. */
|
||||
*internalFormat = GL_RGB565;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
#ifdef HAVE_OPENGLES2
|
||||
*internalFormat = GL_RGBA8_OES;
|
||||
#else
|
||||
*internalFormat = GL_RGBA8;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function should only be used without mipmaps
|
||||
and when data == NULL */
|
||||
void gl_load_texture_image(GLenum target,
|
||||
GLint level,
|
||||
GLint internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
const GLvoid * data)
|
||||
{
|
||||
#if !defined(HAVE_PSGL) && !defined(ORBIS)
|
||||
#ifdef HAVE_OPENGLES2
|
||||
if (gl_check_capability(GL_CAPS_TEX_STORAGE_EXT) && internalFormat != GL_BGRA_EXT)
|
||||
{
|
||||
gl_size_format(&internalFormat);
|
||||
glTexStorage2DEXT(target, 1, internalFormat, width, height);
|
||||
}
|
||||
#else
|
||||
if (gl_check_capability(GL_CAPS_TEX_STORAGE) && internalFormat != GL_BGRA_EXT)
|
||||
{
|
||||
gl_size_format(&internalFormat);
|
||||
glTexStorage2D(target, 1, internalFormat, width, height);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_OPENGLES
|
||||
if (gl_check_capability(GL_CAPS_GLES3_SUPPORTED))
|
||||
#endif
|
||||
gl_size_format(&internalFormat);
|
||||
glTexImage2D(target, level, internalFormat, width, height, border, format, type, data);
|
||||
}
|
||||
}
|
@ -29,13 +29,11 @@
|
||||
#include <retro_inline.h>
|
||||
#include <gfx/math/matrix_4x4.h>
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <glsym/glsym.h>
|
||||
#include <formats/image.h>
|
||||
|
||||
#include "../../verbosity.h"
|
||||
#include "../font_driver.h"
|
||||
#include "../video_coord_array.h"
|
||||
#include "../video_driver.h"
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
@ -92,8 +90,10 @@ RETRO_BEGIN_DECLS
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(HAVE_PSGL)
|
||||
#ifndef GL_RGBA32F
|
||||
#define GL_RGBA32F GL_RGBA32F_ARB
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PSGL)
|
||||
#define RARCH_GL_INTERNAL_FORMAT32 GL_ARGB_SCE
|
||||
@ -156,82 +156,6 @@ RETRO_BEGIN_DECLS
|
||||
#endif
|
||||
|
||||
typedef struct gl gl_t;
|
||||
typedef struct gl_renderchain_driver gl_renderchain_driver_t;
|
||||
|
||||
struct gl_renderchain_driver
|
||||
{
|
||||
void (*set_coords)(void *handle_data,
|
||||
void *chain_data,
|
||||
void *shader_data, const struct video_coords *coords);
|
||||
void (*set_mvp)(void *data,
|
||||
void *chain_data,
|
||||
void *shader_data,
|
||||
const void *mat_data);
|
||||
void (*init_texture_reference)(
|
||||
gl_t *gl, void *chain_data, unsigned i,
|
||||
unsigned internal_fmt, unsigned texture_fmt,
|
||||
unsigned texture_type);
|
||||
void (*fence_iterate)(void *data, void *chain_data,
|
||||
unsigned hard_sync_frames);
|
||||
void (*fence_free)(void *data, void *chain_data);
|
||||
void (*readback)(gl_t *gl,
|
||||
void *chain_data,
|
||||
unsigned alignment,
|
||||
unsigned fmt, unsigned type,
|
||||
void *src);
|
||||
void (*init_pbo)(unsigned size, const void *data);
|
||||
void (*bind_pbo)(unsigned idx);
|
||||
void (*unbind_pbo)(void *data, void *chain_data);
|
||||
void (*copy_frame)(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch);
|
||||
void (*restore_default_state)(gl_t *gl, void *chain_data);
|
||||
void (*new_vao)(void *data, void *chain_data);
|
||||
void (*free_vao)(void *data, void *chain_data);
|
||||
void (*bind_vao)(void *data, void *chain_data);
|
||||
void (*unbind_vao)(void *data, void *chain_data);
|
||||
void (*disable_client_arrays)(void *data, void *chain_data);
|
||||
void (*ff_vertex)(const void *data);
|
||||
void (*ff_matrix)(const void *data);
|
||||
void (*bind_backbuffer)(void *data, void *chain_data);
|
||||
void (*deinit_fbo)(gl_t *gl, void *chain_data);
|
||||
bool (*read_viewport)(
|
||||
gl_t *gl, void *chain_data, uint8_t *buffer, bool is_idle);
|
||||
void (*bind_prev_texture)(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
const struct video_tex_info *tex_info);
|
||||
void (*chain_free)(void *data, void *chain_data);
|
||||
void *(*chain_new)(void);
|
||||
void (*init)(gl_t *gl, void *chain_data,
|
||||
unsigned fbo_width, unsigned fbo_height);
|
||||
bool (*init_hw_render)(gl_t *gl, void *chain_data,
|
||||
unsigned width, unsigned height);
|
||||
void (*free)(gl_t *gl, void *chain_data);
|
||||
void (*deinit_hw_render)(gl_t *gl, void *chain_data);
|
||||
void (*start_render)(gl_t *gl, void *chain_data,
|
||||
video_frame_info_t *video_info);
|
||||
void (*check_fbo_dimensions)(gl_t *gl, void *chain_data);
|
||||
void (*recompute_pass_sizes)(gl_t *gl,
|
||||
void *chain_data,
|
||||
unsigned width, unsigned height,
|
||||
unsigned vp_width, unsigned vp_height);
|
||||
void (*renderchain_render)(gl_t *gl,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
uint64_t frame_count,
|
||||
const struct video_tex_info *tex_info,
|
||||
const struct video_tex_info *feedback_info);
|
||||
void (*resolve_extensions)(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
const char *context_ident,
|
||||
const video_info_t *video);
|
||||
const char *ident;
|
||||
};
|
||||
|
||||
struct gl
|
||||
{
|
||||
@ -315,7 +239,8 @@ struct gl
|
||||
struct video_tex_info prev_info[GFX_MAX_TEXTURES];
|
||||
struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS];
|
||||
|
||||
const gl_renderchain_driver_t *renderchain_driver;
|
||||
const shader_backend_t *shader;
|
||||
void *shader_data;
|
||||
void *renderchain_data;
|
||||
void *ctx_data;
|
||||
const gfx_ctx_driver_t *ctx_driver;
|
||||
@ -331,64 +256,6 @@ static INLINE void gl_bind_texture(GLuint id, GLint wrap_mode, GLint mag_filter,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
|
||||
}
|
||||
|
||||
static INLINE unsigned gl_wrap_type_to_enum(enum gfx_wrap_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
#ifndef HAVE_OPENGLES
|
||||
case RARCH_WRAP_BORDER: /* GL_CLAMP_TO_BORDER: Available since GL 1.3 */
|
||||
return GL_CLAMP_TO_BORDER;
|
||||
#else
|
||||
case RARCH_WRAP_BORDER:
|
||||
#endif
|
||||
case RARCH_WRAP_EDGE:
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
case RARCH_WRAP_REPEAT:
|
||||
return GL_REPEAT;
|
||||
case RARCH_WRAP_MIRRORED_REPEAT:
|
||||
return GL_MIRRORED_REPEAT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool gl_query_core_context_in_use(void);
|
||||
|
||||
void gl_load_texture_image(GLenum target,
|
||||
GLint level,
|
||||
GLint internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
const GLvoid * data);
|
||||
|
||||
void gl_load_texture_data(
|
||||
uint32_t id_data,
|
||||
enum gfx_wrap_type wrap_type,
|
||||
enum texture_filter_type filter_type,
|
||||
unsigned alignment,
|
||||
unsigned width, unsigned height,
|
||||
const void *frame, unsigned base_size);
|
||||
|
||||
static INLINE GLenum gl_min_filter_to_mag(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
return GL_LINEAR;
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
return GL_NEAREST;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static INLINE bool gl_set_core_context(enum retro_hw_context_type ctx_type)
|
||||
{
|
||||
gfx_ctx_flags_t flags;
|
||||
@ -406,6 +273,12 @@ static INLINE bool gl_set_core_context(enum retro_hw_context_type ctx_type)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gl_query_core_context_in_use(void);
|
||||
|
||||
bool gl_load_luts(
|
||||
const void *shader_data,
|
||||
GLuint *textures_lut);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
#import "RendererCommon.h"
|
||||
|
||||
@interface Texture : NSObject
|
||||
|
@ -28,15 +28,13 @@
|
||||
#endif
|
||||
|
||||
#include "vulkan_common.h"
|
||||
#include "../../libretro-common/include/retro_timers.h"
|
||||
#include <retro_timers.h>
|
||||
#include "../../configuration.h"
|
||||
#include "../include/vulkan/vulkan.h"
|
||||
#include "../../libretro-common/include/retro_assert.h"
|
||||
#include <retro_assert.h>
|
||||
#include "vksym.h"
|
||||
#include "../../libretro-common/include/dynamic/dylib.h"
|
||||
#include "../../libretro-common/include/libretro_vulkan.h"
|
||||
#include "../../libretro-common/include/retro_math.h"
|
||||
#include "../../libretro-common/include/string/stdstring.h"
|
||||
#include <libretro_vulkan.h>
|
||||
#include <retro_math.h>
|
||||
|
||||
#define VENDOR_ID_AMD 0x1002
|
||||
#define VENDOR_ID_NV 0x10DE
|
||||
|
@ -48,10 +48,7 @@
|
||||
#include "../font_driver.h"
|
||||
#include "../video_driver.h"
|
||||
#include "../drivers_shader/shader_vulkan.h"
|
||||
#include "../../libretro-common/include/gfx/math/matrix_4x4.h"
|
||||
#include "../include/vulkan/vulkan.h"
|
||||
#include "../../libretro-common/include/gfx/scaler/scaler.h"
|
||||
#include "../../libretro-common/include/libretro_vulkan.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
|
@ -1,29 +1,65 @@
|
||||
#!/bin/sh
|
||||
WAYSCAN=/usr/bin/wayland-scanner
|
||||
WAYLAND_PROTOS=/usr/share/wayland-protocols
|
||||
OUTPUT=gfx/common/wayland
|
||||
|
||||
if [ ! -d $WAYLAND_PROTOS ]; then
|
||||
WAYSCAN=/usr/local/bin/wayland-scanner
|
||||
WAYLAND_PROTOS=/usr/local/share/wayland-protocols
|
||||
fi
|
||||
set -eu
|
||||
|
||||
if [ ! -d $OUTPUT ]; then
|
||||
mkdir $OUTPUT
|
||||
cd -- "$(cd -- "${0%/*}/" && pwd -P)"
|
||||
|
||||
. ../../../qb/qb.init.sh
|
||||
|
||||
SCANNER_VERSION=''
|
||||
SHARE_DIR=''
|
||||
|
||||
usage="generate_wayland_protos.sh - Generates wayland protocols.
|
||||
|
||||
Usage: generate_wayland_protos.sh [OPTIONS]
|
||||
-c, --codegen version Sets the wayland scanner compatibility version.
|
||||
-h, --help Shows this message.
|
||||
-s, --share path Sets the path of the wayland protocols directory."
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
option="$1"
|
||||
shift
|
||||
case "$option" in
|
||||
-- ) break ;;
|
||||
-c|--codegen ) SCANNER_VERSION="$1"; shift ;;
|
||||
-h|--help ) die 0 "$usage" ;;
|
||||
-s|--share ) SHARE_DIR="$1/wayland-protocols"; shift ;;
|
||||
* ) die 1 "Unrecognized option '$option', use -h for help." ;;
|
||||
esac
|
||||
done
|
||||
|
||||
WAYSCAN="$(exists wayland-scanner || :)"
|
||||
|
||||
[ "${WAYSCAN}" ] || die 1 "Error: No wayscan in ($PATH)"
|
||||
|
||||
WAYLAND_PROTOS=''
|
||||
|
||||
for protos in "$SHARE_DIR" /usr/local/share/wayland-protocols /usr/share/wayland-protocols; do
|
||||
[ -d "$protos" ] || continue
|
||||
WAYLAND_PROTOS="$protos"
|
||||
break
|
||||
done
|
||||
|
||||
[ "${WAYLAND_PROTOS}" ] || die 1 'Error: No wayland-protocols directory found.'
|
||||
|
||||
if [ "$SCANNER_VERSION" = '1.12' ]; then
|
||||
CODEGEN=code
|
||||
else
|
||||
CODEGEN=private-code
|
||||
fi
|
||||
|
||||
#Generate xdg-shell_v6 header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml $OUTPUT/xdg-shell-unstable-v6.h
|
||||
$WAYSCAN private-code $WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml $OUTPUT/xdg-shell-unstable-v6.c
|
||||
"$WAYSCAN" client-header "$WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml" ./xdg-shell-unstable-v6.h
|
||||
"$WAYSCAN" $CODEGEN "$WAYLAND_PROTOS/unstable/xdg-shell/xdg-shell-unstable-v6.xml" ./xdg-shell-unstable-v6.c
|
||||
|
||||
#Generate xdg-shell header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml $OUTPUT/xdg-shell.h
|
||||
$WAYSCAN private-code $WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml $OUTPUT/xdg-shell.c
|
||||
"$WAYSCAN" client-header "$WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml" ./xdg-shell.h
|
||||
"$WAYSCAN" $CODEGEN "$WAYLAND_PROTOS/stable/xdg-shell/xdg-shell.xml" ./xdg-shell.c
|
||||
|
||||
#Generate idle-inhibit header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml $OUTPUT/idle-inhibit-unstable-v1.h
|
||||
$WAYSCAN private-code $WAYLAND_PROTOS/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml $OUTPUT/idle-inhibit-unstable-v1.c
|
||||
"$WAYSCAN" client-header "$WAYLAND_PROTOS/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" ./idle-inhibit-unstable-v1.h
|
||||
"$WAYSCAN" $CODEGEN "$WAYLAND_PROTOS/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml" ./idle-inhibit-unstable-v1.c
|
||||
|
||||
#Generate xdg-decoration header and .c files
|
||||
$WAYSCAN client-header $WAYLAND_PROTOS/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml $OUTPUT/xdg-decoration-unstable-v1.h
|
||||
$WAYSCAN private-code $WAYLAND_PROTOS/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml $OUTPUT/xdg-decoration-unstable-v1.c
|
||||
"$WAYSCAN" client-header "$WAYLAND_PROTOS/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ./xdg-decoration-unstable-v1.h
|
||||
"$WAYSCAN" $CODEGEN "$WAYLAND_PROTOS/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" ./xdg-decoration-unstable-v1.c
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "../../driver.h"
|
||||
#include "../../paths.h"
|
||||
#include "../../retroarch.h"
|
||||
#include "../../tasks/task_content.h"
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
#include "../../core_info.h"
|
||||
|
||||
@ -51,7 +52,6 @@
|
||||
|
||||
#include <commdlg.h>
|
||||
#include <dbt.h>
|
||||
#include "../../retroarch.h"
|
||||
#include "../../input/input_driver.h"
|
||||
#include "../../input/input_keymaps.h"
|
||||
#include "../video_thread_wrapper.h"
|
||||
|
@ -405,7 +405,7 @@ bool x11_get_metrics(void *data,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
||||
static void x11_handle_key_event(unsigned keycode, XEvent *event, XIC ic, bool filter)
|
||||
{
|
||||
int i;
|
||||
Status status;
|
||||
@ -419,6 +419,7 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
||||
|
||||
chars[0] = '\0';
|
||||
|
||||
/* this code generates the localized chars using keysyms */
|
||||
if (!filter)
|
||||
{
|
||||
if (down)
|
||||
@ -454,8 +455,10 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
||||
* to feed it keysyms anyway, so here is a little hack... */
|
||||
if (keysym >= XK_A && keysym <= XK_Z)
|
||||
keysym += XK_z - XK_Z;
|
||||
|
||||
key = input_keymaps_translate_keysym_to_rk(keysym);
|
||||
|
||||
/* Get the real keycode,
|
||||
that correctly ignores international layouts as windows code does. */
|
||||
key = input_keymaps_translate_keysym_to_rk(keycode);
|
||||
|
||||
if (state & ShiftMask)
|
||||
mod |= RETROKMOD_SHIFT;
|
||||
@ -465,10 +468,10 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter)
|
||||
mod |= RETROKMOD_CTRL;
|
||||
if (state & Mod1Mask)
|
||||
mod |= RETROKMOD_ALT;
|
||||
if (state & Mod2Mask)
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
if (state & Mod4Mask)
|
||||
mod |= RETROKMOD_META;
|
||||
if (IsKeypadKey(keysym))
|
||||
mod |= RETROKMOD_NUMLOCK;
|
||||
|
||||
input_keyboard_event(down, key, chars[0], mod, RETRO_DEVICE_KEYBOARD);
|
||||
|
||||
@ -483,9 +486,14 @@ bool x11_alive(void *data)
|
||||
{
|
||||
XEvent event;
|
||||
bool filter = false;
|
||||
unsigned keycode = 0;
|
||||
|
||||
/* Can get events from older windows. Check this. */
|
||||
XNextEvent(g_x11_dpy, &event);
|
||||
|
||||
/* IMPORTANT - Get keycode before XFilterEvent
|
||||
because the event is localizated after the call */
|
||||
keycode = event.xkey.keycode;
|
||||
filter = XFilterEvent(&event, g_x11_win);
|
||||
|
||||
switch (event.type)
|
||||
@ -548,7 +556,7 @@ bool x11_alive(void *data)
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
if (event.xkey.window == g_x11_win)
|
||||
x11_handle_key_event(&event, g_x11_xic, filter);
|
||||
x11_handle_key_event(keycode, &event, g_x11_xic, filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static void win32_display_server_destroy(void *data)
|
||||
|
||||
if (win32_orig_width > 0 && win32_orig_height > 0)
|
||||
video_display_server_set_resolution(win32_orig_width, win32_orig_height,
|
||||
win32_orig_refresh, (float)win32_orig_refresh, crt_center );
|
||||
win32_orig_refresh, (float)win32_orig_refresh, crt_center, 0);
|
||||
|
||||
#ifdef HAS_TASKBAR_EXT
|
||||
if (g_taskbarList)
|
||||
@ -210,7 +210,7 @@ static bool win32_display_server_set_window_decorations(void *data, bool on)
|
||||
}
|
||||
|
||||
static bool win32_display_server_set_resolution(void *data,
|
||||
unsigned width, unsigned height, int int_hz, float hz, int center)
|
||||
unsigned width, unsigned height, int int_hz, float hz, int center, int monitor_index)
|
||||
{
|
||||
DEVMODE curDevmode;
|
||||
int iModeNum;
|
||||
|
@ -19,6 +19,10 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h> // run pkg-config --static --libs xrandr
|
||||
#include <X11/extensions/randr.h>
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#include "../../config.h"
|
||||
|
||||
@ -35,11 +39,15 @@
|
||||
static unsigned orig_width = 0;
|
||||
static unsigned orig_height = 0;
|
||||
static char old_mode[250] = {0};
|
||||
static char orig_output[250] = {0};
|
||||
static char new_mode[250] = {0};
|
||||
static char xrandr[250] = {0};
|
||||
static char fbset[150] = {0};
|
||||
static char output[500] = {0};
|
||||
static char output4[500] = {0};
|
||||
static bool crt_en = false;
|
||||
static unsigned crtid = 20;
|
||||
static XRRModeInfo crt_rrmode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -65,25 +73,20 @@ static void x11_display_server_destroy(void *data)
|
||||
if (crt_en)
|
||||
{
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr -s %dx%d", orig_width, orig_height);
|
||||
"xrandr --newmode \"700x480_59.94\" 13.849698 700 742 801 867 480 490 496 533 interlace -hsync -vsync");
|
||||
system(output);
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --addmode %s 700x480_59.94", orig_output);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --output %s --mode 700x480_59.94", orig_output);
|
||||
system(output);
|
||||
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --delmode %s %.s",orig_output, old_mode);
|
||||
system(output);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --delmode %s%d %s", "VGA", i, old_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --delmode %s-%d %s", "VGA", i, old_mode);
|
||||
system(output);
|
||||
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --delmode %s%d %s", "DVI", i, old_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output),
|
||||
"xrandr --delmode %s-%d %s", "DVI", i, old_mode);
|
||||
system(output);
|
||||
}
|
||||
|
||||
snprintf(output, sizeof(output), "xrandr --rmmode %s", old_mode);
|
||||
system(output);
|
||||
@ -126,33 +129,43 @@ static bool x11_display_server_set_window_decorations(void *data, bool on)
|
||||
}
|
||||
|
||||
static bool x11_display_server_set_resolution(void *data,
|
||||
unsigned width, unsigned height, int int_hz, float hz, int center)
|
||||
unsigned width, unsigned height, int int_hz, float hz, int center, int monitor_index)
|
||||
{
|
||||
int i = 0;
|
||||
int hfp = 0;
|
||||
int hsp = 0;
|
||||
int hbp = 0;
|
||||
int vfp = 0;
|
||||
int vsp = 0;
|
||||
int vbp = 0;
|
||||
int hmax = 0;
|
||||
int vmax = 0;
|
||||
int pdefault = 8;
|
||||
int pwidth = 0;
|
||||
float roundw = 0.0f;
|
||||
float roundh = 0.0f;
|
||||
float pixel_clock = 0;
|
||||
int screen;
|
||||
Window window;
|
||||
XRRScreenResources *res = NULL;
|
||||
Display *dsp = NULL;
|
||||
Screen *scrn = NULL;
|
||||
int i = 0;
|
||||
int hfp = 0;
|
||||
int hsp = 0;
|
||||
int hbp = 0;
|
||||
int vfp = 0;
|
||||
int vsp = 0;
|
||||
int vbp = 0;
|
||||
int hmax = 0;
|
||||
int vmax = 0;
|
||||
int pdefault = 8;
|
||||
int pwidth = 0;
|
||||
float roundw = 0.0f;
|
||||
float roundh = 0.0f;
|
||||
float pixel_clock = 0;
|
||||
|
||||
crt_en = true;
|
||||
crt_en = true;
|
||||
|
||||
snprintf(old_mode, sizeof(old_mode), "%s", new_mode);
|
||||
|
||||
dsp = XOpenDisplay(NULL);
|
||||
scrn = DefaultScreenOfDisplay(dsp);
|
||||
screen = DefaultScreen ( dsp );
|
||||
window = RootWindow ( dsp, screen );
|
||||
|
||||
/* set core refresh from hz */
|
||||
video_monitor_set_refresh_rate(hz);
|
||||
|
||||
/* following code is the mode line generator */
|
||||
|
||||
hsp = width * 1.140;
|
||||
hfp = width * 1.055;
|
||||
|
||||
hsp = width * 1.140;
|
||||
hfp = width * 1.055;
|
||||
pwidth = width;
|
||||
|
||||
if (height < 400 && width > 400)
|
||||
@ -169,7 +182,7 @@ static bool x11_display_server_set_resolution(void *data,
|
||||
if (roundw < 1.20)
|
||||
roundw = 1.34;
|
||||
|
||||
hbp = width * roundw - 8;
|
||||
hbp = width * roundw - 8;
|
||||
hmax = hbp;
|
||||
|
||||
if (height < 241)
|
||||
@ -218,76 +231,86 @@ static bool x11_display_server_set_resolution(void *data,
|
||||
/* create interlaced newmode from modline variables */
|
||||
if (height < 300)
|
||||
{
|
||||
snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"%dx%d_%0.2f\" %f %d %d %d %d %d %d %d %d -hsync -vsync", width, height, hz, pixel_clock,
|
||||
snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"CRT_%dx%d_%0.2f\" %f %d %d %d %d %d %d %d %d -hsync -vsync", width, height, hz, pixel_clock,
|
||||
width, hfp, hsp, hbp, height, vfp, vsp, vbp);
|
||||
system(xrandr);
|
||||
}
|
||||
/* create interlaced newmode from modline variables */
|
||||
if (height > 300)
|
||||
{
|
||||
snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"%dx%d_%0.2f\" %f %d %d %d %d %d %d %d %d interlace -hsync -vsync", width, height, hz, pixel_clock,
|
||||
snprintf(xrandr, sizeof(xrandr), "xrandr --newmode \"CRT_%dx%d_%0.2f\" %f %d %d %d %d %d %d %d %d interlace -hsync -vsync", width, height, hz, pixel_clock,
|
||||
width, hfp, hsp, hbp, height, vfp, vsp, vbp);
|
||||
system(xrandr);
|
||||
}
|
||||
|
||||
/* variable for new mode */
|
||||
snprintf(new_mode, sizeof(new_mode), "%dx%d_%0.2f", width, height, hz);
|
||||
snprintf(new_mode, sizeof(new_mode), "CRT_%dx%d_%0.2f", width, height, hz);
|
||||
|
||||
/* need to run loops for DVI0 - DVI-2 and VGA0 - VGA-2 outputs to
|
||||
* add and delete modes */
|
||||
for (i = 0; i < 3; i++)
|
||||
crt_rrmode.id = crtid;
|
||||
crt_rrmode.width = width;
|
||||
crt_rrmode.height = height;
|
||||
crt_rrmode.dotClock = pixel_clock;
|
||||
crt_rrmode.hSyncStart = hfp;
|
||||
crt_rrmode.hSyncEnd = hsp;
|
||||
crt_rrmode.hTotal = hmax;
|
||||
crt_rrmode.hSkew = 0;
|
||||
crt_rrmode.vSyncStart = vfp;
|
||||
crt_rrmode.vSyncEnd = vsp;
|
||||
crt_rrmode.vTotal = vmax;
|
||||
crt_rrmode.name = new_mode;
|
||||
crt_rrmode.nameLength = sizeof(new_mode);
|
||||
crt_rrmode.modeFlags = 0;
|
||||
|
||||
res = XRRGetScreenResources (dsp, window);
|
||||
|
||||
if (monitor_index == 0)
|
||||
{
|
||||
snprintf(output, sizeof(output), "xrandr --addmode %s%d %s", "DVI", i,
|
||||
new_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output), "xrandr --delmode %s%d %s", "DVI", i,
|
||||
old_mode);
|
||||
system(output);
|
||||
}
|
||||
|
||||
for (int i = 0; i < res->noutput; i++)
|
||||
{
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
snprintf(output, sizeof(output), "xrandr --addmode %s-%d %s", "DVI", i,
|
||||
new_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output), "xrandr --delmode %s-%d %s", "DVI", i,
|
||||
old_mode);
|
||||
system(output);
|
||||
}
|
||||
XRROutputInfo *outputs = XRRGetOutputInfo (dsp, res, res->outputs[i]);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
snprintf(output, sizeof(output), "xrandr --addmode %s%d %s", "VGA", i, new_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output), "xrandr --delmode %s%d %s", "VGA", i, old_mode);
|
||||
system(output);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
snprintf(output, sizeof(output), "xrandr --addmode %s-%d %s", "VGA", i, new_mode);
|
||||
system(output);
|
||||
snprintf(output, sizeof(output), "xrandr --delmode %s-%d %s", "VGA", i, old_mode);
|
||||
system(output);
|
||||
}
|
||||
|
||||
snprintf(output, sizeof(output), "xrandr -s %s", new_mode);
|
||||
system(output);
|
||||
|
||||
/* remove old mode */
|
||||
snprintf(output, sizeof(output), "xrandr --rmmode %s", old_mode);
|
||||
system(output);
|
||||
|
||||
/* needs xdotool installed. needed to recapture window. */
|
||||
system("xdotool windowactivate $(xdotool search --class RetroArch)");
|
||||
|
||||
/* variable for old mode */
|
||||
snprintf(old_mode, sizeof(old_mode), "%s", new_mode);
|
||||
|
||||
/* needs xdotool installed. needed to recapture window. */
|
||||
system("xdotool windowactivate $(xdotool search --class RetroArch)");
|
||||
/* Second run needed as some times it runs to fast to capture first time */
|
||||
|
||||
if (outputs->connection == RR_Connected)
|
||||
{
|
||||
snprintf(orig_output, sizeof(orig_output),"%s", outputs->name);
|
||||
|
||||
snprintf(output4, sizeof(output4),"xrandr --addmode %s %s",outputs->name ,new_mode);
|
||||
system(output4);
|
||||
snprintf(output4, sizeof(output4),"xrandr --output %s --mode %s", outputs->name, new_mode);
|
||||
system(output4);
|
||||
|
||||
snprintf(output4, sizeof(output4),"xrandr --delmode %s %s", outputs->name,old_mode);
|
||||
system(output4);
|
||||
snprintf(output4, sizeof(output4),"xrandr --rmmode %s", old_mode);
|
||||
system(output4);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (monitor_index > 0)
|
||||
{
|
||||
|
||||
XRROutputInfo *outputs = XRRGetOutputInfo (dsp, res, res->outputs[monitor_index]);
|
||||
if (outputs->connection == RR_Connected)
|
||||
{
|
||||
snprintf(orig_output, sizeof(orig_output),"%s", outputs->name);
|
||||
|
||||
snprintf(output4, sizeof(output4),"xrandr --addmode %s %s",outputs->name ,new_mode);
|
||||
system(output4);
|
||||
snprintf(output4, sizeof(output4),"xrandr --output %s --mode %s", outputs->name, new_mode);
|
||||
system(output4);
|
||||
|
||||
snprintf(output4, sizeof(output4),"xrandr --delmode %s %s", outputs->name, old_mode);
|
||||
system(output4);
|
||||
snprintf(output4, sizeof(output4),"xrandr --rmmode %s", old_mode);
|
||||
system(output4);
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,18 @@ d3d10_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w,
|
||||
D3D10UnmapBuffer(d3d10->overlays.vbo);
|
||||
}
|
||||
|
||||
static void d3d10_clear_scissor(d3d10_video_t *d3d10, video_frame_info_t *video_info)
|
||||
{
|
||||
D3D10_RECT scissor_rect = {0};
|
||||
|
||||
scissor_rect.left = 0;
|
||||
scissor_rect.top = 0;
|
||||
scissor_rect.right = video_info->width;
|
||||
scissor_rect.bottom = video_info->height;
|
||||
|
||||
D3D10SetScissorRects(d3d10->device, 1, &scissor_rect);
|
||||
}
|
||||
|
||||
static void d3d10_overlay_tex_geom(void* data, unsigned index, float u, float v, float w, float h)
|
||||
{
|
||||
d3d10_sprite_t* sprites = NULL;
|
||||
@ -921,6 +933,7 @@ d3d10_gfx_init(const video_info_t* video,
|
||||
|
||||
desc.FillMode = D3D10_FILL_SOLID;
|
||||
desc.CullMode = D3D10_CULL_NONE;
|
||||
desc.ScissorEnable = TRUE;
|
||||
|
||||
D3D10CreateRasterizerState(d3d10->device, &desc, &d3d10->state);
|
||||
}
|
||||
@ -1318,6 +1331,8 @@ static bool d3d10_gfx_frame(
|
||||
D3D10ClearRenderTargetView(context, d3d10->renderTargetView, d3d10->clearcolor);
|
||||
D3D10SetViewports(context, 1, &d3d10->frame.viewport);
|
||||
|
||||
d3d10_clear_scissor(d3d10, video_info);
|
||||
|
||||
D3D10Draw(context, 4, 0);
|
||||
|
||||
D3D10SetBlendState(context, d3d10->blend_enable, NULL, D3D10_DEFAULT_SAMPLE_MASK);
|
||||
|
@ -81,6 +81,18 @@ d3d11_overlay_vertex_geom(void* data, unsigned index, float x, float y, float w,
|
||||
D3D11UnmapBuffer(d3d11->context, d3d11->overlays.vbo, 0);
|
||||
}
|
||||
|
||||
static void d3d11_clear_scissor(d3d11_video_t *d3d11, video_frame_info_t *video_info)
|
||||
{
|
||||
D3D11_RECT scissor_rect = {0};
|
||||
|
||||
scissor_rect.left = 0;
|
||||
scissor_rect.top = 0;
|
||||
scissor_rect.right = video_info->width;
|
||||
scissor_rect.bottom = video_info->height;
|
||||
|
||||
D3D11SetScissorRects(d3d11->context, 1, &scissor_rect);
|
||||
}
|
||||
|
||||
static void d3d11_overlay_tex_geom(void* data, unsigned index, float u, float v, float w, float h)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_vbo;
|
||||
@ -993,6 +1005,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
|
||||
|
||||
desc.FillMode = D3D11_FILL_SOLID;
|
||||
desc.CullMode = D3D11_CULL_NONE;
|
||||
desc.ScissorEnable = TRUE;
|
||||
|
||||
D3D11CreateRasterizerState(d3d11->device, &desc, &d3d11->state);
|
||||
}
|
||||
@ -1194,7 +1207,9 @@ static bool d3d11_gfx_frame(
|
||||
D3D11SetRenderTargets(context, 1, &d3d11->renderTargetView, NULL);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
PERF_START();
|
||||
#endif
|
||||
|
||||
#if 0 /* custom viewport doesn't call apply_state_changes, so we can't rely on this for now */
|
||||
if (d3d11->resize_viewport)
|
||||
@ -1378,6 +1393,8 @@ static bool d3d11_gfx_frame(
|
||||
D3D11ClearRenderTargetView(context, d3d11->renderTargetView, d3d11->clearcolor);
|
||||
D3D11SetViewports(context, 1, &d3d11->frame.viewport);
|
||||
|
||||
d3d11_clear_scissor(d3d11, video_info);
|
||||
|
||||
D3D11Draw(context, 4, 0);
|
||||
|
||||
D3D11SetBlendState(context, d3d11->blend_enable, NULL, D3D11_DEFAULT_SAMPLE_MASK);
|
||||
@ -1456,7 +1473,9 @@ static bool d3d11_gfx_frame(
|
||||
}
|
||||
d3d11->sprites.enabled = false;
|
||||
|
||||
#if 0
|
||||
PERF_STOP();
|
||||
#endif
|
||||
DXGIPresent(d3d11->swapChain, !!d3d11->vsync, 0);
|
||||
|
||||
return true;
|
||||
|
@ -1033,6 +1033,7 @@ static bool d3d9_initialize(d3d9_video_t *d3d, const video_info_t *info)
|
||||
d3d_matrix_transpose(&d3d->mvp, &d3d->mvp_transposed);
|
||||
|
||||
d3d9_set_render_state(d3d->dev, D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
d3d9_set_render_state(d3d->dev, D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
2260
gfx/drivers/gl.c
2260
gfx/drivers/gl.c
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
||||
#include "shaders_common.h"
|
||||
|
||||
static const char *nuklear_shader = CG(
|
||||
struct input
|
||||
{
|
||||
float time;
|
||||
};
|
||||
|
||||
void main_vertex
|
||||
(
|
||||
float4 position : POSITION,
|
||||
float4 color : COLOR,
|
||||
float2 texCoord : TEXCOORD0,
|
||||
|
||||
uniform float4x4 modelViewProj,
|
||||
|
||||
out float4 oPosition : POSITION,
|
||||
out float4 oColor : COLOR,
|
||||
out float2 otexCoord : TEXCOORD
|
||||
)
|
||||
{
|
||||
oPosition = mul(modelViewProj, position);
|
||||
oColor = color;
|
||||
otexCoord = texCoord;
|
||||
}
|
||||
|
||||
struct output
|
||||
{
|
||||
float4 color : COLOR;
|
||||
};
|
||||
|
||||
output main_fragment(float2 texCoord : TEXCOORD0, uniform sampler2D Texture : TEXUNIT0, uniform input IN)\
|
||||
{
|
||||
output OUT;
|
||||
OUT.color = tex2D(Texture, texCoord);
|
||||
return OUT;
|
||||
}
|
||||
);
|
@ -1,13 +0,0 @@
|
||||
#include "shaders_common.h"
|
||||
|
||||
static const char *nuklear_fragment_shader = GLSL_300(
|
||||
precision mediump float;
|
||||
uniform sampler2D Texture;
|
||||
in vec2 Frag_UV;
|
||||
in vec4 Frag_Color;
|
||||
out vec4 Out_Color;
|
||||
|
||||
void main(){
|
||||
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
||||
}
|
||||
);
|
@ -1,17 +0,0 @@
|
||||
#include "shaders_common.h"
|
||||
|
||||
static const char *nuklear_vertex_shader = GLSL_300(
|
||||
uniform mat4 ProjMtx;
|
||||
in vec2 Position;
|
||||
in vec2 TexCoord;
|
||||
in vec4 Color;
|
||||
out vec2 Frag_UV;
|
||||
out vec4 Frag_Color;
|
||||
|
||||
void main()
|
||||
{
|
||||
Frag_UV = TexCoord;
|
||||
Frag_Color = Color;
|
||||
gl_Position = ProjMtx * vec4(Position.xy, 0, 1);
|
||||
}
|
||||
);
|
@ -197,9 +197,7 @@ static uintptr_t metal_load_texture(void *video_data, void *data,
|
||||
static void metal_unload_texture(void *data, uintptr_t handle)
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Texture *t = (__bridge_transfer Texture *)(void *)handle;
|
||||
t = nil;
|
||||
}
|
||||
|
@ -1867,6 +1867,8 @@ static bool vulkan_frame(void *data, const void *frame,
|
||||
#if defined(HAVE_MENU)
|
||||
if (vk->menu.enable)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
menu_driver_frame(video_info);
|
||||
|
||||
if (vk->menu.textures[vk->menu.last_index].image != VK_NULL_HANDLE ||
|
||||
@ -1882,8 +1884,16 @@ static bool vulkan_frame(void *data, const void *frame,
|
||||
if (optimal->memory != VK_NULL_HANDLE)
|
||||
quad.texture = optimal;
|
||||
|
||||
quad.sampler = optimal->mipmap ?
|
||||
vk->samplers.mipmap_linear : vk->samplers.linear;
|
||||
if (settings->bools.menu_linear_filter)
|
||||
{
|
||||
quad.sampler = optimal->mipmap ?
|
||||
vk->samplers.mipmap_linear : vk->samplers.linear;
|
||||
}
|
||||
else
|
||||
{
|
||||
quad.sampler = optimal->mipmap ?
|
||||
vk->samplers.mipmap_nearest : vk->samplers.nearest;
|
||||
}
|
||||
|
||||
quad.mvp = &vk->mvp_no_rot;
|
||||
quad.color.r = 1.0f;
|
||||
@ -2371,6 +2381,7 @@ static uint32_t vulkan_get_flags(void *data)
|
||||
|
||||
BIT32_SET(flags, GFX_CTX_FLAGS_CUSTOMIZABLE_SWAPCHAIN_IMAGES);
|
||||
BIT32_SET(flags, GFX_CTX_FLAGS_BLACK_FRAME_INSERTION);
|
||||
BIT32_SET(flags, GFX_CTX_FLAGS_MENU_FRAME_FILTERING);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../frontend/drivers/platform_unix.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
static enum gfx_ctx_api android_api = GFX_CTX_NONE;
|
||||
|
||||
|
@ -133,12 +133,16 @@ static void glkitview_init_xibs(void)
|
||||
void *glkitview_init(void)
|
||||
{
|
||||
#if defined(HAVE_COCOATOUCH)
|
||||
#if TARGET_OS_IOS
|
||||
glkitview_init_xibs();
|
||||
#endif
|
||||
|
||||
g_view = [GLKView new];
|
||||
#if TARGET_OS_IOS
|
||||
g_view.multipleTouchEnabled = YES;
|
||||
[g_view addSubview:g_pause_indicator_view];
|
||||
#endif
|
||||
g_view.enableSetNeedsDisplay = NO;
|
||||
[g_view addSubview:g_pause_indicator_view];
|
||||
|
||||
return (BRIDGE void *)((GLKView*)g_view);
|
||||
#else
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <libdrm/drm.h>
|
||||
#include <gbm.h>
|
||||
|
@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include "../video_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
#include "../common/egl_common.h"
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../common/vulkan_common.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <GL/osmesa.h>
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../common/gl_common.h"
|
||||
|
||||
#if (OSMESA_MAJOR_VERSION * 1000 + OSMESA_MINOR_VERSION) >= 11002
|
||||
|
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../../defines/ps3_defines.h"
|
||||
#include "../common/gl_common.h"
|
||||
#include "../video_driver.h"
|
||||
|
@ -45,6 +45,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define WINDOW_BUFFERS 2
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../common/gl_common.h"
|
||||
|
||||
#include "SDL.h"
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "../../config.h"
|
||||
#endif
|
||||
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool smooth;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -14,7 +14,7 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/poll.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
@ -46,6 +46,7 @@
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../input/input_driver.h"
|
||||
#include "../../input/input_keymaps.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
/* Generated from idle-inhibit-unstable-v1.xml */
|
||||
#include "../common/wayland/idle-inhibit-unstable-v1.h"
|
||||
@ -94,8 +95,8 @@ typedef struct gfx_ctx_wayland_data
|
||||
bool resize;
|
||||
bool configured;
|
||||
bool activated;
|
||||
int prev_width;
|
||||
int prev_height;
|
||||
unsigned prev_width;
|
||||
unsigned prev_height;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
struct wl_registry *registry;
|
||||
@ -657,8 +658,11 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
|
||||
wl->width = width;
|
||||
wl->height = height;
|
||||
}
|
||||
|
||||
wl_egl_window_resize(wl->win, width, height, 0, 0);
|
||||
|
||||
if (wl->win)
|
||||
wl_egl_window_resize(wl->win, width, height, 0, 0);
|
||||
else
|
||||
wl->win = wl_egl_window_create(wl->surface, wl->width * wl->buffer_scale, wl->height * wl->buffer_scale);
|
||||
|
||||
wl->configured = false;
|
||||
}
|
||||
@ -724,7 +728,10 @@ static void handle_zxdg_toplevel_config(void *data, struct zxdg_toplevel_v6 *top
|
||||
wl->height = height;
|
||||
}
|
||||
|
||||
wl_egl_window_resize(wl->win, width, height, 0, 0);
|
||||
if (wl->win)
|
||||
wl_egl_window_resize(wl->win, width, height, 0, 0);
|
||||
else
|
||||
wl->win = wl_egl_window_create(wl->surface, wl->width * wl->buffer_scale, wl->height * wl->buffer_scale);
|
||||
|
||||
wl->configured = false;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../dynamic.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../video_driver.h"
|
||||
|
||||
#include "../common/win32_common.h"
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../common/gl_common.h"
|
||||
#include "../common/x11_common.h"
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "../../frontend/frontend_driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#include "../common/egl_common.h"
|
||||
#include "../common/gl_common.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "../common/gl_common.h"
|
||||
#include "../font_driver.h"
|
||||
#include "../video_driver.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
/* TODO: Move viewport side effects to the caller: it's a source of bugs. */
|
||||
|
||||
@ -395,8 +396,6 @@ static void gl_raster_font_render_message(
|
||||
static void gl_raster_font_setup_viewport(unsigned width, unsigned height,
|
||||
gl_raster_t *font, bool full_screen)
|
||||
{
|
||||
video_shader_ctx_info_t shader_info;
|
||||
|
||||
video_driver_set_viewport(width, height, full_screen, false);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
@ -405,11 +404,9 @@ static void gl_raster_font_setup_viewport(unsigned width, unsigned height,
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, font->tex);
|
||||
|
||||
shader_info.data = NULL;
|
||||
shader_info.idx = VIDEO_SHADER_STOCK_BLEND;
|
||||
shader_info.set_active = true;
|
||||
|
||||
video_shader_driver_use(&shader_info);
|
||||
if (font->gl->shader && font->gl->shader->use)
|
||||
font->gl->shader->use(font->gl,
|
||||
font->gl->shader_data, VIDEO_SHADER_STOCK_BLEND, true);
|
||||
}
|
||||
|
||||
static void gl_raster_font_render_msg(
|
||||
|
@ -1,302 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2017 - Daniel De Matteis
|
||||
* Copyright (C) 2012-2015 - Michael Lelli
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "opengl32")
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <formats/image.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_math.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include <gfx/gl_capabilities.h>
|
||||
#include <gfx/video_frame.h>
|
||||
|
||||
#include "../video_driver.h"
|
||||
#include "../video_shader_parse.h"
|
||||
#include "../common/gl_common.h"
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
typedef struct gl1_renderchain
|
||||
{
|
||||
void *empty;
|
||||
} gl1_renderchain_t;
|
||||
|
||||
static bool gl1_renderchain_read_viewport(
|
||||
gl_t *gl, void *chain_data,
|
||||
uint8_t *buffer, bool is_idle)
|
||||
{
|
||||
unsigned num_pixels = gl->vp.width * gl->vp.height;
|
||||
|
||||
/* Use slow synchronous readbacks. Use this with plain screenshots
|
||||
as we don't really care about performance in this case. */
|
||||
|
||||
/* GL1 only guarantees GL_RGBA/GL_UNSIGNED_BYTE
|
||||
* readbacks so do just that.
|
||||
* GL1 also doesn't support reading back data
|
||||
* from front buffer, so render a cached frame
|
||||
* and have gl_frame() do the readback while it's
|
||||
* in the back buffer.
|
||||
*/
|
||||
gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t));
|
||||
|
||||
if (!gl->readback_buffer_screenshot)
|
||||
return false;
|
||||
|
||||
if (!is_idle)
|
||||
video_driver_cached_frame();
|
||||
|
||||
video_frame_convert_rgba_to_bgr(
|
||||
(const void*)gl->readback_buffer_screenshot,
|
||||
buffer,
|
||||
num_pixels);
|
||||
|
||||
free(gl->readback_buffer_screenshot);
|
||||
gl->readback_buffer_screenshot = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void gl1_renderchain_free_internal(void *data, void *chain_data)
|
||||
{
|
||||
gl1_renderchain_t *chain = (gl1_renderchain_t*)chain_data;
|
||||
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
free(chain);
|
||||
}
|
||||
|
||||
static void *gl1_renderchain_new(void)
|
||||
{
|
||||
gl1_renderchain_t *renderchain = (gl1_renderchain_t*)
|
||||
calloc(1, sizeof(*renderchain));
|
||||
if (!renderchain)
|
||||
return NULL;
|
||||
|
||||
return renderchain;
|
||||
}
|
||||
|
||||
static void gl1_renderchain_ff_vertex(const void *data)
|
||||
{
|
||||
const struct video_coords *coords = (const struct video_coords*)data;
|
||||
/* Fall back to fixed function-style if needed and possible. */
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, coords->lut_tex_coord);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glVertexPointer(2, GL_FLOAT, 0, coords->vertex);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glColorPointer(4, GL_FLOAT, 0, coords->color);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, coords->tex_coord);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_ff_matrix(const void *data)
|
||||
{
|
||||
math_matrix_4x4 ident;
|
||||
const math_matrix_4x4 *mat = (const math_matrix_4x4*)data;
|
||||
|
||||
/* Fall back to fixed function-style if needed and possible. */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(mat->data);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
matrix_4x4_identity(ident);
|
||||
glLoadMatrixf(ident.data);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_disable_client_arrays(void *data,
|
||||
void *chain_data)
|
||||
{
|
||||
if (gl_query_core_context_in_use())
|
||||
return;
|
||||
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_restore_default_state(gl_t *gl,
|
||||
void *chain_data)
|
||||
{
|
||||
if (!gl)
|
||||
return;
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DITHER);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_copy_frame(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
const void *frame,
|
||||
unsigned width, unsigned height, unsigned pitch)
|
||||
{
|
||||
const GLvoid *data_buf = frame;
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, video_pixel_get_alignment(pitch));
|
||||
|
||||
if (gl->base_size == 2 && !gl->have_es2_compat)
|
||||
{
|
||||
/* Convert to 32-bit textures on desktop GL.
|
||||
*
|
||||
* It is *much* faster (order of magnitude on my setup)
|
||||
* to use a custom SIMD-optimized conversion routine
|
||||
* than letting GL do it. */
|
||||
video_frame_convert_rgb16_to_rgb32(
|
||||
&gl->scaler,
|
||||
gl->conv_buffer,
|
||||
frame,
|
||||
width,
|
||||
height,
|
||||
pitch);
|
||||
data_buf = gl->conv_buffer;
|
||||
}
|
||||
else
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / gl->base_size);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D,
|
||||
0, 0, 0, width, height, gl->texture_type,
|
||||
gl->texture_fmt, data_buf);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_readback(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
unsigned alignment,
|
||||
unsigned fmt, unsigned type,
|
||||
void *src)
|
||||
{
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, alignment);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
glReadPixels(gl->vp.x, gl->vp.y,
|
||||
gl->vp.width, gl->vp.height,
|
||||
(GLenum)fmt, (GLenum)type, (GLvoid*)src);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_set_mvp(void *data,
|
||||
void *chain_data,
|
||||
void *shader_data, const void *mat_data)
|
||||
{
|
||||
math_matrix_4x4 ident;
|
||||
const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data;
|
||||
|
||||
/* Fall back to fixed function-style if needed and possible. */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(mat->data);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
matrix_4x4_identity(ident);
|
||||
glLoadMatrixf(ident.data);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_set_coords(void *handle_data,
|
||||
void *chain_data,
|
||||
void *shader_data, const struct video_coords *coords)
|
||||
{
|
||||
/* Fall back to fixed function-style if needed and possible. */
|
||||
glClientActiveTexture(GL_TEXTURE1);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, coords->lut_tex_coord);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glClientActiveTexture(GL_TEXTURE0);
|
||||
glVertexPointer(2, GL_FLOAT, 0, coords->vertex);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glColorPointer(4, GL_FLOAT, 0, coords->color);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, coords->tex_coord);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
static void gl1_renderchain_render(
|
||||
gl_t *gl,
|
||||
void *chain_data,
|
||||
video_frame_info_t *video_info,
|
||||
uint64_t frame_count,
|
||||
const struct video_tex_info *tex_info,
|
||||
const struct video_tex_info *feedback_info)
|
||||
{
|
||||
/* TODO/FIXME - implement
|
||||
* check this commit out to see how it looked like way back when -
|
||||
*
|
||||
* https://github.com/libretro/RetroArch/commit/af7819e5cc1f7e413ff100575ed01ce00dfa1509
|
||||
* */
|
||||
}
|
||||
|
||||
gl_renderchain_driver_t gl1_renderchain = {
|
||||
gl1_renderchain_set_coords,
|
||||
gl1_renderchain_set_mvp,
|
||||
NULL, /* init_textures_reference */
|
||||
NULL, /* fence_iterate */
|
||||
NULL, /* fence_free */
|
||||
gl1_renderchain_readback,
|
||||
NULL, /* renderchain_init_pbo */
|
||||
NULL, /* renderchain_bind_pbo */
|
||||
NULL, /* renderchain_unbind_pbo */
|
||||
gl1_renderchain_copy_frame,
|
||||
gl1_renderchain_restore_default_state,
|
||||
NULL, /* new_vao */
|
||||
NULL, /* free_vao */
|
||||
NULL, /* bind_vao */
|
||||
NULL, /* unbind_vao */
|
||||
gl1_renderchain_disable_client_arrays, /* disable_client_arrays */
|
||||
gl1_renderchain_ff_vertex, /* ff_vertex */
|
||||
gl1_renderchain_ff_matrix,
|
||||
NULL, /* bind_backbuffer */
|
||||
NULL, /* deinit_fbo */
|
||||
gl1_renderchain_read_viewport,
|
||||
NULL, /* bind_prev_texture */
|
||||
gl1_renderchain_free_internal,
|
||||
gl1_renderchain_new,
|
||||
NULL, /* renderchain_init */
|
||||
NULL, /* init_hw_render */
|
||||
NULL, /* renderchain_free */
|
||||
NULL, /* deinit_hw_render */
|
||||
NULL, /* start_render */
|
||||
NULL, /* check_fbo_dimensions */
|
||||
NULL, /* recompute_pass_sizes */
|
||||
gl1_renderchain_render,
|
||||
NULL, /* resolve_extensions */
|
||||
"gl1",
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -293,6 +293,8 @@ bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||
|
||||
for (auto &line : lines)
|
||||
{
|
||||
const char *line_c = line.c_str();
|
||||
|
||||
if (line.find("#pragma name ") == 0)
|
||||
{
|
||||
const char *str = NULL;
|
||||
@ -303,7 +305,7 @@ bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||
return false;
|
||||
}
|
||||
|
||||
str = line.c_str() + strlen("#pragma name ");
|
||||
str = line_c + strlen("#pragma name ");
|
||||
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
@ -312,7 +314,7 @@ bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||
else if (line.find("#pragma parameter ") == 0)
|
||||
{
|
||||
float initial, minimum, maximum, step;
|
||||
int ret = sscanf(line.c_str(), "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
int ret = sscanf(line_c, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f",
|
||||
id, desc, &initial, &minimum, &maximum, &step);
|
||||
|
||||
if (ret == 5)
|
||||
@ -347,7 +349,7 @@ bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||
}
|
||||
else
|
||||
{
|
||||
RARCH_ERR("[slang]: Invalid #pragma parameter line: \"%s\".\n", line.c_str());
|
||||
RARCH_ERR("[slang]: Invalid #pragma parameter line: \"%s\".\n", line_c);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -361,7 +363,7 @@ bool glslang_parse_meta(const vector<string> &lines, glslang_meta *meta)
|
||||
return false;
|
||||
}
|
||||
|
||||
str = line.c_str() + strlen("#pragma format ");
|
||||
str = line_c + strlen("#pragma format ");
|
||||
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "../video_driver.h"
|
||||
#include "../video_shader_parse.h"
|
||||
#include "../../core.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../../managers/state_manager.h"
|
||||
|
||||
#define PREV_TEXTURES (GFX_MAX_TEXTURES - 1)
|
||||
@ -761,72 +762,6 @@ static bool gl_cg_load_shader(void *data, unsigned i)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_cg_add_lut(
|
||||
const struct video_shader *shader,
|
||||
unsigned i, void *textures_data)
|
||||
{
|
||||
struct texture_image img;
|
||||
GLuint *textures_lut = (GLuint*)textures_data;
|
||||
enum texture_filter_type filter_type = TEXTURE_FILTER_LINEAR;
|
||||
|
||||
img.width = 0;
|
||||
img.height = 0;
|
||||
img.pixels = NULL;
|
||||
img.supports_rgba = video_driver_supports_rgba();
|
||||
|
||||
if (!image_texture_load(&img, shader->lut[i].path))
|
||||
{
|
||||
RARCH_ERR("[GL]: Failed to load texture image from: \"%s\"\n",
|
||||
shader->lut[i].path);
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_LOG("[GL]: Loaded texture image from: \"%s\" ...\n",
|
||||
shader->lut[i].path);
|
||||
|
||||
if (shader->lut[i].filter == RARCH_FILTER_NEAREST)
|
||||
filter_type = TEXTURE_FILTER_NEAREST;
|
||||
|
||||
if (shader->lut[i].mipmap)
|
||||
{
|
||||
if (filter_type == TEXTURE_FILTER_NEAREST)
|
||||
filter_type = TEXTURE_FILTER_MIPMAP_NEAREST;
|
||||
else
|
||||
filter_type = TEXTURE_FILTER_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
gl_load_texture_data(textures_lut[i],
|
||||
shader->lut[i].wrap,
|
||||
filter_type, 4,
|
||||
img.width, img.height,
|
||||
img.pixels, sizeof(uint32_t));
|
||||
image_texture_free(&img);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_cg_load_luts(
|
||||
const struct video_shader *shader,
|
||||
GLuint *textures_lut)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned num_luts = MIN(shader->luts, GFX_MAX_TEXTURES);
|
||||
|
||||
if (!shader->luts)
|
||||
return true;
|
||||
|
||||
glGenTextures(num_luts, textures_lut);
|
||||
|
||||
for (i = 0; i < num_luts; i++)
|
||||
{
|
||||
if (!gl_cg_add_lut(shader, i, textures_lut))
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_cg_load_preset(void *data, const char *path)
|
||||
{
|
||||
unsigned i;
|
||||
@ -887,7 +822,7 @@ static bool gl_cg_load_preset(void *data, const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl_cg_load_luts(cg->shader, cg->lut_textures))
|
||||
if (!gl_load_luts(cg->shader, cg->lut_textures))
|
||||
{
|
||||
RARCH_ERR("Failed to load lookup textures ...\n");
|
||||
return false;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "shader_glsl.h"
|
||||
#include "../../managers/state_manager.h"
|
||||
#include "../../core.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define PREV_TEXTURES (GFX_MAX_TEXTURES - 1)
|
||||
|
||||
@ -158,72 +159,6 @@ static bool glsl_core;
|
||||
static unsigned glsl_major;
|
||||
static unsigned glsl_minor;
|
||||
|
||||
static bool gl_glsl_add_lut(
|
||||
const struct video_shader *shader,
|
||||
unsigned i, void *textures_data)
|
||||
{
|
||||
struct texture_image img;
|
||||
GLuint *textures_lut = (GLuint*)textures_data;
|
||||
enum texture_filter_type filter_type = TEXTURE_FILTER_LINEAR;
|
||||
|
||||
img.width = 0;
|
||||
img.height = 0;
|
||||
img.pixels = NULL;
|
||||
img.supports_rgba = video_driver_supports_rgba();
|
||||
|
||||
if (!image_texture_load(&img, shader->lut[i].path))
|
||||
{
|
||||
RARCH_ERR("[GL]: Failed to load texture image from: \"%s\"\n",
|
||||
shader->lut[i].path);
|
||||
return false;
|
||||
}
|
||||
|
||||
RARCH_LOG("[GL]: Loaded texture image from: \"%s\" ...\n",
|
||||
shader->lut[i].path);
|
||||
|
||||
if (shader->lut[i].filter == RARCH_FILTER_NEAREST)
|
||||
filter_type = TEXTURE_FILTER_NEAREST;
|
||||
|
||||
if (shader->lut[i].mipmap)
|
||||
{
|
||||
if (filter_type == TEXTURE_FILTER_NEAREST)
|
||||
filter_type = TEXTURE_FILTER_MIPMAP_NEAREST;
|
||||
else
|
||||
filter_type = TEXTURE_FILTER_MIPMAP_LINEAR;
|
||||
}
|
||||
|
||||
gl_load_texture_data(textures_lut[i],
|
||||
shader->lut[i].wrap,
|
||||
filter_type, 4,
|
||||
img.width, img.height,
|
||||
img.pixels, sizeof(uint32_t));
|
||||
image_texture_free(&img);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gl_glsl_load_luts(
|
||||
const struct video_shader *shader,
|
||||
GLuint *textures_lut)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned num_luts = MIN(shader->luts, GFX_MAX_TEXTURES);
|
||||
|
||||
if (!shader->luts)
|
||||
return true;
|
||||
|
||||
glGenTextures(num_luts, textures_lut);
|
||||
|
||||
for (i = 0; i < num_luts; i++)
|
||||
{
|
||||
if (!gl_glsl_add_lut(shader, i, textures_lut))
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLint gl_glsl_get_uniform(glsl_shader_data_t *glsl,
|
||||
GLuint prog, const char *base)
|
||||
{
|
||||
@ -1059,7 +994,7 @@ static void *gl_glsl_init(void *data, const char *path)
|
||||
if (!gl_glsl_compile_programs(glsl, &glsl->prg[1]))
|
||||
goto error;
|
||||
|
||||
if (!gl_glsl_load_luts(glsl->shader, glsl->lut_textures))
|
||||
if (!gl_load_luts(glsl->shader, glsl->lut_textures))
|
||||
{
|
||||
RARCH_ERR("[GL]: Failed to load LUTs.\n");
|
||||
goto error;
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <formats/image.h>
|
||||
@ -473,12 +472,12 @@ class Pass
|
||||
struct PushConstant
|
||||
{
|
||||
VkShaderStageFlags stages = 0;
|
||||
vector<uint32_t> buffer; // uint32_t to have correct alignment.
|
||||
vector<uint32_t> buffer; /* uint32_t to have correct alignment. */
|
||||
};
|
||||
PushConstant push;
|
||||
};
|
||||
|
||||
// struct here since we're implementing the opaque typedef from C.
|
||||
/* struct here since we're implementing the opaque typedef from C. */
|
||||
struct vulkan_filter_chain
|
||||
{
|
||||
public:
|
||||
@ -750,7 +749,8 @@ bool vulkan_filter_chain::init_history()
|
||||
return true;
|
||||
}
|
||||
|
||||
// We don't need to store array element #0, since it's aliased with the actual original.
|
||||
/* We don't need to store array element #0,
|
||||
* since it's aliased with the actual original. */
|
||||
required_images--;
|
||||
original_history.reserve(required_images);
|
||||
common.original_history.resize(required_images);
|
||||
@ -763,8 +763,10 @@ bool vulkan_filter_chain::init_history()
|
||||
|
||||
RARCH_LOG("[Vulkan filter chain]: Using history of %u frames.\n", required_images);
|
||||
|
||||
// On first frame, we need to clear the textures to a known state, but we need
|
||||
// a command buffer for that, so just defer to first frame.
|
||||
/* On first frame, we need to clear the textures to
|
||||
* a known state, but we need
|
||||
* a command buffer for that, so just defer to first frame.
|
||||
*/
|
||||
require_clear = true;
|
||||
return true;
|
||||
}
|
||||
@ -775,7 +777,7 @@ bool vulkan_filter_chain::init_feedback()
|
||||
|
||||
bool use_feedbacks = false;
|
||||
|
||||
// Final pass cannot have feedback.
|
||||
/* Final pass cannot have feedback. */
|
||||
for (unsigned i = 0; i < passes.size() - 1; i++)
|
||||
{
|
||||
bool use_feedback = false;
|
||||
@ -879,7 +881,7 @@ bool vulkan_filter_chain::init_ubo()
|
||||
vkGetPhysicalDeviceProperties(gpu, &props);
|
||||
common.ubo_alignment = props.limits.minUniformBufferOffsetAlignment;
|
||||
|
||||
// Who knows. :)
|
||||
/* Who knows. :) */
|
||||
if (common.ubo_alignment == 0)
|
||||
common.ubo_alignment = 1;
|
||||
|
||||
@ -948,7 +950,7 @@ void vulkan_filter_chain::clear_history_and_feedback(VkCommandBuffer cmd)
|
||||
void vulkan_filter_chain::build_offscreen_passes(VkCommandBuffer cmd,
|
||||
const VkViewport &vp)
|
||||
{
|
||||
// First frame, make sure our history and feedback textures are in a clean state.
|
||||
/* First frame, make sure our history and feedback textures are in a clean state. */
|
||||
if (require_clear)
|
||||
{
|
||||
clear_history_and_feedback(cmd);
|
||||
@ -991,7 +993,7 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu
|
||||
{
|
||||
VkImageLayout src_layout = input_texture.layout;
|
||||
|
||||
// Transition input texture to something appropriate.
|
||||
/* Transition input texture to something appropriate. */
|
||||
if (input_texture.layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
vulkan_image_layout_transition_levels(cmd,
|
||||
@ -1019,7 +1021,7 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu
|
||||
|
||||
tmp->copy(cmd, input_texture.image, src_layout);
|
||||
|
||||
// Transition input texture back.
|
||||
/* Transition input texture back. */
|
||||
if (input_texture.layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
vulkan_image_layout_transition_levels(cmd,
|
||||
@ -1032,16 +1034,17 @@ void vulkan_filter_chain::update_history(DeferredDisposer &disposer, VkCommandBu
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
}
|
||||
|
||||
// Should ring buffer, but we don't have *that* many passes.
|
||||
/* Should ring buffer, but we don't have *that* many passes. */
|
||||
move_backward(begin(original_history), end(original_history) - 1, end(original_history));
|
||||
swap(original_history.front(), tmp);
|
||||
}
|
||||
|
||||
void vulkan_filter_chain::end_frame(VkCommandBuffer cmd)
|
||||
{
|
||||
// If we need to keep old frames, copy it after fragment is complete.
|
||||
// TODO: We can improve pipelining by figuring out which pass is the last that reads from
|
||||
// the history and dispatch the copy earlier.
|
||||
/* If we need to keep old frames, copy it after fragment is complete.
|
||||
* TODO: We can improve pipelining by figuring out which
|
||||
* pass is the last that reads from
|
||||
* the history and dispatch the copy earlier. */
|
||||
if (!original_history.empty())
|
||||
{
|
||||
DeferredDisposer disposer(deferred_calls[current_sync_index]);
|
||||
@ -1052,7 +1055,7 @@ void vulkan_filter_chain::end_frame(VkCommandBuffer cmd)
|
||||
void vulkan_filter_chain::build_viewport_pass(
|
||||
VkCommandBuffer cmd, const VkViewport &vp, const float *mvp)
|
||||
{
|
||||
// First frame, make sure our history and feedback textures are in a clean state.
|
||||
/* First frame, make sure our history and feedback textures are in a clean state. */
|
||||
if (require_clear)
|
||||
{
|
||||
clear_history_and_feedback(cmd);
|
||||
@ -1092,7 +1095,7 @@ void vulkan_filter_chain::build_viewport_pass(
|
||||
passes.back()->build_commands(disposer, cmd,
|
||||
original, source, vp, mvp);
|
||||
|
||||
// For feedback FBOs, swap current and previous.
|
||||
/* For feedback FBOs, swap current and previous. */
|
||||
for (auto &pass : passes)
|
||||
pass->end_frame();
|
||||
}
|
||||
@ -1308,7 +1311,7 @@ bool Pass::init_pipeline_layout()
|
||||
vector<VkDescriptorSetLayoutBinding> bindings;
|
||||
vector<VkDescriptorPoolSize> desc_counts;
|
||||
|
||||
// Main UBO.
|
||||
/* Main UBO. */
|
||||
VkShaderStageFlags ubo_mask = 0;
|
||||
if (reflection.ubo_stage_mask & SLANG_STAGE_VERTEX_MASK)
|
||||
ubo_mask |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
@ -1323,7 +1326,7 @@ bool Pass::init_pipeline_layout()
|
||||
desc_counts.push_back({ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, num_sync_indices });
|
||||
}
|
||||
|
||||
// Semantic textures.
|
||||
/* Semantic textures. */
|
||||
for (auto &semantic : reflection.semantic_textures)
|
||||
{
|
||||
for (auto &texture : semantic)
|
||||
@ -1358,7 +1361,7 @@ bool Pass::init_pipeline_layout()
|
||||
layout_info.setLayoutCount = 1;
|
||||
layout_info.pSetLayouts = &set_layout;
|
||||
|
||||
// Push constants
|
||||
/* Push constants */
|
||||
VkPushConstantRange push_range = {};
|
||||
if (reflection.push_constant_stage_mask && reflection.push_constant_size)
|
||||
{
|
||||
@ -1408,12 +1411,12 @@ bool Pass::init_pipeline()
|
||||
if (!init_pipeline_layout())
|
||||
return false;
|
||||
|
||||
// Input assembly
|
||||
/* Input assembly */
|
||||
VkPipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
|
||||
// VAO state
|
||||
/* VAO state */
|
||||
VkVertexInputAttributeDescription attributes[2] = {{0}};
|
||||
VkVertexInputBindingDescription binding = {0};
|
||||
|
||||
@ -1437,7 +1440,7 @@ bool Pass::init_pipeline()
|
||||
vertex_input.vertexAttributeDescriptionCount = 2;
|
||||
vertex_input.pVertexAttributeDescriptions = attributes;
|
||||
|
||||
// Raster state
|
||||
/* Raster state */
|
||||
VkPipelineRasterizationStateCreateInfo raster = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
raster.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
@ -1448,7 +1451,7 @@ bool Pass::init_pipeline()
|
||||
raster.depthBiasEnable = false;
|
||||
raster.lineWidth = 1.0f;
|
||||
|
||||
// Blend state
|
||||
/* Blend state */
|
||||
VkPipelineColorBlendAttachmentState blend_attachment = {0};
|
||||
VkPipelineColorBlendStateCreateInfo blend = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
|
||||
@ -1457,13 +1460,13 @@ bool Pass::init_pipeline()
|
||||
blend.attachmentCount = 1;
|
||||
blend.pAttachments = &blend_attachment;
|
||||
|
||||
// Viewport state
|
||||
/* Viewport state */
|
||||
VkPipelineViewportStateCreateInfo viewport = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
|
||||
viewport.viewportCount = 1;
|
||||
viewport.scissorCount = 1;
|
||||
|
||||
// Depth-stencil state
|
||||
/* Depth-stencil state */
|
||||
VkPipelineDepthStencilStateCreateInfo depth_stencil = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
depth_stencil.depthTestEnable = false;
|
||||
@ -1473,12 +1476,12 @@ bool Pass::init_pipeline()
|
||||
depth_stencil.minDepthBounds = 0.0f;
|
||||
depth_stencil.maxDepthBounds = 1.0f;
|
||||
|
||||
// Multisample state
|
||||
/* Multisample state */
|
||||
VkPipelineMultisampleStateCreateInfo multisample = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
|
||||
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
// Dynamic state
|
||||
/* Dynamic state */
|
||||
VkPipelineDynamicStateCreateInfo dynamic = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||
static const VkDynamicState dynamics[] = {
|
||||
@ -1486,7 +1489,7 @@ bool Pass::init_pipeline()
|
||||
dynamic.pDynamicStates = dynamics;
|
||||
dynamic.dynamicStateCount = sizeof(dynamics) / sizeof(dynamics[0]);
|
||||
|
||||
// Shaders
|
||||
/* Shaders */
|
||||
VkPipelineShaderStageCreateInfo shader_stages[2] = {
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
{ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO },
|
||||
@ -1539,16 +1542,18 @@ CommonResources::CommonResources(VkDevice device,
|
||||
const VkPhysicalDeviceMemoryProperties &memory_properties)
|
||||
: device(device)
|
||||
{
|
||||
// The final pass uses an MVP designed for [0, 1] range VBO.
|
||||
// For in-between passes, we just go with identity matrices, so keep it simple.
|
||||
/* The final pass uses an MVP designed for [0, 1] range VBO.
|
||||
* For in-between passes, we just go with identity matrices,
|
||||
* so keep it simple.
|
||||
*/
|
||||
const float vbo_data[] = {
|
||||
// Offscreen
|
||||
/* Offscreen */
|
||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
||||
-1.0f, +1.0f, 0.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f, 0.0f,
|
||||
1.0f, +1.0f, 1.0f, 1.0f,
|
||||
|
||||
// Final
|
||||
/* Final */
|
||||
0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, +1.0f, 0.0f, 1.0f,
|
||||
1.0f, 0.0f, 1.0f, 0.0f,
|
||||
@ -1657,12 +1662,12 @@ void Pass::allocate_buffers()
|
||||
{
|
||||
if (reflection.ubo_stage_mask)
|
||||
{
|
||||
// Align
|
||||
/* Align */
|
||||
common->ubo_offset = (common->ubo_offset + common->ubo_alignment - 1) &
|
||||
~(common->ubo_alignment - 1);
|
||||
ubo_offset = common->ubo_offset;
|
||||
|
||||
// Allocate
|
||||
/* Allocate */
|
||||
common->ubo_offset += reflection.ubo_size;
|
||||
}
|
||||
}
|
||||
@ -1719,7 +1724,7 @@ bool Pass::build()
|
||||
if (!slang_reflect_spirv(vertex_shader, fragment_shader, &reflection))
|
||||
return false;
|
||||
|
||||
// Filter out parameters which we will never use anyways.
|
||||
/* Filter out parameters which we will never use anyways. */
|
||||
filtered_parameters.clear();
|
||||
|
||||
for (i = 0; i < reflection.semantic_float_parameters.size(); i++)
|
||||
@ -1837,7 +1842,7 @@ void Pass::build_semantic_parameter(uint8_t *data, unsigned index, float value)
|
||||
{
|
||||
auto &refl = reflection.semantic_float_parameters[index];
|
||||
|
||||
// We will have filtered out stale parameters.
|
||||
/* We will have filtered out stale parameters. */
|
||||
if (data && refl.uniform)
|
||||
*reinterpret_cast<float*>(data + refl.ubo_offset) = value;
|
||||
|
||||
@ -1876,7 +1881,7 @@ void Pass::build_semantic_texture_array(VkDescriptorSet set, uint8_t *buffer,
|
||||
void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
const float *mvp, const Texture &original, const Texture &source)
|
||||
{
|
||||
// MVP
|
||||
/* MVP */
|
||||
if (buffer && reflection.semantics[SLANG_SEMANTIC_MVP].uniform)
|
||||
{
|
||||
size_t offset = reflection.semantics[SLANG_SEMANTIC_MVP].ubo_offset;
|
||||
@ -1895,7 +1900,7 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
build_identity_matrix(reinterpret_cast<float *>(push.buffer.data() + (offset >> 2)));
|
||||
}
|
||||
|
||||
// Output information
|
||||
/* Output information */
|
||||
build_semantic_vec4(buffer, SLANG_SEMANTIC_OUTPUT,
|
||||
current_framebuffer_size.width, current_framebuffer_size.height);
|
||||
build_semantic_vec4(buffer, SLANG_SEMANTIC_FINAL_VIEWPORT,
|
||||
@ -1904,21 +1909,21 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
build_semantic_uint(buffer, SLANG_SEMANTIC_FRAME_COUNT,
|
||||
frame_count_period ? uint32_t(frame_count % frame_count_period) : uint32_t(frame_count));
|
||||
|
||||
// Standard inputs
|
||||
/* Standard inputs */
|
||||
build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL, original);
|
||||
build_semantic_texture(set, buffer, SLANG_TEXTURE_SEMANTIC_SOURCE, source);
|
||||
|
||||
// ORIGINAL_HISTORY[0] is an alias of ORIGINAL.
|
||||
/* ORIGINAL_HISTORY[0] is an alias of ORIGINAL. */
|
||||
build_semantic_texture_array(set, buffer, SLANG_TEXTURE_SEMANTIC_ORIGINAL_HISTORY, 0, original);
|
||||
|
||||
// Parameters.
|
||||
/* Parameters. */
|
||||
for (auto ¶m : filtered_parameters)
|
||||
{
|
||||
float value = common->shader_preset->parameters[param.index].current;
|
||||
build_semantic_parameter(buffer, param.semantic_index, value);
|
||||
}
|
||||
|
||||
// Previous inputs.
|
||||
/* Previous inputs. */
|
||||
unsigned i = 0;
|
||||
for (auto &texture : common->original_history)
|
||||
{
|
||||
@ -1928,7 +1933,7 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
i++;
|
||||
}
|
||||
|
||||
// Previous passes.
|
||||
/* Previous passes. */
|
||||
i = 0;
|
||||
for (auto &texture : common->pass_outputs)
|
||||
{
|
||||
@ -1938,7 +1943,7 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
i++;
|
||||
}
|
||||
|
||||
// Feedback FBOs.
|
||||
/* Feedback FBOs. */
|
||||
i = 0;
|
||||
for (auto &texture : common->framebuffer_feedback)
|
||||
{
|
||||
@ -1948,7 +1953,7 @@ void Pass::build_semantics(VkDescriptorSet set, uint8_t *buffer,
|
||||
i++;
|
||||
}
|
||||
|
||||
// LUTs.
|
||||
/* LUTs. */
|
||||
i = 0;
|
||||
for (auto &lut : common->luts)
|
||||
{
|
||||
@ -1997,10 +2002,10 @@ void Pass::build_commands(
|
||||
reflection.ubo_size);
|
||||
}
|
||||
|
||||
// The final pass is always executed inside
|
||||
// another render pass since the frontend will
|
||||
// want to overlay various things on top for
|
||||
// the passes that end up on-screen.
|
||||
/* The final pass is always executed inside
|
||||
* another render pass since the frontend will
|
||||
* want to overlay various things on top for
|
||||
* the passes that end up on-screen. */
|
||||
if (!final_pass)
|
||||
{
|
||||
/* Render. */
|
||||
@ -2086,7 +2091,7 @@ void Pass::build_commands(
|
||||
framebuffer->generate_mips(cmd);
|
||||
else
|
||||
{
|
||||
// Barrier to sync with next pass.
|
||||
/* Barrier to sync with next pass. */
|
||||
vulkan_image_layout_transition_levels(
|
||||
cmd,
|
||||
framebuffer->get_image(),VK_REMAINING_MIP_LEVELS,
|
||||
@ -2148,19 +2153,20 @@ void Framebuffer::clear(VkCommandBuffer cmd)
|
||||
void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
{
|
||||
unsigned i;
|
||||
// This is run every frame, so make sure
|
||||
// we aren't opting into the "lazy" way of doing this. :)
|
||||
/* This is run every frame, so make sure
|
||||
* we aren't opting into the "lazy" way of doing this. :) */
|
||||
VkImageMemoryBarrier barriers[2] = {
|
||||
{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER },
|
||||
{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER },
|
||||
};
|
||||
|
||||
// First, transfer the input mip level to TRANSFER_SRC_OPTIMAL.
|
||||
// This should allow the surface to stay compressed.
|
||||
// All subsequent mip-layers are now transferred into DST_OPTIMAL from
|
||||
// UNDEFINED at this point.
|
||||
/* First, transfer the input mip level to TRANSFER_SRC_OPTIMAL.
|
||||
* This should allow the surface to stay compressed.
|
||||
* All subsequent mip-layers are now transferred into DST_OPTIMAL from
|
||||
* UNDEFINED at this point.
|
||||
*/
|
||||
|
||||
// Input
|
||||
/* Input */
|
||||
barriers[0].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
barriers[0].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barriers[0].oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
@ -2173,7 +2179,7 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
barriers[0].subresourceRange.levelCount = 1;
|
||||
barriers[0].subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
|
||||
|
||||
// The rest of the mip chain
|
||||
/* The rest of the mip chain */
|
||||
barriers[1].srcAccessMask = 0;
|
||||
barriers[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barriers[1].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
@ -2196,8 +2202,9 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
|
||||
for (i = 1; i < levels; i++)
|
||||
{
|
||||
// For subsequent passes, we have to transition from DST_OPTIMAL to SRC_OPTIMAL,
|
||||
// but only do so one mip-level at a time.
|
||||
/* For subsequent passes, we have to transition
|
||||
* from DST_OPTIMAL to SRC_OPTIMAL,
|
||||
* but only do so one mip-level at a time. */
|
||||
if (i > 1)
|
||||
{
|
||||
barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
@ -2241,10 +2248,15 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
1, &blit_region, VK_FILTER_LINEAR);
|
||||
}
|
||||
|
||||
// We are now done, and we have all mip-levels except the last in TRANSFER_SRC_OPTIMAL,
|
||||
// and the last one still on TRANSFER_DST_OPTIMAL, so do a final barrier which
|
||||
// moves everything to SHADER_READ_ONLY_OPTIMAL in one go along with the execution barrier to next pass.
|
||||
// Read-to-read memory barrier, so only need execution barrier for first transition.
|
||||
/* We are now done, and we have all mip-levels except
|
||||
* the last in TRANSFER_SRC_OPTIMAL,
|
||||
* and the last one still on TRANSFER_DST_OPTIMAL,
|
||||
* so do a final barrier which
|
||||
* moves everything to SHADER_READ_ONLY_OPTIMAL in
|
||||
* one go along with the execution barrier to next pass.
|
||||
* Read-to-read memory barrier, so only need execution
|
||||
* barrier for first transition.
|
||||
*/
|
||||
barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
||||
barriers[0].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
barriers[0].subresourceRange.baseMipLevel = 0;
|
||||
@ -2252,7 +2264,7 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
barriers[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
barriers[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
// This is read-after-write barrier.
|
||||
/* This is read-after-write barrier. */
|
||||
barriers[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
barriers[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
||||
barriers[1].subresourceRange.baseMipLevel = levels - 1;
|
||||
@ -2268,8 +2280,10 @@ void Framebuffer::generate_mips(VkCommandBuffer cmd)
|
||||
0, nullptr,
|
||||
2, barriers);
|
||||
|
||||
// Next pass will wait for ALL_GRAPHICS_BIT, and since we have dstStage as FRAGMENT_SHADER,
|
||||
// the dependency chain will ensure we don't start next pass until the mipchain is complete.
|
||||
/* Next pass will wait for ALL_GRAPHICS_BIT, and since
|
||||
* we have dstStage as FRAGMENT_SHADER,
|
||||
* the dependency chain will ensure we don't start
|
||||
* next pass until the mipchain is complete. */
|
||||
}
|
||||
|
||||
void Framebuffer::copy(VkCommandBuffer cmd,
|
||||
@ -2336,11 +2350,12 @@ void Framebuffer::init(DeferredDisposer *disposer)
|
||||
memory_properties, mem_reqs.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
|
||||
|
||||
// Can reuse already allocated memory.
|
||||
/* Can reuse already allocated memory. */
|
||||
if (memory.size < mem_reqs.size || memory.type != alloc.memoryTypeIndex)
|
||||
{
|
||||
// Memory might still be in use since we don't want to totally stall
|
||||
// the world for framebuffer recreation.
|
||||
/* Memory might still be in use since we don't want
|
||||
* to totally stall
|
||||
* the world for framebuffer recreation. */
|
||||
if (memory.memory != VK_NULL_HANDLE && disposer)
|
||||
{
|
||||
auto d = device;
|
||||
@ -2385,8 +2400,8 @@ void Framebuffer::init_render_pass()
|
||||
VkAttachmentReference color_ref = { 0,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
|
||||
|
||||
// We will always write to the entire framebuffer,
|
||||
// so we don't really need to clear.
|
||||
/* We will always write to the entire framebuffer,
|
||||
* so we don't really need to clear. */
|
||||
VkAttachmentDescription attachment = {0};
|
||||
attachment.format = format;
|
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
@ -2435,13 +2450,13 @@ void Framebuffer::set_size(DeferredDisposer &disposer, const Size2D &size, VkFor
|
||||
size.width, size.height, (unsigned)this->format);
|
||||
|
||||
{
|
||||
// The current framebuffers, etc, might still be in use
|
||||
// so defer deletion.
|
||||
// We'll most likely be able to reuse the memory,
|
||||
// so don't free it here.
|
||||
//
|
||||
// Fake lambda init captures for C++11.
|
||||
//
|
||||
/* The current framebuffers, etc, might still be in use
|
||||
* so defer deletion.
|
||||
* We'll most likely be able to reuse the memory,
|
||||
* so don't free it here.
|
||||
*
|
||||
* Fake lambda init captures for C++11.
|
||||
*/
|
||||
auto d = device;
|
||||
auto i = image;
|
||||
auto v = view;
|
||||
@ -2479,7 +2494,7 @@ Framebuffer::~Framebuffer()
|
||||
vkFreeMemory(device, memory.memory, nullptr);
|
||||
}
|
||||
|
||||
// C glue
|
||||
/* C glue */
|
||||
vulkan_filter_chain_t *vulkan_filter_chain_new(
|
||||
const vulkan_filter_chain_create_info *info)
|
||||
{
|
||||
@ -2871,7 +2886,8 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||
|
||||
if (itr != shader->parameters + shader->num_parameters)
|
||||
{
|
||||
// Allow duplicate #pragma parameter, but only if they are exactly the same.
|
||||
/* Allow duplicate #pragma parameter, but
|
||||
* only if they are exactly the same. */
|
||||
if (meta_param.desc != itr->desc ||
|
||||
meta_param.initial != itr->initial ||
|
||||
meta_param.minimum != itr->minimum ||
|
||||
@ -2914,7 +2930,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||
if (!output.meta.name.empty())
|
||||
chain->set_pass_name(i, output.meta.name.c_str());
|
||||
|
||||
// Preset overrides.
|
||||
/* Preset overrides. */
|
||||
if (*pass->alias)
|
||||
chain->set_pass_name(i, pass->alias);
|
||||
|
||||
@ -2929,9 +2945,10 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||
pass_info.address = wrap_to_address(pass->wrap);
|
||||
pass_info.max_levels = 1;
|
||||
|
||||
// TODO: Expose max_levels in slangp.
|
||||
// CGP format is a bit awkward in that it uses mipmap_input,
|
||||
// so we much check if next pass needs the mipmapping.
|
||||
/* TODO: Expose max_levels in slangp.
|
||||
* CGP format is a bit awkward in that it uses mipmap_input,
|
||||
* so we much check if next pass needs the mipmapping.
|
||||
*/
|
||||
if (next_pass && next_pass->mipmap)
|
||||
pass_info.max_levels = ~0u;
|
||||
|
||||
@ -2940,7 +2957,7 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||
|
||||
bool explicit_format = output.meta.rt_format != SLANG_FORMAT_UNKNOWN;
|
||||
|
||||
// Set a reasonable default.
|
||||
/* Set a reasonable default. */
|
||||
if (output.meta.rt_format == SLANG_FORMAT_UNKNOWN)
|
||||
output.meta.rt_format = SLANG_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
@ -2972,13 +2989,12 @@ vulkan_filter_chain_t *vulkan_filter_chain_create_from_preset(
|
||||
}
|
||||
else
|
||||
{
|
||||
// Preset overrides shader.
|
||||
// Kinda ugly ...
|
||||
/* Preset overrides shader.
|
||||
* Kinda ugly ... */
|
||||
if (pass->fbo.srgb_fbo)
|
||||
output.meta.rt_format = SLANG_FORMAT_R8G8B8A8_SRGB;
|
||||
else if (pass->fbo.fp_fbo)
|
||||
output.meta.rt_format = SLANG_FORMAT_R16G16B16A16_SFLOAT;
|
||||
///
|
||||
|
||||
pass_info.rt_format = glslang_format_to_vk(output.meta.rt_format);
|
||||
RARCH_LOG("[slang]: Using render target format %s for pass output #%u.\n",
|
||||
|
@ -1,4 +1,18 @@
|
||||
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2017 - Hans-Kristian Arntzen
|
||||
*
|
||||
* 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 <fstream>
|
||||
#include <iostream>
|
||||
#include <spirv_glsl.hpp>
|
||||
|
@ -103,7 +103,11 @@
|
||||
|
||||
#ifndef CGGL_NO_OPENGL
|
||||
# ifdef __APPLE__
|
||||
#if MAC_OS_X_VERSION_10_7
|
||||
# include <OpenGL/gl3.h>
|
||||
#else
|
||||
# include <OpenGL/gl.h>
|
||||
#endif
|
||||
# else
|
||||
# include <GL/gl.h>
|
||||
# endif
|
||||
|
32
gfx/include/userland/.gitignore
vendored
Normal file
32
gfx/include/userland/.gitignore
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# Build directory
|
||||
build/
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
|
||||
*.raw
|
||||
*.rgb
|
||||
*.bgr
|
||||
*.h264
|
||||
*.264
|
||||
*.yuyv
|
||||
*.uyvy
|
||||
*.yvyu
|
||||
*.vyuy
|
||||
*.i420
|
||||
*.yuv
|
||||
*.jpg
|
||||
*.avi
|
||||
*.pts
|
||||
*.ppm
|
||||
*.mkv
|
132
gfx/include/userland/CMakeLists.txt
Normal file
132
gfx/include/userland/CMakeLists.txt
Normal file
@ -0,0 +1,132 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(vmcs_host_apps)
|
||||
|
||||
SET(PROJECT_VER_MAJOR 1)
|
||||
SET(PROJECT_VER_MINOR 0)
|
||||
SET(PROJECT_VER_PATCH 0)
|
||||
SET(PROJECT_VER "${PROJECT_VER_MAJOR}.${PROJECT_VER_MINOR}.${PROJECT_VER_PATCH}")
|
||||
SET(PROJECT_APIVER "${PROJECT_VER}")
|
||||
|
||||
if(ARM64)
|
||||
set(BUILD_MMAL FALSE)
|
||||
set(BUILD_MMAL_APPS FALSE)
|
||||
else()
|
||||
set(BUILD_MMAL TRUE)
|
||||
set(BUILD_MMAL_APPS TRUE)
|
||||
endif()
|
||||
set(vmcs_root ${PROJECT_SOURCE_DIR})
|
||||
get_filename_component(VIDEOCORE_ROOT . ABSOLUTE)
|
||||
|
||||
set(VCOS_PTHREADS_BUILD_SHARED TRUE)
|
||||
|
||||
include(makefiles/cmake/global_settings.cmake)
|
||||
include(makefiles/cmake/arm-linux.cmake)
|
||||
include(makefiles/cmake/vmcs.cmake)
|
||||
|
||||
enable_language(ASM)
|
||||
|
||||
# Global include paths
|
||||
include_directories(host_applications/framework)
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
include_directories(interface/vcos/pthreads)
|
||||
include_directories(interface/vmcs_host/linux)
|
||||
include_directories(interface/vmcs_host)
|
||||
include_directories(interface/vmcs_host/khronos)
|
||||
include_directories(interface/khronos/include)
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
include_directories(interface/vchiq_arm)
|
||||
#include_directories(tools/inet_transport)
|
||||
include_directories(host_support/include)
|
||||
|
||||
# Global compiler flags
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar -Wall -Wno-unused-but-set-variable -fPIC")
|
||||
endif()
|
||||
|
||||
add_definitions(-D_REENTRANT)
|
||||
add_definitions(-DUSE_VCHIQ_ARM -DVCHI_BULK_ALIGN=1 -DVCHI_BULK_GRANULARITY=1)
|
||||
add_definitions(-DOMX_SKIP64BIT)
|
||||
add_definitions(-DEGL_SERVER_DISPMANX)
|
||||
add_definitions(-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
|
||||
# do we actually need this?
|
||||
add_definitions(-D__VIDEOCORE4__)
|
||||
add_definitions(-DTV_SUPPORTED_MODE_NO_DEPRECATED)
|
||||
|
||||
# add_definitions(-DKHRONOS_CLIENT_LOGGING)
|
||||
|
||||
# Check for OpenWF-C value set via command line
|
||||
if(KHRONOS_EGL_PLATFORM MATCHES "openwfc")
|
||||
add_definitions(-DKHRONOS_EGL_PLATFORM_OPENWFC)
|
||||
endif()
|
||||
|
||||
# List of subsidiary CMakeLists
|
||||
add_subdirectory(interface/vcos)
|
||||
add_subdirectory(interface/vmcs_host)
|
||||
add_subdirectory(interface/vchiq_arm)
|
||||
if(NOT ARM64)
|
||||
add_subdirectory(interface/khronos)
|
||||
endif()
|
||||
|
||||
#add_subdirectory(opensrc/tools/lua)
|
||||
if(BUILD_MMAL)
|
||||
include_directories(interface/mmal)
|
||||
add_subdirectory(interface/mmal)
|
||||
add_subdirectory(containers)
|
||||
endif()
|
||||
|
||||
# VidTex supports Android and Linux
|
||||
if(BUILD_MMAL_APPS)
|
||||
add_subdirectory(host_applications/android/apps/vidtex)
|
||||
endif(BUILD_MMAL_APPS)
|
||||
|
||||
if(NOT ARM64)
|
||||
add_subdirectory(middleware/openmaxil)
|
||||
endif()
|
||||
|
||||
# 3d demo code
|
||||
#if(NOT ANDROID)
|
||||
# add_subdirectory(thirdparty/applications/demos)
|
||||
# add_subdirectory(opensrc/applications/demos)
|
||||
#endif()
|
||||
|
||||
#if(ENABLE_3D_TESTS)
|
||||
# add_subdirectory(thirdparty/applications/test)
|
||||
#endif()
|
||||
|
||||
# FIXME: we should use a pre-packaged version of freetype
|
||||
# rather than the one included in the repo.
|
||||
#add_subdirectory(opensrc/helpers/freetype)
|
||||
#add_subdirectory(${PROJECT_SOURCE_DIR}/opensrc/helpers/fonts/ttf-bitstream-vera)
|
||||
|
||||
# VMCS Host Applications
|
||||
#add_subdirectory(host_applications/framework)
|
||||
|
||||
# add_subdirectory(interface/vchiq/test/win32)
|
||||
|
||||
# Apps and libraries supporting Camera Tuning Tool
|
||||
#add_subdirectory(tools/inet_transport/linux)
|
||||
#add_subdirectory(host_support/vcstandalone)
|
||||
|
||||
# add linux apps
|
||||
add_subdirectory(host_applications/linux)
|
||||
add_subdirectory(opensrc/helpers/libfdt)
|
||||
add_subdirectory(helpers/dtoverlay)
|
||||
|
||||
set(vmcs_host_apps_VERSION_MAJOR 1)
|
||||
set(vmcs_host_apps_VERSION_MINOR 0)
|
||||
|
||||
include_directories("${PROJECT_BINARY_DIR}")
|
||||
include(FindPkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
# Produce a pkg-config file
|
||||
foreach(PCFILE bcm_host.pc egl.pc glesv2.pc vg.pc brcmegl.pc brcmglesv2.pc brcmvg.pc vcsm.pc mmal.pc )
|
||||
configure_file("pkgconfig/${PCFILE}.in" "${PCFILE}" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PCFILE}"
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
|
||||
endforeach()
|
||||
endif()
|
||||
# Remove cache entry, if one added by command line
|
||||
unset(KHRONOS_EGL_PLATFORM CACHE)
|
26
gfx/include/userland/LICENCE
Normal file
26
gfx/include/userland/LICENCE
Normal file
@ -0,0 +1,26 @@
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
Copyright (c) 2015, Raspberry Pi (Trading) Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
8
gfx/include/userland/README.md
Normal file
8
gfx/include/userland/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
This repository contains the source code for the ARM side libraries used on Raspberry Pi.
|
||||
These typically are installed in /opt/vc/lib and includes source for the ARM side code to interface to:
|
||||
EGL, mmal, GLESv2, vcos, openmaxil, vchiq_arm, bcm_host, WFC, OpenVG.
|
||||
|
||||
Use buildme to build. It requires cmake to be installed and an arm cross compiler. It is set up to use this one:
|
||||
https://github.com/raspberrypi/tools/tree/master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian
|
||||
|
||||
Note that this repository does not contain the source for the edidparser and vcdbg binaries due to licensing restrictions.
|
44
gfx/include/userland/buildme
Normal file
44
gfx/include/userland/buildme
Normal file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
BUILDTYPE=Release
|
||||
|
||||
if [ "$1" = "--debug" ]; then
|
||||
BUILDTYPE=Debug
|
||||
shift
|
||||
fi
|
||||
|
||||
BUILDSUBDIR=`echo $BUILDTYPE | tr '[A-Z]' '[a-z]'`;
|
||||
|
||||
if [ "armv6l" = `arch` ] || [ "armv7l" = `arch` ]; then
|
||||
# Native compile on the Raspberry Pi
|
||||
mkdir -p build/raspberry/$BUILDSUBDIR
|
||||
pushd build/raspberry/$BUILDSUBDIR
|
||||
cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../..
|
||||
if [ "armv6l" = `arch` ]; then
|
||||
make
|
||||
else
|
||||
make -j4
|
||||
fi
|
||||
if [ "$1" != "" ]; then
|
||||
sudo make install DESTDIR=$1
|
||||
else
|
||||
sudo make install
|
||||
fi
|
||||
elif [ "$1" = "--native" ]; then
|
||||
# Build natively on the host
|
||||
mkdir -p build/native/$BUILDSUBDIR
|
||||
pushd build/native/$BUILDSUBDIR
|
||||
cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../..
|
||||
shift
|
||||
make -j `nproc` $*
|
||||
else
|
||||
# Cross compile on a more capable machine
|
||||
mkdir -p build/arm-linux/$BUILDSUBDIR
|
||||
pushd build/arm-linux/$BUILDSUBDIR
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../../makefiles/cmake/toolchains/arm-linux-gnueabihf.cmake -DCMAKE_BUILD_TYPE=$BUILDTYPE ../../..
|
||||
make -j `nproc`
|
||||
|
||||
if [ "$1" != "" ]; then
|
||||
sudo make install DESTDIR=$1
|
||||
fi
|
||||
fi
|
||||
popd
|
124
gfx/include/userland/containers/CMakeLists.txt
Normal file
124
gfx/include/userland/containers/CMakeLists.txt
Normal file
@ -0,0 +1,124 @@
|
||||
SET( SOURCE_DIR . )
|
||||
|
||||
# We support building both static and shared libraries
|
||||
if (NOT DEFINED LIBRARY_TYPE)
|
||||
set(LIBRARY_TYPE SHARED)
|
||||
endif (NOT DEFINED LIBRARY_TYPE)
|
||||
|
||||
# Make sure the compiler can find the necessary include files
|
||||
include_directories (${SOURCE_DIR}/.. ${SOURCE_DIR}/../interface/vcos)
|
||||
|
||||
# Needed for the container loader
|
||||
add_definitions(-DDL_PATH_PREFIX="${VMCS_PLUGIN_DIR}/")
|
||||
|
||||
SET( GCC_COMPILER_FLAGS -Wall -g -O2 -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wcast-qual -Wwrite-strings -Wundef )
|
||||
SET( GCC_COMPILER_FLAGS ${GCC_COMPILER_FLAGS} -Wextra )#-Wno-missing-field-initializers )
|
||||
SET( GCC_COMPILER_FLAGS ${GCC_COMPILER_FLAGS} -std=c99 -D_POSIX_C_SOURCE=200112L )
|
||||
SET( GCC_COMPILER_FLAGS ${GCC_COMPILER_FLAGS} -Wno-missing-field-initializers )
|
||||
SET( GCC_COMPILER_FLAGS ${GCC_COMPILER_FLAGS} -Wno-unused-value )
|
||||
|
||||
add_definitions( ${GCC_COMPILER_FLAGS} )
|
||||
|
||||
# Containers core library
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_io.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_io_helpers.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_codecs.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_utils.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_writer_utils.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_loader.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_filters.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_logging.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_uri.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_bits.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_list.c)
|
||||
set(core_SRCS ${core_SRCS} ${SOURCE_DIR}/core/containers_index.c)
|
||||
|
||||
# Containers io library
|
||||
set(io_SRCS ${io_SRCS} ${SOURCE_DIR}/io/io_file.c)
|
||||
set(io_SRCS ${io_SRCS} ${SOURCE_DIR}/io/io_null.c)
|
||||
set(io_SRCS ${io_SRCS} ${SOURCE_DIR}/io/io_net.c)
|
||||
set(io_SRCS ${io_SRCS} ${SOURCE_DIR}/io/io_pktfile.c)
|
||||
set(io_SRCS ${io_SRCS} ${SOURCE_DIR}/io/io_http.c)
|
||||
add_definitions( -DENABLE_CONTAINER_IO_HTTP )
|
||||
|
||||
# Containers net library
|
||||
if (DEFINED MSVC)
|
||||
set(net_SRCS ${net_SRCS} ${SOURCE_DIR}/net/net_sockets_common.c)
|
||||
set(net_SRCS ${net_SRCS} ${SOURCE_DIR}/net/net_sockets_win32.c)
|
||||
elseif (DEFINED LINUX OR DEFINED UNIX)
|
||||
set(net_SRCS ${net_SRCS} ${SOURCE_DIR}/net/net_sockets_common.c)
|
||||
set(net_SRCS ${net_SRCS} ${SOURCE_DIR}/net/net_sockets_bsd.c)
|
||||
else (DEFINED MSVC)
|
||||
set(net_SRCS ${net_SRCS} ${SOURCE_DIR}/net/net_sockets_null.c)
|
||||
endif (DEFINED MSVC)
|
||||
set(extra_net_SRCS net_sockets_win32.c net_sockets_win32.h net_sockets_null.c)
|
||||
add_custom_target(containers_net_extra ALL
|
||||
COMMAND touch ${extra_net_SRCS}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/containers/net)
|
||||
|
||||
# Packetizers library
|
||||
set(packetizers_SRCS ${packetizers_SRCS} ${SOURCE_DIR}/core/packetizers.c)
|
||||
set(packetizers_SRCS ${packetizers_SRCS} ${SOURCE_DIR}/mpga/mpga_packetizer.c)
|
||||
set(packetizers_SRCS ${packetizers_SRCS} ${SOURCE_DIR}/mpgv/mpgv_packetizer.c)
|
||||
set(packetizers_SRCS ${packetizers_SRCS} ${SOURCE_DIR}/pcm/pcm_packetizer.c)
|
||||
set(packetizers_SRCS ${packetizers_SRCS} ${SOURCE_DIR}/h264/avc1_packetizer.c)
|
||||
|
||||
add_library(containers ${LIBRARY_TYPE} ${core_SRCS} ${io_SRCS} ${net_SRCS} ${packetizers_SRCS})
|
||||
target_link_libraries(containers vcos)
|
||||
install(TARGETS containers DESTINATION lib)
|
||||
|
||||
set(container_readers)
|
||||
set(container_writers)
|
||||
|
||||
# Container modules
|
||||
add_subdirectory(mp4)
|
||||
set(container_readers ${container_readers} reader_mp4)
|
||||
set(container_writers ${container_writers} writer_mp4)
|
||||
add_subdirectory(mpeg)
|
||||
set(container_readers ${container_readers} reader_ps)
|
||||
add_subdirectory(mpga)
|
||||
set(container_readers ${container_readers} reader_mpga)
|
||||
add_subdirectory(binary)
|
||||
set(container_readers ${container_readers} reader_binary)
|
||||
set(container_writers ${container_writers} writer_binary)
|
||||
add_subdirectory(mkv)
|
||||
set(container_readers ${container_readers} reader_mkv)
|
||||
add_subdirectory(wav)
|
||||
set(container_readers ${container_readers} reader_wav)
|
||||
add_subdirectory(asf)
|
||||
set(container_readers ${container_readers} reader_asf)
|
||||
set(container_writers ${container_writers} writer_asf)
|
||||
add_subdirectory(flash)
|
||||
set(container_readers ${container_readers} reader_flv)
|
||||
add_subdirectory(avi)
|
||||
set(container_readers ${container_readers} reader_avi)
|
||||
set(container_writers ${container_writers} writer_avi)
|
||||
add_subdirectory(rtp)
|
||||
set(container_readers ${container_readers} reader_rtp)
|
||||
add_subdirectory(rtsp)
|
||||
set(container_readers ${container_readers} reader_rtsp)
|
||||
add_subdirectory(rcv)
|
||||
set(container_readers ${container_readers} reader_rcv)
|
||||
add_subdirectory(rv9)
|
||||
set(container_readers ${container_readers} reader_rv9)
|
||||
add_subdirectory(qsynth)
|
||||
set(container_readers ${container_readers} reader_qsynth)
|
||||
add_subdirectory(simple)
|
||||
set(container_readers ${container_readers} reader_simple)
|
||||
set(container_writers ${container_writers} writer_simple)
|
||||
add_subdirectory(raw)
|
||||
set(container_readers ${container_readers} reader_raw_video)
|
||||
set(container_writers ${container_writers} writer_raw_video)
|
||||
add_subdirectory(dummy)
|
||||
set(container_writers ${container_writers} writer_dummy)
|
||||
|
||||
add_subdirectory(metadata/id3)
|
||||
set(container_readers ${container_readers} reader_metadata_id3)
|
||||
|
||||
if (${LIBRARY_TYPE} STREQUAL STATIC)
|
||||
target_link_libraries(containers ${container_readers} ${container_writers})
|
||||
endif (${LIBRARY_TYPE} STREQUAL STATIC)
|
||||
|
||||
# Test apps
|
||||
add_subdirectory(test)
|
19
gfx/include/userland/containers/asf/CMakeLists.txt
Normal file
19
gfx/include/userland/containers/asf/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Container module needs to go in as a plugins so different prefix
|
||||
# and install path
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
|
||||
# Make sure the compiler can find the necessary include files
|
||||
include_directories (../..)
|
||||
|
||||
add_library(reader_asf ${LIBRARY_TYPE} asf_reader.c)
|
||||
|
||||
target_link_libraries(reader_asf containers)
|
||||
|
||||
install(TARGETS reader_asf DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
||||
add_library(writer_asf ${LIBRARY_TYPE} asf_writer.c)
|
||||
|
||||
target_link_libraries(writer_asf containers)
|
||||
|
||||
install(TARGETS writer_asf DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
2247
gfx/include/userland/containers/asf/asf_reader.c
Normal file
2247
gfx/include/userland/containers/asf/asf_reader.c
Normal file
File diff suppressed because it is too large
Load Diff
577
gfx/include/userland/containers/asf/asf_writer.c
Normal file
577
gfx/include/userland/containers/asf/asf_writer.c
Normal file
@ -0,0 +1,577 @@
|
||||
/*
|
||||
Copyright (c) 2012, Broadcom Europe Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define ENABLE_CONTAINERS_LOG_FORMAT
|
||||
#include "containers/core/containers_private.h"
|
||||
#include "containers/core/containers_io_helpers.h"
|
||||
#include "containers/core/containers_utils.h"
|
||||
#include "containers/core/containers_writer_utils.h"
|
||||
#include "containers/core/containers_logging.h"
|
||||
#undef CONTAINER_HELPER_LOG_INDENT
|
||||
#define CONTAINER_HELPER_LOG_INDENT(a) (a)->priv->module->object_level
|
||||
|
||||
VC_CONTAINER_STATUS_T asf_writer_open( VC_CONTAINER_T *p_ctx );
|
||||
|
||||
/******************************************************************************
|
||||
Defines.
|
||||
******************************************************************************/
|
||||
#define ASF_TRACKS_MAX 16
|
||||
#define ASF_OBJECT_HEADER_SIZE (16+8)
|
||||
|
||||
/******************************************************************************
|
||||
Type definitions.
|
||||
******************************************************************************/
|
||||
typedef enum {
|
||||
ASF_OBJECT_TYPE_UNKNOWN = 0,
|
||||
ASF_OBJECT_TYPE_HEADER,
|
||||
ASF_OBJECT_TYPE_FILE_PROPS,
|
||||
ASF_OBJECT_TYPE_STREAM_PROPS,
|
||||
ASF_OBJECT_TYPE_EXT_STREAM_PROPS,
|
||||
ASF_OBJECT_TYPE_DATA,
|
||||
ASF_OBJECT_TYPE_SIMPLE_INDEX,
|
||||
ASF_OBJECT_TYPE_INDEX,
|
||||
ASF_OBJECT_TYPE_HEADER_EXT,
|
||||
ASF_OBJECT_TYPE_HEADER_EXT_INTERNAL,
|
||||
ASF_OBJECT_TYPE_CODEC_LIST,
|
||||
ASF_OBJECT_TYPE_CONTENT_DESCRIPTION,
|
||||
ASF_OBJECT_TYPE_EXT_CONTENT_DESCRIPTION,
|
||||
ASF_OBJECT_TYPE_STREAM_BITRATE_PROPS,
|
||||
ASF_OBJECT_TYPE_LANGUAGE_LIST,
|
||||
ASF_OBJECT_TYPE_METADATA,
|
||||
ASF_OBJECT_TYPE_PADDING,
|
||||
} ASF_OBJECT_TYPE_T;
|
||||
|
||||
typedef struct VC_CONTAINER_TRACK_MODULE_T
|
||||
{
|
||||
unsigned int stream_id;
|
||||
uint64_t time_offset;
|
||||
bool b_valid;
|
||||
|
||||
uint64_t index_offset;
|
||||
uint32_t num_index_entries;
|
||||
int64_t index_time_interval;
|
||||
} VC_CONTAINER_TRACK_MODULE_T;
|
||||
|
||||
typedef struct VC_CONTAINER_MODULE_T
|
||||
{
|
||||
int object_level;
|
||||
uint32_t packet_size;
|
||||
|
||||
VC_CONTAINER_TRACK_T *tracks[ASF_TRACKS_MAX];
|
||||
|
||||
VC_CONTAINER_WRITER_EXTRAIO_T null;
|
||||
bool b_header_done;
|
||||
|
||||
unsigned int current_track;
|
||||
|
||||
} VC_CONTAINER_MODULE_T;
|
||||
|
||||
/******************************************************************************
|
||||
Static functions within this file.
|
||||
******************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_write_object( VC_CONTAINER_T *p_ctx, ASF_OBJECT_TYPE_T object_type );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header_ext( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header_ext_internal( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_file_properties( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_stream_properties( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_ext_stream_properties( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_simple_index( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_index( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_data( VC_CONTAINER_T *p_ctx );
|
||||
#if 0
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_codec_list( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_content_description( VC_CONTAINER_T *p_ctx );
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_stream_bitrate_props( VC_CONTAINER_T *p_ctx );
|
||||
#endif
|
||||
|
||||
static const GUID_T asf_guid_header = {0x75B22630, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
static const GUID_T asf_guid_file_props = {0x8CABDCA1, 0xA947, 0x11CF, {0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
|
||||
static const GUID_T asf_guid_stream_props = {0xB7DC0791, 0xA9B7, 0x11CF, {0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
|
||||
static const GUID_T asf_guid_ext_stream_props = {0x14E6A5CB, 0xC672, 0x4332, {0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A}};
|
||||
static const GUID_T asf_guid_data = {0x75B22636, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
static const GUID_T asf_guid_simple_index = {0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};
|
||||
static const GUID_T asf_guid_index = {0xD6E229D3, 0x35DA, 0x11D1, {0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}};
|
||||
static const GUID_T asf_guid_header_ext = {0x5FBF03B5, 0xA92E, 0x11CF, {0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}};
|
||||
static const GUID_T asf_guid_codec_list = {0x86D15240, 0x311D, 0x11D0, {0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6}};
|
||||
static const GUID_T asf_guid_content_description = {0x75B22633, 0x668E, 0x11CF, {0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}};
|
||||
static const GUID_T asf_guid_ext_content_description = {0xD2D0A440, 0xE307, 0x11D2, {0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50}};
|
||||
static const GUID_T asf_guid_stream_bitrate_props = {0x7BF875CE, 0x468D, 0x11D1, {0x8D, 0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2}};
|
||||
static const GUID_T asf_guid_language_list = {0x7C4346A9, 0xEFE0, 0x4BFC, {0xB2, 0x29, 0x39, 0x3E, 0xDE, 0x41, 0x5C, 0x85}};
|
||||
static const GUID_T asf_guid_metadata = {0xC5F8CBEA, 0x5BAF, 0x4877, {0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}};
|
||||
static const GUID_T asf_guid_padding = {0x1806D474, 0xCADF, 0x4509, {0xA4, 0xBA, 0x9A, 0xAB, 0xCB, 0x96, 0xAA, 0xE8}};
|
||||
|
||||
static const GUID_T asf_guid_stream_type_video = {0xBC19EFC0, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
|
||||
static const GUID_T asf_guid_stream_type_audio = {0xF8699E40, 0x5B4D, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
|
||||
static const GUID_T asf_guid_error_correction = {0x20FB5700, 0x5B55, 0x11CF, {0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}};
|
||||
|
||||
static struct {
|
||||
const ASF_OBJECT_TYPE_T type;
|
||||
const GUID_T *guid;
|
||||
const char *psz_name;
|
||||
VC_CONTAINER_STATUS_T (*pf_func)( VC_CONTAINER_T * );
|
||||
|
||||
} asf_object_list[] =
|
||||
{
|
||||
{ASF_OBJECT_TYPE_HEADER, &asf_guid_header, "header", asf_write_object_header},
|
||||
{ASF_OBJECT_TYPE_FILE_PROPS, &asf_guid_file_props, "file properties", asf_write_object_file_properties},
|
||||
{ASF_OBJECT_TYPE_STREAM_PROPS, &asf_guid_stream_props, "stream properties", asf_write_object_stream_properties},
|
||||
{ASF_OBJECT_TYPE_EXT_STREAM_PROPS, &asf_guid_ext_stream_props, "extended stream properties", asf_write_object_ext_stream_properties},
|
||||
{ASF_OBJECT_TYPE_DATA, &asf_guid_data, "data", asf_write_object_data},
|
||||
{ASF_OBJECT_TYPE_SIMPLE_INDEX, &asf_guid_simple_index, "simple index", asf_write_object_simple_index},
|
||||
{ASF_OBJECT_TYPE_INDEX, &asf_guid_index, "index", asf_write_object_index},
|
||||
{ASF_OBJECT_TYPE_HEADER_EXT, &asf_guid_header_ext, "header extension", asf_write_object_header_ext},
|
||||
{ASF_OBJECT_TYPE_HEADER_EXT_INTERNAL, &asf_guid_header_ext, "header extension", asf_write_object_header_ext_internal},
|
||||
#if 0
|
||||
{ASF_OBJECT_TYPE_CODEC_LIST, &asf_guid_codec_list, "codec list", asf_write_object_codec_list},
|
||||
{ASF_OBJECT_TYPE_CONTENT_DESCRIPTION, &asf_guid_content_description, "content description", asf_write_object_content_description},
|
||||
{ASF_OBJECT_TYPE_EXT_CONTENT_DESCRIPTION, &asf_guid_ext_content_description, "extended content description", 0},
|
||||
{ASF_OBJECT_TYPE_STREAM_BITRATE_PROPS, &asf_guid_stream_bitrate_props, "stream bitrate properties", asf_write_object_stream_bitrate_props},
|
||||
#endif
|
||||
{ASF_OBJECT_TYPE_UNKNOWN, 0, "unknown", 0}
|
||||
};
|
||||
|
||||
static GUID_T guid_null;
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_write_object( VC_CONTAINER_T *p_ctx, ASF_OBJECT_TYPE_T type )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
|
||||
int64_t object_size = 0;
|
||||
unsigned int i;
|
||||
|
||||
/* Find out which object we want to write */
|
||||
for( i = 0; asf_object_list[i].type && asf_object_list[i].type != type; i++ );
|
||||
|
||||
/* Check we found the requested type */
|
||||
if(!asf_object_list[i].type)
|
||||
{
|
||||
vc_container_assert(0);
|
||||
return VC_CONTAINER_ERROR_CORRUPTED;
|
||||
}
|
||||
|
||||
/* We need to find out the size of the object we're going to write.
|
||||
* Because we want to be streamable, we can't just come back later to update the size field.
|
||||
* The easiest way to find out the size of the data we're going to write is to write a dummy
|
||||
* version of it and get the size from that. It is a bit wasteful but is so much easier and
|
||||
* shouldn't really impact performance as there's no actual i/o involved. */
|
||||
if(!vc_container_writer_extraio_enable(p_ctx, &module->null))
|
||||
{
|
||||
asf_object_list[i].pf_func(p_ctx);
|
||||
object_size = STREAM_POSITION(p_ctx);
|
||||
}
|
||||
vc_container_writer_extraio_disable(p_ctx, &module->null);
|
||||
|
||||
/* Special case for header extension internal function */
|
||||
if(type == ASF_OBJECT_TYPE_HEADER_EXT_INTERNAL)
|
||||
{
|
||||
WRITE_U32(p_ctx, object_size, "Header Extension Data Size");
|
||||
/* Call the object specific writing function */
|
||||
status = asf_object_list[i].pf_func(p_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Write the object header */
|
||||
|
||||
if(WRITE_GUID(p_ctx, asf_object_list[i].guid, "Object ID") != sizeof(GUID_T))
|
||||
return VC_CONTAINER_ERROR_EOS;
|
||||
|
||||
LOG_FORMAT(p_ctx, "Object Name: %s", asf_object_list[i].psz_name);
|
||||
|
||||
WRITE_U64(p_ctx, object_size + ASF_OBJECT_HEADER_SIZE, "Object Size");
|
||||
|
||||
module->object_level++;
|
||||
|
||||
/* Call the object specific writing function */
|
||||
status = asf_object_list[i].pf_func(p_ctx);
|
||||
|
||||
module->object_level--;
|
||||
|
||||
if(status != VC_CONTAINER_SUCCESS)
|
||||
LOG_DEBUG(p_ctx, "object %s appears to be corrupted", asf_object_list[i].psz_name);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
|
||||
WRITE_U32(p_ctx, 0, "Number of Header Objects"); /* FIXME: could use that */
|
||||
WRITE_U8(p_ctx, 0, "Reserved1");
|
||||
WRITE_U8(p_ctx, 0, "Reserved2");
|
||||
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_FILE_PROPS);
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_HEADER_EXT);
|
||||
|
||||
for(module->current_track = 0; module->current_track < p_ctx->tracks_num;
|
||||
module->current_track++)
|
||||
{
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_STREAM_PROPS);
|
||||
}
|
||||
|
||||
/* Codec List */
|
||||
/* Content Description */
|
||||
/* Stream Bitrate Properties */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header_ext( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
WRITE_GUID(p_ctx, &guid_null, "Reserved Field 1");
|
||||
WRITE_U16(p_ctx, 0, "Reserved Field 2");
|
||||
|
||||
return asf_write_object(p_ctx, ASF_OBJECT_TYPE_HEADER_EXT_INTERNAL);
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_header_ext_internal( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
|
||||
|
||||
for(module->current_track = 0; module->current_track < p_ctx->tracks_num;
|
||||
module->current_track++)
|
||||
{
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_EXT_STREAM_PROPS);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_file_properties( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
|
||||
WRITE_GUID(p_ctx, &guid_null, "File ID");
|
||||
WRITE_U64(p_ctx, 0, "File Size");
|
||||
WRITE_U64(p_ctx, 0, "Creation Date");
|
||||
WRITE_U64(p_ctx, 0, "Data Packets Count");
|
||||
WRITE_U64(p_ctx, 0, "Play Duration");
|
||||
WRITE_U64(p_ctx, 0, "Send Duration");
|
||||
WRITE_U64(p_ctx, 0, "Preroll");
|
||||
WRITE_U32(p_ctx, 0, "Flags");
|
||||
WRITE_U32(p_ctx, module->packet_size, "Minimum Data Packet Size");
|
||||
WRITE_U32(p_ctx, module->packet_size, "Maximum Data Packet Size");
|
||||
WRITE_U32(p_ctx, 0, "Maximum Bitrate");
|
||||
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_bitmapinfoheader( VC_CONTAINER_T *p_ctx,
|
||||
VC_CONTAINER_TRACK_T *p_track )
|
||||
{
|
||||
uint32_t fourcc;
|
||||
|
||||
/* Write the preamble to the BITMAPINFOHEADER */
|
||||
WRITE_U32(p_ctx, p_track->format->type->video.width, "Encoded Image Width");
|
||||
WRITE_U32(p_ctx, p_track->format->type->video.height, "Encoded Image Height");
|
||||
WRITE_U8(p_ctx, 0, "Reserved Flags");
|
||||
WRITE_U16(p_ctx, 40 + p_track->format->extradata_size, "Format Data Size");
|
||||
|
||||
/* Write BITMAPINFOHEADER structure */
|
||||
WRITE_U32(p_ctx, 40 + p_track->format->extradata_size, "Format Data Size");
|
||||
WRITE_U32(p_ctx, p_track->format->type->video.width, "Image Width");
|
||||
WRITE_U32(p_ctx, p_track->format->type->video.height, "Image Height");
|
||||
WRITE_U16(p_ctx, 0, "Reserved");
|
||||
WRITE_U16(p_ctx, 0, "Bits Per Pixel Count");
|
||||
fourcc = codec_to_fourcc(p_track->format->codec);
|
||||
WRITE_BYTES(p_ctx, (char *)&fourcc, 4); /* Compression ID */
|
||||
LOG_FORMAT(p_ctx, "Compression ID: %4.4s", (char *)&fourcc);
|
||||
WRITE_U32(p_ctx, 0, "Image Size");
|
||||
WRITE_U32(p_ctx, 0, "Horizontal Pixels Per Meter");
|
||||
WRITE_U32(p_ctx, 0, "Vertical Pixels Per Meter");
|
||||
WRITE_U32(p_ctx, 0, "Colors Used Count");
|
||||
WRITE_U32(p_ctx, 0, "Important Colors Count");
|
||||
|
||||
WRITE_BYTES(p_ctx, p_track->format->extradata, p_track->format->extradata_size);
|
||||
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_waveformatex( VC_CONTAINER_T *p_ctx,
|
||||
VC_CONTAINER_TRACK_T *p_track)
|
||||
{
|
||||
/* Write WAVEFORMATEX structure */
|
||||
WRITE_U16(p_ctx, codec_to_waveformat(p_track->format->codec), "Codec ID");
|
||||
WRITE_U16(p_ctx, p_track->format->type->audio.channels, "Number of Channels");
|
||||
WRITE_U32(p_ctx, p_track->format->type->audio.sample_rate, "Samples per Second");
|
||||
WRITE_U32(p_ctx, p_track->format->bitrate, "Average Number of Bytes Per Second");
|
||||
WRITE_U16(p_ctx, p_track->format->type->audio.block_align, "Block Alignment");
|
||||
WRITE_U16(p_ctx, p_track->format->type->audio.bits_per_sample, "Bits Per Sample");
|
||||
WRITE_U16(p_ctx, p_track->format->extradata_size, "Codec Specific Data Size");
|
||||
WRITE_BYTES(p_ctx, p_track->format->extradata, p_track->format->extradata_size);
|
||||
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_stream_properties( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
unsigned int track = module->current_track, ts_size = 0;
|
||||
const GUID_T *p_guid = &guid_null;
|
||||
|
||||
if(p_ctx->tracks[track]->format->es_type == VC_CONTAINER_ES_TYPE_VIDEO)
|
||||
{
|
||||
p_guid = &asf_guid_stream_type_video;
|
||||
ts_size = 11 + 40 + p_ctx->tracks[track]->format->extradata_size;
|
||||
}
|
||||
else if(p_ctx->tracks[track]->format->es_type == VC_CONTAINER_ES_TYPE_AUDIO)
|
||||
{
|
||||
p_guid = &asf_guid_stream_type_audio;
|
||||
ts_size = 18 + p_ctx->tracks[track]->format->extradata_size;
|
||||
}
|
||||
|
||||
WRITE_GUID(p_ctx, p_guid, "Stream Type");
|
||||
WRITE_GUID(p_ctx, &asf_guid_error_correction, "Error Correction Type");
|
||||
WRITE_U64(p_ctx, 0, "Time Offset");
|
||||
WRITE_U32(p_ctx, ts_size, "Type-Specific Data Length");
|
||||
WRITE_U32(p_ctx, 0, "Error Correction Data Length");
|
||||
WRITE_U16(p_ctx, track + 1, "Flags");
|
||||
WRITE_U32(p_ctx, 0, "Reserved");
|
||||
|
||||
/* Type-Specific Data */
|
||||
if(ts_size)
|
||||
{
|
||||
if(p_ctx->tracks[track]->format->es_type == VC_CONTAINER_ES_TYPE_VIDEO)
|
||||
status = asf_write_bitmapinfoheader( p_ctx, p_ctx->tracks[track]);
|
||||
else if(p_ctx->tracks[track]->format->es_type == VC_CONTAINER_ES_TYPE_AUDIO)
|
||||
status = asf_write_waveformatex( p_ctx, p_ctx->tracks[track]);
|
||||
}
|
||||
|
||||
/* Error Correction Data */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_ext_stream_properties( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
|
||||
WRITE_U64(p_ctx, 0, "Start Time");
|
||||
WRITE_U64(p_ctx, 0, "End Time");
|
||||
WRITE_U32(p_ctx, 0, "Data Bitrate");
|
||||
WRITE_U32(p_ctx, 0, "Buffer Size");
|
||||
WRITE_U32(p_ctx, 0, "Initial Buffer Fullness");
|
||||
WRITE_U32(p_ctx, 0, "Alternate Data Bitrate");
|
||||
WRITE_U32(p_ctx, 0, "Alternate Buffer Size");
|
||||
WRITE_U32(p_ctx, 0, "Alternate Initial Buffer Fullness");
|
||||
WRITE_U32(p_ctx, 0, "Maximum Object Size");
|
||||
WRITE_U32(p_ctx, 0, "Flags");
|
||||
WRITE_U16(p_ctx, module->current_track + 1, "Stream Number");
|
||||
WRITE_U16(p_ctx, 0, "Stream Language ID Index");
|
||||
WRITE_U64(p_ctx, 0, "Average Time Per Frame");
|
||||
WRITE_U16(p_ctx, 0, "Stream Name Count");
|
||||
WRITE_U16(p_ctx, 0, "Payload Extension System Count");
|
||||
/* Stream Names */
|
||||
/* Payload Extension Systems */
|
||||
/* Stream Properties Object */
|
||||
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_index( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_PARAM_UNUSED(p_ctx);
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_simple_index( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_PARAM_UNUSED(p_ctx);
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
static VC_CONTAINER_STATUS_T asf_write_object_data( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_PARAM_UNUSED(p_ctx);
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_write_header( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_STATUS_T status;
|
||||
|
||||
/* TODO Sanity check the tracks */
|
||||
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_HEADER);
|
||||
status = asf_write_object(p_ctx, ASF_OBJECT_TYPE_DATA);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_writer_write( VC_CONTAINER_T *p_ctx,
|
||||
VC_CONTAINER_PACKET_T *p_packet )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
|
||||
VC_CONTAINER_PARAM_UNUSED(p_packet);
|
||||
|
||||
if(!module->b_header_done)
|
||||
{
|
||||
module->b_header_done = true;
|
||||
status = asf_write_header(p_ctx);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_writer_close( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
|
||||
for(; p_ctx->tracks_num > 0; p_ctx->tracks_num--)
|
||||
vc_container_free_track(p_ctx, p_ctx->tracks[p_ctx->tracks_num-1]);
|
||||
|
||||
vc_container_writer_extraio_delete(p_ctx, &module->null);
|
||||
free(module);
|
||||
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_writer_add_track( VC_CONTAINER_T *p_ctx, VC_CONTAINER_ES_FORMAT_T *format )
|
||||
{
|
||||
VC_CONTAINER_STATUS_T status;
|
||||
VC_CONTAINER_TRACK_T *track;
|
||||
|
||||
/* TODO check we support this format */
|
||||
|
||||
if(!(format->flags & VC_CONTAINER_ES_FORMAT_FLAG_FRAMED))
|
||||
return VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION;
|
||||
|
||||
/* Allocate and initialise track data */
|
||||
if(p_ctx->tracks_num >= ASF_TRACKS_MAX) return VC_CONTAINER_ERROR_OUT_OF_RESOURCES;
|
||||
p_ctx->tracks[p_ctx->tracks_num] = track =
|
||||
vc_container_allocate_track(p_ctx, sizeof(*p_ctx->tracks[0]->priv->module));
|
||||
if(!track) return VC_CONTAINER_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if(format->extradata_size)
|
||||
{
|
||||
status = vc_container_track_allocate_extradata( p_ctx, track, format->extradata_size );
|
||||
if(status) goto error;
|
||||
}
|
||||
|
||||
vc_container_format_copy(track->format, format, format->extradata_size);
|
||||
p_ctx->tracks_num++;
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
|
||||
error:
|
||||
vc_container_free_track(p_ctx, track);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static VC_CONTAINER_STATUS_T asf_writer_control( VC_CONTAINER_T *p_ctx, VC_CONTAINER_CONTROL_T operation, va_list args )
|
||||
{
|
||||
VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
|
||||
VC_CONTAINER_STATUS_T status;
|
||||
|
||||
switch(operation)
|
||||
{
|
||||
case VC_CONTAINER_CONTROL_TRACK_ADD:
|
||||
{
|
||||
VC_CONTAINER_ES_FORMAT_T *p_format =
|
||||
(VC_CONTAINER_ES_FORMAT_T *)va_arg( args, VC_CONTAINER_ES_FORMAT_T * );
|
||||
return asf_writer_add_track(p_ctx, p_format);
|
||||
}
|
||||
|
||||
case VC_CONTAINER_CONTROL_TRACK_ADD_DONE:
|
||||
if(!module->b_header_done)
|
||||
{
|
||||
status = asf_write_header(p_ctx);
|
||||
if(status != VC_CONTAINER_SUCCESS) return status;
|
||||
module->b_header_done = true;
|
||||
}
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
|
||||
default: return VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Global function definitions.
|
||||
******************************************************************************/
|
||||
|
||||
VC_CONTAINER_STATUS_T asf_writer_open( VC_CONTAINER_T *p_ctx )
|
||||
{
|
||||
VC_CONTAINER_STATUS_T status = VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
const char *extension = vc_uri_path_extension(p_ctx->priv->uri);
|
||||
VC_CONTAINER_MODULE_T *module = 0;
|
||||
unsigned int i;
|
||||
|
||||
/* Check if the user has specified a container */
|
||||
vc_uri_find_query(p_ctx->priv->uri, 0, "container", &extension);
|
||||
|
||||
/* Check we're the right writer for this */
|
||||
if(!extension)
|
||||
return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
if(strcasecmp(extension, "asf") && strcasecmp(extension, "wmv") &&
|
||||
strcasecmp(extension, "wma"))
|
||||
return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
/* Allocate our context */
|
||||
module = malloc(sizeof(*module));
|
||||
if(!module) { status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error; }
|
||||
memset(module, 0, sizeof(*module));
|
||||
p_ctx->priv->module = module;
|
||||
p_ctx->tracks = module->tracks;
|
||||
|
||||
/* Create a null i/o writer to help us out in writing our data */
|
||||
status = vc_container_writer_extraio_create_null(p_ctx, &module->null);
|
||||
if(status != VC_CONTAINER_SUCCESS) goto error;
|
||||
|
||||
/* We'll only write the header once we've got all our tracks */
|
||||
|
||||
p_ctx->priv->pf_close = asf_writer_close;
|
||||
p_ctx->priv->pf_write = asf_writer_write;
|
||||
p_ctx->priv->pf_control = asf_writer_control;
|
||||
return VC_CONTAINER_SUCCESS;
|
||||
|
||||
error:
|
||||
LOG_DEBUG(p_ctx, "asf: error opening stream");
|
||||
for(i = 0; i < ASF_TRACKS_MAX && p_ctx->tracks && p_ctx->tracks[i]; i++)
|
||||
vc_container_free_track(p_ctx, p_ctx->tracks[i]);
|
||||
free(module);
|
||||
return status;
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
Entrypoint function
|
||||
********************************************************************************/
|
||||
|
||||
#if !defined(ENABLE_CONTAINERS_STANDALONE) && defined(__HIGHC__)
|
||||
# pragma weak writer_open asf_writer_open
|
||||
#endif
|
19
gfx/include/userland/containers/avi/CMakeLists.txt
Normal file
19
gfx/include/userland/containers/avi/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Container module needs to go in as a plugins so different prefix
|
||||
# and install path
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
|
||||
# Make sure the compiler can find the necessary include files
|
||||
include_directories (../..)
|
||||
|
||||
add_library(reader_avi ${LIBRARY_TYPE} avi_reader.c)
|
||||
|
||||
target_link_libraries(reader_avi containers)
|
||||
|
||||
install(TARGETS reader_avi DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
||||
add_library(writer_avi ${LIBRARY_TYPE} avi_writer.c)
|
||||
|
||||
target_link_libraries(writer_avi containers)
|
||||
|
||||
install(TARGETS writer_avi DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
1521
gfx/include/userland/containers/avi/avi_reader.c
Normal file
1521
gfx/include/userland/containers/avi/avi_reader.c
Normal file
File diff suppressed because it is too large
Load Diff
1171
gfx/include/userland/containers/avi/avi_writer.c
Normal file
1171
gfx/include/userland/containers/avi/avi_writer.c
Normal file
File diff suppressed because it is too large
Load Diff
19
gfx/include/userland/containers/binary/CMakeLists.txt
Normal file
19
gfx/include/userland/containers/binary/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Container module needs to go in as a plugins so different prefix
|
||||
# and install path
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||
|
||||
# Make sure the compiler can find the necessary include files
|
||||
include_directories (../..)
|
||||
|
||||
add_library(reader_binary ${LIBRARY_TYPE} binary_reader.c)
|
||||
|
||||
target_link_libraries(reader_binary containers)
|
||||
|
||||
install(TARGETS reader_binary DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
||||
add_library(writer_binary ${LIBRARY_TYPE} binary_writer.c)
|
||||
|
||||
target_link_libraries(writer_binary containers)
|
||||
|
||||
install(TARGETS writer_binary DESTINATION ${VMCS_PLUGIN_DIR})
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user