diff --git a/.gitignore b/.gitignore
index dca3baf9dc..ac6110512b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,7 @@ Debug
Release
ipch
*.user
-/wii/app_booter/app_booter.bin
+/bootstrap/gx/wii/app_booter/app_booter.bin
*.zip
RetroArch-w32/
RetroArch-w64/
@@ -62,12 +62,12 @@ apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
/obj-w32/
# Android
-/android/phoenix/obj/
-/android/phoenix/assets/
-/android/phoenix/libs/
-/android/phoenix/bin/
-/android/phoenix/gen/
-/android/phoenix/local.properties
+/pkg/android/phoenix/obj/
+/pkg/android/phoenix/assets/
+/pkg/android/phoenix/libs/
+/pkg/android/phoenix/bin/
+/pkg/android/phoenix/gen/
+/pkg/android/phoenix/local.properties
# Cloned by libretro-fetch.sh
/media/assets/
@@ -76,8 +76,8 @@ apple/RetroArch_iOS.xcodeproj/project.xcworkspace/*
/media/shaders_cg/
/media/libretrodb/
-apple/iOS/build/
-apple/iOS/modules/
+pkg/apple/iOS/build/
+pkg/apple/iOS/modules/
obj-unix/
.vagrant/
diff --git a/Makefile b/Makefile
index 5078e6bb3f..ed9f5253ad 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,10 @@
HAVE_FILE_LOGGER=1
MISSING_DECLS =0
+ifneq ($(C90_BUILD),)
+ C89_BUILD=1
+endif
+
include config.mk
TARGET = retroarch
@@ -77,9 +81,8 @@ else
endif
endif
- ifneq ($(C89_BUILD)$(C90_BUILD),)
- #looks kinda ugly, but it makes both C89_BUILD and C90_BUILD work and refer to the same thing
- CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic
+ ifneq ($(C89_BUILD),)
+ CFLAGS += -std=c89 -ansi -pedantic -Werror=pedantic -Wno-long-long
endif
endif
diff --git a/Makefile.common b/Makefile.common
index 74bb2d092c..a76c417441 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -54,7 +54,7 @@ ifeq ($(TDM_GCC),)
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
- CFLAGS += -DHAVE_FILE_LOGGER -Ilogger/netlogger
+ CFLAGS += -DHAVE_FILE_LOGGER
endif
CFLAGS += -I./libretro-common/include
@@ -131,6 +131,8 @@ OBJ += frontend/frontend.o \
libretro-common/file/file_list.o \
libretro-common/file/dir_list.o \
libretro-common/file/retro_dirent.o \
+ libretro-common/file/retro_file.o \
+ libretro-common/file/retro_stat.o \
libretro-common/string/string_list.o \
libretro-common/string/stdstring.o \
libretro-common/memmap/memalign.o \
@@ -210,15 +212,10 @@ OBJ += frontend/frontend.o \
OBJ += gfx/image/image.o
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# stb_image is not a C89/C90-compliant API.
ifeq ($(HAVE_IMAGEVIEWER), 1)
DEFINES += -DHAVE_IMAGEVIEWER
OBJ += cores/image_core.o
endif
-endif
-endif
# Qt
@@ -237,7 +234,8 @@ OBJ += libretro-db/bintree.o \
libretro-db/rmsgpack.o \
libretro-db/rmsgpack_dom.o \
database_info.o \
- tasks/task_database.o
+ tasks/task_database.o \
+ tasks/task_database_cue.o
endif
# Miscellaneous
@@ -246,16 +244,11 @@ ifeq ($(HAVE_STDIN_CMD), 1)
DEFINES += -DHAVE_COMMAND -DHAVE_STDIN_CMD
endif
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# Python 3.x bindings are not C89/C90-compliant.
ifeq ($(HAVE_PYTHON), 1)
DEFINES += $(PYTHON_CFLAGS) -Wno-unused-parameter
LIBS += $(PYTHON_LIBS)
OBJ += gfx/video_state_python.o
endif
-endif
-endif
ifeq ($(HAVE_EMSCRIPTEN), 1)
OBJ += frontend/drivers/platform_emscripten.o \
@@ -315,16 +308,11 @@ ifeq ($(HAVE_JACK),1)
DEFINES += $(JACK_CFLAGS)
endif
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# PulseAudio is not a C89/C90-compliant API.
ifeq ($(HAVE_PULSE), 1)
OBJ += audio/drivers/pulse.o
LIBS += $(PULSE_LIBS)
DEFINES += $(PULSE_CFLAGS)
endif
-endif
-endif
ifeq ($(HAVE_OSS_LIB), 1)
LIBS += -lossaudio
@@ -474,16 +462,11 @@ endif
#Input
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# Wayland is not a C89/C90-compliant API.
ifeq ($(HAVE_WAYLAND), 1)
#OBJ += input/drivers/wayland.o
DEFINES += $(WAYLAND_CFLAGS)
LIBS += $(WAYLAND_LIBS)
endif
-endif
-endif
ifeq ($(HAVE_DINPUT), 1)
LIBS += -ldinput8 -ldxguid -lole32
@@ -521,9 +504,6 @@ ifeq ($(HAVE_UDEV), 1)
input/drivers_joypad/udev_joypad.o
endif
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# libusb is not a C89/C90-compliant API.
ifeq ($(HAVE_LIBUSB), 1)
DEFINES += -DHAVE_LIBUSB
OBJ += input/drivers_hid/libusb_hid.o
@@ -531,8 +511,6 @@ ifeq ($(HAVE_LIBUSB), 1)
JOYCONFIG_LIBS += -lusb-1.0
HAVE_HID = 1
endif
-endif
-endif
ifeq ($(HAVE_IOHIDMANAGER), 1)
DEFINES += -DHAVE_IOHIDMANAGER
@@ -612,16 +590,11 @@ ifeq ($(HAVE_GL_CONTEXT), 1)
endif
endif
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
- # Wayland is not a C89/C90-compliant API.
ifeq ($(HAVE_WAYLAND), 1)
ifeq ($(HAVE_EGL), 1)
OBJ += gfx/drivers_context/wayland_ctx.o
endif
endif
-endif
-endif
ifeq ($(HAVE_GLES), 1)
LIBS += $(GLES_LIBS)
@@ -689,7 +662,7 @@ endif
ifeq ($(HAVE_EXYNOS), 1)
OBJ += gfx/drivers/exynos_gfx.o \
- mem/neon/memcpy-neon.o
+ memory/neon/memcpy-neon.o
LIBS += $(DRM_LIBS) $(EXYNOS_LIBS)
DEFINES += $(DRM_CFLAGS) $(EXYNOS_CFLAGS)
endif
@@ -770,7 +743,6 @@ ifeq ($(HAVE_7ZIP),1)
OBJ += $(7ZOBJ)
endif
- OBJ += libretro-common/formats/tga/tga_decode.o
ifeq ($(HAVE_ZLIB), 1)
OBJ += libretro-common/file/file_extract.o
@@ -791,11 +763,11 @@ ifdef HAVE_RPNG
endif
ifeq ($(HAVE_RPNG), 1)
- OBJ += libretro-common/formats/png/rpng_nbio.o \
- libretro-common/formats/png/rpng_fbio.o \
- libretro-common/formats/png/rpng_decode.o \
+ OBJ += libretro-common/formats/png/rpng.o \
libretro-common/formats/png/rpng_encode.o
endif
+OBJ += libretro-common/formats/bmp/rbmp_encode.o \
+ libretro-common/formats/tga/rtga.o
ifdef HAVE_COMPRESSION
DEFINES += -DHAVE_COMPRESSION
@@ -874,9 +846,6 @@ endif
# Record
-ifneq ($(C89_BUILD), 1)
-ifneq ($(C90_BUILD), 1)
-# ffmpeg and friends are not C89/C90-compliant APIs.
ifeq ($(HAVE_FFMPEG), 1)
OBJ += record/drivers/record_ffmpeg.o \
cores/ffmpeg_core.o
@@ -884,8 +853,6 @@ ifeq ($(HAVE_FFMPEG), 1)
DEFINES += $(AVCODEC_CFLAGS) $(AVFORMAT_CFLAGS) $(AVUTIL_CFLAGS) $(SWSCALE_CFLAGS) $(SWRESAMPLE_CFLAGS)
DEFINES += -DHAVE_FFMPEG -Iffmpeg
endif
-endif
-endif
ifeq ($(HAVE_COMPRESSION), 1)
DEFINES += -DHAVE_COMPRESSION
diff --git a/Makefile.ctr b/Makefile.ctr
index 7b20d89b29..16dbcb0100 100644
--- a/Makefile.ctr
+++ b/Makefile.ctr
@@ -1,11 +1,12 @@
TARGET := retroarch_3ds
LIBRETRO =
-DEBUG = 0
-GRIFFIN_BUILD = 1
+DEBUG = 0
+GRIFFIN_BUILD = 1
WHOLE_ARCHIVE_LINK = 0
-BUILD_3DSX = 1
-BUILD_CIA = 1
+BIG_STACK = 0
+BUILD_3DSX = 1
+BUILD_CIA = 1
APP_TITLE = Retroarch 3DS
APP_DESCRIPTION = Retroarch 3DS
@@ -15,6 +16,16 @@ APP_UNIQUE_ID = 0xBAC00
APP_ICON = ctr/default.png
APP_BANNER = ctr/libretro_banner.png
APP_AUDIO = ctr/silent.wav
+APP_CIA_RSF = ctr/tools/template-cia.rsf
+APP_3DS_RSF = ctr/tools/template-3ds.rsf
+
+
+ifeq ($(BIG_STACK),1)
+CTR_STACK_SIZE = 0x400000
+else
+CTR_STACK_SIZE = 0x100000
+endif
+CTR_LINEAR_HEAP_SIZE = 0x600000
include ctr/Makefile.cores
@@ -39,11 +50,10 @@ else
OBJS += gfx/drivers_context/gfx_null_ctx.o
OBJS += gfx/image/image.o
OBJS += gfx/video_texture.o
- OBJS += libretro-common/formats/tga/tga_decode.o
- OBJS += libretro-common/formats/png/rpng_fbio.o
- OBJS += libretro-common/formats/png/rpng_nbio.o
- OBJS += libretro-common/formats/png/rpng_decode.o
+ OBJS += libretro-common/formats/tga/rtga.o
+ OBJS += libretro-common/formats/png/rpng.o
OBJS += libretro-common/formats/png/rpng_encode.o
+ OBJS += libretro-common/formats/bmp/rbmp_encode.o
OBJS += gfx/drivers/ctr_gfx.o
OBJS += gfx/drivers/nullgfx.o
OBJS += gfx/font_renderer_driver.o
@@ -117,6 +127,7 @@ else
OBJS += file_path_special.o
OBJS += libretro-common/file/dir_list.o
OBJS += libretro-common/file/retro_dirent.o
+ OBJS += libretro-common/file/retro_file.o
OBJS += dir_list_special.o
OBJS += libretro-common/string/string_list.o
OBJS += libretro-common/string/stdstring.o
@@ -264,6 +275,14 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1)
WHOLE_END := -Wl,--no-whole-archive
endif
+ifneq ($(CTR_STACK_SIZE),)
+ CFLAGS += -DCTR_STACK_SIZE=$(CTR_STACK_SIZE)
+endif
+
+ifneq ($(CTR_LINEAR_HEAP_SIZE),)
+ CFLAGS += -DCTR_LINEAR_HEAP_SIZE=$(CTR_LINEAR_HEAP_SIZE)
+endif
+
CFLAGS += -I. -Ideps/zlib -Ideps/7zip -Ilibretro-common/include
CFLAGS += -DRARCH_INTERNAL -DRARCH_CONSOLE -DSINC_LOWEST_QUALITY
@@ -316,13 +335,13 @@ NM := $(PREFIX)nm
LD := $(CXX)
ifneq ($(findstring Linux,$(shell uname -a)),)
- MAKEROM = ctr/tools/makerom-linux
+ MAKEROM = ctr/tools/makerom-linux
BANNERTOOL = ctr/tools/bannertool-linux
else ifneq ($(findstring Darwin,$(shell uname -a)),)
- MAKEROM = ctr/tools/makerom-mac
+ MAKEROM = ctr/tools/makerom-mac
BANNERTOOL = ctr/tools/bannertool-mac
else
- MAKEROM = ctr/tools/makerom.exe
+ MAKEROM = ctr/tools/makerom.exe
BANNERTOOL = ctr/tools/bannertool.exe
endif
@@ -369,15 +388,12 @@ $(TARGET).bnr: $(APP_BANNER) $(APP_AUDIO)
$(TARGET).icn: $(APP_ICON)
$(BANNERTOOL) makesmdh -s "$(APP_TITLE)" -l "$(APP_TITLE)" -p "$(APP_AUTHOR)" -i $(APP_ICON) -o $@
-$(TARGET).rsf: ctr/tools/template-cia.rsf
- cat ctr/tools/template-cia.rsf | sed 's/{APP_TITLE}/$(APP_TITLE)/' | sed 's/{APP_PRODUCT_CODE}/$(APP_PRODUCT_CODE)/' | sed 's/{APP_UNIQUE_ID}/$(APP_UNIQUE_ID)/' > $@
-
$(TARGET)_stripped.elf: $(TARGET).elf
cp $(TARGET).elf $@
$(STRIP) $@
-$(TARGET).cia: $(TARGET)_stripped.elf $(TARGET).bnr $(TARGET).icn $(TARGET).rsf
- $(MAKEROM) -f cia -o $@ -rsf $(TARGET).rsf -target t -exefslogo -elf $(TARGET)_stripped.elf -icon $(TARGET).icn -banner $(TARGET).bnr
+$(TARGET).cia: $(TARGET)_stripped.elf $(TARGET).bnr $(TARGET).icn
+ $(MAKEROM) -f cia -o $@ -rsf $(APP_CIA_RSF) -target t -exefslogo -elf $(TARGET)_stripped.elf -icon $(TARGET).icn -banner $(TARGET).bnr -DAPP_TITLE="$(APP_TITLE)" -DAPP_PRODUCT_CODE="$(APP_PRODUCT_CODE)" -DAPP_UNIQUE_ID=$(APP_UNIQUE_ID)
clean:
rm -f $(OBJS)
@@ -387,7 +403,6 @@ clean:
rm -f $(TARGET).cia
rm -f $(TARGET).bnr
rm -f $(TARGET).icn
- rm -f $(TARGET).rsf
rm -f *_shader_shbin.h
.PHONY: clean
diff --git a/Makefile.griffin b/Makefile.griffin
index ffdc147432..7b193c6e79 100644
--- a/Makefile.griffin
+++ b/Makefile.griffin
@@ -100,12 +100,12 @@ endif
ifeq ($(platform), ngc)
LDFLAGS += $(MACHDEP) -Wl,-Map,$(notdir $(EXT_INTER_TARGET)).map
ifeq ($(BIG_STACK), 1)
- LDFLAGS += -T gx/ld/ogc.ld
+ LDFLAGS += -T bootstrap/gx/ogc.ld
endif
else ifeq ($(platform), wii)
LDFLAGS += $(MACHDEP) -Wl,-Map,$(notdir $(EXT_INTER_TARGET)).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,strdup,-wrap,strndup,-wrap,malloc_usable_size
ifeq ($(BIG_STACK), 1)
- LDFLAGS += -T gx/ld/rvl.ld
+ LDFLAGS += -T bootstrap/gx/rvl.ld
endif
endif
LIBS += -lfat -logc
@@ -202,10 +202,10 @@ else ifeq ($(platform), vita)
EXT_TARGET := $(TARGET_NAME)_$(platform).velf
EXT_INTER_TARGET := $(TARGET_NAME)_$(platform).elf
MACHDEP := -DVITA
- PLATCFLAGS := -O3 -U__ARM_NEON__
+ PLATCFLAGS := -O3 -mfloat-abi=hard -ffast-math -fsingle-precision-constant
LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub \
- -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub \
- -lScePower_stub -lSceRtc_stub -lz -lm -lc
+ -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lUVLoader_stub \
+ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lz -lm -lc
PLATOBJS += audio/audio_utils_neon.o audio/drivers_resampler/sinc_neon.o \
audio/drivers_resampler/cc_resampler_neon.o
@@ -213,6 +213,7 @@ else ifeq ($(platform), vita)
LIBDIRS += -L.
LDFLAGS += -Wl,-q
+ HAVE_FILTERS_BUILTIN := 1
HAVE_LIBRETRO_MANAGEMENT := 1
HAVE_BUILTIN_AUTOCONFIG := 1
HAVE_RPNG := 1
@@ -231,7 +232,6 @@ INCLUDE += -I./libretro-common/include
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
-INCLUDE += -Ilogger/netlogger
endif
ifeq ($(platform), wii)
@@ -276,7 +276,6 @@ endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
-INCLUDE += -Ilogger/netlogger
endif
ifeq ($(HAVE_RARCH_EXEC), 1)
@@ -359,7 +358,7 @@ all: $(EXT_TARGET)
%.velf: %.elf
arm-vita-eabi-strip -g $<
- vita-elf-create $< $@ $(VITASDK)/bin/db.json
+ vita-elf-create $< $@ $(VITASDK)/bin/db.json $(VITASDK)/bin/extra.json
%.elf32: %.elf
ifeq ($(platform), xenon360)
diff --git a/Makefile.pandora b/Makefile.pandora
index 1e3194ba18..5c6da85a7f 100644
--- a/Makefile.pandora
+++ b/Makefile.pandora
@@ -2,7 +2,7 @@
# $ source /usr/local/angstrom/arm/environment-setup
# $ setprj retroarch
-PNDDIR=./pandora
+PNDDIR=./pkg/pandora
BINDIR=$(PNDDIR)/bin
all: $(BINDIR)/retroarch
diff --git a/Makefile.ps3 b/Makefile.ps3
index 1e4c5e6e47..4bec6692c0 100644
--- a/Makefile.ps3
+++ b/Makefile.ps3
@@ -34,7 +34,7 @@ EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN
CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF
LDDIRS = -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt
-INCDIRS = -I. -Ips3 -Icommon -Ideps/zlib -Ilibretro-common/include
+INCDIRS = -I. -Idefines -Ideps/zlib -Ilibretro-common/include
# system platform
system_platform = unix
@@ -47,7 +47,7 @@ else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
-PKG_SCRIPT = ps3/ps3py/pkg.py
+PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
@@ -116,7 +116,6 @@ endif
ifeq ($(HAVE_LOGGER), 1)
DEFINES += -DHAVE_LOGGER
-INCDIRS += -Ilogger/netlogger
endif
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
diff --git a/Makefile.ps3.cobra b/Makefile.ps3.cobra
index 753b171666..bce87a24df 100644
--- a/Makefile.ps3.cobra
+++ b/Makefile.ps3.cobra
@@ -34,7 +34,7 @@ EBOOT_PATH = pkg/ps3/USRDIR/EBOOT.BIN
CORE_PATH = pkg/ps3/USRDIR/cores/CORE.SELF
LDDIRS = -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/ultra-opt
-INCDIRS = -I. -Ips3 -Icommon
+INCDIRS = -I. -Idefines
# system platform
system_platform = unix
@@ -47,7 +47,7 @@ else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
-PKG_SCRIPT = ps3/ps3py/pkg.py
+PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
@@ -116,7 +116,6 @@ endif
ifeq ($(HAVE_LOGGER), 1)
DEFINES += -DHAVE_LOGGER
-INCDIRS += -Ilogger/netlogger
endif
PPU_CFLAGS := $(PPU_OPTIMIZE_LV) $(INCDIRS) $(DEFINES)
diff --git a/Makefile.ps3.salamander b/Makefile.ps3.salamander
index 2842f195c9..62922783c3 100644
--- a/Makefile.ps3.salamander
+++ b/Makefile.ps3.salamander
@@ -26,14 +26,16 @@ PPU_SRCS = frontend/frontend_salamander.c \
libretro-common/file/file_path.c \
libretro-common/file/dir_list.c \
libretro-common/file/retro_dirent.c \
+ libretro-common/file/retro_stat.c \
libretro-common/hash/rhash.c \
libretro-common/string/string_list.c \
libretro-common/compat/compat.c \
+ libretro-common/file/retro_file.c \
libretro-common/file/config_file.c
ifeq ($(HAVE_LOGGER), 1)
-PPU_CFLAGS += -DHAVE_LOGGER -Ilogger/netlogger
-PPU_SRCS += logger/netlogger/logger.c
+PPU_CFLAGS += -DHAVE_LOGGER
+PPU_SRCS += netlogger.c
endif
PPU_TARGET = retroarch-salamander_ps3.elf
diff --git a/Makefile.psl1ght b/Makefile.psl1ght
index 2d36fb4638..3a15014ecd 100644
--- a/Makefile.psl1ght
+++ b/Makefile.psl1ght
@@ -36,7 +36,7 @@ else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
-PKG_SCRIPT = ps3/ps3py/pkg.py
+PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
@@ -61,7 +61,7 @@ else ifneq ($(findstring MINGW,$(shell uname -a)),)
system_platform = win
endif
-PKG_SCRIPT = ps3/ps3py/pkg.py
+PKG_SCRIPT = tools/ps3/ps3py/pkg.py
ifeq ($(shell uname), Linux)
PKG_FINALIZE = package_finalize
MAKE_SELF_WC = make_self_wc
diff --git a/Makefile.psp1 b/Makefile.psp1
index d4d43ebafa..6c00736853 100644
--- a/Makefile.psp1
+++ b/Makefile.psp1
@@ -51,7 +51,7 @@ CFLAGS += $(RARCH_DEFINES)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = RetroArch PSP1
-PSP_OBJECTS = griffin/griffin.o psp1/kernel_functions.o
+PSP_OBJECTS = griffin/griffin.o bootstrap/psp1/kernel_functions.o
OBJS = $(PSP_OBJECTS)
diff --git a/Makefile.psp1.salamander b/Makefile.psp1.salamander
index 28208574c1..c9799487b2 100644
--- a/Makefile.psp1.salamander
+++ b/Makefile.psp1.salamander
@@ -26,10 +26,10 @@ endif
CFLAGS += $(RARCH_DEFINES)
-EXTRA_TARGETS = EBOOT.PBP
+EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = RetroArch
-PSP_EBOOT_ICON = psp1/ICON0.PNG
-PSP_EBOOT_PIC1 = psp1/PIC1.PNG
+PSP_EBOOT_ICON = pkg/psp1/ICON0.PNG
+PSP_EBOOT_PIC1 = pkg/psp1/PIC1.PNG
OBJS = frontend/frontend_salamander.o \
frontend/frontend_driver.o \
@@ -41,8 +41,10 @@ OBJS = frontend/frontend_salamander.o \
libretro-common/file/retro_dirent.o \
libretro-common/compat/compat.o \
libretro-common/file/config_file.o \
+ libretro-common/file/retro_file.o \
+ libretro-common/file/retro_stat.o \
libretro-common/hash/rhash.o \
- psp1/kernel_functions.o
+ bootstrap/psp1/kernel_functions.o
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
diff --git a/Makefile.wii.salamander b/Makefile.wii.salamander
index af395708f5..530e20341a 100644
--- a/Makefile.wii.salamander
+++ b/Makefile.wii.salamander
@@ -48,7 +48,9 @@ OBJ = frontend/frontend_salamander.o \
libretro-common/hash/rhash.o \
libretro-common/string/string_list.o \
libretro-common/file/dir_list.o \
+ libretro-common/file/retro_file.o \
libretro-common/file/retro_dirent.o \
+ libretro-common/file/retro_stat.o \
libretro-common/compat/compat.o \
libretro-common/file/config_file.o \
$(APP_BOOTER_DIR)/app_booter.binobj
@@ -56,13 +58,11 @@ OBJ = frontend/frontend_salamander.o \
ifeq ($(HAVE_LOGGER), 1)
CFLAGS += -DHAVE_LOGGER
CFLAGS += -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT)
-CFLAGS += -Ilogger/netlogger
-OBJ += logger/netlogger/logger.o
+OBJ += logger/netlogger.o
endif
ifeq ($(HAVE_FILE_LOGGER), 1)
CFLAGS += -DHAVE_FILE_LOGGER
-CFLAGS += -Ilogger/netlogger
endif
CFLAGS += -std=gnu99 -DIS_SALAMANDER -DRARCH_CONSOLE -DHAVE_RARCH_EXEC -DGEKKO -Wno-char-subscripts
diff --git a/README.md b/README.md
index 7b8fa5c1ab..8b4b5e5e74 100644
--- a/README.md
+++ b/README.md
@@ -123,20 +123,20 @@ make
Mac
- Prerequisites: [XCode](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB4QFjAA&url=https%3A%2F%2Fitunes.apple.com%2Fus%2Fapp%2Fxcode%2Fid497799835%3Fmt%3D12&ei=ZmfeVNPtIILVoASBnoCYBw&usg=AFQjCNGrxKmVtXUdvUU3MhqZhP4MHT6Gtg&sig2=RIXKsWQ79YTQBt_lK5fdKA&bvm=bv.85970519,d.cGU), [Cg](https://developer.nvidia.com/cg-toolkit-download).
-- You can open the project (**apple/RetroArch.xcodeproj**) in the Xcode IDE and build (**⌘-B**) and run (**⌘-R**) it there. Or you can use the command line...
+- You can open the project (**pkg/apple/RetroArch.xcodeproj**) in the Xcode IDE and build (**⌘-B**) and run (**⌘-R**) it there. Or you can use the command line...
- Debug:
```bash
# Build
-xcodebuild -target RetroArch -configuration Debug -project apple/RetroArch.xcodeproj
+xcodebuild -target RetroArch -configuration Debug -project pkg/apple/RetroArch.xcodeproj
# Run
-open ./apple/build/Debug/RetroArch.app/
+open ./pkg/apple/build/Debug/RetroArch.app/
```
- Release:
```bash
# Build
-xcodebuild -target RetroArch -configuration Release -project apple/RetroArch.xcodeproj
+xcodebuild -target RetroArch -configuration Release -project pkg/apple/RetroArch.xcodeproj
# Run
-open ./apple/build/Release/RetroArch.app/
+open ./pkg/apple/build/Release/RetroArch.app/
```
PC
@@ -186,9 +186,9 @@ You will need Microsoft Visual Studio 2010 installed (or higher) in order to com
The solution file can be found at the following location:
-msvc-360/RetroArch-360.sln
+pkg/msvc-360/RetroArch-360.sln
-NOTE: A pre-existing libretro library needs to be present in the `msvc-360/RetroArch-360/Release` directory in order to link RetroArch 360. This file needs to be
+NOTE: A pre-existing libretro library needs to be present in the `pkg/msvc-360/RetroArch-360/Release` directory in order to link RetroArch 360. This file needs to be
called `libretro_xdk360.lib`.
Xbox 360 (Libxenon)
diff --git a/audio/audio_driver.c b/audio/audio_driver.c
index 1e20bb1e6b..56be7bea87 100644
--- a/audio/audio_driver.c
+++ b/audio/audio_driver.c
@@ -594,15 +594,19 @@ void audio_driver_set_nonblocking_state(bool enable)
**/
bool audio_driver_flush(const int16_t *data, size_t samples)
{
- const void *output_data = NULL;
- unsigned output_frames = 0;
- size_t output_size = sizeof(float);
- struct resampler_data src_data = {0};
- struct rarch_dsp_data dsp_data = {0};
- driver_t *driver = driver_get_ptr();
- const audio_driver_t *audio = driver ?
+ static struct retro_perf_counter audio_convert_s16 = {0};
+ static struct retro_perf_counter audio_convert_float = {0};
+ static struct retro_perf_counter audio_dsp = {0};
+ static struct retro_perf_counter resampler_proc = {0};
+ struct resampler_data src_data = {0};
+ struct rarch_dsp_data dsp_data = {0};
+ const void *output_data = NULL;
+ unsigned output_frames = 0;
+ size_t output_size = sizeof(float);
+ driver_t *driver = driver_get_ptr();
+ const audio_driver_t *audio = driver ?
(const audio_driver_t*)driver->audio : NULL;
- settings_t *settings = config_get_ptr();
+ settings_t *settings = config_get_ptr();
if (driver->recording_data)
{
@@ -619,11 +623,11 @@ bool audio_driver_flush(const int16_t *data, size_t samples)
if (!driver->audio_active || !audio_data.data)
return false;
- RARCH_PERFORMANCE_INIT(audio_convert_s16);
- RARCH_PERFORMANCE_START(audio_convert_s16);
+ rarch_perf_init(&audio_convert_s16, "audio_convert_s16");
+ retro_perf_start(&audio_convert_s16);
audio_convert_s16_to_float(audio_data.data, data, samples,
audio_data.volume_gain);
- RARCH_PERFORMANCE_STOP(audio_convert_s16);
+ retro_perf_stop(&audio_convert_s16);
src_data.data_in = audio_data.data;
src_data.input_frames = samples >> 1;
@@ -633,10 +637,10 @@ bool audio_driver_flush(const int16_t *data, size_t samples)
if (audio_data.dsp)
{
- RARCH_PERFORMANCE_INIT(audio_dsp);
- RARCH_PERFORMANCE_START(audio_dsp);
+ rarch_perf_init(&audio_dsp, "audio_dsp");
+ retro_perf_start(&audio_dsp);
rarch_dsp_filter_process(audio_data.dsp, &dsp_data);
- RARCH_PERFORMANCE_STOP(audio_dsp);
+ retro_perf_stop(&audio_dsp);
if (dsp_data.output)
{
@@ -654,22 +658,22 @@ bool audio_driver_flush(const int16_t *data, size_t samples)
if (rarch_main_is_slowmotion())
src_data.ratio *= settings->slowmotion_ratio;
- RARCH_PERFORMANCE_INIT(resampler_proc);
- RARCH_PERFORMANCE_START(resampler_proc);
+ rarch_perf_init(&resampler_proc, "resampler_proc");
+ retro_perf_start(&resampler_proc);
rarch_resampler_process(driver->resampler,
driver->resampler_data, &src_data);
- RARCH_PERFORMANCE_STOP(resampler_proc);
+ retro_perf_stop(&resampler_proc);
output_data = audio_data.outsamples;
output_frames = src_data.output_frames;
if (!audio_data.use_float)
{
- RARCH_PERFORMANCE_INIT(audio_convert_float);
- RARCH_PERFORMANCE_START(audio_convert_float);
+ rarch_perf_init(&audio_convert_float, "audio_convert_float");
+ retro_perf_start(&audio_convert_float);
audio_convert_float_to_s16(audio_data.conv_outsamples,
(const float*)output_data, output_frames * 2);
- RARCH_PERFORMANCE_STOP(audio_convert_float);
+ retro_perf_stop(&audio_convert_float);
output_data = audio_data.conv_outsamples;
output_size = sizeof(int16_t);
diff --git a/audio/audio_dsp_filter.c b/audio/audio_dsp_filter.c
index c0b9d77d02..923b052ab9 100644
--- a/audio/audio_dsp_filter.c
+++ b/audio/audio_dsp_filter.c
@@ -146,7 +146,7 @@ static const dspfilter_get_implementation_t dsp_plugs_builtin[] = {
static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
{
unsigned i;
- dspfilter_simd_mask_t mask = rarch_get_cpu_features();
+ dspfilter_simd_mask_t mask = retro_get_cpu_features();
(void)list;
@@ -170,7 +170,7 @@ static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
{
unsigned i;
- dspfilter_simd_mask_t mask = rarch_get_cpu_features();
+ dspfilter_simd_mask_t mask = retro_get_cpu_features();
for (i = 0; i < list->size; i++)
{
diff --git a/audio/audio_filters/Makefile b/audio/audio_filters/Makefile
index 44b9e38df5..3d3be558fc 100644
--- a/audio/audio_filters/Makefile
+++ b/audio/audio_filters/Makefile
@@ -42,7 +42,7 @@ ifeq (debug,$(build))
extra_flags += -O0 -g
endif
-ldflags := -shared -lm -Wl,--version-script=link.T
+ldflags := $(LDFLAGS) -shared -lm -Wl,--version-script=link.T
ifeq ($(platform), unix)
DYLIB = so
@@ -57,8 +57,8 @@ endif
CC := $(compiler) -Wall
CXX := $(subst CC,++,$(compiler)) -std=gnu++0x -Wall
-flags := -fPIC $(extra_flags) -I../../libretro-common/include
-asflags := -fPIC $(extra_flags)
+flags := $(CFLAGS) -fPIC $(extra_flags) -I../../libretro-common/include
+asflags := $(ASFLAGS) -fPIC $(extra_flags)
objects :=
ifeq (1,$(use_neon))
diff --git a/audio/audio_resampler_driver.c b/audio/audio_resampler_driver.c
index c483104f85..495f9317fa 100644
--- a/audio/audio_resampler_driver.c
+++ b/audio/audio_resampler_driver.c
@@ -171,7 +171,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb;
static resampler_simd_mask_t resampler_get_cpu_features(void)
{
#ifdef RARCH_INTERNAL
- return rarch_get_cpu_features();
+ return retro_get_cpu_features();
#else
return perf_get_cpu_features_cb();
#endif
diff --git a/audio/audio_utils.c b/audio/audio_utils.c
index 6fb1196df4..63f6b99bd1 100644
--- a/audio/audio_utils.c
+++ b/audio/audio_utils.c
@@ -215,7 +215,7 @@ void audio_convert_float_to_s16_altivec(int16_t *out,
}
audio_convert_float_to_s16_C(out, in, samples_in);
}
-#elif defined(__ARM_NEON__)
+#elif defined(__ARM_NEON__) && !defined(VITA)
/* Avoid potential hard-float/soft-float ABI issues. */
void audio_convert_s16_float_asm(float *out, const int16_t *in,
size_t samples, const float *gain);
@@ -409,7 +409,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb;
static unsigned audio_convert_get_cpu_features(void)
{
#ifdef RARCH_INTERNAL
- return rarch_get_cpu_features();
+ return retro_get_cpu_features();
#else
return perf_get_cpu_features_cb();
#endif
@@ -426,7 +426,7 @@ void audio_convert_init_simd(void)
unsigned cpu = audio_convert_get_cpu_features();
(void)cpu;
-#if defined(__ARM_NEON__)
+#if defined(__ARM_NEON__) && !defined(VITA)
audio_convert_s16_to_float_arm = cpu & RETRO_SIMD_NEON ?
audio_convert_s16_to_float_neon : audio_convert_s16_to_float_C;
audio_convert_float_to_s16_arm = cpu & RETRO_SIMD_NEON ?
diff --git a/audio/audio_utils.h b/audio/audio_utils.h
index 915f44881a..024ece150f 100644
--- a/audio/audio_utils.h
+++ b/audio/audio_utils.h
@@ -93,7 +93,7 @@ void audio_convert_s16_to_float_altivec(float *out,
void audio_convert_float_to_s16_altivec(int16_t *out,
const float *in, size_t samples);
-#elif defined(__ARM_NEON__)
+#elif defined(__ARM_NEON__) && !defined(VITA)
#define audio_convert_s16_to_float audio_convert_s16_to_float_arm
#define audio_convert_float_to_s16 audio_convert_float_to_s16_arm
diff --git a/audio/drivers/coreaudio.c b/audio/drivers/coreaudio.c
index 5ec6ba8d4d..95d1c35a23 100644
--- a/audio/drivers/coreaudio.c
+++ b/audio/drivers/coreaudio.c
@@ -15,7 +15,6 @@
*/
#include
-#include
#if TARGET_OS_IPHONE
#include
@@ -29,6 +28,7 @@
#include
#include
+#include
#include
#include "../../driver.h"
@@ -44,8 +44,8 @@
typedef struct coreaudio
{
- pthread_mutex_t lock;
- pthread_cond_t cond;
+ slock_t *lock;
+ scond_t *cond;
#ifdef OSX_PPC
ComponentInstance dev;
@@ -82,8 +82,8 @@ static void coreaudio_free(void *data)
if (dev->buffer)
fifo_free(dev->buffer);
- pthread_mutex_destroy(&dev->lock);
- pthread_cond_destroy(&dev->cond);
+ slock_free(dev->lock);
+ scond_free(dev->cond);
free(dev);
}
@@ -109,7 +109,7 @@ static OSStatus audio_write_cb(void *userdata,
write_avail = io_data->mBuffers[0].mDataByteSize;
outbuf = io_data->mBuffers[0].mData;
- pthread_mutex_lock(&dev->lock);
+ slock_lock(dev->lock);
if (fifo_read_avail(dev->buffer) < write_avail)
{
@@ -118,16 +118,16 @@ static OSStatus audio_write_cb(void *userdata,
/* Seems to be needed. */
memset(outbuf, 0, write_avail);
- pthread_mutex_unlock(&dev->lock);
+ slock_unlock(dev->lock);
/* Technically possible to deadlock without. */
- pthread_cond_signal(&dev->cond);
+ scond_signal(dev->cond);
return noErr;
}
fifo_read(dev->buffer, outbuf, write_avail);
- pthread_mutex_unlock(&dev->lock);
- pthread_cond_signal(&dev->cond);
+ slock_unlock(dev->lock);
+ scond_signal(dev->cond);
return noErr;
}
@@ -218,8 +218,8 @@ static void *coreaudio_init(const char *device,
if (!dev)
return NULL;
- pthread_mutex_init(&dev->lock, NULL);
- pthread_cond_init(&dev->cond, NULL);
+ dev->lock = slock_new();
+ dev->cond = scond_new();
#if TARGET_OS_IPHONE
if (!session_initialized)
@@ -343,22 +343,11 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
const uint8_t *buf = (const uint8_t*)buf_;
size_t written = 0;
-#if TARGET_OS_IPHONE
- struct timespec timeout;
- struct timeval time;
-
- gettimeofday(&time, 0);
-
- memset(&timeout, 0, sizeof(timeout));
- timeout.tv_sec = time.tv_sec + 3;
- timeout.tv_nsec = time.tv_usec * 1000;
-#endif
-
while (!g_interrupted && size > 0)
{
size_t write_avail;
- pthread_mutex_lock(&dev->lock);
+ slock_lock(dev->lock);
write_avail = fifo_write_avail(dev->buffer);
if (write_avail > size)
@@ -371,19 +360,19 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
if (dev->nonblock)
{
- pthread_mutex_unlock(&dev->lock);
+ slock_unlock(dev->lock);
break;
}
#if TARGET_OS_IPHONE
- if (write_avail == 0 && pthread_cond_timedwait(
- &dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
+ if (write_avail == 0 && !scond_wait_timeout(
+ dev->cond, dev->lock, 3000000))
g_interrupted = true;
#else
if (write_avail == 0)
- pthread_cond_wait(&dev->cond, &dev->lock);
+ scond_wait(dev->cond, dev->lock);
#endif
- pthread_mutex_unlock(&dev->lock);
+ slock_unlock(dev->lock);
}
return written;
@@ -433,9 +422,9 @@ static size_t coreaudio_write_avail(void *data)
size_t avail;
coreaudio_t *dev = (coreaudio_t*)data;
- pthread_mutex_lock(&dev->lock);
+ slock_lock(dev->lock);
avail = fifo_write_avail(dev->buffer);
- pthread_mutex_unlock(&dev->lock);
+ slock_unlock(dev->lock);
return avail;
}
diff --git a/audio/drivers/ctr_audio.c b/audio/drivers/ctr_audio.c
index a4119ef6a9..809f530055 100644
--- a/audio/drivers/ctr_audio.c
+++ b/audio/drivers/ctr_audio.c
@@ -34,7 +34,6 @@ typedef struct
uint64_t cpu_ticks_last;
int rate;
-
} ctr_audio_t;
#define CTR_AUDIO_COUNT (1u << 11u)
@@ -44,28 +43,26 @@ typedef struct
static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
{
+ ctr_audio_t *ctr = (ctr_audio_t*)calloc(1, sizeof(ctr_audio_t));
+ if (!ctr)
+ return NULL;
(void)device;
(void)rate;
(void)latency;
-// if(!csndInit())
-// return NULL;
-
- ctr_audio_t *ctr = (ctr_audio_t*)calloc(1, sizeof(ctr_audio_t));
-
- ctr->l = linearAlloc(CTR_AUDIO_SIZE);
- ctr->r = linearAlloc(CTR_AUDIO_SIZE);
+ ctr->l = linearAlloc(CTR_AUDIO_SIZE);
+ ctr->r = linearAlloc(CTR_AUDIO_SIZE);
memset(ctr->l, 0, CTR_AUDIO_SIZE);
memset(ctr->r, 0, CTR_AUDIO_SIZE);
- ctr->l_paddr = osConvertVirtToPhys((u32)ctr->l);
- ctr->r_paddr = osConvertVirtToPhys((u32)ctr->r);
+ ctr->l_paddr = osConvertVirtToPhys((u32)ctr->l);
+ ctr->r_paddr = osConvertVirtToPhys((u32)ctr->r);
- ctr->pos = 0;
- ctr->rate = rate;
+ ctr->pos = 0;
+ ctr->rate = rate;
ctr->cpu_ticks_per_sample = CSND_TIMER(rate) * 4;
GSPGPU_FlushDataCache(NULL, (u8*)ctr->l_paddr, CTR_AUDIO_SIZE);
@@ -76,9 +73,9 @@ static void *ctr_audio_init(const char *device, unsigned rate, unsigned latency)
csndPlaySound(0x9, SOUND_LOOPMODE(CSND_LOOPMODE_NORMAL)| SOUND_FORMAT(CSND_ENCODING_PCM16),
rate, 1.0, 1.0, ctr->r, ctr->r, CTR_AUDIO_SIZE);
- ctr->playpos = 0;
- ctr->cpu_ticks_last = svcGetSystemTick();
- ctr->playing = true;
+ ctr->playpos = 0;
+ ctr->cpu_ticks_last = svcGetSystemTick();
+ ctr->playing = true;
return ctr;
}
@@ -100,20 +97,22 @@ static void ctr_audio_free(void *data)
static ssize_t ctr_audio_write(void *data, const void *buf, size_t size)
{
+ int i;
+ uint32_t samples_played;
+ uint64_t current_tick;
+ static struct retro_perf_counter ctraudio_f = {0};
+ const uint16_t *src = buf;
+ ctr_audio_t *ctr = (ctr_audio_t*)data;
+
(void)data;
(void)buf;
- ctr_audio_t* ctr = (ctr_audio_t*)data;
+ rarch_perf_init(&ctraudio_f, "ctraudio_f");
+ retro_perf_start(&ctraudio_f);
- int i;
- const uint16_t* src = buf;
-
- RARCH_PERFORMANCE_INIT(ctraudio_f);
- RARCH_PERFORMANCE_START(ctraudio_f);
-
- uint64_t current_tick = svcGetSystemTick();
- uint32_t samples_played = (current_tick - ctr->cpu_ticks_last) / ctr->cpu_ticks_per_sample;
- ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK;
+ current_tick = svcGetSystemTick();
+ samples_played = (current_tick - ctr->cpu_ticks_last) / ctr->cpu_ticks_per_sample;
+ ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK;
ctr->cpu_ticks_last += samples_played * ctr->cpu_ticks_per_sample;
@@ -127,7 +126,7 @@ static ssize_t ctr_audio_write(void *data, const void *buf, size_t size)
{
do{
/* todo: compute the correct sleep period */
- rarch_sleep(1);
+ retro_sleep(1);
current_tick = svcGetSystemTick();
samples_played = (current_tick - ctr->cpu_ticks_last) / ctr->cpu_ticks_per_sample;
ctr->playpos = (ctr->playpos + samples_played) & CTR_AUDIO_COUNT_MASK;
@@ -144,11 +143,11 @@ static ssize_t ctr_audio_write(void *data, const void *buf, size_t size)
ctr->pos++;
ctr->pos &= CTR_AUDIO_COUNT_MASK;
}
+
GSPGPU_FlushDataCache(NULL, (u8*)ctr->l, CTR_AUDIO_SIZE);
GSPGPU_FlushDataCache(NULL, (u8*)ctr->r, CTR_AUDIO_SIZE);
-
- RARCH_PERFORMANCE_STOP(ctraudio_f);
+ retro_perf_stop(&ctraudio_f);
return size;
}
@@ -160,8 +159,10 @@ static bool ctr_audio_stop(void *data)
/* using SetPlayState would make tracking the playback
* position more difficult */
-// CSND_SetPlayState(0x8, 0);
-// CSND_SetPlayState(0x9, 0);
+#if 0
+ CSND_SetPlayState(0x8, 0);
+ CSND_SetPlayState(0x9, 0);
+#endif
/* setting the channel volume to 0 seems to make it
* impossible to set it back to full volume later */
@@ -186,14 +187,16 @@ static bool ctr_audio_start(void *data)
ctr_audio_t* ctr = (ctr_audio_t*)data;
rarch_system_info_t *system = rarch_system_info_get_ptr();
- /* prevents restarting audio when the menu
+ /* Prevents restarting audio when the menu
* is toggled off on shutdown */
if (system->shutdown)
return true;
-// CSND_SetPlayState(0x8, 1);
-// CSND_SetPlayState(0x9, 1);
+#if 0
+ CSND_SetPlayState(0x8, 1);
+ CSND_SetPlayState(0x9, 1);
+#endif
CSND_SetVol(0x8, 0x00008000, 0);
CSND_SetVol(0x9, 0x80000000, 0);
diff --git a/audio/drivers/dsound.c b/audio/drivers/dsound.c
index aeb27713fd..26a6b5bb85 100644
--- a/audio/drivers/dsound.c
+++ b/audio/drivers/dsound.c
@@ -166,7 +166,7 @@ static void dsound_thread(void *data)
* but it is not guaranteed to work, so use high
* priority sleeping patterns.
*/
- rarch_sleep(1);
+ retro_sleep(1);
continue;
}
diff --git a/audio/drivers/openal.c b/audio/drivers/openal.c
index 1a746e5a6b..e8ce4495aa 100644
--- a/audio/drivers/openal.c
+++ b/audio/drivers/openal.c
@@ -151,7 +151,7 @@ static bool al_get_buffer(al_t *al, ALuint *buffer)
return false;
/* Must sleep as there is no proper blocking method. */
- rarch_sleep(1);
+ retro_sleep(1);
}
}
diff --git a/audio/drivers/psp_audio.c b/audio/drivers/psp_audio.c
index b07d14903a..02df989dc7 100644
--- a/audio/drivers/psp_audio.c
+++ b/audio/drivers/psp_audio.c
@@ -48,6 +48,13 @@ typedef struct psp_audio
#define AUDIO_BUFFER_SIZE (1u<<13u)
#define AUDIO_BUFFER_SIZE_MASK (AUDIO_BUFFER_SIZE-1)
+#ifdef VITA
+#define PSP_THREAD_STOPPED PSP2_THREAD_STOPPED
+#else
+#define SceKernelThreadInfo SceKernelThreadRunStatus
+#define sceKernelGetThreadInfo sceKernelReferThreadRunStatus
+#endif
+
static int audioMainLoop(SceSize args, void* argp)
{
psp_audio_t* psp = *((psp_audio_t**)argp);
@@ -190,37 +197,22 @@ static bool psp_audio_alive(void *data)
return psp->running;
}
+
static bool psp_audio_stop(void *data)
{
+ SceKernelThreadInfo info;
SceUInt timeout = 100000;
psp_audio_t* psp = (psp_audio_t*)data;
-#if defined(VITA)
- SceKernelThreadInfo info;
-
info.size = sizeof(SceKernelThreadInfo);
if (sceKernelGetThreadInfo(
psp->thread, &info) < 0) /* Error */
return false;
- if (info.status == PSP2_THREAD_STOPPED)
+ if (info.status == PSP_THREAD_STOPPED)
return false;
-#else
- SceKernelThreadRunStatus runStatus;
-
- runStatus.size = sizeof(SceKernelThreadRunStatus);
-
- if (sceKernelReferThreadRunStatus(
- psp->thread, &runStatus) < 0) /* Error */
- return false;
-
- if (runStatus.status == PSP_THREAD_STOPPED)
- return false;
-
-#endif
-
psp->running = false;
#if defined(VITA)
sceKernelWaitThreadEnd(psp->thread, NULL, &timeout);
@@ -233,10 +225,8 @@ static bool psp_audio_stop(void *data)
static bool psp_audio_start(void *data)
{
- psp_audio_t* psp = (psp_audio_t*)data;
-
-#if defined(VITA)
SceKernelThreadInfo info;
+ psp_audio_t* psp = (psp_audio_t*)data;
info.size = sizeof(SceKernelThreadInfo);
@@ -244,22 +234,9 @@ static bool psp_audio_start(void *data)
psp->thread, &info) < 0) /* Error */
return false;
- if (info.status != PSP2_THREAD_STOPPED)
+ if (info.status != PSP_THREAD_STOPPED)
return false;
-#else
- SceKernelThreadRunStatus runStatus;
-
- runStatus.size = sizeof(SceKernelThreadRunStatus);
-
- if (sceKernelReferThreadRunStatus(
- psp->thread, &runStatus) < 0) /* Error */
- return false;
- if (runStatus.status != PSP_THREAD_STOPPED)
- return false;
-
-#endif
-
psp->running = true;
sceKernelStartThread(psp->thread, sizeof(psp_audio_t*), &psp);
diff --git a/audio/drivers_resampler/sinc.c b/audio/drivers_resampler/sinc.c
index 2ae4edf194..8605aeae3d 100644
--- a/audio/drivers_resampler/sinc.c
+++ b/audio/drivers_resampler/sinc.c
@@ -334,7 +334,7 @@ static void process_sinc(rarch_sinc_resampler_t *resamp, float *out_buffer)
/* movehl { X, R, X, L } == { X, R, X, R } */
_mm_store_ss(out_buffer + 1, _mm_movehl_ps(sum, sum));
}
-#elif defined(__ARM_NEON__)
+#elif defined(__ARM_NEON__) && !defined(VITA)
#if SINC_COEFF_LERP
#error "NEON asm does not support SINC lerp."
@@ -437,7 +437,7 @@ static void *resampler_sinc_new(const struct resampler_config *config,
}
/* Be SIMD-friendly. */
-#if (defined(__AVX__) && ENABLE_AVX) || defined(__ARM_NEON__)
+#if (defined(__AVX__) && ENABLE_AVX) || (defined(__ARM_NEON__)&& !defined(VITA))
re->taps = (re->taps + 7) & ~7;
#else
re->taps = (re->taps + 3) & ~3;
@@ -460,7 +460,7 @@ static void *resampler_sinc_new(const struct resampler_config *config,
init_sinc_table(re, cutoff, re->phase_table,
1 << PHASE_BITS, re->taps, SINC_COEFF_LERP);
-#if defined(__ARM_NEON__)
+#if defined(__ARM_NEON__) && !defined(VITA)
process_sinc_func = mask & RESAMPLER_SIMD_NEON
? process_sinc_neon : process_sinc_C;
#endif
@@ -480,4 +480,3 @@ rarch_resampler_t sinc_resampler = {
"sinc",
"sinc"
};
-
diff --git a/audio/librsound.c b/audio/librsound.c
index 30f5e3d2bb..2c583206ee 100644
--- a/audio/librsound.c
+++ b/audio/librsound.c
@@ -153,7 +153,6 @@ static int rsnd_send_info_query(rsound_t *rd);
static int rsnd_update_server_info(rsound_t *rd);
static int rsnd_poll(struct pollfd *fd, int numfd, int timeout);
-static void rsnd_sleep(int msec);
static void rsnd_cb_thread(void *thread_data);
static void rsnd_thread(void *thread_data);
@@ -363,12 +362,12 @@ static int rsnd_send_header_info(rsound_t *rd)
#define LSB16(x) if ( !rsnd_is_little_endian() ) { rsnd_swap_endian_16(&(x)); }
#define LSB32(x) if ( !rsnd_is_little_endian() ) { rsnd_swap_endian_32(&(x)); }
- // Here we embed in the rest of the WAV header for it to be somewhat valid
+ /* Here we embed in the rest of the WAV header for it to be somewhat valid */
- strcpy(header, "RIFF");
+ strlcpy(header, "RIFF", sizeof(header));
SET32(header, 4, 0);
- strcpy(header+8, "WAVE");
- strcpy(header+12, "fmt ");
+ strlcpy(header+8, "WAVE", sizeof(header));
+ strlcpy(header+12, "fmt ", sizeof(header));
temp32 = 16;
LSB32(temp32);
@@ -414,15 +413,15 @@ static int rsnd_send_header_info(rsound_t *rd)
LSB16(temp_bits);
SET16(header, FRAMESIZE, temp_bits);
- strcpy(header+36, "data");
+ strlcpy(header+36, "data", sizeof(header));
- // Do not care about cksize here (impossible to know beforehand). It is used by
- // the server for format.
+ /* Do not care about cksize here (impossible to know beforehand).
+ * It is used by the server for format. */
LSB16(temp_format);
SET16(header, FORMAT, temp_format);
- // End static header
+ /* End static header */
if ( rsnd_send_chunk(rd->conn.socket, header, HEADER_SIZE, 1) != HEADER_SIZE )
{
@@ -748,12 +747,6 @@ static int64_t rsnd_get_time_usec(void)
#endif
}
-static void rsnd_sleep(int msec)
-{
- rarch_sleep(msec);
-}
-
-
/* Calculates how many bytes there are in total in the virtual buffer. This is calculated client side.
It should be accurate enough unless we have big problems with buffer underruns.
This function is called by rsd_delay() to determine the latency.
@@ -1246,7 +1239,7 @@ static void rsnd_cb_thread(void *thread_data)
// The network might do things in large chunks, so it may request large amounts of data in short periods of time.
// This breaks when the caller cannot buffer up big buffers beforehand, so do short sleeps inbetween.
// This is somewhat dirty, but I cannot see a better solution
- rsnd_sleep(1);
+ retro_sleep(1);
}
}
}
@@ -1513,7 +1506,7 @@ void rsd_delay_wait(rsound_t *rd)
{
int64_t sleep_ms = latency_ms - rd->max_latency;
RSD_DEBUG("[RSound] Delay wait: %d ms.\n", (int)sleep_ms);
- rsnd_sleep((int)sleep_ms);
+ retro_sleep((int)sleep_ms);
}
}
}
diff --git a/audio/test/Makefile b/audio/test/Makefile
index 87db6b367e..c6c421a7b7 100644
--- a/audio/test/Makefile
+++ b/audio/test/Makefile
@@ -23,6 +23,7 @@ SHAREDOBJ += $(LIBRETRO_COMM_DIR)/memmap/memalign.o \
$(LIBRETRO_COMM_DIR)/string/string_list.o \
$(LIBRETRO_COMM_DIR)/file/config_file_userdata.o \
$(LIBRETRO_COMM_DIR)/file/config_file.o \
+ $(LIBRETRO_COMM_DIR)/file/retro_file.o \
$(LIBRETRO_COMM_DIR)/file/file_path.o \
$(LIBRETRO_COMM_DIR)/compat/compat.o \
$(LIBRETRO_COMM_DIR)/hash/rhash.o \
diff --git a/gx/ld/ogc.ld b/bootstrap/gx/ogc.ld
similarity index 100%
rename from gx/ld/ogc.ld
rename to bootstrap/gx/ogc.ld
diff --git a/gx/ld/rvl.ld b/bootstrap/gx/rvl.ld
similarity index 100%
rename from gx/ld/rvl.ld
rename to bootstrap/gx/rvl.ld
diff --git a/psp1/kernel_functions_prx/Makefile b/bootstrap/psp1/kernel_functions_prx/Makefile
similarity index 93%
rename from psp1/kernel_functions_prx/Makefile
rename to bootstrap/psp1/kernel_functions_prx/Makefile
index b417ccb4f2..0b6cdc3d41 100644
--- a/psp1/kernel_functions_prx/Makefile
+++ b/bootstrap/psp1/kernel_functions_prx/Makefile
@@ -21,7 +21,7 @@ include $(PSPSDK)/lib/build.mak
all:
psp-build-exports -s $(PRX_EXPORTS)
- cp $(TARGET).prx ../../$(TARGET).prx
+ cp $(TARGET).prx ../../../$(TARGET).prx
cp $(TARGET).S ../$(TARGET).S
cp $(TARGET).h ../$(TARGET).h
rm -f $(TARGET).prx
diff --git a/psp1/kernel_functions_prx/kernel_functions.exp b/bootstrap/psp1/kernel_functions_prx/kernel_functions.exp
similarity index 100%
rename from psp1/kernel_functions_prx/kernel_functions.exp
rename to bootstrap/psp1/kernel_functions_prx/kernel_functions.exp
diff --git a/psp1/kernel_functions_prx/kernel_functions.h b/bootstrap/psp1/kernel_functions_prx/kernel_functions.h
similarity index 99%
rename from psp1/kernel_functions_prx/kernel_functions.h
rename to bootstrap/psp1/kernel_functions_prx/kernel_functions.h
index 52cec35adb..07254f5598 100644
--- a/psp1/kernel_functions_prx/kernel_functions.h
+++ b/bootstrap/psp1/kernel_functions_prx/kernel_functions.h
@@ -8,6 +8,7 @@ extern "C" {
#endif
unsigned int read_system_buttons(void);
+
void exitspawn_kernel( const char* fileName, SceSize args, void * argp);
#ifdef __cplusplus
diff --git a/psp1/kernel_functions_prx/main.c b/bootstrap/psp1/kernel_functions_prx/main.c
similarity index 95%
rename from psp1/kernel_functions_prx/main.c
rename to bootstrap/psp1/kernel_functions_prx/main.c
index a17bc5a8b3..335b156097 100644
--- a/psp1/kernel_functions_prx/main.c
+++ b/bootstrap/psp1/kernel_functions_prx/main.c
@@ -1,16 +1,15 @@
#include
+#include
#include
#include
#include
#include
#include
-#include
PSP_MODULE_INFO("kernel_functions", PSP_MODULE_KERNEL, 0, 0);
PSP_MAIN_THREAD_ATTR(0);
-
static volatile int thread_active;
static unsigned int buttons;
static SceUID main_thread_id;
@@ -33,16 +32,17 @@ static int main_thread(SceSize args, void *argp)
return 0;
}
-
unsigned int read_system_buttons(void)
{
return buttons;
}
-void exitspawn_kernel( const char* fileName, SceSize args, void * argp){
- thread_active = 0;
+void exitspawn_kernel(const char *fileName, SceSize args, void *argp)
+{
struct SceKernelLoadExecVSHParam game_param;
+ thread_active = 0;
+
memset(&game_param,0,sizeof(game_param));
game_param.size = sizeof(game_param);
@@ -75,7 +75,6 @@ int module_start(SceSize args, void *argp)
return 0;
}
-
int module_stop(void)
{
if (main_thread_id >= 0)
diff --git a/camera/drivers/video4linux2.c b/camera/drivers/video4linux2.c
index aa8a837d75..07e142e76d 100644
--- a/camera/drivers/video4linux2.c
+++ b/camera/drivers/video4linux2.c
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -35,6 +34,7 @@
#include
#include
#include
+#include
#include
@@ -63,13 +63,14 @@ typedef struct video4linux
char dev_name[PATH_MAX_LENGTH];
} video4linux_t;
-static void process_image(video4linux_t *v4l,
- const uint8_t *buffer_yuv)
+static void process_image(video4linux_t *v4l, const uint8_t *buffer_yuv)
{
- RARCH_PERFORMANCE_INIT(yuv_convert_direct);
- RARCH_PERFORMANCE_START(yuv_convert_direct);
+ static struct retro_perf_counter yuv_convert_direct = {0};
+
+ rarch_perf_init(&yuv_convert_direct, "yuv_convert_direct");
+ retro_perf_start(&yuv_convert_direct);
scaler_ctx_scale(&v4l->scaler, v4l->buffer_output, buffer_yuv);
- RARCH_PERFORMANCE_STOP(yuv_convert_direct);
+ retro_perf_stop(&yuv_convert_direct);
}
static int xioctl(int fd, int request, void *args)
@@ -95,7 +96,7 @@ static bool init_mmap(void *data)
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
- if (xioctl(v4l->fd, VIDIOC_REQBUFS, &req) == -1)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_REQBUFS, &req) == -1)
{
if (errno == EINVAL)
RARCH_ERR("%s does not support memory mapping.\n", v4l->dev_name);
@@ -128,7 +129,7 @@ static bool init_mmap(void *data)
buf.memory = V4L2_MEMORY_MMAP;
buf.index = v4l->n_buffers;
- if (xioctl(v4l->fd, VIDIOC_QUERYBUF, &buf) == -1)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_QUERYBUF, &buf) == -1)
{
RARCH_ERR("Error - xioctl VIDIOC_QUERYBUF.\n");
return false;
@@ -158,7 +159,7 @@ static bool init_device(void *data)
struct v4l2_format fmt;
video4linux_t *v4l = (video4linux_t*)data;
- if (xioctl(v4l->fd, VIDIOC_QUERYCAP, &cap) < 0)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_QUERYCAP, &cap) < 0)
{
if (errno == EINVAL)
RARCH_ERR("%s is no V4L2 device.\n", v4l->dev_name);
@@ -183,7 +184,7 @@ static bool init_device(void *data)
memset(&cropcap, 0, sizeof(cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (xioctl(v4l->fd, VIDIOC_CROPCAP, &cropcap) == 0)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_CROPCAP, &cropcap) == 0)
{
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
crop.c = cropcap.defrect;
@@ -199,7 +200,7 @@ static bool init_device(void *data)
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
- if (xioctl(v4l->fd, VIDIOC_S_FMT, &fmt) < 0)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_S_FMT, &fmt) < 0)
{
RARCH_ERR("Error - VIDIOC_S_FMT\n");
return false;
@@ -259,7 +260,7 @@ static bool v4l_start(void *data)
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
- if (xioctl(v4l->fd, VIDIOC_QBUF, &buf) == -1)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_QBUF, &buf) == -1)
{
RARCH_ERR("Error - VIDIOC_QBUF.\n");
return false;
@@ -299,7 +300,6 @@ static void v4l_free(void *data)
static void *v4l_init(const char *device, uint64_t caps,
unsigned width, unsigned height)
{
- struct stat st;
video4linux_t *v4l = NULL;
if ((caps & (UINT64_C(1) << RETRO_CAMERA_BUFFER_RAW_FRAMEBUFFER)) == 0)
@@ -319,14 +319,7 @@ static void *v4l_init(const char *device, uint64_t caps,
v4l->height = height;
v4l->ready = false;
- if (stat(v4l->dev_name, &st) == -1)
- {
- RARCH_ERR("Cannot identify '%s' : %d, %s\n", v4l->dev_name,
- errno, strerror(errno));
- goto error;
- }
-
- if (!S_ISCHR(st.st_mode))
+ if (!path_is_character_special(v4l->dev_name))
{
RARCH_ERR("%s is no device.\n", v4l->dev_name);
goto error;
@@ -384,7 +377,7 @@ static bool preprocess_image(void *data)
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
- if (xioctl(v4l->fd, VIDIOC_DQBUF, &buf) == -1)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_DQBUF, &buf) == -1)
{
switch (errno)
{
@@ -400,7 +393,7 @@ static bool preprocess_image(void *data)
process_image(v4l, (const uint8_t*)v4l->buffers[buf.index].start);
- if (xioctl(v4l->fd, VIDIOC_QBUF, &buf) == -1)
+ if (xioctl(v4l->fd, (uint8_t)VIDIOC_QBUF, &buf) == -1)
RARCH_ERR("VIDIOC_QBUF\n");
return true;
diff --git a/command.c b/command.c
index 51c13a6c56..83fdbcba08 100644
--- a/command.c
+++ b/command.c
@@ -19,7 +19,6 @@
#include
#ifndef _WIN32
-#include
#include
#endif
diff --git a/configuration.c b/configuration.c
index fe9f3a9ad2..8a32a1dacf 100644
--- a/configuration.c
+++ b/configuration.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include "config.def.h"
#include "input/input_common.h"
@@ -1630,6 +1631,7 @@ static bool config_load_file(const char *path, bool set_defaults)
CONFIG_GET_BOOL_BASE(conf, settings, network_cmd_enable, "network_cmd_enable");
CONFIG_GET_INT_BASE(conf, settings, network_cmd_port, "network_cmd_port");
CONFIG_GET_BOOL_BASE(conf, settings, stdin_cmd_enable, "stdin_cmd_enable");
+ CONFIG_GET_BOOL_BASE(conf, settings, debug_panel_enable, "debug_panel_enable");
CONFIG_GET_PATH_BASE(conf, settings, content_history_directory, "content_history_dir");
diff --git a/configuration.h b/configuration.h
index 895d9a7f3b..57e3eec6cd 100644
--- a/configuration.h
+++ b/configuration.h
@@ -326,6 +326,7 @@ typedef struct settings
bool network_cmd_enable;
unsigned network_cmd_port;
bool stdin_cmd_enable;
+ bool debug_panel_enable;
char core_assets_directory[PATH_MAX_LENGTH];
char assets_directory[PATH_MAX_LENGTH];
diff --git a/content.c b/content.c
index 60c777be1b..e02ecad309 100644
--- a/content.c
+++ b/content.c
@@ -33,6 +33,8 @@
#include
#include
#include
+#include
+#include
#include "msg_hash.h"
#include "content.h"
@@ -118,7 +120,7 @@ static void dump_to_file_desperate(const void *data,
strftime(timebuf, sizeof(timebuf), "%Y-%m-%d-%H-%M-%S", localtime(&time_));
strlcat(path, timebuf, sizeof(path));
- if (write_file(path, data, size))
+ if (retro_write_file(path, data, size))
RARCH_WARN("Succeeded in saving RAM data to \"%s\".\n", path);
else
goto error;
@@ -169,7 +171,7 @@ bool save_state(const char *path)
ret = pretro_serialize(data, size);
if (ret)
- ret = write_file(path, data, size);
+ ret = retro_write_file(path, data, size);
if (!ret)
RARCH_ERR("%s \"%s\".\n",
@@ -332,7 +334,7 @@ void save_ram_file(const char *path, int type)
if (size <= 0)
return;
- if (!write_file(path, data, size))
+ if (!retro_write_file(path, data, size))
{
RARCH_ERR("%s.\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_SRAM));
diff --git a/core_info.c b/core_info.c
index 1f748ba46a..47c70ba345 100644
--- a/core_info.c
+++ b/core_info.c
@@ -460,11 +460,13 @@ bool core_info_does_support_file(const core_info_t *core, const char *path)
core->supported_extensions_list, ".", path_get_extension(path));
}
-const char *core_info_list_get_all_extensions(core_info_list_t *core_info_list)
+const char *core_info_list_get_all_extensions(void)
{
- if (!core_info_list)
- return "";
- return core_info_list->all_ext;
+ global_t *global = global_get_ptr();
+ core_info_list_t *list = (global->core_info.list) ? global->core_info.list : NULL;
+ if (!list)
+ return NULL;
+ return list->all_ext;
}
/* qsort_r() is not in standard C, sadly. */
diff --git a/core_info.h b/core_info.h
index f223a435bf..d76c2c8ba1 100644
--- a/core_info.h
+++ b/core_info.h
@@ -99,7 +99,7 @@ void core_info_list_update_missing_firmware(core_info_list_t *list,
bool core_info_list_get_info(core_info_list_t *list,
core_info_t *info, const char *path);
-const char *core_info_list_get_all_extensions(core_info_list_t *list);
+const char *core_info_list_get_all_extensions(void);
bool core_info_list_get_display_name(core_info_list_t *list,
const char *path, char *buf, size_t size);
diff --git a/cores/image_core.c b/cores/image_core.c
index cb7ef113b9..b60bd540ab 100644
--- a/cores/image_core.c
+++ b/cores/image_core.c
@@ -17,7 +17,7 @@
#define STBI_SUPPORT_ZLIB
#endif
-#include "stb_image.h"
+#include "../deps/stb/stb_image.h"
#ifdef RARCH_INTERNAL
#include "internal_cores.h"
diff --git a/ctr/Makefile.cores b/ctr/Makefile.cores
index b973716d2b..fee4bf0caa 100644
--- a/ctr/Makefile.cores
+++ b/ctr/Makefile.cores
@@ -131,4 +131,85 @@ else ifeq ($(LIBRETRO), snes9x_next)
#APP_BANNER = ctr/libretro_banner.png
#APP_AUDIO = ctr/silent.wav
+else ifeq ($(LIBRETRO), mgba)
+ APP_TITLE = mGBA Libretro
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = Jeffrey Pfau
+ APP_PRODUCT_CODE = RARCH-MGBA
+ APP_UNIQUE_ID = 0xBAC0E
+ APP_ICON = ctr/mgba.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), quicknes)
+ APP_TITLE = QuickNES Libretro
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = blargg, kode54
+ APP_PRODUCT_CODE = RARCH-QUICKNES
+ APP_UNIQUE_ID = 0xBAC0F
+ APP_ICON = ctr/quicknes.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), fb_alpha_neo)
+ APP_TITLE = Neo Geo (FB Alpha)
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = Team FB Alpha
+ APP_PRODUCT_CODE = RARCH-FBANEOGEO
+ APP_UNIQUE_ID = 0xBAC10
+ APP_ICON = ctr/fb_alpha_neo.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), fb_alpha_cps1)
+ APP_TITLE = Final Burn Alpha - CPS-1
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = Team FB Alpha
+ APP_PRODUCT_CODE = RARCH-FBACPS1
+ APP_UNIQUE_ID = 0xBAC11
+ APP_ICON = ctr/fb_alpha_cps1.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), fb_alpha_cps2)
+ APP_TITLE = Final Burn Alpha - CPS-2
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = Team FB Alpha
+ APP_PRODUCT_CODE = RARCH-FBACPS2
+ APP_UNIQUE_ID = 0xBAC12
+ APP_ICON = ctr/fb_alpha_cps2.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), catsfc_plus)
+ APP_TITLE = CATSFC Plus Libretro
+ #APP_DESCRIPTION = Retroarch 3DS
+ #APP_AUTHOR = Team Libretro
+ APP_PRODUCT_CODE = RARCH-CATSFCPLUS
+ APP_UNIQUE_ID = 0xBAC13
+ APP_ICON = ctr/catsfc_plus.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), mednafen_pce_fast)
+ APP_TITLE = Mednafen/Beetle PCE FAST
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = Ryphecha
+ APP_PRODUCT_CODE = RARCH-M-PCE-FAST
+ APP_UNIQUE_ID = 0xBAC14
+ APP_ICON = ctr/mednafen_pce_fast.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+
+else ifeq ($(LIBRETRO), pcsx_rearmed)
+ APP_TITLE = PCSX ReARMed
+ #APP_DESCRIPTION = Retroarch 3DS
+ APP_AUTHOR = PCSX Team, notaz, Exophase
+ APP_PRODUCT_CODE = RARCH-PCSXRARMD
+ APP_UNIQUE_ID = 0xBAC15
+ APP_ICON = ctr/pcsx_rearmed.png
+ #APP_BANNER = ctr/libretro_banner.png
+ #APP_AUDIO = ctr/silent.wav
+ BUILD_3DSX = 0
+
endif
diff --git a/ctr/catsfc_plus.png b/ctr/catsfc_plus.png
new file mode 100644
index 0000000000..071967f690
Binary files /dev/null and b/ctr/catsfc_plus.png differ
diff --git a/ctr/fb_alpha_cps1.png b/ctr/fb_alpha_cps1.png
new file mode 100644
index 0000000000..6ba4673a0b
Binary files /dev/null and b/ctr/fb_alpha_cps1.png differ
diff --git a/ctr/fb_alpha_cps2.png b/ctr/fb_alpha_cps2.png
new file mode 100644
index 0000000000..69176af840
Binary files /dev/null and b/ctr/fb_alpha_cps2.png differ
diff --git a/ctr/fb_alpha_neo.png b/ctr/fb_alpha_neo.png
new file mode 100644
index 0000000000..e849770aee
Binary files /dev/null and b/ctr/fb_alpha_neo.png differ
diff --git a/ctr/mednafen_ngp.png b/ctr/mednafen_ngp.png
index d0e98e66dc..f0b3527d96 100644
Binary files a/ctr/mednafen_ngp.png and b/ctr/mednafen_ngp.png differ
diff --git a/ctr/mednafen_pce_fast.png b/ctr/mednafen_pce_fast.png
new file mode 100644
index 0000000000..eac6426613
Binary files /dev/null and b/ctr/mednafen_pce_fast.png differ
diff --git a/ctr/mednafen_vb.png b/ctr/mednafen_vb.png
index d0e98e66dc..b61718d175 100644
Binary files a/ctr/mednafen_vb.png and b/ctr/mednafen_vb.png differ
diff --git a/ctr/pcsx_rearmed.png b/ctr/pcsx_rearmed.png
new file mode 100644
index 0000000000..7333804dfb
Binary files /dev/null and b/ctr/pcsx_rearmed.png differ
diff --git a/ctr/picodrive.png b/ctr/picodrive.png
index d0e98e66dc..80252b6224 100644
Binary files a/ctr/picodrive.png and b/ctr/picodrive.png differ
diff --git a/ctr/quicknes.png b/ctr/quicknes.png
new file mode 100644
index 0000000000..11b11e0743
Binary files /dev/null and b/ctr/quicknes.png differ
diff --git a/ctr/snes9x_next.png b/ctr/snes9x_next.png
index d0e98e66dc..071967f690 100644
Binary files a/ctr/snes9x_next.png and b/ctr/snes9x_next.png differ
diff --git a/ctr/tools/makerom-linux b/ctr/tools/makerom-linux
index 82c2f391a1..afca324859 100755
Binary files a/ctr/tools/makerom-linux and b/ctr/tools/makerom-linux differ
diff --git a/ctr/tools/template-3ds.rsf b/ctr/tools/template-3ds.rsf
index daae50c076..18a5f1feed 100644
--- a/ctr/tools/template-3ds.rsf
+++ b/ctr/tools/template-3ds.rsf
@@ -1,7 +1,7 @@
BasicInfo:
- Title : "{APP_TITLE}"
+ Title : "$(APP_TITLE)"
CompanyCode : "00"
- ProductCode : "{APP_PRODUCT_CODE}"
+ ProductCode : "$(APP_PRODUCT_CODE)"
ContentType : Application
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
@@ -9,9 +9,8 @@ BasicInfo:
# Specifies the root path of the file system to include in the ROM.
# HostRoot : "romfs"
-
TitleInfo:
- UniqueId : {APP_UNIQUE_ID}
+ UniqueId : $(APP_UNIQUE_ID)
Category : Application
CardInfo:
diff --git a/ctr/tools/template-cia.rsf b/ctr/tools/template-cia.rsf
index e3cd2b9296..bfe87699ea 100644
--- a/ctr/tools/template-cia.rsf
+++ b/ctr/tools/template-cia.rsf
@@ -1,7 +1,7 @@
BasicInfo:
- Title : "{APP_TITLE}"
+ Title : "$(APP_TITLE)"
CompanyCode : "00"
- ProductCode : "{APP_PRODUCT_CODE}"
+ ProductCode : "$(APP_PRODUCT_CODE)"
ContentType : Application
Logo : Nintendo # Nintendo / Licensed / Distributed / iQue / iQueForSystem
@@ -10,7 +10,7 @@ BasicInfo:
# HostRoot : "romfs"
TitleInfo:
- UniqueId : {APP_UNIQUE_ID}
+ UniqueId : $(APP_UNIQUE_ID)
Category : Application
CardInfo:
@@ -90,6 +90,7 @@ AccessControlInfo:
Priority : 16
MaxCpu : 0x9E # Default
+ CpuSpeed : 804mhz
DisableDebug : false
EnableForceDebug : false
diff --git a/database_info.c b/database_info.c
index 61b4dd5421..4759c348d6 100644
--- a/database_info.c
+++ b/database_info.c
@@ -201,7 +201,7 @@ int database_info_build_query(char *s, size_t len,
return 0;
}
-static char *bin_to_hex_alloc(const uint8_t *data, size_t len)
+char *bin_to_hex_alloc(const uint8_t *data, size_t len)
{
size_t i;
char *ret = (char*)malloc(len * 2 + 1);
@@ -447,15 +447,18 @@ void database_info_free(database_info_handle_t *db)
database_info_list_t *database_info_list_new(
const char *rdb_path, const char *query)
{
- libretrodb_t db;
- libretrodb_cursor_t cur;
int ret = 0;
unsigned k = 0;
database_info_t *database_info = NULL;
database_info_list_t *database_info_list = NULL;
+ libretrodb_t *db = libretrodb_new();
+ libretrodb_cursor_t *cur = libretrodb_cursor_new();
- if ((database_cursor_open(&db, &cur, rdb_path, query) != 0))
- return NULL;
+ if (!db || !cur)
+ goto end;
+
+ if ((database_cursor_open(db, cur, rdb_path, query) != 0))
+ goto end;
database_info_list = (database_info_list_t*)
calloc(1, sizeof(*database_info_list));
@@ -466,7 +469,7 @@ database_info_list_t *database_info_list_new(
while (ret != -1)
{
database_info_t db_info = {0};
- ret = database_cursor_iterate(&cur, &db_info);
+ ret = database_cursor_iterate(cur, &db_info);
if (ret == 0)
{
@@ -496,7 +499,12 @@ database_info_list_t *database_info_list_new(
database_info_list->count = k;
end:
- database_cursor_close(&db, &cur);
+ database_cursor_close(db, cur);
+
+ if (db)
+ libretrodb_free(db);
+ if (cur)
+ libretrodb_cursor_free(cur);
return database_info_list;
}
diff --git a/database_info.h b/database_info.h
index 7b9d843930..e31a09ae4e 100644
--- a/database_info.h
+++ b/database_info.h
@@ -44,6 +44,7 @@ enum database_type
DATABASE_TYPE_NONE = 0,
DATABASE_TYPE_ITERATE,
DATABASE_TYPE_ITERATE_ZIP,
+ DATABASE_TYPE_SERIAL_LOOKUP,
DATABASE_TYPE_CRC_LOOKUP
};
@@ -112,6 +113,8 @@ void database_info_free(database_info_handle_t *handle);
int database_info_build_query(
char *query, size_t len, const char *label, const char *path);
+char *bin_to_hex_alloc(const uint8_t *data, size_t len);
+
#ifdef __cplusplus
}
#endif
diff --git a/cores/stb_image.h b/deps/stb/stb_image.h
similarity index 94%
rename from cores/stb_image.h
rename to deps/stb/stb_image.h
index 4afd0433a0..5b959364dd 100644
--- a/cores/stb_image.h
+++ b/deps/stb/stb_image.h
@@ -386,14 +386,13 @@ License:
#ifndef STBI_NO_STDIO
#include
-#endif // STBI_NO_STDIO
+#endif /* STBI_NO_STDIO */
#define STBI_VERSION 1
enum
{
- STBI_default = 0, // only used for req_comp
-
+ STBI_default = 0, /* only used for req_comp */
STBI_grey = 1,
STBI_grey_alpha = 2,
STBI_rgb = 3,
@@ -417,15 +416,13 @@ extern "C" {
// PRIMARY API - works on images of any type
//
-//
-// load image by filename, open file, or memory buffer
-//
+/* load image by filename, open file, or memory buffer */
typedef struct
{
- int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
- void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative
- int (*eof) (void *user); // returns nonzero if we are at end of file/data
+ int (*read) (void *user,char *data,int size); /* fill 'data' with 'size' bytes. return number of bytes actually read */
+ void (*skip) (void *user,int n); /* skip the next 'n' bytes, or 'unget' the last -n bytes if negative */
+ int (*eof) (void *user); /* returns nonzero if we are at end of file/data */
} stbi_io_callbacks;
STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
@@ -434,7 +431,7 @@ STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void
#ifndef STBI_NO_STDIO
STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
-// for stbi_load_from_file, file pointer is left pointing immediately after image
+/* for stbi_load_from_file, file pointer is left pointing immediately after image */
#endif
#ifndef STBI_NO_LINEAR
@@ -455,25 +452,25 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y,
#ifndef STBI_NO_LINEAR
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
STBIDEF void stbi_ldr_to_hdr_scale(float scale);
-#endif // STBI_NO_HDR
+#endif /* STBI_NO_HDR */
-// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
+/* stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR */
STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
#ifndef STBI_NO_STDIO
STBIDEF int stbi_is_hdr (char const *filename);
STBIDEF int stbi_is_hdr_from_file(FILE *f);
-#endif // STBI_NO_STDIO
+#endif /* STBI_NO_STDIO */
-// get a VERY brief reason for failure
-// NOT THREADSAFE
+/* get a VERY brief reason for failure
+ * NOT THREADSAFE */
STBIDEF const char *stbi_failure_reason (void);
-// free the loaded image -- this is just free()
+/* free the loaded image -- this is just free() */
STBIDEF void stbi_image_free (void *retval_from_stbi_load);
-// get image dimensions & components without fully decoding
+/* get image dimensions & components without fully decoding */
STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
@@ -483,8 +480,6 @@ STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y,
#endif
-
-
// for image formats that explicitly notate that they have premultiplied alpha,
// we just return the colors as stored in the file. set this flag to force
// unpremultiplication. results are undefined if the unpremultiply overflow.
@@ -494,10 +489,10 @@ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultipl
// or just pass them through "as-is"
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
-// flip the image vertically, so the first pixel in the output array is the bottom left
+/* flip the image vertically, so the first pixel in the output array is the bottom left */
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
-// ZLIB client - used by PNG, available for other purposes
+/* ZLIB client - used by PNG, available for other purposes */
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header);
@@ -512,10 +507,8 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
}
#endif
-//
-//
//// end header file /////////////////////////////////////////////////////
-#endif // STBI_INCLUDE_STB_IMAGE_H
+#endif /* STBI_INCLUDE_STB_IMAGE_H */
#ifdef STB_IMAGE_IMPLEMENTATION
@@ -558,12 +551,12 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#include
-#include // ptrdiff_t on osx
+#include /* ptrdiff_t on osx */
#include
#include
#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR)
-#include // ldexp
+#include /* ldexp */
#endif
#ifndef STBI_NO_STDIO
@@ -600,7 +593,7 @@ typedef uint32_t stbi__uint32;
typedef int32_t stbi__int32;
#endif
-// should produce compiler error if size is wrong
+/* should produce compiler error if size is wrong */
typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#ifdef _MSC_VER
@@ -641,26 +634,28 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#endif
#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
-// NOTE: not clear do we actually need this for the 64-bit path?
-// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
-// (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
-// this is just broken and gcc are jerks for not fixing it properly
-// http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
+/* NOTE: not clear do we actually need this for the 64-bit path?
+ * gcc doesn't support sse2 intrinsics unless you compile with -msse2,
+ * (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
+ * this is just broken and gcc are jerks for not fixing it properly
+ * http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
+ */
#define STBI_NO_SIMD
#endif
#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
-// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
-//
-// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
-// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
-// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
-// simultaneously enabling "-mstackrealign".
-//
-// See https://github.com/nothings/stb/issues/81 for more information.
-//
-// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
-// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
+/* Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
+ *
+ * 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
+ * Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
+ * As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
+ * simultaneously enabling "-mstackrealign".
+ *
+ * See https://github.com/nothings/stb/issues/81 for more information.
+ *
+ * So default to no SSE2 on 32-bit MinGW. If you've read this far and added
+ * -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
+ */
#define STBI_NO_SIMD
#endif
@@ -670,8 +665,8 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#ifdef _MSC_VER
-#if _MSC_VER >= 1400 // not VC6
-#include // __cpuid
+#if _MSC_VER >= 1400 /* not VC6 */
+#include /* __cpuid */
static int stbi__cpuid3(void)
{
int info[4];
@@ -698,31 +693,31 @@ static int stbi__sse2_available()
int info3 = stbi__cpuid3();
return ((info3 >> 26) & 1) != 0;
}
-#else // assume GCC-style if not VC++
+#else /* assume GCC-style if not VC++ */
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
static int stbi__sse2_available()
{
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
- // GCC 4.8+ has a nice way to do this
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 /* GCC 4.8 or later */
+ /* GCC 4.8+ has a nice way to do this */
return __builtin_cpu_supports("sse2");
#else
- // portable way to do this, preferably without using GCC inline ASM?
- // just bail for now.
+ /* portable way to do this, preferably without using GCC inline ASM?
+ * just bail for now. */
return 0;
#endif
}
#endif
#endif
-// ARM NEON
+/* ARM NEON */
#if defined(STBI_NO_SIMD) && defined(STBI_NEON)
#undef STBI_NEON
#endif
#ifdef STBI_NEON
#include
-// assume GCC or Clang on ARM targets
+/* assume GCC or Clang on ARM targets */
#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
#endif
@@ -804,15 +799,14 @@ static void stbi__start_file(stbi__context *s, FILE *f)
stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f);
}
-//static void stop_file(stbi__context *s) { }
-
-#endif // !STBI_NO_STDIO
+#endif /* !STBI_NO_STDIO */
static void stbi__rewind(stbi__context *s)
{
- // conceptually rewind SHOULD rewind to the beginning of the stream,
- // but we just rewind to the beginning of the initial buffer, because
- // we only use it after doing 'test', which only ever looks at at most 92 bytes
+ /* conceptually rewind SHOULD rewind to the beginning of the stream,
+ * but we just rewind to the beginning of the initial buffer, because
+ * we only use it after doing 'test', which only ever looks at at most 92 bytes
+ */
s->img_buffer = s->img_buffer_original;
}
@@ -1045,12 +1039,12 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
stbi__start_file(&s,f);
result = stbi__load_flip(&s,x,y,comp,req_comp);
if (result) {
- // need to 'unget' all the characters in the IO buffer
+ /* need to 'unget' all the characters in the IO buffer */
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
}
return result;
}
-#endif //!STBI_NO_STDIO
+#endif /* !STBI_NO_STDIO */
STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
{
@@ -2009,20 +2003,22 @@ static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64])
}
#ifdef STBI_SSE2
-// sse2 integer IDCT. not the fastest possible implementation but it
-// produces bit-identical results to the generic C version so it's
-// fully "transparent".
+/* sse2 integer IDCT. not the fastest possible implementation but it
+ * produces bit-identical results to the generic C version so it's
+ * fully "transparent".
+ */
static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
{
- // This is constructed to match our regular (generic) integer IDCT exactly.
+ /* This is constructed to match our regular (generic) integer IDCT exactly. */
__m128i row0, row1, row2, row3, row4, row5, row6, row7;
__m128i tmp;
- // dot product constant: even elems=x, odd elems=y
+ /* dot product constant: even elems=x, odd elems=y */
#define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y))
- // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit)
- // out(1) = c1[even]*x + c1[odd]*y
+ /* out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit)
+ * out(1) = c1[even]*x + c1[odd]*y
+ */
#define dct_rot(out0,out1, x,y,c0,c1) \
__m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \
__m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \
@@ -2031,22 +2027,22 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
__m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \
__m128i out1##_h = _mm_madd_epi16(c0##hi, c1)
- // out = in << 12 (in 16-bit, out 32-bit)
+ /* out = in << 12 (in 16-bit, out 32-bit) */
#define dct_widen(out, in) \
__m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \
__m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4)
- // wide add
+ /* wide add */
#define dct_wadd(out, a, b) \
__m128i out##_l = _mm_add_epi32(a##_l, b##_l); \
__m128i out##_h = _mm_add_epi32(a##_h, b##_h)
- // wide sub
+ /* wide sub */
#define dct_wsub(out, a, b) \
__m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \
__m128i out##_h = _mm_sub_epi32(a##_h, b##_h)
- // butterfly a/b, add bias, then shift by "s" and pack
+ /* butterfly a/b, add bias, then shift by "s" and pack */
#define dct_bfly32o(out0, out1, a,b,bias,s) \
{ \
__m128i abiased_l = _mm_add_epi32(a##_l, bias); \
@@ -2057,13 +2053,13 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \
}
- // 8-bit interleave step (for transposes)
+ /* 8-bit interleave step (for transposes) */
#define dct_interleave8(a, b) \
tmp = a; \
a = _mm_unpacklo_epi8(a, b); \
b = _mm_unpackhi_epi8(tmp, b)
- // 16-bit interleave step (for transposes)
+ /* 16-bit interleave step (for transposes) */
#define dct_interleave16(a, b) \
tmp = a; \
a = _mm_unpacklo_epi16(a, b); \
@@ -2106,11 +2102,11 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
__m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f));
__m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f));
- // rounding biases in column/row passes, see stbi__idct_block for explanation.
+ /* rounding biases in column/row passes, see stbi__idct_block for explanation. */
__m128i bias_0 = _mm_set1_epi32(512);
__m128i bias_1 = _mm_set1_epi32(65536 + (128<<17));
- // load
+ /* load */
row0 = _mm_load_si128((const __m128i *) (data + 0*8));
row1 = _mm_load_si128((const __m128i *) (data + 1*8));
row2 = _mm_load_si128((const __m128i *) (data + 2*8));
@@ -2120,34 +2116,34 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
row6 = _mm_load_si128((const __m128i *) (data + 6*8));
row7 = _mm_load_si128((const __m128i *) (data + 7*8));
- // column pass
+ /* column pass */
dct_pass(bias_0, 10);
{
- // 16bit 8x8 transpose pass 1
+ /* 16bit 8x8 transpose pass 1 */
dct_interleave16(row0, row4);
dct_interleave16(row1, row5);
dct_interleave16(row2, row6);
dct_interleave16(row3, row7);
- // transpose pass 2
+ /* transpose pass 2 */
dct_interleave16(row0, row2);
dct_interleave16(row1, row3);
dct_interleave16(row4, row6);
dct_interleave16(row5, row7);
- // transpose pass 3
+ /* transpose pass 3 */
dct_interleave16(row0, row1);
dct_interleave16(row2, row3);
dct_interleave16(row4, row5);
dct_interleave16(row6, row7);
}
- // row pass
+ /* row pass */
dct_pass(bias_1, 17);
{
- // pack
+ /* pack */
__m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7
__m128i p1 = _mm_packus_epi16(row2, row3);
__m128i p2 = _mm_packus_epi16(row4, row5);
@@ -2187,12 +2183,12 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
#undef dct_pass
}
-#endif // STBI_SSE2
+#endif /* STBI_SSE2 */
#ifdef STBI_NEON
-// NEON integer IDCT. should produce bit-identical
-// results to the generic C version.
+/* NEON integer IDCT. should produce bit-identical
+ * results to the generic C version. */
static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
{
int16x8_t row0, row1, row2, row3, row4, row5, row6, row7;
@@ -2222,12 +2218,12 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \
int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12)
-// wide add
+/* wide add */
#define dct_wadd(out, a, b) \
int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \
int32x4_t out##_h = vaddq_s32(a##_h, b##_h)
-// wide sub
+/* wide sub */
#define dct_wsub(out, a, b) \
int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \
int32x4_t out##_h = vsubq_s32(a##_h, b##_h)
@@ -2335,7 +2331,7 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
dct_pass(vshrn_n_s32, 16);
{
- // pack and round
+ /* pack and round */
uint8x8_t p0 = vqrshrun_n_s16(row0, 1);
uint8x8_t p1 = vqrshrun_n_s16(row1, 1);
uint8x8_t p2 = vqrshrun_n_s16(row2, 1);
@@ -2345,33 +2341,33 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
uint8x8_t p6 = vqrshrun_n_s16(row6, 1);
uint8x8_t p7 = vqrshrun_n_s16(row7, 1);
- // again, these can translate into one instruction, but often don't.
+ /* again, these can translate into one instruction, but often don't. */
#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; }
#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); }
#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); }
- // sadly can't use interleaved stores here since we only write
- // 8 bytes to each scan line!
+ /* sadly can't use interleaved stores here since we only write
+ * 8 bytes to each scan line! */
- // 8x8 8-bit transpose pass 1
+ /* 8x8 8-bit transpose pass 1 */
dct_trn8_8(p0, p1);
dct_trn8_8(p2, p3);
dct_trn8_8(p4, p5);
dct_trn8_8(p6, p7);
- // pass 2
+ /* pass 2 */
dct_trn8_16(p0, p2);
dct_trn8_16(p1, p3);
dct_trn8_16(p4, p6);
dct_trn8_16(p5, p7);
- // pass 3
+ /* pass 3 */
dct_trn8_32(p0, p4);
dct_trn8_32(p1, p5);
dct_trn8_32(p2, p6);
dct_trn8_32(p3, p7);
- // store
+ /* store */
vst1_u8(out, p0); out += out_stride;
vst1_u8(out, p1); out += out_stride;
vst1_u8(out, p2); out += out_stride;
@@ -2395,12 +2391,13 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
#undef dct_pass
}
-#endif // STBI_NEON
+#endif /* STBI_NEON */
#define STBI__MARKER_none 0xff
-// if there's a pending marker from the entropy stream, return that
-// otherwise, fetch from the stream and get a marker. if there's no
-// marker, return 0xff, which is never a valid marker value
+/* if there's a pending marker from the entropy stream, return that
+ * otherwise, fetch from the stream and get a marker. if there's no
+ * marker, return 0xff, which is never a valid marker value
+ */
static stbi_uc stbi__get_marker(stbi__jpeg *j)
{
stbi_uc x;
@@ -2412,12 +2409,14 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j)
return x;
}
-// in each scan, we'll have scan_n components, and the order
-// of the components is specified by order[]
+/* in each scan, we'll have scan_n components, and the order
+ * of the components is specified by order[]
+ */
#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7)
-// after a restart interval, stbi__jpeg_reset the entropy decoder and
-// the dc prediction
+/* after a restart interval, stbi__jpeg_reset the entropy decoder and
+ * the dc prediction
+ */
static void stbi__jpeg_reset(stbi__jpeg *j)
{
j->code_bits = 0;
@@ -2918,7 +2917,7 @@ static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc
#if defined(STBI_SSE2) || defined(STBI_NEON)
static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
{
- // need to generate 2x2 samples for every one in input
+ /* need to generate 2x2 samples for every one in input */
int i=0,t0,t1;
if (w == 1) {
@@ -2927,13 +2926,15 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
}
t1 = 3*in_near[0] + in_far[0];
- // process groups of 8 pixels for as long as we can.
- // note we can't handle the last pixel in a row in this loop
- // because we need to handle the filter boundary conditions.
- for (; i < ((w-1) & ~7); i += 8) {
+ /* process groups of 8 pixels for as long as we can.
+ * note we can't handle the last pixel in a row in this loop
+ * because we need to handle the filter boundary conditions.
+ */
+ for (; i < ((w-1) & ~7); i += 8)
+ {
#if defined(STBI_SSE2)
- // load and perform the vertical filtering pass
- // this uses 3*x + y = 4*x + (y - x)
+ /* load and perform the vertical filtering pass
+ * this uses 3*x + y = 4*x + (y - x) */
__m128i zero = _mm_setzero_si128();
__m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i));
__m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i));
@@ -2941,22 +2942,23 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
__m128i nearw = _mm_unpacklo_epi8(nearb, zero);
__m128i diff = _mm_sub_epi16(farw, nearw);
__m128i nears = _mm_slli_epi16(nearw, 2);
- __m128i curr = _mm_add_epi16(nears, diff); // current row
+ __m128i curr = _mm_add_epi16(nears, diff); /* current row */
- // horizontal filter works the same based on shifted vers of current
- // row. "prev" is current row shifted right by 1 pixel; we need to
- // insert the previous pixel value (from t1).
- // "next" is current row shifted left by 1 pixel, with first pixel
- // of next block of 8 pixels added in.
+ /* horizontal filter works the same based on shifted vers of current
+ * row. "prev" is current row shifted right by 1 pixel; we need to
+ * insert the previous pixel value (from t1).
+ * "next" is current row shifted left by 1 pixel, with first pixel
+ * of next block of 8 pixels added in.
+ */
__m128i prv0 = _mm_slli_si128(curr, 2);
__m128i nxt0 = _mm_srli_si128(curr, 2);
__m128i prev = _mm_insert_epi16(prv0, t1, 0);
__m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7);
- // horizontal filter, polyphase implementation since it's convenient:
- // even pixels = 3*cur + prev = cur*4 + (prev - cur)
- // odd pixels = 3*cur + next = cur*4 + (next - cur)
- // note the shared term.
+ /* horizontal filter, polyphase implementation since it's convenient:
+ * even pixels = 3*cur + prev = cur*4 + (prev - cur)
+ * odd pixels = 3*cur + next = cur*4 + (next - cur)
+ * note the shared term. */
__m128i bias = _mm_set1_epi16(8);
__m128i curs = _mm_slli_epi16(curr, 2);
__m128i prvd = _mm_sub_epi16(prev, curr);
@@ -2965,13 +2967,13 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
__m128i even = _mm_add_epi16(prvd, curb);
__m128i odd = _mm_add_epi16(nxtd, curb);
- // interleave even and odd pixels, then undo scaling.
+ /* interleave even and odd pixels, then undo scaling. */
__m128i int0 = _mm_unpacklo_epi16(even, odd);
__m128i int1 = _mm_unpackhi_epi16(even, odd);
__m128i de0 = _mm_srli_epi16(int0, 4);
__m128i de1 = _mm_srli_epi16(int1, 4);
- // pack and write output
+ /* pack and write output */
__m128i outv = _mm_packus_epi16(de0, de1);
_mm_storeu_si128((__m128i *) (out + i*2), outv);
#elif defined(STBI_NEON)
@@ -2993,24 +2995,25 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
int16x8_t prev = vsetq_lane_s16(t1, prv0, 0);
int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7);
- // horizontal filter, polyphase implementation since it's convenient:
- // even pixels = 3*cur + prev = cur*4 + (prev - cur)
- // odd pixels = 3*cur + next = cur*4 + (next - cur)
- // note the shared term.
+ /* horizontal filter, polyphase implementation since it's convenient:
+ * even pixels = 3*cur + prev = cur*4 + (prev - cur)
+ * odd pixels = 3*cur + next = cur*4 + (next - cur)
+ * note the shared term.
+ */
int16x8_t curs = vshlq_n_s16(curr, 2);
int16x8_t prvd = vsubq_s16(prev, curr);
int16x8_t nxtd = vsubq_s16(next, curr);
int16x8_t even = vaddq_s16(curs, prvd);
int16x8_t odd = vaddq_s16(curs, nxtd);
- // undo scaling and round, then store with even/odd phases interleaved
+ /* undo scaling and round, then store with even/odd phases interleaved */
uint8x8x2_t o;
o.val[0] = vqrshrun_n_s16(even, 4);
o.val[1] = vqrshrun_n_s16(odd, 4);
vst2_u8(out + i*2, o);
#endif
- // "previous" value for next iter
+ /* "previous" value for next iteration */
t1 = 3*in_near[i+7] + in_far[i+7];
}
@@ -3034,7 +3037,7 @@ static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stb
static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs)
{
- // resample with nearest-neighbor
+ /* resample with nearest-neighbor */
int i,j;
STBI_NOTUSED(in_far);
for (i=0; i < w; ++i)
@@ -3044,8 +3047,8 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_
}
#ifdef STBI_JPEG_OLD
-// this is the same YCbCr-to-RGB calculation that stb_image has used
-// historically before the algorithm changes in 1.49
+/* this is the same YCbCr-to-RGB calculation that stb_image has used
+ * historically before the algorithm changes in 1.49 */
#define float2fixed(x) ((int) ((x) * 65536 + 0.5))
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
{
@@ -3072,14 +3075,14 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
}
}
#else
-// this is a reduced-precision calculation of YCbCr-to-RGB introduced
-// to make sure the code produces the same results in both SIMD and scalar
+/* this is a reduced-precision calculation of YCbCr-to-RGB introduced
+ * to make sure the code produces the same results in both SIMD and scalar */
#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
{
int i;
for (i=0; i < count; ++i) {
- int y_fixed = (y[i] << 20) + (1<<19); // rounding
+ int y_fixed = (y[i] << 20) + (1<<19); /* rounding */
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
@@ -3107,20 +3110,23 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
int i = 0;
#ifdef STBI_SSE2
- // step == 3 is pretty ugly on the final interleave, and i'm not convinced
- // it's useful in practice (you wouldn't use it for textures, for example).
- // so just accelerate step == 4 case.
- if (step == 4) {
- // this is a fairly straightforward implementation and not super-optimized.
+ /* step == 3 is pretty ugly on the final interleave, and i'm not convinced
+ * it's useful in practice (you wouldn't use it for textures, for example).
+ * so just accelerate step == 4 case.
+ */
+ if (step == 4)
+ {
+ /* this is a fairly straightforward implementation and not super-optimized. */
__m128i signflip = _mm_set1_epi8(-0x80);
__m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f));
__m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
__m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
__m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f));
__m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
- __m128i xw = _mm_set1_epi16(255); // alpha channel
+ __m128i xw = _mm_set1_epi16(255); /* alpha channel */
- for (; i+7 < count; i += 8) {
+ for (; i+7 < count; i += 8)
+ {
// load
__m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i));
__m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i));
@@ -3236,7 +3242,7 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
}
#endif
-// set up the kernels
+/* set up the kernels */
static void stbi__setup_jpeg(stbi__jpeg *j)
{
j->idct_block_kernel = stbi__idct_block;
@@ -3262,7 +3268,7 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
#endif
}
-// clean up the temporary component buffers
+/* clean up the temporary component buffers */
static void stbi__cleanup_jpeg(stbi__jpeg *j)
{
int i;
@@ -5044,8 +5050,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
}
#endif
-// *************************************************************************************************
-// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB
+/* Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB */
#ifndef STBI_NO_PSD
static int stbi__psd_test(stbi__context *s)
@@ -5063,27 +5068,27 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
int w,h;
stbi_uc *out;
- // Check identifier
+ /* Check identifier */
if (stbi__get32be(s) != 0x38425053) // "8BPS"
return stbi__errpuc("not PSD", "Corrupt PSD image");
- // Check file type version.
+ /* Check file type version. */
if (stbi__get16be(s) != 1)
return stbi__errpuc("wrong version", "Unsupported version of PSD image");
- // Skip 6 reserved bytes.
+ /* Skip 6 reserved bytes. */
stbi__skip(s, 6 );
- // Read the number of channels (R, G, B, A, etc).
+ /* Read the number of channels (R, G, B, A, etc). */
channelCount = stbi__get16be(s);
if (channelCount < 0 || channelCount > 16)
return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");
- // Read the rows and columns of the image.
+ /* Read the rows and columns of the image. */
h = stbi__get32be(s);
w = stbi__get32be(s);
- // Make sure the depth is 8 bits.
+ /* Make sure the depth is 8 bits. */
if (stbi__get16be(s) != 8)
return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit");
@@ -5100,13 +5105,13 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
if (stbi__get16be(s) != 3)
return stbi__errpuc("wrong color format", "PSD is not in RGB color format");
- // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.)
+ /* Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) */
stbi__skip(s,stbi__get32be(s) );
- // Skip the image resources. (resolution, pen tool paths, etc)
+ /* Skip the image resources. (resolution, pen tool paths, etc) */
stbi__skip(s, stbi__get32be(s) );
- // Skip the reserved data.
+ /* Skip the reserved data. */
stbi__skip(s, stbi__get32be(s) );
// Find out if the data is compressed.
@@ -5122,11 +5127,9 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
if (!out) return stbi__errpuc("outofmem", "Out of memory");
pixelCount = w*h;
- // Initialize the data to zero.
- //memset( out, 0, pixelCount * 4 );
-
- // Finally, the image data.
- if (compression) {
+ /* Finally, the image data. */
+ if (compression)
+ {
// RLE as used by .PSD and .TIFF
// Loop until you get the number of unpacked bytes you are expecting:
// Read the next source byte into n.
@@ -5135,8 +5138,8 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
// Else if n is 128, noop.
// Endloop
- // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
- // which we're going to just skip.
+ /* The RLE-compressed data is preceeded by a 2-byte data count
+ * for each row in the data, which we're going to just skip. */
stbi__skip(s, h * channelCount * 2 );
// Read the RLE data by channel.
@@ -5216,12 +5219,13 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
}
#endif
-// *************************************************************************************************
-// Softimage PIC loader
-// by Tom Seddon
-//
-// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format
-// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
+/* *************************************************************************************************
+ * Softimage PIC loader
+ * by Tom Seddon
+ *
+ * See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format
+ * See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
+ */
#ifndef STBI_NO_PIC
static int stbi__pic_is4(stbi__context *s,const char *str)
@@ -5283,9 +5287,11 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
int act_comp=0,num_packets=0,y,chained;
stbi__pic_packet packets[10];
- // this will (should...) cater for even some bizarre stuff like having data
- // for the same channel in multiple packets.
- do {
+ /* this will (should...) cater for even some bizarre stuff like having data
+ * for the same channel in multiple packets.
+ */
+ do
+ {
stbi__pic_packet *packet;
if (num_packets==sizeof(packets)/sizeof(packets[0]))
@@ -5304,7 +5310,7 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp");
} while (chained);
- *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel?
+ *comp = (act_comp & 0x10 ? 4 : 3); /* has alpha channel? */
for(y=0; ychannel,dest))
- return 0;
- break;
- }
+ for(x=0;xchannel,dest))
+ return 0;
+ break;
+ }
case 1://Pure RLE
- {
- int left=width, i;
+ {
+ int left=width, i;
- while (left>0) {
- stbi_uc count,value[4];
+ while (left>0) {
+ stbi_uc count,value[4];
- count=stbi__get8(s);
- if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)");
+ count=stbi__get8(s);
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)");
- if (count > left)
- count = (stbi_uc) left;
+ if (count > left)
+ count = (stbi_uc) left;
- if (!stbi__readval(s,packet->channel,value)) return 0;
+ if (!stbi__readval(s,packet->channel,value)) return 0;
- for(i=0; ichannel,dest,value);
- left -= count;
- }
- }
- break;
+ for(i=0; ichannel,dest,value);
+ left -= count;
+ }
+ }
+ break;
case 2: {//Mixed RLE
- int left=width;
- while (left>0) {
- int count = stbi__get8(s), i;
- if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)");
+ int left=width;
+ while (left>0) {
+ int count = stbi__get8(s), i;
+ if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)");
- if (count >= 128) { // Repeated
- stbi_uc value[4];
- int i;
+ if (count >= 128) { // Repeated
+ stbi_uc value[4];
+ int i;
- if (count==128)
- count = stbi__get16be(s);
- else
- count -= 127;
- if (count > left)
- return stbi__errpuc("bad file","scanline overrun");
+ if (count==128)
+ count = stbi__get16be(s);
+ else
+ count -= 127;
+ if (count > left)
+ return stbi__errpuc("bad file","scanline overrun");
- if (!stbi__readval(s,packet->channel,value))
- return 0;
+ if (!stbi__readval(s,packet->channel,value))
+ return 0;
- for(i=0;ichannel,dest,value);
- } else { // Raw
- ++count;
- if (count>left) return stbi__errpuc("bad file","scanline overrun");
+ for(i=0;ichannel,dest,value);
+ } else { // Raw
+ ++count;
+ if (count>left) return stbi__errpuc("bad file","scanline overrun");
- for(i=0;ichannel,dest))
- return 0;
- }
- left-=count;
- }
- break;
- }
+ for(i=0;ichannel,dest))
+ return 0;
+ }
+ left-=count;
+ }
+ break;
+ }
}
}
}
@@ -5402,15 +5408,16 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
if ((1 << 28) / x < y) return stbi__errpuc("too large", "Image too large to decode");
- stbi__get32be(s); //skip `ratio'
- stbi__get16be(s); //skip `fields'
- stbi__get16be(s); //skip `pad'
+ stbi__get32be(s); /* skip `ratio' */
+ stbi__get16be(s); /* skip `fields' */
+ stbi__get16be(s); /* skip `pad' */
- // intermediate buffer is RGBA
+ /* intermediate buffer is RGBA */
result = (stbi_uc *) stbi__malloc(x*y*4);
memset(result, 0xff, x*y*4);
- if (!stbi__pic_load_core(s,x,y,comp, result)) {
+ if (!stbi__pic_load_core(s,x,y,comp, result))
+ {
STBI_FREE(result);
result=0;
}
@@ -5430,8 +5437,9 @@ static int stbi__pic_test(stbi__context *s)
}
#endif
-// *************************************************************************************************
-// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
+/* *************************************************************************************************
+ * GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb
+ */
#ifndef STBI_NO_GIF
typedef struct
@@ -5444,7 +5452,7 @@ typedef struct
typedef struct
{
int w,h;
- stbi_uc *out; // output buffer (always 4 components)
+ stbi_uc *out; /* output buffer (always 4 components) */
int flags, bgindex, ratio, transparent, eflags;
stbi_uc pal[256][4];
stbi_uc lpal[256][4];
@@ -5504,7 +5512,7 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
g->ratio = stbi__get8(s);
g->transparent = -1;
- if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
+ if (comp != 0) *comp = 4; /* can't actually tell whether it's 3 or 4 until we parse the comments */
if (is_info) return 1;
@@ -5530,12 +5538,14 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
{
stbi_uc *p, *c;
- // recurse to decode the prefixes, since the linked-list is backwards,
- // and working backwards through an interleaved image would be nasty
+ /* recurse to decode the prefixes, since the linked-list is backwards,
+ * and working backwards through an interleaved image would be nasty
+ */
if (g->codes[code].prefix >= 0)
stbi__out_gif_code(g, g->codes[code].prefix);
- if (g->cur_y >= g->max_y) return;
+ if (g->cur_y >= g->max_y)
+ return;
p = &g->out[g->cur_x + g->cur_y];
c = &g->color_table[g->codes[code].suffix * 4];
@@ -5582,7 +5592,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
g->codes[code].suffix = (stbi_uc) code;
}
- // support no starting clear code
+ /* support no starting clear code */
avail = clear+2;
oldcode = -1;
@@ -5590,7 +5600,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
for(;;) {
if (valid_bits < codesize) {
if (len == 0) {
- len = stbi__get8(s); // start new block
+ len = stbi__get8(s); /* start new block */
if (len == 0)
return g->out;
}
@@ -5644,8 +5654,9 @@ static void stbi__fill_gif_background(stbi__gif *g)
{
int i;
stbi_uc *c = g->pal[g->bgindex];
- // @OPTIMIZE: write a dword at a time
- for (i = 0; i < g->w * g->h * 4; i += 4) {
+ /* @OPTIMIZE: write a dword at a time */
+ for (i = 0; i < g->w * g->h * 4; i += 4)
+ {
stbi_uc *p = &g->out[i];
p[0] = c[2];
p[1] = c[1];
@@ -5654,14 +5665,16 @@ static void stbi__fill_gif_background(stbi__gif *g)
}
}
-// this function is designed to support animated gifs, although stb_image doesn't support it
+/* this function is designed to support animated gifs, although stb_image doesn't support it */
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp)
{
int i;
stbi_uc *old_out = 0;
if (g->out == 0) {
- if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
+ if (!stbi__gif_header(s, g, comp,0))
+ return 0;
+
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
stbi__fill_gif_background(g);
@@ -5907,7 +5920,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
}
}
} else {
- // Read RLE-encoded data
+ /* Read RLE-encoded data */
scanline = NULL;
for (j = 0; j < height; ++j) {
@@ -5915,8 +5928,10 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
c2 = stbi__get8(s);
len = stbi__get8(s);
if (c1 != 2 || c2 != 2 || (len & 0x80)) {
- // not run-length encoded, so we have to actually use THIS data as a decoded
- // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
+ /* not run-length encoded, so we have to
+ * actually use THIS data as a decoded
+ * pixel (note this can't be a valid pixel
+ * --one of RGB must be >= 128) */
stbi_uc rgbe[4];
rgbe[0] = (stbi_uc) c1;
rgbe[1] = (stbi_uc) c2;
@@ -5997,7 +6012,7 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
*comp = 3;
return 1;
}
-#endif // STBI_NO_HDR
+#endif /* STBI_NO_HDR */
#ifndef STBI_NO_BMP
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
@@ -6281,7 +6296,7 @@ STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
fseek(f,pos,SEEK_SET);
return r;
}
-#endif // !STBI_NO_STDIO
+#endif /* !STBI_NO_STDIO */
STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
{
@@ -6297,7 +6312,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
return stbi__info_main(&s,x,y,comp);
}
-#endif // STB_IMAGE_IMPLEMENTATION
+#endif /* STB_IMAGE_IMPLEMENTATION */
/*
revision history:
diff --git a/deps/stb/stb_rect_pack.h b/deps/stb/stb_rect_pack.h
index 63a5b15944..f31258adb9 100644
--- a/deps/stb/stb_rect_pack.h
+++ b/deps/stb/stb_rect_pack.h
@@ -1,46 +1,43 @@
-// stb_rect_pack.h - v0.06 - public domain - rectangle packing
-// Sean Barrett 2014
-//
-// Useful for e.g. packing rectangular textures into an atlas.
-// Does not do rotation.
-//
-// Not necessarily the awesomest packing method, but better than
-// the totally naive one in stb_truetype (which is primarily what
-// this is meant to replace).
-//
-// Has only had a few tests run, may have issues.
-//
-// More docs to come.
-//
-// No memory allocations; uses qsort() and assert() from stdlib.
-// Can override those by defining STBRP_SORT and STBRP_ASSERT.
-//
-// This library currently uses the Skyline Bottom-Left algorithm.
-//
-// Please note: better rectangle packers are welcome! Please
-// implement them to the same API, but with a different init
-// function.
-//
-// Credits
-//
-// Library
-// Sean Barrett
-// Minor features
-// Martins Mozeiko
-// Bugfixes / warning fixes
-// [your name could be here]
-//
-// Version history:
-//
-// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
-// 0.05: added STBRP_ASSERT to allow replacing assert
-// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
-// 0.01: initial release
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// INCLUDE SECTION
-//
+/*
+ * stb_rect_pack.h - v0.06 - public domain - rectangle packing
+ * Sean Barrett 2014
+ *
+ * Useful for e.g. packing rectangular textures into an atlas.
+ * Does not do rotation.
+ *
+ * Not necessarily the awesomest packing method, but better than
+ * the totally naive one in stb_truetype (which is primarily what
+ * this is meant to replace).
+ *
+ * Has only had a few tests run, may have issues.
+ *
+ * More docs to come.
+ *
+ * No memory allocations; uses qsort() and assert() from stdlib.
+ * Can override those by defining STBRP_SORT and STBRP_ASSERT.
+ *
+ * This library currently uses the Skyline Bottom-Left algorithm.
+ *
+ * Please note: better rectangle packers are welcome! Please
+ * implement them to the same API, but with a different init
+ * function.
+ *
+ * Credits
+ *
+ * Library
+ * Sean Barrett
+ * Minor features
+ * Martins Mozeiko
+ * Bugfixes / warning fixes
+ * [your name could be here]
+ *
+ * Version history:
+ *
+ * 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
+ * 0.05: added STBRP_ASSERT to allow replacing assert
+ * 0.04: fixed minor bug in STBRP_LARGE_RECTS support
+ * 0.01: initial release
+*/
#ifndef STB_INCLUDE_STB_RECT_PACK_H
#define STB_INCLUDE_STB_RECT_PACK_H
@@ -67,87 +64,89 @@ typedef int stbrp_coord;
typedef unsigned short stbrp_coord;
#endif
-STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
-// Assign packed locations to rectangles. The rectangles are of type
-// 'stbrp_rect' defined below, stored in the array 'rects', and there
-// are 'num_rects' many of them.
-//
-// Rectangles which are successfully packed have the 'was_packed' flag
-// set to a non-zero value and 'x' and 'y' store the minimum location
-// on each axis (i.e. bottom-left in cartesian coordinates, top-left
-// if you imagine y increasing downwards). Rectangles which do not fit
-// have the 'was_packed' flag set to 0.
-//
-// You should not try to access the 'rects' array from another thread
-// while this function is running, as the function temporarily reorders
-// the array while it executes.
-//
-// To pack into another rectangle, you need to call stbrp_init_target
-// again. To continue packing into the same rectangle, you can call
-// this function again. Calling this multiple times with multiple rect
-// arrays will probably produce worse packing results than calling it
-// a single time with the full rectangle array, but the option is
-// available.
+STBRP_DEF void stbrp_pack_rects (stbrp_context *context,
+ stbrp_rect *rects, int num_rects);
+
+/* Assign packed locations to rectangles. The rectangles are of type
+ * 'stbrp_rect' defined below, stored in the array 'rects', and there
+ * are 'num_rects' many of them.
+ *
+ * Rectangles which are successfully packed have the 'was_packed' flag
+ * set to a non-zero value and 'x' and 'y' store the minimum location
+ * on each axis (i.e. bottom-left in cartesian coordinates, top-left
+ * if you imagine y increasing downwards). Rectangles which do not fit
+ * have the 'was_packed' flag set to 0.
+ *
+ * You should not try to access the 'rects' array from another thread
+ * while this function is running, as the function temporarily reorders
+ * the array while it executes.
+ *
+ * To pack into another rectangle, you need to call stbrp_init_target
+ * again. To continue packing into the same rectangle, you can call
+ * this function again. Calling this multiple times with multiple rect
+ * arrays will probably produce worse packing results than calling it
+ * a single time with the full rectangle array, but the option is
+ * available.
+ */
struct stbrp_rect
{
- // reserved for your use:
- int id;
-
- // input:
- stbrp_coord w, h;
-
- // output:
- stbrp_coord x, y;
- int was_packed; // non-zero if valid packing
-
-}; // 16 bytes, nominally
+ int id; /* reserved for your use: */
+ stbrp_coord w, h; /* input: */
+ stbrp_coord x, y; /* output: */
+ int was_packed; /* non-zero if valid packing */
+}; /* 16 bytes, nominally */
-STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
-// Initialize a rectangle packer to:
-// pack a rectangle that is 'width' by 'height' in dimensions
-// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
-//
-// You must call this function every time you start packing into a new target.
-//
-// There is no "shutdown" function. The 'nodes' memory must stay valid for
-// the following stbrp_pack_rects() call (or calls), but can be freed after
-// the call (or calls) finish.
-//
-// Note: to guarantee best results, either:
-// 1. make sure 'num_nodes' >= 'width'
-// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
-//
-// If you don't do either of the above things, widths will be quantized to multiples
-// of small integers to guarantee the algorithm doesn't run out of temporary storage.
-//
-// If you do #2, then the non-quantized algorithm will be used, but the algorithm
-// may run out of temporary storage and be unable to pack some rectangles.
+STBRP_DEF void stbrp_init_target (stbrp_context *context,
+ int width, int height, stbrp_node *nodes, int num_nodes);
+
+/* Initialize a rectangle packer to:
+ * pack a rectangle that is 'width' by 'height' in dimensions
+ * using temporary storage provided by the array 'nodes', which is 'num_nodes' long
+ *
+ * You must call this function every time you start packing into a new target.
+ *
+ * There is no "shutdown" function. The 'nodes' memory must stay valid for
+ * the following stbrp_pack_rects() call (or calls), but can be freed after
+ * the call (or calls) finish.
+ *
+ * Note: to guarantee best results, either:
+ * 1. make sure 'num_nodes' >= 'width'
+ * or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
+ *
+ * If you don't do either of the above things, widths will be quantized to multiples
+ * of small integers to guarantee the algorithm doesn't run out of temporary storage.
+ *
+ * If you do #2, then the non-quantized algorithm will be used, but the algorithm
+ * may run out of temporary storage and be unable to pack some rectangles.
+ */
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
-// Optionally call this function after init but before doing any packing to
-// change the handling of the out-of-temp-memory scenario, described above.
-// If you call init again, this will be reset to the default (false).
+
+/* Optionally call this function after init but before doing any packing to
+ * change the handling of the out-of-temp-memory scenario, described above.
+ * If you call init again, this will be reset to the default (false).
+ */
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
-// Optionally select which packing heuristic the library should use. Different
-// heuristics will produce better/worse results for different data sets.
-// If you call init again, this will be reset to the default.
+
+/* Optionally select which packing heuristic the library should use. Different
+ * heuristics will produce better/worse results for different data sets.
+ * If you call init again, this will be reset to the default.
+ */
enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
- STBRP_HEURISTIC_Skyline_BF_sortHeight,
+ STBRP_HEURISTIC_Skyline_BF_sortHeight
};
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// the details of the following structures don't matter to you, but they must
-// be visible so you can handle the memory allocations for them
+/* the details of the following structures don't matter to you, but they must
+ * be visible so you can handle the memory allocations for them
+ */
struct stbrp_node
{
@@ -165,7 +164,7 @@ struct stbrp_context
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
- stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
+ stbrp_node extra[2]; /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */
};
#ifdef __cplusplus
@@ -174,10 +173,7 @@ struct stbrp_context
#endif
-//////////////////////////////////////////////////////////////////////////////
-//
-// IMPLEMENTATION SECTION
-//
+/* IMPLEMENTATION SECTION */
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
@@ -192,12 +188,13 @@ struct stbrp_context
enum
{
- STBRP__INIT_skyline = 1,
+ STBRP__INIT_skyline = 1
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
- switch (context->init_mode) {
+ switch (context->init_mode)
+ {
case STBRP__INIT_skyline:
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
@@ -209,20 +206,22 @@ STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
+ /* if it's ok to run out of memory, then don't bother aligning them;
+ * this gives better packing, but may fail due to OOM (even though
+ * the rectangles easily fit). @TODO a smarter approach would be to only
+ * quantize once we've hit OOM, then we could get rid of this parameter.
+ */
if (allow_out_of_mem)
- // if it's ok to run out of memory, then don't bother aligning them;
- // this gives better packing, but may fail due to OOM (even though
- // the rectangles easily fit). @TODO a smarter approach would be to only
- // quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
- else {
- // if it's not ok to run out of memory, then quantize the widths
- // so that num_nodes is always enough nodes.
- //
- // I.e. num_nodes * align >= width
- // align >= width / num_nodes
- // align = ceil(width/num_nodes)
-
+ else
+ {
+ /* if it's not ok to run out of memory, then quantize the widths
+ * so that num_nodes is always enough nodes.
+ *
+ * I.e. num_nodes * align >= width
+ * align >= width / num_nodes
+ * align = ceil(width/num_nodes)
+ */
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
@@ -246,7 +245,8 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
- // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
+ /* node 0 is the full width,
+ * node 1 is the sentinel (lets us not store width explicitly) */
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
@@ -259,41 +259,41 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->extra[1].next = NULL;
}
-// find minimum y position if it starts at x1
-static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
+/* Find minimum y position if it starts at x1 */
+static int stbrp__skyline_find_min_y(stbrp_context *c,
+ stbrp_node *first, int x0, int width, int *pwaste)
{
+ int min_y, visited_width, waste_area;
stbrp_node *node = first;
int x1 = x0 + width;
- int min_y, visited_width, waste_area;
+
STBRP_ASSERT(first->x <= x0);
-
- #if 0
- // skip in case we're past the node
- while (node->next->x <= x0)
- ++node;
- #else
- STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
- #endif
-
+ STBRP_ASSERT(node->next->x > x0);
STBRP_ASSERT(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
- while (node->x < x1) {
- if (node->y > min_y) {
- // raise min_y higher.
- // we've accounted for all waste up to min_y,
- // but we'll now add more waste for everything we've visted
+ while (node->x < x1)
+ {
+ if (node->y > min_y)
+ {
+ /* raise min_y higher.
+ * we've accounted for all waste up to min_y,
+ * but we'll now add more waste for everything we've visted
+ */
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
- // the first time through, visited_width might be reduced
+
+ /* the first time through, visited_width might be reduced */
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
- } else {
- // add waste area
+ }
+ else
+ {
+ /* add waste area */
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
@@ -319,27 +319,35 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
- // align to multiple of c->align
+ /* align to multiple of c->align */
width = (width + c->align - 1);
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
node = c->active_head;
prev = &c->active_head;
- while (node->x + width <= c->width) {
- int y,waste;
- y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
- if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
- // bottom left
- if (y < best_y) {
+ while (node->x + width <= c->width)
+ {
+ int waste;
+ int y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
+
+ if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight)
+ {
+ /* actually just want to test BL bottom left */
+ if (y < best_y)
+ {
best_y = y;
best = prev;
}
- } else {
- // best-fit
- if (y + height <= c->height) {
- // can only use it if it first vertically
- if (y < best_y || (y == best_y && waste < best_waste)) {
+ }
+ else
+ {
+ /* best-fit */
+ if (y + height <= c->height)
+ {
+ /* can only use it if it first vertically */
+ if (y < best_y || (y == best_y && waste < best_waste))
+ {
best_y = y;
best_waste = waste;
best = prev;
@@ -352,44 +360,54 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
best_x = (best == NULL) ? 0 : (*best)->x;
- // if doing best-fit (BF), we also have to try aligning right edge to each node position
- //
- // e.g, if fitting
- //
- // ____________________
- // |____________________|
- //
- // into
- //
- // | |
- // | ____________|
- // |____________|
- //
- // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
- //
- // This makes BF take about 2x the time
+ /* if doing best-fit (BF), we also have to try aligning right edge to each node position
+ *
+ * e.g, if fitting
+ *
+ * ____________________
+ * |____________________|
+ *
+ * into
+ *
+ * | |
+ * | ____________|
+ * |____________|
+ *
+ * then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
+ *
+ * This makes BF take about 2x the time
+ */
- if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
+ if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight)
+ {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
- // find first node that's admissible
+ /* find first node that's admissible */
while (tail->x < width)
tail = tail->next;
- while (tail) {
+ while (tail)
+ {
int xpos = tail->x - width;
int y,waste;
STBRP_ASSERT(xpos >= 0);
- // find the left position that matches this
- while (node->next->x <= xpos) {
+
+ /* find the left position that matches this */
+ while (node->next->x <= xpos)
+ {
prev = &node->next;
node = node->next;
}
+
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
- if (y + height < c->height) {
- if (y <= best_y) {
- if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
+
+ if (y + height < c->height)
+ {
+ if (y <= best_y)
+ {
+ if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x))
+ {
best_x = xpos;
STBRP_ASSERT(y <= best_y);
best_y = y;
@@ -410,83 +428,62 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
- // find best position according to heuristic
- stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
+ /* find best position according to heuristic */
stbrp_node *node, *cur;
+ stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
- // bail if:
- // 1. it failed
- // 2. the best node doesn't fit (we don't always check this)
- // 3. we're out of memory
- if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
+ /* bail if:
+ * 1. it failed
+ * 2. the best node doesn't fit (we don't always check this)
+ * 3. we're out of memory
+ */
+ if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL)
+ {
res.prev_link = NULL;
return res;
}
- // on success, create new node
+ /* on success, create new node */
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
- // insert the new node into the right starting point, and
- // let 'cur' point to the remaining nodes needing to be
- // stiched back in
+ /* insert the new node into the right starting point, and
+ * let 'cur' point to the remaining nodes needing to be
+ * stiched back in
+ */
cur = *res.prev_link;
- if (cur->x < res.x) {
- // preserve the existing one, so start testing with the next one
+ if (cur->x < res.x)
+ {
+ /* preserve the existing one, so start testing with the next one */
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
- } else {
- *res.prev_link = node;
}
+ else
+ *res.prev_link = node;
- // from here, traverse cur and free the nodes, until we get to one
- // that shouldn't be freed
- while (cur->next && cur->next->x <= res.x + width) {
+ /* from here, traverse cur and free the nodes, until we get to one
+ * that shouldn't be freed */
+ while (cur->next && cur->next->x <= res.x + width)
+ {
stbrp_node *next = cur->next;
- // move the current node to the free list
+
+ /* move the current node to the free list */
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
- // stitch the list back in
+ /* stitch the list back in */
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
-#ifdef _DEBUG
- cur = context->active_head;
- while (cur->x < context->width) {
- STBRP_ASSERT(cur->x < cur->next->x);
- cur = cur->next;
- }
- STBRP_ASSERT(cur->next == NULL);
-
- {
- stbrp_node *L1 = NULL, *L2 = NULL;
- int count=0;
- cur = context->active_head;
- while (cur) {
- L1 = cur;
- cur = cur->next;
- ++count;
- }
- cur = context->free_head;
- while (cur) {
- L2 = cur;
- cur = cur->next;
- ++count;
- }
- STBRP_ASSERT(count == context->num_nodes+2);
- }
-#endif
-
return res;
}
@@ -529,20 +526,23 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
{
int i;
- // we use the 'was_packed' field internally to allow sorting/unsorting
- for (i=0; i < num_rects; ++i) {
+ /* we use the 'was_packed' field internally to allow sorting/unsorting */
+ for (i=0; i < num_rects; ++i)
+ {
rects[i].was_packed = i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
#endif
}
- // sort according to heuristic
+ /* sort according to heuristic */
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
- for (i=0; i < num_rects; ++i) {
+ for (i=0; i < num_rects; ++i)
+ {
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
- if (fr.prev_link) {
+ if (fr.prev_link)
+ {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
@@ -550,10 +550,10 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
}
}
- // unsort
+ /* unsort */
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
- // set was_packed flags
+ /* set was_packed flags */
for (i=0; i < num_rects; ++i)
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
}
diff --git a/deps/stb/stb_truetype.h b/deps/stb/stb_truetype.h
index 13d4b9f58f..5cd5f018d3 100644
--- a/deps/stb/stb_truetype.h
+++ b/deps/stb/stb_truetype.h
@@ -1,401 +1,259 @@
-// stb_truetype.h - v1.06 - public domain
-// authored from 2009-2014 by Sean Barrett / RAD Game Tools
-//
-// This library processes TrueType files:
-// parse files
-// extract glyph metrics
-// extract glyph shapes
-// render glyphs to one-channel bitmaps with antialiasing (box filter)
-//
-// Todo:
-// non-MS cmaps
-// crashproof on bad data
-// hinting? (no longer patented)
-// cleartype-style AA?
-// optimize: use simple memory allocator for intermediates
-// optimize: build edge-list directly from curves
-// optimize: rasterize directly from curves?
-//
-// ADDITIONAL CONTRIBUTORS
-//
-// Mikko Mononen: compound shape support, more cmap formats
-// Tor Andersson: kerning, subpixel rendering
-//
-// Bug/warning reports/fixes:
-// "Zer" on mollyrocket (with fix)
-// Cass Everitt
-// stoiko (Haemimont Games)
-// Brian Hook
-// Walter van Niftrik
-// David Gow
-// David Given
-// Ivan-Assen Ivanov
-// Anthony Pesch
-// Johan Duparc
-// Hou Qiming
-// Fabian "ryg" Giesen
-// Martins Mozeiko
-// Cap Petschulat
-// Omar Cornut
-// github:aloucks
-// Peter LaValle
-//
-// Misc other:
-// Ryan Gordon
-//
-// VERSION HISTORY
-//
-// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
-// also more precise AA rasterizer, except if shapes overlap
-// remove need for STBTT_sort
-// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
-// 1.04 (2015-04-15) typo in example
-// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
-// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
-// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
-// non-oversampled; STBTT_POINT_SIZE for packed case only
-// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
-// 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
-// 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID
-// 0.8b (2014-07-07) fix a warning
-// 0.8 (2014-05-25) fix a few more warnings
-// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
-// 0.6c (2012-07-24) improve documentation
-// 0.6b (2012-07-20) fix a few more warnings
-// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
-// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
-// 0.5 (2011-12-09) bugfixes:
-// subpixel glyph renderer computed wrong bounding box
-// first vertex of shape can be off-curve (FreeSans)
-// 0.4b (2011-12-03) fixed an error in the font baking example
-// 0.4 (2011-12-01) kerning, subpixel rendering (tor)
-// bugfixes for:
-// codepoint-to-glyph conversion using table fmt=12
-// codepoint-to-glyph conversion using table fmt=4
-// stbtt_GetBakedQuad with non-square texture (Zer)
-// updated Hello World! sample to use kerning and subpixel
-// fixed some warnings
-// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
-// userdata, malloc-from-userdata, non-zero fill (stb)
-// 0.2 (2009-03-11) Fix unsigned/signed char warnings
-// 0.1 (2009-03-09) First public release
-//
-// LICENSE
-//
-// This software is in the public domain. Where that dedication is not
-// recognized, you are granted a perpetual, irrevokable license to copy
-// and modify this file as you see fit.
-//
-// USAGE
-//
-// Include this file in whatever places neeed to refer to it. In ONE C/C++
-// file, write:
-// #define STB_TRUETYPE_IMPLEMENTATION
-// before the #include of this file. This expands out the actual
-// implementation into that C/C++ file.
-//
-// To make the implementation private to the file that generates the implementation,
-// #define STBTT_STATIC
-//
-// Simple 3D API (don't ship this, but it's fine for tools and quick start)
-// stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture
-// stbtt_GetBakedQuad() -- compute quad to draw for a given char
-//
-// Improved 3D API (more shippable):
-// #include "stb_rect_pack.h" -- optional, but you really want it
-// stbtt_PackBegin()
-// stbtt_PackSetOversample() -- for improved quality on small fonts
-// stbtt_PackFontRanges()
-// stbtt_PackEnd()
-// stbtt_GetPackedQuad()
-//
-// "Load" a font file from a memory buffer (you have to keep the buffer loaded)
-// stbtt_InitFont()
-// stbtt_GetFontOffsetForIndex() -- use for TTC font collections
-//
-// Render a unicode codepoint to a bitmap
-// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
-// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
-// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
-//
-// Character advance/positioning
-// stbtt_GetCodepointHMetrics()
-// stbtt_GetFontVMetrics()
-// stbtt_GetCodepointKernAdvance()
-//
-// Starting with version 1.06, the rasterizer was replaced with a new,
-// faster and generally-more-precise rasterizer. The new rasterizer more
-// accurately measures pixel coverage for anti-aliasing, except in the case
-// where multiple shapes overlap, in which case it overestimates the AA pixel
-// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If
-// this turns out to be a problem, you can re-enable the old rasterizer with
-// #define STBTT_RASTERIZER_VERSION 1
-// which will incur about a 15% speed hit.
-//
-// ADDITIONAL DOCUMENTATION
-//
-// Immediately after this block comment are a series of sample programs.
-//
-// After the sample programs is the "header file" section. This section
-// includes documentation for each API function.
-//
-// Some important concepts to understand to use this library:
-//
-// Codepoint
-// Characters are defined by unicode codepoints, e.g. 65 is
-// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
-// the hiragana for "ma".
-//
-// Glyph
-// A visual character shape (every codepoint is rendered as
-// some glyph)
-//
-// Glyph index
-// A font-specific integer ID representing a glyph
-//
-// Baseline
-// Glyph shapes are defined relative to a baseline, which is the
-// bottom of uppercase characters. Characters extend both above
-// and below the baseline.
-//
-// Current Point
-// As you draw text to the screen, you keep track of a "current point"
-// which is the origin of each character. The current point's vertical
-// position is the baseline. Even "baked fonts" use this model.
-//
-// Vertical Font Metrics
-// The vertical qualities of the font, used to vertically position
-// and space the characters. See docs for stbtt_GetFontVMetrics.
-//
-// Font Size in Pixels or Points
-// The preferred interface for specifying font sizes in stb_truetype
-// is to specify how tall the font's vertical extent should be in pixels.
-// If that sounds good enough, skip the next paragraph.
-//
-// Most font APIs instead use "points", which are a common typographic
-// measurement for describing font size, defined as 72 points per inch.
-// stb_truetype provides a point API for compatibility. However, true
-// "per inch" conventions don't make much sense on computer displays
-// since they different monitors have different number of pixels per
-// inch. For example, Windows traditionally uses a convention that
-// there are 96 pixels per inch, thus making 'inch' measurements have
-// nothing to do with inches, and thus effectively defining a point to
-// be 1.333 pixels. Additionally, the TrueType font data provides
-// an explicit scale factor to scale a given font's glyphs to points,
-// but the author has observed that this scale factor is often wrong
-// for non-commercial fonts, thus making fonts scaled in points
-// according to the TrueType spec incoherently sized in practice.
-//
-// ADVANCED USAGE
-//
-// Quality:
-//
-// - Use the functions with Subpixel at the end to allow your characters
-// to have subpixel positioning. Since the font is anti-aliased, not
-// hinted, this is very import for quality. (This is not possible with
-// baked fonts.)
-//
-// - Kerning is now supported, and if you're supporting subpixel rendering
-// then kerning is worth using to give your text a polished look.
-//
-// Performance:
-//
-// - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
-// if you don't do this, stb_truetype is forced to do the conversion on
-// every call.
-//
-// - There are a lot of memory allocations. We should modify it to take
-// a temp buffer and allocate from the temp buffer (without freeing),
-// should help performance a lot.
-//
-// NOTES
-//
-// The system uses the raw data found in the .ttf file without changing it
-// and without building auxiliary data structures. This is a bit inefficient
-// on little-endian systems (the data is big-endian), but assuming you're
-// caching the bitmaps or glyph shapes this shouldn't be a big deal.
-//
-// It appears to be very hard to programmatically determine what font a
-// given file is in a general way. I provide an API for this, but I don't
-// recommend it.
-//
-//
-// SOURCE STATISTICS (based on v0.6c, 2050 LOC)
-//
-// Documentation & header file 520 LOC \___ 660 LOC documentation
-// Sample code 140 LOC /
-// Truetype parsing 620 LOC ---- 620 LOC TrueType
-// Software rasterization 240 LOC \ .
-// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
-// Bitmap management 100 LOC /
-// Baked bitmap interface 70 LOC /
-// Font name matching & access 150 LOC ---- 150
-// C runtime library abstraction 60 LOC ---- 60
-//
-//
-// PERFORMANCE MEASUREMENTS FOR 1.06:
-//
-// 32-bit 64-bit
-// Previous release: 8.83 s 7.68 s
-// Pool allocations: 7.72 s 6.34 s
-// Inline sort : 6.54 s 5.65 s
-// New rasterizer : 5.63 s 5.00 s
+/*
+ * stb_truetype.h - v1.06 - public domain
+ * authored from 2009-2014 by Sean Barrett / RAD Game Tools
+ *
+ * This library processes TrueType files:
+ * parse files
+ * extract glyph metrics
+ * extract glyph shapes
+ * render glyphs to one-channel bitmaps with antialiasing (box filter)
+ *
+ * Todo:
+ * non-MS cmaps
+ * crashproof on bad data
+ * hinting? (no longer patented)
+ * cleartype-style AA?
+ * optimize: use simple memory allocator for intermediates
+ * optimize: build edge-list directly from curves
+ * optimize: rasterize directly from curves?
+ *
+ * ADDITIONAL CONTRIBUTORS
+ *
+ * Mikko Mononen: compound shape support, more cmap formats
+ * Tor Andersson: kerning, subpixel rendering
+ *
+ * Bug/warning reports/fixes:
+ * "Zer" on mollyrocket (with fix)
+ * Cass Everitt
+ * stoiko (Haemimont Games)
+ * Brian Hook
+ * Walter van Niftrik
+ * David Gow
+ * David Given
+ * Ivan-Assen Ivanov
+ * Anthony Pesch
+ * Johan Duparc
+ * Hou Qiming
+ * Fabian "ryg" Giesen
+ * Martins Mozeiko
+ * Cap Petschulat
+ * Omar Cornut
+ * github:aloucks
+ * Peter LaValle
+ *
+ * Misc other:
+ * Ryan Gordon
+ *
+ * VERSION HISTORY
+ *
+ * 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine)
+ * also more precise AA rasterizer, except if shapes overlap
+ * remove need for STBTT_sort
+ * 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC
+ * 1.04 (2015-04-15) typo in example
+ * 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes
+ * 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
+ * 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
+ * non-oversampled; STBTT_POINT_SIZE for packed case only
+ * 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
+ * 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
+ * 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID
+ * 0.8b (2014-07-07) fix a warning
+ * 0.8 (2014-05-25) fix a few more warnings
+ * 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
+ * 0.6c (2012-07-24) improve documentation
+ * 0.6b (2012-07-20) fix a few more warnings
+ * 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
+ * stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
+ * 0.5 (2011-12-09) bugfixes:
+ * subpixel glyph renderer computed wrong bounding box
+ * first vertex of shape can be off-curve (FreeSans)
+ * 0.4b (2011-12-03) fixed an error in the font baking example
+ * 0.4 (2011-12-01) kerning, subpixel rendering (tor)
+ * bugfixes for:
+ * codepoint-to-glyph conversion using table fmt=12
+ * codepoint-to-glyph conversion using table fmt=4
+ * stbtt_GetBakedQuad with non-square texture (Zer)
+ * updated Hello World! sample to use kerning and subpixel
+ * fixed some warnings
+ * 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
+ * userdata, malloc-from-userdata, non-zero fill (stb)
+ * 0.2 (2009-03-11) Fix unsigned/signed char warnings
+ * 0.1 (2009-03-09) First public release
+ *
+ * LICENSE
+ *
+ * This software is in the public domain. Where that dedication is not
+ * recognized, you are granted a perpetual, irrevokable license to copy
+ * and modify this file as you see fit.
+ *
+ * USAGE
+ *
+ * Include this file in whatever places neeed to refer to it. In ONE C/C++
+ * file, write:
+ * #define STB_TRUETYPE_IMPLEMENTATION
+ * before the #include of this file. This expands out the actual
+ * implementation into that C/C++ file.
+ *
+ * To make the implementation private to the file that generates the implementation,
+ * #define STBTT_STATIC
+ *
+ * Simple 3D API (don't ship this, but it's fine for tools and quick start)
+ * stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture
+ * stbtt_GetBakedQuad() -- compute quad to draw for a given char
+ *
+ * Improved 3D API (more shippable):
+ * #include "stb_rect_pack.h" -- optional, but you really want it
+ * stbtt_PackBegin()
+ * stbtt_PackSetOversample() -- for improved quality on small fonts
+ * stbtt_PackFontRanges()
+ * stbtt_PackEnd()
+ * stbtt_GetPackedQuad()
+ *
+ * "Load" a font file from a memory buffer (you have to keep the buffer loaded)
+ * stbtt_InitFont()
+ * stbtt_GetFontOffsetForIndex() -- use for TTC font collections
+ *
+ * Render a unicode codepoint to a bitmap
+ * stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
+ * stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
+ * stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
+ *
+ * Character advance/positioning
+ * stbtt_GetCodepointHMetrics()
+ * stbtt_GetFontVMetrics()
+ * stbtt_GetCodepointKernAdvance()
+ *
+ * Starting with version 1.06, the rasterizer was replaced with a new,
+ * faster and generally-more-precise rasterizer. The new rasterizer more
+ * accurately measures pixel coverage for anti-aliasing, except in the case
+ * where multiple shapes overlap, in which case it overestimates the AA pixel
+ * coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If
+ * this turns out to be a problem, you can re-enable the old rasterizer with
+ * #define STBTT_RASTERIZER_VERSION 1
+ * which will incur about a 15% speed hit.
+ *
+ * ADDITIONAL DOCUMENTATION
+ *
+ * Immediately after this block comment are a series of sample programs.
+ *
+ * After the sample programs is the "header file" section. This section
+ * includes documentation for each API function.
+ *
+ * Some important concepts to understand to use this library:
+ *
+ * Codepoint
+ * Characters are defined by unicode codepoints, e.g. 65 is
+ * uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
+ * the hiragana for "ma".
+ *
+ * Glyph
+ * A visual character shape (every codepoint is rendered as
+ * some glyph)
+ *
+ * Glyph index
+ * A font-specific integer ID representing a glyph
+ *
+ * Baseline
+ * Glyph shapes are defined relative to a baseline, which is the
+ * bottom of uppercase characters. Characters extend both above
+ * and below the baseline.
+ *
+ * Current Point
+ * As you draw text to the screen, you keep track of a "current point"
+ * which is the origin of each character. The current point's vertical
+ * position is the baseline. Even "baked fonts" use this model.
+ *
+ * Vertical Font Metrics
+ * The vertical qualities of the font, used to vertically position
+ * and space the characters. See docs for stbtt_GetFontVMetrics.
+ *
+ * Font Size in Pixels or Points
+ * The preferred interface for specifying font sizes in stb_truetype
+ * is to specify how tall the font's vertical extent should be in pixels.
+ * If that sounds good enough, skip the next paragraph.
+ *
+ * Most font APIs instead use "points", which are a common typographic
+ * measurement for describing font size, defined as 72 points per inch.
+ * stb_truetype provides a point API for compatibility. However, true
+ * "per inch" conventions don't make much sense on computer displays
+ * since they different monitors have different number of pixels per
+ * inch. For example, Windows traditionally uses a convention that
+ * there are 96 pixels per inch, thus making 'inch' measurements have
+ * nothing to do with inches, and thus effectively defining a point to
+ * be 1.333 pixels. Additionally, the TrueType font data provides
+ * an explicit scale factor to scale a given font's glyphs to points,
+ * but the author has observed that this scale factor is often wrong
+ * for non-commercial fonts, thus making fonts scaled in points
+ * according to the TrueType spec incoherently sized in practice.
+ *
+ * ADVANCED USAGE
+ *
+ * Quality:
+ *
+ * - Use the functions with Subpixel at the end to allow your characters
+ * to have subpixel positioning. Since the font is anti-aliased, not
+ * hinted, this is very import for quality. (This is not possible with
+ * baked fonts.)
+ *
+ * - Kerning is now supported, and if you're supporting subpixel rendering
+ * then kerning is worth using to give your text a polished look.
+ *
+ * Performance:
+ *
+ * - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
+ * if you don't do this, stb_truetype is forced to do the conversion on
+ * every call.
+ *
+ * - There are a lot of memory allocations. We should modify it to take
+ * a temp buffer and allocate from the temp buffer (without freeing),
+ * should help performance a lot.
+ *
+ * NOTES
+ *
+ * The system uses the raw data found in the .ttf file without changing it
+ * and without building auxiliary data structures. This is a bit inefficient
+ * on little-endian systems (the data is big-endian), but assuming you're
+ * caching the bitmaps or glyph shapes this shouldn't be a big deal.
+ *
+ * It appears to be very hard to programmatically determine what font a
+ * given file is in a general way. I provide an API for this, but I don't
+ * recommend it.
+ *
+ *
+ * SOURCE STATISTICS (based on v0.6c, 2050 LOC)
+ *
+ * Documentation & header file 520 LOC \___ 660 LOC documentation
+ * Sample code 140 LOC /
+ * Truetype parsing 620 LOC ---- 620 LOC TrueType
+ * Software rasterization 240 LOC \ .
+ * Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
+ * Bitmap management 100 LOC /
+ * Baked bitmap interface 70 LOC /
+ * Font name matching & access 150 LOC ---- 150
+ * C runtime library abstraction 60 LOC ---- 60
+ *
+ *
+ * PERFORMANCE MEASUREMENTS FOR 1.06:
+ *
+ * 32-bit 64-bit
+ * Previous release: 8.83 s 7.68 s
+ * Pool allocations: 7.72 s 6.34 s
+ * Inline sort : 6.54 s 5.65 s
+ * New rasterizer : 5.63 s 5.00 s
+*/
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-////
-//// SAMPLE PROGRAMS
-////
-//
-// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
-//
-#if 0
-#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
-#include "stb_truetype.h"
+/* SAMPLE PROGRAMS
+ * Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
+ */
-unsigned char ttf_buffer[1<<20];
-unsigned char temp_bitmap[512*512];
+/* INTEGRATION WITH YOUR CODEBASE */
-stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
-GLuint ftex;
-
-void my_stbtt_initfont(void)
-{
- fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
- stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits!
- // can free ttf_buffer at this point
- glGenTextures(1, &ftex);
- glBindTexture(GL_TEXTURE_2D, ftex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
- // can free temp_bitmap at this point
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-}
-
-void my_stbtt_print(float x, float y, char *text)
-{
- // assume orthographic projection with units = screen pixels, origin at top left
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, ftex);
- glBegin(GL_QUADS);
- while (*text) {
- if (*text >= 32 && *text < 128) {
- stbtt_aligned_quad q;
- stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
- glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
- glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
- glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
- glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
- }
- ++text;
- }
- glEnd();
-}
-#endif
-//
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-// Complete program (this compiles): get a single bitmap, print as ASCII art
-//
-#if 0
-#include
-#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
-#include "stb_truetype.h"
-
-char ttf_buffer[1<<25];
-
-int main(int argc, char **argv)
-{
- stbtt_fontinfo font;
- unsigned char *bitmap;
- int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
-
- fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
-
- stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
- bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
-
- for (j=0; j < h; ++j) {
- for (i=0; i < w; ++i)
- putchar(" .:ioVM@"[bitmap[j*w+i]>>5]);
- putchar('\n');
- }
- return 0;
-}
-#endif
-//
-// Output:
-//
-// .ii.
-// @@@@@@.
-// V@Mio@@o
-// :i. V@V
-// :oM@@M
-// :@@@MM@M
-// @@o o@M
-// :@@. M@M
-// @@@o@@@@
-// :M@@V:@@.
-//
-//////////////////////////////////////////////////////////////////////////////
-//
-// Complete program: print "Hello World!" banner, with bugs
-//
-#if 0
-char buffer[24<<20];
-unsigned char screen[20][79];
-
-int main(int arg, char **argv)
-{
- stbtt_fontinfo font;
- int i,j,ascent,baseline,ch=0;
- float scale, xpos=2; // leave a little padding in case the character extends left
- char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness
-
- fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
- stbtt_InitFont(&font, buffer, 0);
-
- scale = stbtt_ScaleForPixelHeight(&font, 15);
- stbtt_GetFontVMetrics(&font, &ascent,0,0);
- baseline = (int) (ascent*scale);
-
- while (text[ch]) {
- int advance,lsb,x0,y0,x1,y1;
- float x_shift = xpos - (float) floor(xpos);
- stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
- stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
- stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
- // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong
- // because this API is really for baking character bitmaps into textures. if you want to render
- // a sequence of characters, you really need to render each bitmap to a temp buffer, then
- // "alpha blend" that into the working buffer
- xpos += (advance * scale);
- if (text[ch+1])
- xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
- ++ch;
- }
-
- for (j=0; j < 20; ++j) {
- for (i=0; i < 78; ++i)
- putchar(" .:ioVM@"[screen[j][i]>>5]);
- putchar('\n');
- }
-
- return 0;
-}
-#endif
-
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-////
-//// INTEGRATION WITH YOUR CODEBASE
-////
-//// The following sections allow you to supply alternate definitions
-//// of C library functions used by stb_truetype.
+/* The following sections allow you to supply alternate definitions
+ * of C library functions used by stb_truetype. */
#ifdef STB_TRUETYPE_IMPLEMENTATION
- // #define your own (u)stbtt_int8/16/32 before including to override this
+ /* #define your own (u)stbtt_int8/16/32 before including to override this */
#ifndef stbtt_uint8
typedef unsigned char stbtt_uint8;
typedef signed char stbtt_int8;
@@ -408,7 +266,7 @@ int main(int arg, char **argv)
typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
- // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
+ /* #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h */
#ifndef STBTT_ifloor
#include
#define STBTT_ifloor(x) ((int) floor(x))
@@ -420,35 +278,11 @@ int main(int arg, char **argv)
#define STBTT_sqrt(x) sqrt(x)
#endif
- // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
- #ifndef STBTT_malloc
#include
- #define STBTT_malloc(x,u) ((void)(u),malloc(x))
- #define STBTT_free(x,u) ((void)(u),free(x))
- #endif
-
- #ifndef STBTT_assert
- #include
- #define STBTT_assert(x) assert(x)
- #endif
-
- #ifndef STBTT_strlen
#include
- #define STBTT_strlen(x) strlen(x)
- #endif
-
- #ifndef STBTT_memcpy
- #define STBTT_memcpy memcpy
- #define STBTT_memset memset
- #endif
#endif
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-////
-//// INTERFACE
-////
-////
+/* INTERFACE */
#ifndef __STB_INCLUDE_STB_TRUETYPE_H__
#define __STB_INCLUDE_STB_TRUETYPE_H__
@@ -463,134 +297,148 @@ int main(int arg, char **argv)
extern "C" {
#endif
-//////////////////////////////////////////////////////////////////////////////
-//
-// TEXTURE BAKING API
-//
-// If you use this API, you only have to call two functions ever.
-//
+/* TEXTURE BAKING API */
+
+/* If you use this API, you only have to call two functions ever. */
typedef struct
{
- unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
+ uint16_t x0,y0,x1,y1; /* coordinates of bbox in bitmap */
float xoff,yoff,xadvance;
} stbtt_bakedchar;
-STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
- float pixel_height, // height of font in pixels
- unsigned char *pixels, int pw, int ph, // bitmap to be filled in
- int first_char, int num_chars, // characters to bake
- stbtt_bakedchar *chardata); // you allocate this, it's num_chars long
-// if return is positive, the first unused row of the bitmap
-// if return is negative, returns the negative of the number of characters that fit
-// if return is 0, no characters fit and no rows were used
-// This uses a very crappy packing.
+STBTT_DEF int stbtt_BakeFontBitmap(
+ const unsigned char *data, int offset, /* font location (use offset=0 for plain .ttf) */
+ float pixel_height, /* height of font in pixels */
+ unsigned char *pixels, int pw, int ph, /* bitmap to be filled in */
+ int first_char, int num_chars, /* characters to bake */
+ stbtt_bakedchar *chardata); /* you allocate this, it's num_chars long */
+
+/* if return is positive, the first unused row of the bitmap
+ * if return is negative, returns the negative of the number of characters that fit
+ * if return is 0, no characters fit and no rows were used
+ * This uses a very crappy packing.
+ */
typedef struct
{
- float x0,y0,s0,t0; // top-left
- float x1,y1,s1,t1; // bottom-right
+ float x0,y0,s0,t0; /* top-left */
+ float x1,y1,s1,t1; /* bottom-right */
} stbtt_aligned_quad;
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
- int char_index, // character to display
- float *xpos, float *ypos, // pointers to current position in screen pixel space
- stbtt_aligned_quad *q, // output: quad to draw
- int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier
-// Call GetBakedQuad with char_index = 'character - first_char', and it
-// creates the quad you need to draw and advances the current position.
-//
-// The coordinate system used assumes y increases downwards.
-//
-// Characters will extend both above and below the current position;
-// see discussion of "BASELINE" above.
-//
-// It's inefficient; you might want to c&p it and optimize it.
+STBTT_DEF void stbtt_GetBakedQuad(
+ stbtt_bakedchar *chardata, int pw, int ph, /* same data as above */
+ int char_index, /* character to display */
+ float *xpos, float *ypos, /* pointers to current position in screen pixel space */
+ stbtt_aligned_quad *q, /* output: quad to draw */
+ int opengl_fillrule); /* true if opengl fill rule; false if DX9 or earlier */
+/* Call GetBakedQuad with char_index = 'character - first_char', and it
+ * creates the quad you need to draw and advances the current position. */
+/* The coordinate system used assumes y increases downwards.
+ *
+ * Characters will extend both above and below the current position;
+ * see discussion of "BASELINE" above.
+ *
+ * It's inefficient; you might want to c&p it and optimize it.
+ */
-//////////////////////////////////////////////////////////////////////////////
-//
-// NEW TEXTURE BAKING API
-//
-// This provides options for packing multiple fonts into one atlas, not
-// perfectly but better than nothing.
+/* NEW TEXTURE BAKING API */
+
+/* This provides options for packing multiple fonts into one atlas, not
+ * perfectly but better than nothing. */
typedef struct
{
- unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
+ unsigned short x0,y0,x1,y1; /* coordinates of bbox in bitmap */
float xoff,yoff,xadvance;
float xoff2,yoff2;
} stbtt_packedchar;
typedef struct stbtt_pack_context stbtt_pack_context;
-STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
-// Initializes a packing context stored in the passed-in stbtt_pack_context.
-// Future calls using this context will pack characters into the bitmap passed
-// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
-// the distance from one row to the next (or 0 to mean they are packed tightly
-// together). "padding" is // the amount of padding to leave between each
-// character (normally you want '1' for bitmaps you'll use as textures with
-// bilinear filtering).
-//
-// Returns 0 on failure, 1 on success.
+STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc,
+ unsigned char *pixels, int width, int height,
+ int stride_in_bytes, int padding, void *alloc_context);
+
+/* Initializes a packing context stored in the passed-in stbtt_pack_context.
+ * Future calls using this context will pack characters into the bitmap passed
+ * in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
+ * the distance from one row to the next (or 0 to mean they are packed tightly
+ * together). "padding" is // the amount of padding to leave between each
+ * character (normally you want '1' for bitmaps you'll use as textures with
+ * bilinear filtering).
+ *
+ * Returns 0 on failure, 1 on success.
+ */
STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc);
-// Cleans up the packing context and frees all memory.
+
+/* Cleans up the packing context and frees all memory. */
#define STBTT_POINT_SIZE(x) (-(x))
STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
-// Creates character bitmaps from the font_index'th font found in fontdata (use
-// font_index=0 if you don't know what that is). It creates num_chars_in_range
-// bitmaps for characters with unicode values starting at first_unicode_char_in_range
-// and increasing. Data for how to render them is stored in chardata_for_range;
-// pass these to stbtt_GetPackedQuad to get back renderable quads.
-//
-// font_size is the full height of the character from ascender to descender,
-// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
-// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
-// and pass that result as 'font_size':
-// ..., 20 , ... // font max minus min y is 20 pixels tall
-// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
+
+/* Creates character bitmaps from the font_index'th font found in fontdata (use
+ * font_index=0 if you don't know what that is). It creates num_chars_in_range
+ * bitmaps for characters with unicode values starting at first_unicode_char_in_range
+ * and increasing. Data for how to render them is stored in chardata_for_range;
+ * pass these to stbtt_GetPackedQuad to get back renderable quads.
+ *
+ * font_size is the full height of the character from ascender to descender,
+ * as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
+ * by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
+ * and pass that result as 'font_size':
+ * ..., 20 , ... // font max minus min y is 20 pixels tall
+ * ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
+ */
typedef struct
{
float font_size;
int first_unicode_char_in_range;
int num_chars_in_range;
- stbtt_packedchar *chardata_for_range; // output
+ stbtt_packedchar *chardata_for_range; /* output */
} stbtt_pack_range;
-STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
-// Creates character bitmaps from multiple ranges of characters stored in
-// ranges. This will usually create a better-packed bitmap than multiple
-// calls to stbtt_PackFontRange.
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata,
+ int font_index, stbtt_pack_range *ranges, int num_ranges);
+
+/* Creates character bitmaps from multiple ranges of characters stored in
+ * ranges. This will usually create a better-packed bitmap than multiple
+ * calls to stbtt_PackFontRange.
+ */
-STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
-// Oversampling a font increases the quality by allowing higher-quality subpixel
-// positioning, and is especially valuable at smaller text sizes.
-//
-// This function sets the amount of oversampling for all following calls to
-// stbtt_PackFontRange(s). The default (no oversampling) is achieved by
-// h_oversample=1, v_oversample=1. The total number of pixels required is
-// h_oversample*v_oversample larger than the default; for example, 2x2
-// oversampling requires 4x the storage of 1x1. For best results, render
-// oversampled textures with bilinear filtering. Look at the readme in
-// stb/tests/oversample for information about oversampled fonts
+STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample,
+ unsigned int v_oversample);
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
- int char_index, // character to display
- float *xpos, float *ypos, // pointers to current position in screen pixel space
- stbtt_aligned_quad *q, // output: quad to draw
- int align_to_integer);
+/* Oversampling a font increases the quality by allowing higher-quality subpixel
+ * positioning, and is especially valuable at smaller text sizes.
+ *
+ * This function sets the amount of oversampling for all following calls to
+ * stbtt_PackFontRange(s). The default (no oversampling) is achieved by
+ * h_oversample=1, v_oversample=1. The total number of pixels required is
+ * h_oversample*v_oversample larger than the default; for example, 2x2
+ * oversampling requires 4x the storage of 1x1. For best results, render
+ * oversampled textures with bilinear filtering. Look at the readme in
+ * stb/tests/oversample for information about oversampled fonts
+ */
-// this is an opaque structure that you shouldn't mess with which holds
-// all the context needed from PackBegin to PackEnd.
-struct stbtt_pack_context {
+STBTT_DEF void stbtt_GetPackedQuad(
+ stbtt_packedchar *chardata, int pw, int ph, /* same data as above */
+ int char_index, /* character to display */
+ float *xpos, float *ypos, /* pointers to current position in screen pixel space */
+ stbtt_aligned_quad *q, /* output: quad to draw */
+ int align_to_integer);
+
+/* this is an opaque structure that you shouldn't mess with which holds
+ * all the context needed from PackBegin to PackEnd. */
+struct stbtt_pack_context
+{
void *user_allocator_context;
void *pack_info;
int width;
@@ -602,257 +450,312 @@ struct stbtt_pack_context {
void *nodes;
};
-//////////////////////////////////////////////////////////////////////////////
-//
-// FONT LOADING
-//
-//
+/* FONT LOADING */
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
-// Each .ttf/.ttc file may have more than one font. Each font has a sequential
-// index number starting from 0. Call this function to get the font offset for
-// a given index; it returns -1 if the index is out of range. A regular .ttf
-// file will only define one font and it always be at offset 0, so it will
-// return '0' for index 0, and -1 for all other indices. You can just skip
-// this step if you know it's that kind of font.
+/* Each .ttf/.ttc file may have more than one font. Each font has a sequential
+ * index number starting from 0. Call this function to get the font offset for
+ * a given index; it returns -1 if the index is out of range. A regular .ttf
+ * file will only define one font and it always be at offset 0, so it will
+ * return '0' for index 0, and -1 for all other indices. You can just skip
+ * this step if you know it's that kind of font.
+ */
-// The following structure is defined publically so you can declare one on
-// the stack or as a global or etc, but you should treat it as opaque.
+/* The following structure is defined publically so you can declare one on
+ * the stack or as a global or etc, but you should treat it as opaque.
+ */
typedef struct stbtt_fontinfo
{
- void * userdata;
- unsigned char * data; // pointer to .ttf file
- int fontstart; // offset of start of font
+ void *userdata;
+ unsigned char *data; /* pointer to .ttf file */
+ int fontstart; /* offset of start of font */
- int numGlyphs; // number of glyphs, needed for range checking
+ int numGlyphs; /* number of glyphs, needed for range checking */
- int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
- int index_map; // a cmap mapping for our chosen character encoding
- int indexToLocFormat; // format needed to map from glyph index to glyph
+ int loca,head,glyf,hhea,hmtx,kern; /* table locations as offset from start of .ttf */
+ int index_map; /* a cmap mapping for our chosen character encoding */
+ int indexToLocFormat; /* format needed to map from glyph index to glyph */
} stbtt_fontinfo;
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
-// Given an offset into the file that defines a font, this function builds
-// the necessary cached info for the rest of the system. You must allocate
-// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
-// need to do anything special to free it, because the contents are pure
-// value data with no additional data structures. Returns 0 on failure.
+/* Given an offset into the file that defines a font, this function builds
+ * the necessary cached info for the rest of the system. You must allocate
+ * the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
+ * need to do anything special to free it, because the contents are pure
+ * value data with no additional data structures. Returns 0 on failure.
+ */
-//////////////////////////////////////////////////////////////////////////////
-//
-// CHARACTER TO GLYPH-INDEX CONVERSIOn
+/* CHARACTER TO GLYPH-INDEX CONVERSION */
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
-// If you're going to perform multiple operations on the same character
-// and you want a speed-up, call this function with the character you're
-// going to process, then use glyph-based functions instead of the
-// codepoint-based functions.
+/* If you're going to perform multiple operations on the same character
+ * and you want a speed-up, call this function with the character you're
+ * going to process, then use glyph-based functions instead of the
+ * codepoint-based functions.
+ */
-//////////////////////////////////////////////////////////////////////////////
-//
-// CHARACTER PROPERTIES
-//
+/* CHARACTER PROPERTIES */
STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
-// computes a scale factor to produce a font whose "height" is 'pixels' tall.
-// Height is measured as the distance from the highest ascender to the lowest
-// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
-// and computing:
-// scale = pixels / (ascent - descent)
-// so if you prefer to measure height by the ascent only, use a similar calculation.
+
+/* computes a scale factor to produce a font whose "height" is 'pixels' tall.
+ * Height is measured as the distance from the highest ascender to the lowest
+ * descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
+ * and computing:
+ * scale = pixels / (ascent - descent)
+ * so if you prefer to measure height by the ascent only, use a similar calculation.
+ */
STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
-// computes a scale factor to produce a font whose EM size is mapped to
-// 'pixels' tall. This is probably what traditional APIs compute, but
-// I'm not positive.
+
+/* computes a scale factor to produce a font whose EM size is mapped to
+ * 'pixels' tall. This is probably what traditional APIs compute, but
+ * I'm not positive.
+ */
STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
-// ascent is the coordinate above the baseline the font extends; descent
-// is the coordinate below the baseline the font extends (i.e. it is typically negative)
-// lineGap is the spacing between one row's descent and the next row's ascent...
-// so you should advance the vertical position by "*ascent - *descent + *lineGap"
-// these are expressed in unscaled coordinates, so you must multiply by
-// the scale factor for a given size
+
+/* ascent is the coordinate above the baseline the font extends; descent
+ * is the coordinate below the baseline the font extends (i.e. it is typically negative)
+ * lineGap is the spacing between one row's descent and the next row's ascent...
+ * so you should advance the vertical position by "*ascent - *descent + *lineGap"
+ * these are expressed in unscaled coordinates, so you must multiply by
+ * the scale factor for a given size
+ */
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
-// the bounding box around all possible characters
-STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
-// leftSideBearing is the offset from the current horizontal position to the left edge of the character
-// advanceWidth is the offset from the current horizontal position to the next horizontal position
-// these are expressed in unscaled coordinates
+/* the bounding box around all possible characters */
+STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info,
+ int codepoint, int *advanceWidth, int *leftSideBearing);
+/* leftSideBearing is the offset from the current horizontal position to the left edge of the character
+ * advanceWidth is the offset from the current horizontal position to the next horizontal position
+ * these are expressed in unscaled coordinates
+ */
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
-// an additional amount to add to the 'advance' value between ch1 and ch2
-STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
-// Gets the bounding box of the visible part of the glyph, in unscaled coordinates
+/* an additional amount to add to the 'advance' value between ch1 and ch2 */
+STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint,
+ int *x0, int *y0, int *x1, int *y1);
+
+/* Gets the bounding box of the visible part of the glyph, in unscaled coordinates */
+
+STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info,
+ int glyph_index, int *advanceWidth, int *leftSideBearing);
-STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
-STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
-// as above, but takes one or more glyph indices for greater efficiency
+STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info,
+ int glyph_index, int *x0, int *y0, int *x1, int *y1);
-//////////////////////////////////////////////////////////////////////////////
-//
-// GLYPH SHAPES (you probably don't need these, but they have to go before
-// the bitmaps for C declaration-order reasons)
-//
+/* as above, but takes one or more glyph indices for greater efficiency */
-#ifndef STBTT_vmove // you can predefine these to use different values (but why?)
- enum {
- STBTT_vmove=1,
- STBTT_vline,
- STBTT_vcurve
- };
+/* GLYPH SHAPES (you probably don't need these, but they have to go before
+ * the bitmaps for C declaration-order reasons) */
+
+#ifndef STBTT_vmove
+enum
+{
+ STBTT_vmove=1,
+ STBTT_vline,
+ STBTT_vcurve
+};
#endif
-#ifndef stbtt_vertex // you can predefine this to use different values
- // (we share this with other code at RAD)
- #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
- typedef struct
- {
- stbtt_vertex_type x,y,cx,cy;
- unsigned char type,padding;
- } stbtt_vertex;
+#ifndef stbtt_vertex
+
+/* can't use stbtt_int16 because that's not visible in the header file */
+#define stbtt_vertex_type short
+
+typedef struct
+{
+ stbtt_vertex_type x,y,cx,cy;
+ unsigned char type,padding;
+} stbtt_vertex;
#endif
STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
-// returns non-zero if nothing is drawn for this glyph
+
+/* returns non-zero if nothing is drawn for this glyph */
STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
-// returns # of vertices and fills *vertices with the pointer to them
-// these are expressed in "unscaled" coordinates
-//
-// The shape is a series of countours. Each one starts with
-// a STBTT_moveto, then consists of a series of mixed
-// STBTT_lineto and STBTT_curveto segments. A lineto
-// draws a line from previous endpoint to its x,y; a curveto
-// draws a quadratic bezier from previous endpoint to
-// its x,y, using cx,cy as the bezier control point.
+
+/* returns # of vertices and fills *vertices with the pointer to them
+ * these are expressed in "unscaled" coordinates
+ *
+ * The shape is a series of countours. Each one starts with
+ * a STBTT_moveto, then consists of a series of mixed
+ * STBTT_lineto and STBTT_curveto segments. A lineto
+ * draws a line from previous endpoint to its x,y; a curveto
+ * draws a quadratic bezier from previous endpoint to
+ * its x,y, using cx,cy as the bezier control point.
+ */
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
-// frees the data allocated above
-//////////////////////////////////////////////////////////////////////////////
-//
-// BITMAP RENDERING
-//
+/* frees the data allocated above */
+
+/* BITMAP RENDERING */
STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
-// frees the bitmap allocated below
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
-// allocates a large-enough single-channel 8bpp bitmap and renders the
-// specified character/glyph at the specified scale into it, with
-// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
-// *width & *height are filled out with the width & height of the bitmap,
-// which is stored left-to-right, top-to-bottom.
-//
-// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
+/* frees the bitmap allocated below */
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
-// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
-// shift for the character
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info,
+ float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
-// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
-// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
-// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
-// width and height and positioning info for it first.
+/* allocates a large-enough single-channel 8bpp bitmap and renders the
+ * specified character/glyph at the specified scale into it, with
+ * antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
+ * *width & *height are filled out with the width & height of the bitmap,
+ * which is stored left-to-right, top-to-bottom.
+ *
+ * xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
+ */
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
-// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
-// shift for the character
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info,
+ float scale_x, float scale_y, float shift_x, float shift_y, int codepoint,
+ int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
-// get the bbox of the bitmap centered around the glyph origin; so the
-// bitmap width is ix1-ix0, height is iy1-iy0, and location to place
-// the bitmap top left is (leftSideBearing*scale,iy0).
-// (Note that the bitmap uses y-increases-down, but the shape uses
-// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
+/* the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
+ * shift for the character
+ */
-STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
-// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
-// shift for the character
+STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
-// the following functions are equivalent to the above functions, but operate
-// on glyph indices instead of Unicode codepoints (for efficiency)
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff);
-STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
-STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
-STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
+/* the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
+ * in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
+ * is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
+ * width and height and positioning info for it first.
+ */
+
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
+
+/* same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
+ * shift for the character */
+
+STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint,
+ float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+/* get the bbox of the bitmap centered around the glyph origin; so the
+ * bitmap width is ix1-ix0, height is iy1-iy0, and location to place
+ * the bitmap top left is (leftSideBearing*scale,iy0).
+ * (Note that the bitmap uses y-increases-down, but the shape uses
+ * y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
+ */
+
+STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint,
+ float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+/* same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
+ * shift for the character */
+
+/* the following functions are equivalent to the above functions, but operate
+ * on glyph indices instead of Unicode codepoints (for efficiency) */
+
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info,
+ float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
+
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info,
+ float scale_x, float scale_y, float shift_x, float shift_y, int glyph,
+ int *width, int *height, int *xoff, int *yoff);
+
+STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
+
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y,
+ float shift_x, float shift_y, int glyph);
+
+STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x,
+ float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
+
+STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph,
+ float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
-// @TODO: don't expose this structure
+/* @TODO: don't expose this structure */
+
typedef struct
{
int w,h,stride;
unsigned char *pixels;
} stbtt__bitmap;
-STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata);
+STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts,
+ float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata);
-//////////////////////////////////////////////////////////////////////////////
-//
-// Finding the right font...
-//
-// You should really just solve this offline, keep your own tables
-// of what font is what, and don't try to get it out of the .ttf file.
-// That's because getting it out of the .ttf file is really hard, because
-// the names in the file can appear in many possible encodings, in many
-// possible languages, and e.g. if you need a case-insensitive comparison,
-// the details of that depend on the encoding & language in a complex way
-// (actually underspecified in truetype, but also gigantic).
-//
-// But you can use the provided functions in two possible ways:
-// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
-// unicode-encoded names to try to find the font you want;
-// you can run this before calling stbtt_InitFont()
-//
-// stbtt_GetFontNameString() lets you get any of the various strings
-// from the file yourself and do your own comparisons on them.
-// You have to have called stbtt_InitFont() first.
+/* Finding the right font...
+ *
+ * You should really just solve this offline, keep your own tables
+ * of what font is what, and don't try to get it out of the .ttf file.
+ * That's because getting it out of the .ttf file is really hard, because
+ * the names in the file can appear in many possible encodings, in many
+ * possible languages, and e.g. if you need a case-insensitive comparison,
+ * the details of that depend on the encoding & language in a complex way
+ * (actually underspecified in truetype, but also gigantic).
+ *
+ * But you can use the provided functions in two possible ways:
+ * stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
+ * unicode-encoded names to try to find the font you want;
+ * you can run this before calling stbtt_InitFont()
+ *
+ * stbtt_GetFontNameString() lets you get any of the various strings
+ * from the file yourself and do your own comparisons on them.
+ * You have to have called stbtt_InitFont() first.
+ */
STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
-// returns the offset (not index) of the font that matches, or -1 if none
-// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
-// if you use any other flag, use a font name like "Arial"; this checks
-// the 'macStyle' header field; i don't know if fonts set this consistently
+
+/* returns the offset (not index) of the font that matches, or -1 if none
+ * if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
+ * if you use any other flag, use a font name like "Arial"; this checks
+ * the 'macStyle' header field; i don't know if fonts set this consistently
+ */
+
#define STBTT_MACSTYLE_DONTCARE 0
#define STBTT_MACSTYLE_BOLD 1
#define STBTT_MACSTYLE_ITALIC 2
#define STBTT_MACSTYLE_UNDERSCORE 4
-#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
+#define STBTT_MACSTYLE_NONE 8 /* <= not same as 0, this makes us check the bitfield is 0 */
STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
-// returns 1/0 whether the first string interpreted as utf8 is identical to
-// the second string interpreted as big-endian utf16... useful for strings from next func
-STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
-// returns the string (which may be big-endian double byte, e.g. for unicode)
-// and puts the length in bytes in *length.
-//
-// some of the values for the IDs are below; for more see the truetype spec:
-// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
-// http://www.microsoft.com/typography/otspec/name.htm
+/* returns I/0 whether the first string interpreted as UTF8 is identical to
+ * the second string interpreted as big-endian UTF16... useful for strings from next func
+ */
-enum { // platformID
+STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font,
+ int *length, int platformID, int encodingID, int languageID, int nameID);
+
+/* returns the string (which may be big-endian double byte, e.g. for unicode)
+ * and puts the length in bytes in *length.
+ *
+ * some of the values for the IDs are below; for more see the truetype spec:
+ * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
+ * http://www.microsoft.com/typography/otspec/name.htm
+ */
+
+enum
+{
+ /* platformID */
STBTT_PLATFORM_ID_UNICODE =0,
STBTT_PLATFORM_ID_MAC =1,
STBTT_PLATFORM_ID_ISO =2,
STBTT_PLATFORM_ID_MICROSOFT =3
};
-enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
+enum
+{
+ /* encodingID for STBTT_PLATFORM_ID_UNICODE */
STBTT_UNICODE_EID_UNICODE_1_0 =0,
STBTT_UNICODE_EID_UNICODE_1_1 =1,
STBTT_UNICODE_EID_ISO_10646 =2,
@@ -860,22 +763,29 @@ enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
};
-enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
+enum
+{
+ /* encodingID for STBTT_PLATFORM_ID_MICROSOFT */
STBTT_MS_EID_SYMBOL =0,
STBTT_MS_EID_UNICODE_BMP =1,
STBTT_MS_EID_SHIFTJIS =2,
STBTT_MS_EID_UNICODE_FULL =10
};
-enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
+enum
+{
+ /* encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes */
STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
};
-enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
- // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
+enum
+{
+ /* languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
+ * problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
+ */
STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
@@ -884,7 +794,8 @@ enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
};
-enum { // languageID for STBTT_PLATFORM_ID_MAC
+enum
+{ /* languageID for STBTT_PLATFORM_ID_MAC */
STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
@@ -898,14 +809,11 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC
}
#endif
-#endif // __STB_INCLUDE_STB_TRUETYPE_H__
+#endif /* __STB_INCLUDE_STB_TRUETYPE_H__ */
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-////
-//// IMPLEMENTATION
-////
-////
+#include
+
+/* IMPLEMENTATION */
#ifdef STB_TRUETYPE_IMPLEMENTATION
@@ -919,19 +827,17 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define STBTT_RASTERIZER_VERSION 2
#endif
-//////////////////////////////////////////////////////////////////////////
-//
-// accessors to parse data from file
-//
+/* accessors to parse data from file */
-// on platforms that don't allow misaligned reads, if we want to allow
-// truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
+/* on platforms that don't allow misaligned reads, if we want to allow
+ * truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
+ */
#define ttBYTE(p) (* (stbtt_uint8 *) (p))
#define ttCHAR(p) (* (stbtt_int8 *) (p))
#define ttFixed(p) ttLONG(p)
-#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
+#if defined(MSB_FIRST) && !defined(ALLOW_UNALIGNED_TRUETYPE)
#define ttUSHORT(p) (* (stbtt_uint16 *) (p))
#define ttSHORT(p) (* (stbtt_int16 *) (p))
@@ -952,21 +858,27 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
static int stbtt__isfont(const stbtt_uint8 *font)
{
- // check the version number
- if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1
- if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this!
- if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF
- if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
+ /* check the version number */
+ if (stbtt_tag4(font, '1',0,0,0))
+ return 1; /* TrueType 1 */
+ if (stbtt_tag(font, "typ1"))
+ return 1; /* TrueType with type 1 font -- we don't support this! */
+ if (stbtt_tag(font, "OTTO"))
+ return 1; /* OpenType with CFF */
+ if (stbtt_tag4(font, 0,1,0,0))
+ return 1; /* OpenType 1.0 */
return 0;
}
-// @OPTIMIZE: binary search
+/* @OPTIMIZE: binary search */
static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
{
+ stbtt_int32 i;
stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
stbtt_uint32 tabledir = fontstart + 12;
- stbtt_int32 i;
- for (i=0; i < num_tables; ++i) {
+
+ for (i=0; i < num_tables; ++i)
+ {
stbtt_uint32 loc = tabledir + 16*i;
if (stbtt_tag(data+loc+0, tag))
return ttULONG(data+loc+8);
@@ -976,14 +888,16 @@ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart,
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index)
{
- // if it's just a font, there's only one valid index
+ /* if it's just a font, there's only one valid index */
if (stbtt__isfont(font_collection))
return index == 0 ? 0 : -1;
- // check if it's a TTC
- if (stbtt_tag(font_collection, "ttcf")) {
- // version 1?
- if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
+ /* check if it's a TTC */
+ if (stbtt_tag(font_collection, "ttcf"))
+ {
+ /* version 1? */
+ if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000)
+ {
stbtt_int32 n = ttLONG(font_collection+8);
if (index >= n)
return -1;
@@ -1002,13 +916,14 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i
info->data = data;
info->fontstart = fontstart;
- cmap = stbtt__find_table(data, fontstart, "cmap"); // required
- info->loca = stbtt__find_table(data, fontstart, "loca"); // required
- info->head = stbtt__find_table(data, fontstart, "head"); // required
- info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
- info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
- info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
- info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
+ cmap = stbtt__find_table(data, fontstart, "cmap"); /* required */
+ info->loca = stbtt__find_table(data, fontstart, "loca"); /* required */
+ info->head = stbtt__find_table(data, fontstart, "head"); /* required */
+ info->glyf = stbtt__find_table(data, fontstart, "glyf"); /* required */
+ info->hhea = stbtt__find_table(data, fontstart, "hhea"); /* required */
+ info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); /* required */
+ info->kern = stbtt__find_table(data, fontstart, "kern"); /* not required */
+
if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
return 0;
@@ -1018,27 +933,34 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i
else
info->numGlyphs = 0xffff;
- // find a cmap encoding table we understand *now* to avoid searching
- // later. (todo: could make this installable)
- // the same regardless of glyph.
+ /* find a cmap encoding table we understand *now* to avoid searching
+ * later. (todo: could make this installable)
+ * the same regardless of glyph.
+ */
numTables = ttUSHORT(data + cmap + 2);
info->index_map = 0;
- for (i=0; i < numTables; ++i) {
+ for (i=0; i < numTables; ++i)
+ {
stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
- // find an encoding we understand:
- switch(ttUSHORT(data+encoding_record)) {
+
+ /* find an encoding we understand: */
+
+ switch(ttUSHORT(data+encoding_record))
+ {
case STBTT_PLATFORM_ID_MICROSOFT:
- switch (ttUSHORT(data+encoding_record+2)) {
+ switch (ttUSHORT(data+encoding_record+2))
+ {
case STBTT_MS_EID_UNICODE_BMP:
case STBTT_MS_EID_UNICODE_FULL:
- // MS/Unicode
+ /* MS/Unicode */
info->index_map = cmap + ttULONG(data+encoding_record+4);
break;
}
break;
- case STBTT_PLATFORM_ID_UNICODE:
- // Mac/iOS has these
- // all the encodingIDs are unicode, so we don't bother to check it
+ case STBTT_PLATFORM_ID_UNICODE:
+ /* Mac/iOS has these
+ * all the encodingIDs are unicode, so we don't bother to check it
+ */
info->index_map = cmap + ttULONG(data+encoding_record+4);
break;
}
@@ -1056,41 +978,51 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
stbtt_uint32 index_map = info->index_map;
stbtt_uint16 format = ttUSHORT(data + index_map + 0);
- if (format == 0) { // apple byte encoding
+ if (format == 0)
+ {
+ /* apple byte encoding */
stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
if (unicode_codepoint < bytes-6)
return ttBYTE(data + index_map + 6 + unicode_codepoint);
return 0;
- } else if (format == 6) {
+ }
+ else if (format == 6)
+ {
stbtt_uint32 first = ttUSHORT(data + index_map + 6);
stbtt_uint32 count = ttUSHORT(data + index_map + 8);
if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
return 0;
- } else if (format == 2) {
- STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
+ }
+ else if (format == 2)
+ {
+ rarch_assert(0); /* @TODO: high-byte mapping for japanese/chinese/korean */
return 0;
- } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
+ }
+ else if (format == 4)
+ {
+ /* standard mapping for windows fonts: binary search collection of ranges */
stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
- // do a binary search of the segments
+ /* do a binary search of the segments */
stbtt_uint32 endCount = index_map + 14;
stbtt_uint32 search = endCount;
if (unicode_codepoint > 0xffff)
return 0;
- // they lie from endCount .. endCount + segCount
- // but searchRange is the nearest power of two, so...
+ /* they lie from endCount .. endCount + segCount
+ * but searchRange is the nearest power of two, so... */
if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
search += rangeShift*2;
- // now decrement to bias correctly to find smallest
+ /* now decrement to bias correctly to find smallest */
search -= 2;
- while (entrySelector) {
+ while (entrySelector)
+ {
stbtt_uint16 end;
searchRange >>= 1;
end = ttUSHORT(data + search + searchRange*2);
@@ -1104,7 +1036,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
stbtt_uint16 offset, start;
stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1);
- STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
+ rarch_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
if (unicode_codepoint < start)
return 0;
@@ -1115,13 +1047,16 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
}
- } else if (format == 12 || format == 13) {
+ }
+ else if (format == 12 || format == 13)
+ {
stbtt_uint32 ngroups = ttULONG(data+index_map+12);
stbtt_int32 low,high;
low = 0; high = (stbtt_int32)ngroups;
- // Binary search the right group.
- while (low < high) {
- stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
+ /* Binary search the right group. */
+ while (low < high)
+ {
+ stbtt_int32 mid = low + ((high-low) >> 1); /* rounds down, so low <= mid < high */
stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
if ((stbtt_uint32) unicode_codepoint < start_char)
@@ -1132,14 +1067,14 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
if (format == 12)
return start_glyph + unicode_codepoint-start_char;
- else // format == 13
+ else /* format == 13 */
return start_glyph;
}
}
- return 0; // not found
+ return 0; /* not found */
}
- // @TODO
- STBTT_assert(0);
+ /* @TODO */
+ rarch_assert(0);
return 0;
}
@@ -1161,21 +1096,27 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
{
int g1,g2;
- if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
- if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format
+ if (glyph_index >= info->numGlyphs)
+ return -1; /* glyph index out of range */
+ if (info->indexToLocFormat >= 2)
+ return -1; /* unknown index->glyph map format */
- if (info->indexToLocFormat == 0) {
+ if (info->indexToLocFormat == 0)
+ {
g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
- } else {
+ }
+ else
+ {
g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
}
- return g1==g2 ? -1 : g1; // if length is 0, return -1
+ return g1==g2 ? -1 : g1; /* if length is 0, return -1 */
}
-STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
+STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info,
+ int glyph_index, int *x0, int *y0, int *x1, int *y1)
{
int g = stbtt__GetGlyfOffset(info, glyph_index);
if (g < 0) return 0;
@@ -1187,7 +1128,8 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int
return 1;
}
-STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
+STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info,
+ int codepoint, int *x0, int *y0, int *x1, int *y1)
{
return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
}
@@ -1243,24 +1185,27 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
- m = n + 2*numberOfContours; // a loose bound on how many vertices we might need
- vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
+ m = n + 2*numberOfContours; /* a loose bound on how many vertices we might need */
+ vertices = (stbtt_vertex *)malloc(m * sizeof(vertices[0]));
if (vertices == 0)
return 0;
next_move = 0;
flagcount=0;
- // in first pass, we load uninterpreted data into the allocated array
- // above, shifted to the end of the array so we won't overwrite it when
- // we create our final data starting from the front
+ /* in first pass, we load uninterpreted data into the allocated array
+ * above, shifted to the end of the array so we won't overwrite it when
+ * we create our final data starting from the front
+ */
- off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
+ off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */
- // first load flags
+ /* first load flags */
- for (i=0; i < n; ++i) {
- if (flagcount == 0) {
+ for (i=0; i < n; ++i)
+ {
+ if (flagcount == 0)
+ {
flags = *points++;
if (flags & 8)
flagcount = *points++;
@@ -1269,15 +1214,20 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
vertices[off+i].type = flags;
}
- // now load x coordinates
+ /* now load x coordinates */
x=0;
- for (i=0; i < n; ++i) {
+ for (i=0; i < n; ++i)
+ {
flags = vertices[off+i].type;
- if (flags & 2) {
+ if (flags & 2)
+ {
stbtt_int16 dx = *points++;
- x += (flags & 16) ? dx : -dx; // ???
- } else {
- if (!(flags & 16)) {
+ x += (flags & 16) ? dx : -dx; /* ??? */
+ }
+ else
+ {
+ if (!(flags & 16))
+ {
x = x + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
}
@@ -1285,14 +1235,18 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
vertices[off+i].x = (stbtt_int16) x;
}
- // now load y coordinates
+ /* now load y coordinates */
y=0;
- for (i=0; i < n; ++i) {
+ for (i=0; i < n; ++i)
+ {
flags = vertices[off+i].type;
- if (flags & 4) {
+ if (flags & 4)
+ {
stbtt_int16 dy = *points++;
- y += (flags & 32) ? dy : -dy; // ???
- } else {
+ y += (flags & 32) ? dy : -dy; /* ??? */
+ }
+ else
+ {
if (!(flags & 32)) {
y = y + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
@@ -1301,34 +1255,42 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
vertices[off+i].y = (stbtt_int16) y;
}
- // now convert them to our format
+ /* now convert them to our format */
num_vertices=0;
sx = sy = cx = cy = scx = scy = 0;
- for (i=0; i < n; ++i) {
+ for (i=0; i < n; ++i)
+ {
flags = vertices[off+i].type;
x = (stbtt_int16) vertices[off+i].x;
y = (stbtt_int16) vertices[off+i].y;
- if (next_move == i) {
+ if (next_move == i)
+ {
if (i != 0)
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
- // now start the new one
+ /* now start the new one */
start_off = !(flags & 1);
- if (start_off) {
- // if we start off with an off-curve point, then when we need to find a point on the curve
- // where we can start, and we need to save some state for when we wraparound.
+
+ if (start_off)
+ {
+ /* if we start off with an off-curve point,
+ * then when we need to find a point on the curve
+ * where we can start, and we need to save some state for when we wraparound. */
scx = x;
scy = y;
- if (!(vertices[off+i+1].type & 1)) {
- // next point is also a curve point, so interpolate an on-point curve
+ if (!(vertices[off+i+1].type & 1))
+ {
+ /* next point is also a curve point, so interpolate an on-point curve */
sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
- } else {
- // otherwise just use the next point as our start point
+ }
+ else
+ {
+ /* otherwise just use the next point as our start point */
sx = (stbtt_int32) vertices[off+i+1].x;
sy = (stbtt_int32) vertices[off+i+1].y;
- ++i; // we're using point i+1 as the starting point, so skip it
+ ++i; /* we're using point i+1 as the starting point, so skip it */
}
} else {
sx = x;
@@ -1338,14 +1300,20 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
was_off = 0;
next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
++j;
- } else {
- if (!(flags & 1)) { // if it's a curve
- if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
+ }
+ else
+ {
+ if (!(flags & 1))
+ {
+ /* if it's a curve */
+ if (was_off) /* two off-curve control points in a row means interpolate an on-curve midpoint */
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
cx = x;
cy = y;
was_off = 1;
- } else {
+ }
+ else
+ {
if (was_off)
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
else
@@ -1355,57 +1323,76 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
}
}
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
- } else if (numberOfContours == -1) {
- // Compound shapes.
+ }
+ else if (numberOfContours == -1)
+ {
+ /* Compound shapes. */
int more = 1;
stbtt_uint8 *comp = data + g + 10;
num_vertices = 0;
vertices = 0;
- while (more) {
+ while (more)
+ {
stbtt_uint16 flags, gidx;
int comp_num_verts = 0, i;
stbtt_vertex *comp_verts = 0, *tmp = 0;
float mtx[6] = {1,0,0,1,0,0}, m, n;
-
+
flags = ttSHORT(comp); comp+=2;
gidx = ttSHORT(comp); comp+=2;
- if (flags & 2) { // XY values
- if (flags & 1) { // shorts
+ if (flags & 2)
+ {
+ /* XY values */
+ if (flags & 1)
+ { /* shorts */
mtx[4] = ttSHORT(comp); comp+=2;
mtx[5] = ttSHORT(comp); comp+=2;
- } else {
+ }
+ else
+ {
mtx[4] = ttCHAR(comp); comp+=1;
mtx[5] = ttCHAR(comp); comp+=1;
}
}
- else {
- // @TODO handle matching point
- STBTT_assert(0);
+ else
+ {
+ /* @TODO handle matching point */
+ rarch_assert(0);
}
- if (flags & (1<<3)) { // WE_HAVE_A_SCALE
+ if (flags & (1<<3))
+ {
+ /* WE_HAVE_A_SCALE */
mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
- } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
+ }
+ else if (flags & (1<<6))
+ {
+ /* WE_HAVE_AN_X_AND_YSCALE */
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
- } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
+ }
+ else if (flags & (1<<7))
+ {
+ /* WE_HAVE_A_TWO_BY_TWO */
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
}
-
- // Find transformation scales.
+
+ /* Find transformation scales. */
m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
- // Get indexed glyph.
+ /* Get indexed glyph. */
comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
- if (comp_num_verts > 0) {
- // Transform vertices.
- for (i = 0; i < comp_num_verts; ++i) {
+ if (comp_num_verts > 0)
+ {
+ /* Transform vertices. */
+ for (i = 0; i < comp_num_verts; ++i)
+ {
stbtt_vertex* v = &comp_verts[i];
stbtt_vertex_type x,y;
x=v->x; y=v->y;
@@ -1415,58 +1402,78 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
}
- // Append vertices.
- tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
- if (!tmp) {
- if (vertices) STBTT_free(vertices, info->userdata);
- if (comp_verts) STBTT_free(comp_verts, info->userdata);
+
+ /* Append vertices. */
+ tmp = (stbtt_vertex*)malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex));
+ if (!tmp)
+ {
+ if (vertices)
+ free(vertices);
+ if (comp_verts)
+ free(comp_verts);
return 0;
}
- if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
- STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
- if (vertices) STBTT_free(vertices, info->userdata);
+ if (num_vertices > 0)
+ memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
+ memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
+
+ if (vertices)
+ free(vertices);
+
vertices = tmp;
- STBTT_free(comp_verts, info->userdata);
+ free(comp_verts);
num_vertices += comp_num_verts;
}
- // More components ?
+ /* More components ? */
more = flags & (1<<5);
}
- } else if (numberOfContours < 0) {
- // @TODO other compound variations?
- STBTT_assert(0);
- } else {
- // numberOfCounters == 0, do nothing
+ }
+ else if (numberOfContours < 0)
+ {
+ /* @TODO other compound variations? */
+ rarch_assert(0);
+ }
+ else
+ {
+ /* numberOfCounters == 0, do nothing */
}
*pvertices = vertices;
return num_vertices;
}
-STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
+STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info,
+ int glyph_index, int *advanceWidth, int *leftSideBearing)
{
stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
- if (glyph_index < numOfLongHorMetrics) {
- if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
- if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
- } else {
- if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
- if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
+ if (glyph_index < numOfLongHorMetrics)
+ {
+ if (advanceWidth)
+ *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
+ if (leftSideBearing)
+ *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
+ }
+ else
+ {
+ if (advanceWidth)
+ *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
+ if (leftSideBearing)
+ *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
}
}
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{
- stbtt_uint8 *data = info->data + info->kern;
- stbtt_uint32 needle, straw;
int l, r, m;
+ stbtt_uint32 needle, straw;
+ stbtt_uint8 *data = info->data + info->kern;
- // we only look at the first table. it must be 'horizontal' and format 0.
+ /* we only look at the first table. it must be 'horizontal' and format 0. */
if (!info->kern)
return 0;
- if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
+ if (ttUSHORT(data+2) < 1) /* number of tables, need at least 1 */
return 0;
- if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
+ if (ttUSHORT(data+8) != 1) /* horizontal flag must be set in format */
return 0;
l = 0;
@@ -1474,7 +1481,7 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
needle = glyph1 << 16 | glyph2;
while (l <= r) {
m = (l + r) >> 1;
- straw = ttULONG(data+18+(m*6)); // note: unaligned read
+ straw = ttULONG(data+18+(m*6)); /* note: unaligned read */
if (needle < straw)
r = m - 1;
else if (needle > straw)
@@ -1487,24 +1494,27 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
{
- if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
+ if (!info->kern) /* if no kerning table, don't waste time looking up both codepoint->glyphs */
return 0;
return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
}
-STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
+STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info,
+ int codepoint, int *advanceWidth, int *leftSideBearing)
{
stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
}
-STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
+STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info,
+ int *ascent, int *descent, int *lineGap)
{
if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
}
-STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
+STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info,
+ int *x0, int *y0, int *x1, int *y1)
{
*x0 = ttSHORT(info->data + info->head + 36);
*y0 = ttSHORT(info->data + info->head + 38);
@@ -1526,25 +1536,28 @@ STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, floa
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
{
- STBTT_free(v, info->userdata);
+ free(v);
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// antialiasing software rasterizer
-//
+/* antialiasing software rasterizer */
-STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
+STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font,
+ int glyph, float scale_x, float scale_y,float shift_x, float shift_y,
+ int *ix0, int *iy0, int *ix1, int *iy1)
{
int x0,y0,x1,y1;
- if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
- // e.g. space character
+ if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1))
+ {
+ /* e.g. space character */
if (ix0) *ix0 = 0;
if (iy0) *iy0 = 0;
if (ix1) *ix1 = 0;
if (iy1) *iy1 = 0;
- } else {
- // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
+ }
+ else
+ {
+ /* move to integral bboxes
+ * (treating pixels as little squares, what pixels get touched)? */
if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
@@ -1552,24 +1565,25 @@ STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int g
}
}
-STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
+STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,
+ int *ix0, int *iy0, int *ix1, int *iy1)
{
stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
}
-STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
+STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y,
+ float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
{
stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
}
-STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
+STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y,
+ int *ix0, int *iy0, int *ix1, int *iy1)
{
stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// Rasterizer
+/* Rasterizer */
typedef struct stbtt__hheap_chunk
{
@@ -1592,7 +1606,8 @@ static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata)
} else {
if (hh->num_remaining_in_head_chunk == 0) {
int count = (size < 32 ? 2000 : size < 128 ? 800 : 100);
- stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata);
+ stbtt__hheap_chunk *c = (stbtt__hheap_chunk *)
+ malloc(sizeof(stbtt__hheap_chunk) + size * count);
if (c == NULL)
return NULL;
c->next = hh->head;
@@ -1615,7 +1630,7 @@ static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata)
stbtt__hheap_chunk *c = hh->head;
while (c) {
stbtt__hheap_chunk *n = c->next;
- STBTT_free(c, userdata);
+ free(c);
c = n;
}
}
@@ -1654,13 +1669,13 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
if (!z) return z;
- // round dx down to avoid overshooting
+ /* round dx down to avoid overshooting */
if (dxdy < 0)
z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy);
else
z->dx = STBTT_ifloor(STBTT_FIX * dxdy);
- z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount
+ z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); /* use z->dx so when we offset later it's by the same amount */
z->x -= off_x * STBTT_FIX;
z->ey = e->y1;
@@ -1673,7 +1688,6 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
- //STBTT_assert(e->y0 <= start_point);
if (!z) return z;
z->fdx = dxdy;
z->fdy = (1/dxdy);
@@ -1690,22 +1704,29 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
#endif
#if STBTT_RASTERIZER_VERSION == 1
-// note: this routine clips fills that extend off the edges... ideally this
-// wouldn't happen, but it could happen if the truetype glyph bounding boxes
-// are wrong, or if the user supplies a too-small bitmap
+/* note: this routine clips fills that extend off the edges... ideally this
+ * wouldn't happen, but it could happen if the truetype glyph bounding boxes
+ * are wrong, or if the user supplies a too-small bitmap
+ */
static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
{
- // non-zero winding fill
+ /* non-zero winding fill */
int x0=0, w=0;
- while (e) {
- if (w == 0) {
- // if we're currently at zero, we need to record the edge start point
+ while (e)
+ {
+ if (w == 0)
+ {
+ /* if we're currently at zero, we need to record the edge start point */
x0 = e->x; w += e->direction;
- } else {
+ }
+ else
+ {
int x1 = e->x; w += e->direction;
- // if we went to zero, we need to draw
- if (w == 0) {
+ /* if we went to zero, we need to draw */
+
+ if (w == 0)
+ {
int i = x0 >> STBTT_FIXSHIFT;
int j = x1 >> STBTT_FIXSHIFT;
@@ -1735,17 +1756,18 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac
}
}
-static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
+static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n,
+ int vsubsample, int off_x, int off_y, void *userdata)
{
+ unsigned char scanline_data[512], *scanline;
stbtt__hheap hh = { 0 };
stbtt__active_edge *active = NULL;
int y,j=0;
- int max_weight = (255 / vsubsample); // weight per vertical scanline
- int s; // vertical subsample index
- unsigned char scanline_data[512], *scanline;
+ int max_weight = (255 / vsubsample); /* weight per vertical scanline */
+ int s; /* vertical subsample index */
if (result->w > 512)
- scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
+ scanline = (unsigned char *)malloc(result->w);
else
scanline = scanline_data;
@@ -1753,7 +1775,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
while (j < result->h) {
- STBTT_memset(scanline, 0, result->w);
+ memset(scanline, 0, result->w);
for (s=0; s < vsubsample; ++s) {
// find center of pixel for this scanline
float scan_y = y + 0.5f;
@@ -1765,7 +1787,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
stbtt__active_edge * z = *step;
if (z->ey <= scan_y) {
*step = z->next; // delete from list
- STBTT_assert(z->direction);
+ rarch_assert(z->direction);
z->direction = 0;
stbtt__hheap_free(&hh, z);
} else {
@@ -1823,21 +1845,23 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
++y;
}
- STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
+ memcpy(result->pixels + j * result->stride, scanline, result->w);
++j;
}
stbtt__hheap_cleanup(&hh, userdata);
if (scanline != scanline_data)
- STBTT_free(scanline, userdata);
+ free(scanline);
}
#elif STBTT_RASTERIZER_VERSION == 2
-// the edge passed in here does not cross the vertical line at x or the vertical line at x+1
-// (i.e. it has already been clipped to those)
-static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1)
+/* the edge passed in here does not cross the vertical line at x or the vertical line at x+1
+ * (i.e. it has already been clipped to those)
+ */
+static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e,
+ float x0, float y0, float x1, float y1)
{
if (y0 == y1) return;
assert(y0 < y1);
@@ -1870,18 +1894,20 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg
;
else {
assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1);
- scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position
+ scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); /* coverage = 1 - average x position */
}
}
-static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top)
+static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
+ int len, stbtt__active_edge *e, float y_top)
{
float y_bottom = y_top+1;
- while (e) {
- // brute force every pixel
+ while (e)
+ {
+ /* brute force every pixel */
- // compute intersection points with top & bottom
+ /* compute intersection points with top & bottom */
assert(e->ey >= y_top);
if (e->fdx == 0) {
@@ -1903,9 +1929,10 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float dy = e->fdy;
assert(e->sy <= y_bottom && e->ey >= y_top);
- // compute endpoints of line segment clipped to this scanline (if the
- // line segment starts on this scanline. x0 is the intersection of the
- // line with y_top, but that may be off the line segment.
+ /* compute endpoints of line segment clipped to this scanline (if the
+ * line segment starts on this scanline. x0 is the intersection of the
+ * line with y_top, but that may be off the line segment.
+ */
if (e->sy > y_top) {
x_top = x0 + dx * (e->sy - y_top);
y0 = e->sy;
@@ -1921,23 +1948,30 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
y1 = y_bottom;
}
- if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
- // from here on, we don't have to range check x values
+ if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len)
+ {
+ /* from here on, we don't have to range check x values */
+
+ if ((int) x_top == (int) x_bottom)
+ {
+ /* simple case, only spans one pixel */
- if ((int) x_top == (int) x_bottom) {
float height;
- // simple case, only spans one pixel
int x = (int) x_top;
height = y1 - y0;
assert(x >= 0 && x < len);
scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
- scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
- } else {
+ scanline_fill[x] += e->direction * height; /* everything right of this pixel is filled */
+ }
+ else
+ {
int x,x1,x2;
float y_crossing, step, sign, area;
- // covers 2+ pixels
- if (x_top > x_bottom) {
- // flip scanline vertically; signed area is the same
+
+ /* covers 2+ pixels */
+ if (x_top > x_bottom)
+ {
+ /* flip scanline vertically; signed area is the same */
float t;
y0 = y_bottom - (y0 - y_top);
y1 = y_bottom - (y1 - y_top);
@@ -1950,17 +1984,18 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
x1 = (int) x_top;
x2 = (int) x_bottom;
- // compute intersection with y axis at x1+1
+ /* compute intersection with y axis at x1+1 */
y_crossing = (x1+1 - x0) * dy + y_top;
sign = e->direction;
- // area of the rectangle covered from y0..y_crossing
+ /* area of the rectangle covered from y0..y_crossing */
area = sign * (y_crossing-y0);
- // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
+ /* area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) */
scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
step = sign * dy;
- for (x = x1+1; x < x2; ++x) {
+ for (x = x1+1; x < x2; ++x)
+ {
scanline[x] += area + step/2;
area += step;
}
@@ -1972,23 +2007,27 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
scanline_fill[x2] += sign * (y1-y0);
}
- } else {
- // if edge goes outside of box we're drawing, we require
- // clipping logic. since this does not match the intended use
- // of this library, we use a different, very slow brute
- // force implementation
+ }
+ else
+ {
+ /* if edge goes outside of box we're drawing, we require
+ * clipping logic. since this does not match the intended use
+ * of this library, we use a different, very slow brute
+ * force implementation
+ */
int x;
- for (x=0; x < len; ++x) {
- // cases:
- //
- // there can be up to two intersections with the pixel. any intersection
- // with left or right edges can be handled by splitting into two (or three)
- // regions. intersections with top & bottom do not necessitate case-wise logic.
+
+ for (x=0; x < len; ++x)
+ {
+ /* cases:
+ *
+ * there can be up to two intersections with the pixel. any intersection
+ * with left or right edges can be handled by splitting into two (or three)
+ * regions. intersections with top & bottom do not necessitate case-wise logic.
+ */
float y0,y1;
float y_cur = y_top, x_cur = x0;
- // x = e->x + e->dx * (y-y_top)
- // (y-y_top) = (x - e->x) / e->dx
- // y = (x - e->x) / e->dx + y_top
+
y0 = (x - x0) / dx + y_top;
y1 = (x+1 - x0) / dx + y_top;
@@ -2023,8 +2062,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
}
}
-// directly AA rasterize edges w/o supersampling
-static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
+/* directly AA rasterize edges w/o supersampling */
+static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
+ int n, int vsubsample, int off_x, int off_y, void *userdata)
{
stbtt__hheap hh = { 0 };
stbtt__active_edge *active = NULL;
@@ -2032,7 +2072,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
float scanline_data[129], *scanline, *scanline2;
if (result->w > 64)
- scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
+ scanline = (float *)malloc((result->w*2+1) * sizeof(float));
else
scanline = scanline_data;
@@ -2041,46 +2081,52 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
y = off_y;
e[n].y0 = (float) (off_y + result->h) + 1;
- while (j < result->h) {
- // find center of pixel for this scanline
+ while (j < result->h)
+ {
float scan_y_top = y + 0.0f;
float scan_y_bottom = y + 1.0f;
stbtt__active_edge **step = &active;
- STBTT_memset(scanline , 0, result->w*sizeof(scanline[0]));
- STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
+ /* find center of pixel for this scanline */
- // update all active edges;
- // remove all active edges that terminate before the top of this scanline
+ memset(scanline , 0, result->w*sizeof(scanline[0]));
+ memset(scanline2, 0, (result->w+1)*sizeof(scanline[0]));
+
+ /* update all active edges,
+ * remove all active edges that terminate
+ * before the top of this scanline */
while (*step) {
stbtt__active_edge * z = *step;
if (z->ey <= scan_y_top) {
- *step = z->next; // delete from list
- STBTT_assert(z->direction);
+ *step = z->next; /* delete from list */
+ rarch_assert(z->direction);
z->direction = 0;
stbtt__hheap_free(&hh, z);
} else {
- step = &((*step)->next); // advance through list
+ step = &((*step)->next); /* advance through list */
}
}
- // insert all edges that start before the bottom of this scanline
- while (e->y0 <= scan_y_bottom) {
+ /* insert all edges that start before the bottom of this scanline */
+ while (e->y0 <= scan_y_bottom)
+ {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
assert(z->ey >= scan_y_top);
- // insert at front
+
+ /* insert at front */
z->next = active;
active = z;
++e;
}
- // now process all active edges
+ /* now process all active edges */
if (active)
stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top);
{
float sum = 0;
- for (i=0; i < result->w; ++i) {
+ for (i=0; i < result->w; ++i)
+ {
float k;
int m;
sum += scanline2[i];
@@ -2091,12 +2137,16 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
result->pixels[j*result->stride + i] = (unsigned char) m;
}
}
- // advance all the edges
+
+ /* advance all the edges */
+
step = &active;
- while (*step) {
+
+ while (*step)
+ {
stbtt__active_edge *z = *step;
- z->fx += z->fdx; // advance to position for current scanline
- step = &((*step)->next); // advance through list
+ z->fx += z->fdx; /* advance to position for current scanline */
+ step = &((*step)->next); /* advance through list */
}
++y;
@@ -2106,7 +2156,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
stbtt__hheap_cleanup(&hh, userdata);
if (scanline != scanline_data)
- STBTT_free(scanline, userdata);
+ free(scanline);
}
#else
#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
@@ -2205,7 +2255,9 @@ typedef struct
float x,y;
} stbtt__point;
-static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata)
+static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings,
+ float scale_x, float scale_y, float shift_x, float shift_y,
+ int off_x, int off_y, int invert, void *userdata)
{
float y_scale_inv = invert ? -scale_y : scale_y;
stbtt__edge *e;
@@ -2217,14 +2269,14 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
#else
#error "Unrecognized value of STBTT_RASTERIZER_VERSION"
#endif
- // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
+ /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */
- // now we have to blow out the windings into explicit edge lists
+ /* now we have to blow out the windings into explicit edge lists */
n = 0;
for (i=0; i < windings; ++i)
n += wcount[i];
- e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
+ e = (stbtt__edge *)malloc(sizeof(*e) * (n+1)); /* add an extra one as a sentinel */
if (e == 0) return;
n = 0;
@@ -2235,10 +2287,10 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
j = wcount[i]-1;
for (k=0; k < wcount[i]; j=k++) {
int a=k,b=j;
- // skip the edge if horizontal
+ /* skip the edge if horizontal */
if (p[j].y == p[k].y)
continue;
- // add edge from j to k to the list
+ /* add edge from j to k to the list */
e[n].invert = 0;
if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
e[n].invert = 1;
@@ -2252,46 +2304,53 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
}
}
- // now sort the edges by their highest point (should snap to integer, and then by x)
- //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
+ /* now sort the edges by their highest point (should snap to integer, and then by x) */
stbtt__sort_edges(e, n);
- // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
+ /* now, traverse the scanlines and find the
+ * intersections on each scanline, use XOR winding rule */
stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
- STBTT_free(e, userdata);
+ free(e);
}
static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
{
- if (!points) return; // during first pass, it's unallocated
+ if (!points) return; /* during first pass, it's unallocated */
points[n].x = x;
points[n].y = y;
}
-// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
-static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
+/* tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching */
+static int stbtt__tesselate_curve(stbtt__point *points, int *num_points,
+ float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
{
- // midpoint
+ /* midpoint */
float mx = (x0 + 2*x1 + x2)/4;
float my = (y0 + 2*y1 + y2)/4;
- // versus directly drawn line
+ /* versus directly drawn line */
float dx = (x0+x2)/2 - mx;
float dy = (y0+y2)/2 - my;
- if (n > 16) // 65536 segments on one curve better be enough!
+ if (n > 16) /* 65536 segments on one curve better be enough! */
return 1;
- if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
+
+ if (dx*dx+dy*dy > objspace_flatness_squared)
+ {
+ /* half-pixel error allowed... need to be smaller if AA */
stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
- } else {
+ }
+ else
+ {
stbtt__add_point(points, *num_points,x2,y2);
*num_points = *num_points+1;
}
return 1;
}
-// returns number of contours
-static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
+/* Returns number of contours */
+static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts,
+ float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
{
stbtt__point *points=0;
int num_points=0;
@@ -2299,7 +2358,7 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts,
float objspace_flatness_squared = objspace_flatness * objspace_flatness;
int i,n=0,start=0, pass;
- // count how many "moves" there are to get the contour count
+ /* count how many "moves" there are to get the contour count */
for (i=0; i < num_verts; ++i)
if (vertices[i].type == STBTT_vmove)
++n;
@@ -2307,26 +2366,32 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts,
*num_contours = n;
if (n == 0) return 0;
- *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
+ *contour_lengths = (int *)malloc(sizeof(**contour_lengths) * n);
if (*contour_lengths == 0) {
*num_contours = 0;
return 0;
}
- // make two passes through the points so we don't need to realloc
- for (pass=0; pass < 2; ++pass) {
+ /* make two passes through the points so we don't need to realloc */
+ for (pass=0; pass < 2; ++pass)
+ {
float x=0,y=0;
- if (pass == 1) {
- points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
+
+ if (pass == 1)
+ {
+ points = (stbtt__point *)malloc(num_points * sizeof(points[0]));
if (points == NULL) goto error;
}
num_points = 0;
n= -1;
- for (i=0; i < num_verts; ++i) {
- switch (vertices[i].type) {
+
+ for (i=0; i < num_verts; ++i)
+ {
+ switch (vertices[i].type)
+ {
case STBTT_vmove:
- // start the next contour
+ /* start the next contour */
if (n >= 0)
(*contour_lengths)[n] = num_points - start;
++n;
@@ -2353,31 +2418,35 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts,
return points;
error:
- STBTT_free(points, userdata);
- STBTT_free(*contour_lengths, userdata);
+ free(points);
+ free(*contour_lengths);
*contour_lengths = 0;
*num_contours = 0;
return NULL;
}
-STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
+STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels,
+ stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y,
+ float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
{
float scale = scale_x > scale_y ? scale_y : scale_x;
int winding_count, *winding_lengths;
stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
- if (windings) {
+ if (windings)
+ {
stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
- STBTT_free(winding_lengths, userdata);
- STBTT_free(windings, userdata);
+ free(winding_lengths);
+ free(windings);
}
}
STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
{
- STBTT_free(bitmap, userdata);
+ free(bitmap);
}
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y,
+ float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
{
int ix0,iy0,ix1,iy1;
stbtt__bitmap gbm;
@@ -2385,41 +2454,49 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
if (scale_x == 0) scale_x = scale_y;
- if (scale_y == 0) {
- if (scale_x == 0) return NULL;
+ if (scale_y == 0)
+ {
+ if (scale_x == 0)
+ return NULL;
scale_y = scale_x;
}
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
- // now we get the size
- gbm.w = (ix1 - ix0);
- gbm.h = (iy1 - iy0);
- gbm.pixels = NULL; // in case we error
+ /* now we get the size */
+ gbm.w = (ix1 - ix0);
+ gbm.h = (iy1 - iy0);
+ gbm.pixels = NULL; /* in case we error */
if (width ) *width = gbm.w;
if (height) *height = gbm.h;
if (xoff ) *xoff = ix0;
if (yoff ) *yoff = iy0;
- if (gbm.w && gbm.h) {
- gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
- if (gbm.pixels) {
+ if (gbm.w && gbm.h)
+ {
+ gbm.pixels = (unsigned char *)malloc(gbm.w * gbm.h);
+ if (gbm.pixels)
+ {
gbm.stride = gbm.w;
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
}
}
- STBTT_free(vertices, info->userdata);
+
+ free(vertices);
return gbm.pixels;
}
-STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
+STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y,
+ int glyph, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
}
-STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
+STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride,
+ float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
{
int ix0,iy0;
stbtt_vertex *vertices;
@@ -2435,22 +2512,29 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne
if (gbm.w && gbm.h)
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
- STBTT_free(vertices, info->userdata);
+ free(vertices);
}
-STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
+STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
{
stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
}
-STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
+STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info,
+ float scale_x, float scale_y, float shift_x, float shift_y, int codepoint,
+ int *width, int *height, int *xoff, int *yoff)
{
- return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
+ return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y,
+ stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
}
-STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
+STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output,
+ int out_w, int out_h, int out_stride, float scale_x, float scale_y,
+ float shift_x, float shift_y, int codepoint)
{
- stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
+ stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y,
+ shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
}
STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
@@ -2458,29 +2542,32 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl
return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
}
-STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
+STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info,
+ unsigned char *output, int out_w, int out_h,
+ int out_stride, float scale_x, float scale_y, int codepoint)
{
- stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
+ stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h,
+ out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// bitmap baking
-//
-// This is SUPER-CRAPPY packing to keep source code small
+/* bitmap baking
+ *
+ * This is SUPER-CRAPPY packing to keep source code small
+ */
-STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
- float pixel_height, // height of font in pixels
- unsigned char *pixels, int pw, int ph, // bitmap to be filled in
- int first_char, int num_chars, // characters to bake
- stbtt_bakedchar *chardata)
+STBTT_DEF int stbtt_BakeFontBitmap(
+ const unsigned char *data, int offset, /* font location (use offset=0 for plain .ttf) */
+ float pixel_height, /* height of font in pixels */
+ unsigned char *pixels, int pw, int ph, /* bitmap to be filled in */
+ int first_char, int num_chars, /* characters to bake */
+ stbtt_bakedchar *chardata)
{
float scale;
int x,y,bottom_y, i;
stbtt_fontinfo f;
if (!stbtt_InitFont(&f, data, offset))
return -1;
- STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
+ memset(pixels, 0, pw*ph); /* background of 0 around pixels */
x=y=1;
bottom_y = 1;
@@ -2494,11 +2581,11 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
gw = x1-x0;
gh = y1-y0;
if (x + gw + 1 >= pw)
- y = bottom_y, x = 1; // advance to next row
- if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
+ y = bottom_y, x = 1; /* advance to next row */
+ if (y + gh + 1 >= ph) /* check if it fits vertically AFTER potentially moving to next row */
return -i;
- STBTT_assert(x+gw < pw);
- STBTT_assert(y+gh < ph);
+ rarch_assert(x+gw < pw);
+ rarch_assert(y+gh < ph);
stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
chardata[i].x0 = (stbtt_int16) x;
chardata[i].y0 = (stbtt_int16) y;
@@ -2514,7 +2601,9 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
return bottom_y;
}
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
+STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph,
+ int char_index, float *xpos, float *ypos,
+ stbtt_aligned_quad *q, int opengl_fillrule)
{
float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
@@ -2535,10 +2624,7 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
*xpos += b->xadvance;
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// rectangle packing replacement routines if you don't have stb_rect_pack.h
-//
+/* rectangle packing replacement routines if you don't have stb_rect_pack.h */
#ifndef STB_RECT_PACK_VERSION
#ifdef _MSC_VER
@@ -2549,16 +2635,12 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
typedef int stbrp_coord;
-////////////////////////////////////////////////////////////////////////////////////
-// //
-// //
-// COMPILER WARNING ?!?!? //
-// //
-// //
-// if you get a compile warning due to these symbols being defined more than //
-// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" //
-// //
-////////////////////////////////////////////////////////////////////////////////////
+/*
+ * COMPILER WARNING ?!?!?
+ *
+ * if you get a compile warning due to these symbols being defined more than
+ * once, move #include "stb_rect_pack.h" before #include "stb_truetype.h"
+ */
typedef struct
{
@@ -2577,7 +2659,8 @@ typedef struct
int id,w,h,was_packed;
} stbrp_rect;
-static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
+static void stbrp_init_target(stbrp_context *con, int pw, int ph,
+ stbrp_node *nodes, int num_nodes)
{
con->width = pw;
con->height = ph;
@@ -2588,20 +2671,26 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no
STBTT__NOTUSED(num_nodes);
}
-static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
+static void stbrp_pack_rects(stbrp_context *con,
+ stbrp_rect *rects, int num_rects)
{
int i;
- for (i=0; i < num_rects; ++i) {
- if (con->x + rects[i].w > con->width) {
+ for (i=0; i < num_rects; ++i)
+ {
+ if (con->x + rects[i].w > con->width)
+ {
con->x = 0;
con->y = con->bottom_y;
}
+
if (con->y + rects[i].h > con->height)
break;
+
rects[i].x = con->x;
rects[i].y = con->y;
rects[i].was_packed = 1;
con->x += rects[i].w;
+
if (con->y + rects[i].h > con->bottom_y)
con->bottom_y = con->y + rects[i].h;
}
@@ -2610,22 +2699,25 @@ static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rect
}
#endif
-//////////////////////////////////////////////////////////////////////////////
-//
-// bitmap baking
-//
-// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
-// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
+/* bitmap baking
+ *
+ * This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
+ * stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
+ */
-STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
+STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels,
+ int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
{
- stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
+ stbrp_context *context = (stbrp_context *)malloc(sizeof(*context));
int num_nodes = pw - padding;
- stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
+ stbrp_node *nodes = (stbrp_node *)malloc(sizeof(*nodes) * num_nodes);
- if (context == NULL || nodes == NULL) {
- if (context != NULL) STBTT_free(context, alloc_context);
- if (nodes != NULL) STBTT_free(nodes , alloc_context);
+ if (context == NULL || nodes == NULL)
+ {
+ if (context != NULL)
+ free(context);
+ if (nodes != NULL)
+ free(nodes);
return 0;
}
@@ -2642,21 +2734,22 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
- STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
+ memset(pixels, 0, pw*ph); /* background of 0 around pixels */
return 1;
}
STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc)
{
- STBTT_free(spc->nodes , spc->user_allocator_context);
- STBTT_free(spc->pack_info, spc->user_allocator_context);
+ free(spc->nodes);
+ free(spc->pack_info);
}
-STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
+STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc,
+ unsigned int h_oversample, unsigned int v_oversample)
{
- STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
- STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
+ rarch_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
+ rarch_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
if (h_oversample <= STBTT_MAX_OVERSAMPLE)
spc->h_oversample = h_oversample;
if (v_oversample <= STBTT_MAX_OVERSAMPLE)
@@ -2665,19 +2758,23 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
-static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
+static void stbtt__h_prefilter(unsigned char *pixels, int w, int h,
+ int stride_in_bytes, unsigned int kernel_width)
{
+ int j;
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width;
- int j;
- for (j=0; j < h; ++j) {
+
+ for (j=0; j < h; ++j)
+ {
int i;
unsigned int total;
- STBTT_memset(buffer, 0, kernel_width);
+ memset(buffer, 0, kernel_width);
total = 0;
- // make kernel_width a constant in common cases so compiler can optimize out the divide
+ /* make kernel_width a constant in common cases
+ * so compiler can optimize out the divide */
switch (kernel_width) {
case 2:
for (i=0; i <= safe_w; ++i) {
@@ -2709,8 +2806,9 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
break;
}
- for (; i < w; ++i) {
- STBTT_assert(pixels[i] == 0);
+ for (; i < w; ++i)
+ {
+ rarch_assert(pixels[i] == 0);
total -= buffer[i & STBTT__OVER_MASK];
pixels[i] = (unsigned char) (total / kernel_width);
}
@@ -2721,41 +2819,47 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
{
+ int j;
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width;
- int j;
- for (j=0; j < w; ++j) {
+
+ for (j=0; j < w; ++j)
+ {
int i;
- unsigned int total;
- STBTT_memset(buffer, 0, kernel_width);
+ unsigned int total = 0;
- total = 0;
+ memset(buffer, 0, kernel_width);
- // make kernel_width a constant in common cases so compiler can optimize out the divide
- switch (kernel_width) {
+ /* make kernel_width a constant in common cases so compiler can optimize out the divide */
+ switch (kernel_width)
+ {
case 2:
- for (i=0; i <= safe_h; ++i) {
+ for (i=0; i <= safe_h; ++i)
+ {
total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
}
break;
case 3:
- for (i=0; i <= safe_h; ++i) {
+ for (i=0; i <= safe_h; ++i)
+ {
total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
}
break;
case 4:
- for (i=0; i <= safe_h; ++i) {
+ for (i=0; i <= safe_h; ++i)
+ {
total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
}
break;
default:
- for (i=0; i <= safe_h; ++i) {
+ for (i=0; i <= safe_h; ++i)
+ {
total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
@@ -2763,8 +2867,9 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i
break;
}
- for (; i < h; ++i) {
- STBTT_assert(pixels[i*stride_in_bytes] == 0);
+ for (; i < h; ++i)
+ {
+ rarch_assert(pixels[i*stride_in_bytes] == 0);
total -= buffer[i & STBTT__OVER_MASK];
pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
}
@@ -2778,15 +2883,17 @@ static float stbtt__oversample_shift(int oversample)
if (!oversample)
return 0.0f;
- // The prefilter is a box filter of width "oversample",
- // which shifts phase by (oversample - 1)/2 pixels in
- // oversampled space. We want to shift in the opposite
- // direction to counter this.
+ /* The prefilter is a box filter of width "oversample",
+ * which shifts phase by (oversample - 1)/2 pixels in
+ * oversampled space. We want to shift in the opposite
+ * direction to counter this. */
return (float)-(oversample - 1) / (2.0f * (float)oversample);
}
-STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
+STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata,
+ int font_index, stbtt_pack_range *ranges, int num_ranges)
{
+ stbrp_rect *rects;
stbtt_fontinfo info;
float recip_h = 1.0f / spc->h_oversample;
float recip_v = 1.0f / spc->v_oversample;
@@ -2794,9 +2901,8 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
float sub_y = stbtt__oversample_shift(spc->v_oversample);
int i,j,k,n, return_value = 1;
stbrp_context *context = (stbrp_context *) spc->pack_info;
- stbrp_rect *rects;
- // flag all characters as NOT packed
+ /* flag all characters as NOT packed */
for (i=0; i < num_ranges; ++i)
for (j=0; j < ranges[i].num_chars_in_range; ++j)
ranges[i].chardata_for_range[j].x0 =
@@ -2808,7 +2914,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
for (i=0; i < num_ranges; ++i)
n += ranges[i].num_chars_in_range;
- rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
+ rects = (stbrp_rect *)malloc(sizeof(*rects) * n);
if (rects == NULL)
return 0;
@@ -2838,13 +2944,14 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
for (j=0; j < ranges[i].num_chars_in_range; ++j) {
stbrp_rect *r = &rects[k];
- if (r->was_packed) {
+ if (r->was_packed)
+ {
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
int advance, lsb, x0,y0,x1,y1;
int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j);
stbrp_coord pad = (stbrp_coord) spc->padding;
- // pad on left and top
+ /* pad on left and top */
r->x += pad;
r->y += pad;
r->w -= pad;
@@ -2883,15 +2990,15 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
bc->yoff = (float) y0 * recip_v + sub_y;
bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
- } else {
- return_value = 0; // if any fail, report failure
}
+ else
+ return_value = 0; /* if any fail, report failure */
++k;
}
}
- STBTT_free(rects, spc->user_allocator_context);
+ free(rects);
return return_value;
}
@@ -2906,7 +3013,9 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
}
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
+STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw,
+ int ph, int char_index, float *xpos, float *ypos,
+ stbtt_aligned_quad *q, int align_to_integer)
{
float ipw = 1.0f / pw, iph = 1.0f / ph;
stbtt_packedchar *b = chardata + char_index;
@@ -2934,27 +3043,29 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// font name matching -- recommended not to use this
-//
+/* font name matching -- recommended not to use this */
-// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
+/* check if a UTF8 string contains a prefix which is the UTF16 string; if so return length of matching UTF8 string */
static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
{
stbtt_int32 i=0;
- // convert utf16 to utf8 and compare the results while converting
+ /* convert UTF16 to UTF8 and compare the results while converting */
while (len2) {
stbtt_uint16 ch = s2[0]*256 + s2[1];
- if (ch < 0x80) {
+ if (ch < 0x80)
+ {
if (i >= len1) return -1;
if (s1[i++] != ch) return -1;
- } else if (ch < 0x800) {
+ }
+ else if (ch < 0x800)
+ {
if (i+1 >= len1) return -1;
if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
- } else if (ch >= 0xd800 && ch < 0xdc00) {
+ }
+ else if (ch >= 0xd800 && ch < 0xdc00)
+ {
stbtt_uint32 c;
stbtt_uint16 ch2 = s2[2]*256 + s2[3];
if (i+3 >= len1) return -1;
@@ -2963,11 +3074,13 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8
if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1;
if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1;
- s2 += 2; // plus another 2 below
+ s2 += 2; /* plus another 2 below */
len2 -= 2;
- } else if (ch >= 0xdc00 && ch < 0xe000) {
+ }
+ else if (ch >= 0xdc00 && ch < 0xe000)
return -1;
- } else {
+ else
+ {
if (i+2 >= len1) return -1;
if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
@@ -2984,9 +3097,10 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2);
}
-// returns results in whatever encoding you request... but note that 2-byte encodings
-// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
-STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
+/* returns results in whatever encoding you request... but note that 2-byte encodings
+ * will be MSB_FIRST... use stbtt_CompareUTF8toUTF16_bigendian() to compare */
+STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font,
+ int *length, int platformID, int encodingID, int languageID, int nameID)
{
stbtt_int32 i,count,stringOffset;
stbtt_uint8 *fc = font->data;
@@ -2996,10 +3110,13 @@ STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *l
count = ttUSHORT(fc+nm+2);
stringOffset = nm + ttUSHORT(fc+nm+4);
- for (i=0; i < count; ++i) {
+
+ for (i=0; i < count; ++i)
+ {
stbtt_uint32 loc = nm + 6 + 12 * i;
if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
- && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
+ && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6))
+ {
*length = ttUSHORT(fc+loc+8);
return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
}
@@ -3007,48 +3124,63 @@ STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *l
return NULL;
}
-static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
+static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name,
+ stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
{
stbtt_int32 i;
stbtt_int32 count = ttUSHORT(fc+nm+2);
stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
- for (i=0; i < count; ++i) {
+ for (i=0; i < count; ++i)
+ {
stbtt_uint32 loc = nm + 6 + 12 * i;
stbtt_int32 id = ttUSHORT(fc+loc+6);
- if (id == target_id) {
- // find the encoding
+ if (id == target_id)
+ {
+ /* find the encoding */
stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
- // is this a Unicode encoding?
- if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
+ /* is this a Unicode encoding? */
+ if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10))
+ {
stbtt_int32 slen = ttUSHORT(fc+loc+8);
stbtt_int32 off = ttUSHORT(fc+loc+10);
- // check if there's a prefix match
+ /* check if there's a prefix match */
stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
- if (matchlen >= 0) {
- // check for target_id+1 immediately following, with same encoding & language
- if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) {
+ if (matchlen >= 0)
+ {
+ /* check for target_id+1 immediately following, with same encoding & language */
+ if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id
+ && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding
+ && ttUSHORT(fc+loc+12+4) == language)
+ {
slen = ttUSHORT(fc+loc+12+8);
off = ttUSHORT(fc+loc+12+10);
- if (slen == 0) {
+
+ if (slen == 0)
+ {
if (matchlen == nlen)
return 1;
- } else if (matchlen < nlen && name[matchlen] == ' ') {
+ }
+ else if (matchlen < nlen && name[matchlen] == ' ')
+ {
++matchlen;
- if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
+ if (stbtt_CompareUTF8toUTF16_bigendian((char*)(name+matchlen),
+ nlen-matchlen, (char*)(fc+stringOffset+off),slen))
return 1;
}
- } else {
- // if nothing immediately following
+ }
+ else
+ {
+ /* if nothing immediately following */
if (matchlen == nlen)
return 1;
}
}
}
- // @TODO handle other encodings
+ /* @TODO handle other encodings */
}
}
return 0;
@@ -3056,42 +3188,57 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name,
static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
{
- stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
+ stbtt_int32 nlen = (stbtt_int32)strlen((char*)name);
stbtt_uint32 nm,hd;
- if (!stbtt__isfont(fc+offset)) return 0;
+ if (!stbtt__isfont(fc+offset))
+ return 0;
- // check italics/bold/underline flags in macStyle...
- if (flags) {
+ /* check italics/bold/underline flags in macStyle... */
+ if (flags)
+ {
hd = stbtt__find_table(fc, offset, "head");
if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
}
nm = stbtt__find_table(fc, offset, "name");
- if (!nm) return 0;
+ if (!nm)
+ return 0;
- if (flags) {
- // if we checked the macStyle flags, then just check the family and ignore the subfamily
- if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1;
- if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1;
- if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
- } else {
- if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1;
- if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1;
- if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
+ if (flags)
+ {
+ /* if we checked the macStyle flags, then just check the family and ignore the subfamily */
+ if (stbtt__matchpair(fc, nm, name, nlen, 16, -1))
+ return 1;
+ if (stbtt__matchpair(fc, nm, name, nlen, 1, -1))
+ return 1;
+ if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
+ return 1;
+ }
+ else
+ {
+ if (stbtt__matchpair(fc, nm, name, nlen, 16, 17))
+ return 1;
+ if (stbtt__matchpair(fc, nm, name, nlen, 1, 2))
+ return 1;
+ if (stbtt__matchpair(fc, nm, name, nlen, 3, -1))
+ return 1;
}
return 0;
}
-STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags)
+STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection,
+ const char *name_utf8, stbtt_int32 flags)
{
stbtt_int32 i;
- for (i=0;;++i) {
+ for (i=0;;++i)
+ {
stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
- if (off < 0) return off;
+ if (off < 0)
+ return off;
if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
return off;
}
}
-#endif // STB_TRUETYPE_IMPLEMENTATION
+#endif
diff --git a/dir_list_special.c b/dir_list_special.c
index 463359c43b..1270ef58d4 100644
--- a/dir_list_special.c
+++ b/dir_list_special.c
@@ -25,7 +25,6 @@ struct string_list *dir_list_new_special(const char *input_dir, enum dir_list_ty
const char *exts = NULL;
bool include_dirs = false;
- global_t *global = global_get_ptr();
settings_t *settings = config_get_ptr();
(void)input_dir;
@@ -39,7 +38,7 @@ struct string_list *dir_list_new_special(const char *input_dir, enum dir_list_ty
break;
case DIR_LIST_CORE_INFO:
dir = input_dir;
- exts = (global->core_info.list) ? core_info_list_get_all_extensions(global->core_info.list) : NULL;
+ exts = core_info_list_get_all_extensions();
break;
case DIR_LIST_SHADERS:
dir = settings->video.shader_dir;
diff --git a/dist-scripts/dist-cores.sh b/dist-scripts/dist-cores.sh
index 41d81019e6..ba8df73fac 100755
--- a/dist-scripts/dist-cores.sh
+++ b/dist-scripts/dist-cores.sh
@@ -13,8 +13,8 @@ EXT=a
mkdir -p ../pkg/${platform}/cores/
-make -C ../${platform}/kernel_functions_prx/ clean || exit 1
-make -C ../${platform}/kernel_functions_prx/ || exit 1
+make -C ../bootstrap/${platform}/kernel_functions_prx/ clean || exit 1
+make -C ../bootstrap/${platform}/kernel_functions_prx/ || exit 1
cp -f ../kernel_functions.prx ../pkg/${platform}/kernel_functions.prx
# Vita
@@ -158,7 +158,7 @@ for f in *_${platform}.${EXT} ; do
# Move executable files
if [ $platform = "ps3" ] ; then
if [ $PLATFORM = "ode-ps3" ] ; then
- mv -f ../CORE.SELF ../${platform}/iso/PS3_GAME/USRDIR/cores/"${name}_libretro_${platform}.SELF"
+ mv -f ../CORE.SELF ../pkg/${platform}_iso/PS3_GAME/USRDIR/cores/"${name}_libretro_${platform}.SELF"
else
mv -f ../CORE.SELF ../pkg/${platform}/USRDIR/cores/"${name}_libretro_${platform}.SELF"
fi
@@ -227,8 +227,8 @@ elif [ $PLATFORM = "cex-ps3" ] ; then
rm -rf ../retroarch-salamander_${platform}.elf
python2 ../ps3/ps3py/pkg.py --contentid UP0001-SSNE10000_00-0000000000000001 ../pkg/${platform} retroarch-${platform}-cfw-$RARCH_VERSION.pkg
elif [ $PLATFORM = "ode-ps3" ] ; then
- $SCETOOL_PATH $SCETOOL_FLAGS --encrypt ../retroarch-salamander_${platform}.elf ../${platform}/iso/PS3_GAME/USRDIR/EBOOT.BIN
+ $SCETOOL_PATH $SCETOOL_FLAGS --encrypt ../retroarch-salamander_${platform}.elf ../pkg/${platform}_iso/PS3_GAME/USRDIR/EBOOT.BIN
rm -rf ../retroarch-salamander_${platform}.elf
- $GENPS3ISO_PATH ../${platform}/iso RetroArch-COBRA-ODE.iso
+ $GENPS3ISO_PATH ../pkg/${platform}_iso/RetroArch-COBRA-ODE.iso
fi
diff --git a/dynamic.c b/dynamic.c
index 641d2672bf..e83d7a4ded 100644
--- a/dynamic.c
+++ b/dynamic.c
@@ -17,12 +17,13 @@
#include
#include
-#include
#include
#include
#include
#include
+#include
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -39,8 +40,7 @@
#include "input/input_sensor.h"
#ifdef HAVE_DYNAMIC
-#undef SYM
-#define SYM(x) do { \
+#define SYMBOL(x) do { \
function_t func = dylib_proc(lib_handle, #x); \
memcpy(&p##x, &func, sizeof(func)); \
if (p##x == NULL) { RARCH_ERR("Failed to load symbol: \"%s\"\n", #x); rarch_fail(1, "init_libretro_sym()"); } \
@@ -48,17 +48,17 @@
static dylib_t lib_handle;
#else
-#define SYM(x) p##x = x
+#define SYMBOL(x) p##x = x
#endif
-#define SYM_DUMMY(x) p##x = libretro_dummy_##x
+#define SYMBOL_DUMMY(x) p##x = libretro_dummy_##x
#ifdef HAVE_FFMPEG
-#define SYM_FFMPEG(x) p##x = libretro_ffmpeg_##x
+#define SYMBOL_FFMPEG(x) p##x = libretro_ffmpeg_##x
#endif
#ifdef HAVE_IMAGEVIEWER
-#define SYM_IMAGEVIEWER(x) p##x = libretro_imageviewer_##x
+#define SYMBOL_IMAGEVIEWER(x) p##x = libretro_imageviewer_##x
#endif
void (*pretro_init)(void);
@@ -333,147 +333,147 @@ static void load_symbols(enum rarch_core_type type)
#endif
}
- SYM(retro_init);
- SYM(retro_deinit);
+ SYMBOL(retro_init);
+ SYMBOL(retro_deinit);
- SYM(retro_api_version);
- SYM(retro_get_system_info);
- SYM(retro_get_system_av_info);
+ SYMBOL(retro_api_version);
+ SYMBOL(retro_get_system_info);
+ SYMBOL(retro_get_system_av_info);
- SYM(retro_set_environment);
- SYM(retro_set_video_refresh);
- SYM(retro_set_audio_sample);
- SYM(retro_set_audio_sample_batch);
- SYM(retro_set_input_poll);
- SYM(retro_set_input_state);
+ SYMBOL(retro_set_environment);
+ SYMBOL(retro_set_video_refresh);
+ SYMBOL(retro_set_audio_sample);
+ SYMBOL(retro_set_audio_sample_batch);
+ SYMBOL(retro_set_input_poll);
+ SYMBOL(retro_set_input_state);
- SYM(retro_set_controller_port_device);
+ SYMBOL(retro_set_controller_port_device);
- SYM(retro_reset);
- SYM(retro_run);
+ SYMBOL(retro_reset);
+ SYMBOL(retro_run);
- SYM(retro_serialize_size);
- SYM(retro_serialize);
- SYM(retro_unserialize);
+ SYMBOL(retro_serialize_size);
+ SYMBOL(retro_serialize);
+ SYMBOL(retro_unserialize);
- SYM(retro_cheat_reset);
- SYM(retro_cheat_set);
+ SYMBOL(retro_cheat_reset);
+ SYMBOL(retro_cheat_set);
- SYM(retro_load_game);
- SYM(retro_load_game_special);
+ SYMBOL(retro_load_game);
+ SYMBOL(retro_load_game_special);
- SYM(retro_unload_game);
- SYM(retro_get_region);
- SYM(retro_get_memory_data);
- SYM(retro_get_memory_size);
+ SYMBOL(retro_unload_game);
+ SYMBOL(retro_get_region);
+ SYMBOL(retro_get_memory_data);
+ SYMBOL(retro_get_memory_size);
break;
case CORE_TYPE_DUMMY:
- SYM_DUMMY(retro_init);
- SYM_DUMMY(retro_deinit);
+ SYMBOL_DUMMY(retro_init);
+ SYMBOL_DUMMY(retro_deinit);
- SYM_DUMMY(retro_api_version);
- SYM_DUMMY(retro_get_system_info);
- SYM_DUMMY(retro_get_system_av_info);
+ SYMBOL_DUMMY(retro_api_version);
+ SYMBOL_DUMMY(retro_get_system_info);
+ SYMBOL_DUMMY(retro_get_system_av_info);
- SYM_DUMMY(retro_set_environment);
- SYM_DUMMY(retro_set_video_refresh);
- SYM_DUMMY(retro_set_audio_sample);
- SYM_DUMMY(retro_set_audio_sample_batch);
- SYM_DUMMY(retro_set_input_poll);
- SYM_DUMMY(retro_set_input_state);
+ SYMBOL_DUMMY(retro_set_environment);
+ SYMBOL_DUMMY(retro_set_video_refresh);
+ SYMBOL_DUMMY(retro_set_audio_sample);
+ SYMBOL_DUMMY(retro_set_audio_sample_batch);
+ SYMBOL_DUMMY(retro_set_input_poll);
+ SYMBOL_DUMMY(retro_set_input_state);
- SYM_DUMMY(retro_set_controller_port_device);
+ SYMBOL_DUMMY(retro_set_controller_port_device);
- SYM_DUMMY(retro_reset);
- SYM_DUMMY(retro_run);
+ SYMBOL_DUMMY(retro_reset);
+ SYMBOL_DUMMY(retro_run);
- SYM_DUMMY(retro_serialize_size);
- SYM_DUMMY(retro_serialize);
- SYM_DUMMY(retro_unserialize);
+ SYMBOL_DUMMY(retro_serialize_size);
+ SYMBOL_DUMMY(retro_serialize);
+ SYMBOL_DUMMY(retro_unserialize);
- SYM_DUMMY(retro_cheat_reset);
- SYM_DUMMY(retro_cheat_set);
+ SYMBOL_DUMMY(retro_cheat_reset);
+ SYMBOL_DUMMY(retro_cheat_set);
- SYM_DUMMY(retro_load_game);
- SYM_DUMMY(retro_load_game_special);
+ SYMBOL_DUMMY(retro_load_game);
+ SYMBOL_DUMMY(retro_load_game_special);
- SYM_DUMMY(retro_unload_game);
- SYM_DUMMY(retro_get_region);
- SYM_DUMMY(retro_get_memory_data);
- SYM_DUMMY(retro_get_memory_size);
+ SYMBOL_DUMMY(retro_unload_game);
+ SYMBOL_DUMMY(retro_get_region);
+ SYMBOL_DUMMY(retro_get_memory_data);
+ SYMBOL_DUMMY(retro_get_memory_size);
break;
#ifdef HAVE_FFMPEG
case CORE_TYPE_FFMPEG:
- SYM_FFMPEG(retro_init);
- SYM_FFMPEG(retro_deinit);
+ SYMBOL_FFMPEG(retro_init);
+ SYMBOL_FFMPEG(retro_deinit);
- SYM_FFMPEG(retro_api_version);
- SYM_FFMPEG(retro_get_system_info);
- SYM_FFMPEG(retro_get_system_av_info);
+ SYMBOL_FFMPEG(retro_api_version);
+ SYMBOL_FFMPEG(retro_get_system_info);
+ SYMBOL_FFMPEG(retro_get_system_av_info);
- SYM_FFMPEG(retro_set_environment);
- SYM_FFMPEG(retro_set_video_refresh);
- SYM_FFMPEG(retro_set_audio_sample);
- SYM_FFMPEG(retro_set_audio_sample_batch);
- SYM_FFMPEG(retro_set_input_poll);
- SYM_FFMPEG(retro_set_input_state);
+ SYMBOL_FFMPEG(retro_set_environment);
+ SYMBOL_FFMPEG(retro_set_video_refresh);
+ SYMBOL_FFMPEG(retro_set_audio_sample);
+ SYMBOL_FFMPEG(retro_set_audio_sample_batch);
+ SYMBOL_FFMPEG(retro_set_input_poll);
+ SYMBOL_FFMPEG(retro_set_input_state);
- SYM_FFMPEG(retro_set_controller_port_device);
+ SYMBOL_FFMPEG(retro_set_controller_port_device);
- SYM_FFMPEG(retro_reset);
- SYM_FFMPEG(retro_run);
+ SYMBOL_FFMPEG(retro_reset);
+ SYMBOL_FFMPEG(retro_run);
- SYM_FFMPEG(retro_serialize_size);
- SYM_FFMPEG(retro_serialize);
- SYM_FFMPEG(retro_unserialize);
+ SYMBOL_FFMPEG(retro_serialize_size);
+ SYMBOL_FFMPEG(retro_serialize);
+ SYMBOL_FFMPEG(retro_unserialize);
- SYM_FFMPEG(retro_cheat_reset);
- SYM_FFMPEG(retro_cheat_set);
+ SYMBOL_FFMPEG(retro_cheat_reset);
+ SYMBOL_FFMPEG(retro_cheat_set);
- SYM_FFMPEG(retro_load_game);
- SYM_FFMPEG(retro_load_game_special);
+ SYMBOL_FFMPEG(retro_load_game);
+ SYMBOL_FFMPEG(retro_load_game_special);
- SYM_FFMPEG(retro_unload_game);
- SYM_FFMPEG(retro_get_region);
- SYM_FFMPEG(retro_get_memory_data);
- SYM_FFMPEG(retro_get_memory_size);
+ SYMBOL_FFMPEG(retro_unload_game);
+ SYMBOL_FFMPEG(retro_get_region);
+ SYMBOL_FFMPEG(retro_get_memory_data);
+ SYMBOL_FFMPEG(retro_get_memory_size);
break;
#endif
case CORE_TYPE_IMAGEVIEWER:
#ifdef HAVE_IMAGEVIEWER
- SYM_IMAGEVIEWER(retro_init);
- SYM_IMAGEVIEWER(retro_deinit);
+ SYMBOL_IMAGEVIEWER(retro_init);
+ SYMBOL_IMAGEVIEWER(retro_deinit);
- SYM_IMAGEVIEWER(retro_api_version);
- SYM_IMAGEVIEWER(retro_get_system_info);
- SYM_IMAGEVIEWER(retro_get_system_av_info);
+ SYMBOL_IMAGEVIEWER(retro_api_version);
+ SYMBOL_IMAGEVIEWER(retro_get_system_info);
+ SYMBOL_IMAGEVIEWER(retro_get_system_av_info);
- SYM_IMAGEVIEWER(retro_set_environment);
- SYM_IMAGEVIEWER(retro_set_video_refresh);
- SYM_IMAGEVIEWER(retro_set_audio_sample);
- SYM_IMAGEVIEWER(retro_set_audio_sample_batch);
- SYM_IMAGEVIEWER(retro_set_input_poll);
- SYM_IMAGEVIEWER(retro_set_input_state);
+ SYMBOL_IMAGEVIEWER(retro_set_environment);
+ SYMBOL_IMAGEVIEWER(retro_set_video_refresh);
+ SYMBOL_IMAGEVIEWER(retro_set_audio_sample);
+ SYMBOL_IMAGEVIEWER(retro_set_audio_sample_batch);
+ SYMBOL_IMAGEVIEWER(retro_set_input_poll);
+ SYMBOL_IMAGEVIEWER(retro_set_input_state);
- SYM_IMAGEVIEWER(retro_set_controller_port_device);
+ SYMBOL_IMAGEVIEWER(retro_set_controller_port_device);
- SYM_IMAGEVIEWER(retro_reset);
- SYM_IMAGEVIEWER(retro_run);
+ SYMBOL_IMAGEVIEWER(retro_reset);
+ SYMBOL_IMAGEVIEWER(retro_run);
- SYM_IMAGEVIEWER(retro_serialize_size);
- SYM_IMAGEVIEWER(retro_serialize);
- SYM_IMAGEVIEWER(retro_unserialize);
+ SYMBOL_IMAGEVIEWER(retro_serialize_size);
+ SYMBOL_IMAGEVIEWER(retro_serialize);
+ SYMBOL_IMAGEVIEWER(retro_unserialize);
- SYM_IMAGEVIEWER(retro_cheat_reset);
- SYM_IMAGEVIEWER(retro_cheat_set);
+ SYMBOL_IMAGEVIEWER(retro_cheat_reset);
+ SYMBOL_IMAGEVIEWER(retro_cheat_set);
- SYM_IMAGEVIEWER(retro_load_game);
- SYM_IMAGEVIEWER(retro_load_game_special);
+ SYMBOL_IMAGEVIEWER(retro_load_game);
+ SYMBOL_IMAGEVIEWER(retro_load_game_special);
- SYM_IMAGEVIEWER(retro_unload_game);
- SYM_IMAGEVIEWER(retro_get_region);
- SYM_IMAGEVIEWER(retro_get_memory_data);
- SYM_IMAGEVIEWER(retro_get_memory_size);
+ SYMBOL_IMAGEVIEWER(retro_unload_game);
+ SYMBOL_IMAGEVIEWER(retro_get_region);
+ SYMBOL_IMAGEVIEWER(retro_get_memory_data);
+ SYMBOL_IMAGEVIEWER(retro_get_memory_size);
#endif
break;
}
@@ -1120,12 +1120,12 @@ bool rarch_environment_cb(unsigned cmd, void *data)
struct retro_perf_callback *cb = (struct retro_perf_callback*)data;
RARCH_LOG("Environ GET_PERF_INTERFACE.\n");
- cb->get_time_usec = rarch_get_time_usec;
- cb->get_cpu_features = rarch_get_cpu_features;
- cb->get_perf_counter = rarch_get_perf_counter;
+ cb->get_time_usec = retro_get_time_usec;
+ cb->get_cpu_features = retro_get_cpu_features;
+ cb->get_perf_counter = retro_get_perf_counter;
cb->perf_register = retro_perf_register; /* libretro specific path. */
- cb->perf_start = rarch_perf_start;
- cb->perf_stop = rarch_perf_stop;
+ cb->perf_start = retro_perf_start;
+ cb->perf_stop = retro_perf_stop;
cb->perf_log = retro_perf_log; /* libretro specific path. */
break;
}
diff --git a/file_ops.c b/file_ops.c
index 3fadbbaccf..648fda7190 100644
--- a/file_ops.c
+++ b/file_ops.c
@@ -30,6 +30,7 @@
#include
#include
#include
+#include
#include
#ifdef HAVE_COMPRESSION
#include
@@ -200,17 +201,19 @@ static int read_7zip_file(
SRes res;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
- uint16_t *temp = NULL;
- size_t tempSize = 0;
- long outsize = -1;
- bool file_found = false;
+ uint8_t *outBuffer = 0;
+ size_t outBufferSize = 0;
+ uint16_t *temp = NULL;
+ size_t tempSize = 0;
+ long outsize = -1;
+ bool file_found = false;
/*These are the allocation routines.
* Currently using the non-standard 7zip choices. */
- allocImp.Alloc = SzAlloc;
- allocImp.Free = SzFree;
- allocTempImp.Alloc = SzAllocTemp;
- allocTempImp.Free = SzFreeTemp;
+ allocImp.Alloc = SzAlloc;
+ allocImp.Free = SzFree;
+ allocTempImp.Alloc = SzAllocTemp;
+ allocTempImp.Free = SzFreeTemp;
if (InFile_Open(&archiveStream.file, archive_path))
{
@@ -235,8 +238,6 @@ static int read_7zip_file(
{
uint32_t i;
uint32_t blockIndex = 0xFFFFFFFF;
- uint8_t *outBuffer = 0;
- size_t outBufferSize = 0;
for (i = 0; i < db.db.NumFiles; i++)
{
@@ -246,14 +247,13 @@ static int read_7zip_file(
size_t outSizeProcessed = 0;
const CSzFileItem *f = db.db.Files + i;
+ /* We skip over everything which is not a directory.
+ * FIXME: Why continue then if f->IsDir is true?*/
if (f->IsDir)
- {
- /* We skip over everything which is not a directory.
- * FIXME: Why continue then if f->IsDir is true?*/
continue;
- }
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
+
if (len > tempSize)
{
free(temp);
@@ -265,6 +265,7 @@ static int read_7zip_file(
break;
}
}
+
SzArEx_GetFileNameUtf16(&db, i, temp);
res = ConvertUtf16toCharString(temp,infile);
@@ -277,26 +278,25 @@ static int read_7zip_file(
res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex,
&outBuffer, &outBufferSize,&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
+
if (res != SZ_OK)
- {
break; /* This goes to the error section. */
- }
+
outsize = outSizeProcessed;
+
if (optional_outfile != NULL)
{
- FILE* outsink = fopen(optional_outfile,"wb");
- if (outsink == NULL)
+ const void *ptr = (const void*)(outBuffer + offset);
+
+ if (!retro_write_file(optional_outfile, ptr, outsize))
{
RARCH_ERR("Could not open outfilepath %s.\n",
optional_outfile);
- IAlloc_Free(&allocImp, outBuffer);
- SzArEx_Free(&db, &allocImp);
- free(temp);
- File_Close(&archiveStream.file);
- return -1;
+ res = SZ_OK;
+ file_found = true;
+ outsize = -1;
+ break;
}
- fwrite(outBuffer+offset,1,outsize,outsink);
- fclose(outsink);
}
else
{
@@ -309,14 +309,14 @@ static int read_7zip_file(
((char*)(*buf))[outsize] = '\0';
memcpy(*buf,outBuffer+offset,outsize);
}
- IAlloc_Free(&allocImp, outBuffer);
break;
}
}
}
+
+ IAlloc_Free(&allocImp, outBuffer);
SzArEx_Free(&db, &allocImp);
free(temp);
-
File_Close(&archiveStream.file);
if (res == SZ_OK && file_found == true)
@@ -559,31 +559,27 @@ static int read_zip_file(const char *archive_path,
else
{
char read_buffer[RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX] = {0};
- FILE* outsink = fopen(optional_outfile,"wb");
+ RFILE* outsink = retro_fopen(optional_outfile, RFILE_MODE_WRITE, -1);
- if (outsink == NULL)
+ if (!outsink)
goto close;
bytes_read = 0;
do
{
- ssize_t fwrite_bytes;
-
bytes_read = unzReadCurrentFile(zipfile, read_buffer,
RARCH_ZIP_SUPPORT_BUFFER_SIZE_MAX );
- fwrite_bytes = fwrite(read_buffer, 1, bytes_read,outsink);
- if (fwrite_bytes == bytes_read)
+ if (retro_fwrite(outsink, read_buffer, bytes_read) == bytes_read)
continue;
- /* couldn't write all bytes */
- RARCH_ERR("Error writing to %s.\n",optional_outfile);
- fclose(outsink);
+ RARCH_ERR("Error writing to %s.\n", optional_outfile);
+ retro_fclose(outsink);
goto close;
} while(bytes_read > 0);
- fclose(outsink);
+ retro_fclose(outsink);
}
finished_reading = true;
}
@@ -619,90 +615,6 @@ error:
#endif
-/**
- * write_file:
- * @path : path to file.
- * @data : contents to write to the file.
- * @size : size of the contents.
- *
- * Writes data to a file.
- *
- * Returns: true (1) on success, false (0) otherwise.
- */
-bool write_file(const char *path, const void *data, ssize_t size)
-{
- ssize_t ret = 0;
- FILE *file = fopen(path, "wb");
- if (!file)
- return false;
-
- ret = fwrite(data, 1, size, file);
- fclose(file);
- return (ret == size);
-}
-
-/**
- * read_generic_file:
- * @path : path to file.
- * @buf : buffer to allocate and read the contents of the
- * file into. Needs to be freed manually.
- *
- * Read the contents of a file into @buf.
- *
- * Returns: number of items read, -1 on error.
- */
-static int read_generic_file(const char *path, void **buf, ssize_t *len)
-{
- size_t bytes_read = 0;
- size_t content_buf_size = 0;
- void *content_buf = NULL;
- FILE *file = fopen(path, "rb");
-
- if (!file)
- goto error;
-
- if (fseek(file, 0, SEEK_END) != 0)
- goto error;
-
- content_buf_size = ftell(file);
- if (content_buf_size < 0)
- goto error;
-
- rewind(file);
-
- content_buf = malloc(content_buf_size + 1);
-
- if (!content_buf)
- goto error;
-
- if ((bytes_read = fread(content_buf, 1, content_buf_size, file)) < content_buf_size)
- RARCH_WARN("Didn't read whole file.\n");
-
- *buf = content_buf;
-
- /* Allow for easy reading of strings to be safe.
- * Will only work with sane character formatting (Unix). */
- ((char*)content_buf)[content_buf_size] = '\0';
-
- if (fclose(file) != 0)
- RARCH_WARN("Failed to close file stream.\n");
-
- if (len)
- *len = bytes_read;
-
- return 1;
-
-error:
- if (file)
- fclose(file);
- if (content_buf)
- free(content_buf);
- if (len)
- *len = -1;
- *buf = NULL;
- return 0;
-}
-
#ifdef HAVE_COMPRESSION
/* Generic compressed file loader.
* Extracts to buf, unless optional_filename != 0
@@ -783,7 +695,7 @@ int read_compressed_file(const char * path, void **buf,
* @length : Number of items read, -1 on error.
*
* Read the contents of a file into @buf. Will call read_compressed_file
- * if path contains a compressed file, otherwise will call read_generic_file.
+ * if path contains a compressed file, otherwise will call retro_read_file().
*
* Returns: 1 if file read, 0 on error.
*/
@@ -796,7 +708,7 @@ int read_file(const char *path, void **buf, ssize_t *length)
return 1;
}
#endif
- return read_generic_file(path, buf, length);
+ return retro_read_file(path, buf, length);
}
struct string_list *compressed_file_list_new(const char *path,
diff --git a/file_path_special.c b/file_path_special.c
index a4dcb29864..d34ec77a4a 100644
--- a/file_path_special.c
+++ b/file_path_special.c
@@ -26,26 +26,16 @@
#include
#include
-#ifdef __HAIKU__
-#include
-#endif
-
#ifdef _WIN32
#include
#else
-#include /* stat() is defined here */
+#include
#endif
#ifdef __APPLE__
#include
#endif
-#if defined(__CELLOS_LV2__)
-#ifndef S_ISDIR
-#define S_ISDIR(x) (x & 0040000)
-#endif
-#endif
-
#include
#include
#include
@@ -131,8 +121,8 @@ void fill_pathname_abbreviate_special(char *out_path,
rarch_assert(src_size < size);
out_path += src_size;
- size -= src_size;
- in_path += strlen(candidates[i]);
+ size -= src_size;
+ in_path += strlen(candidates[i]);
if (!path_char_is_slash(*in_path))
{
@@ -193,7 +183,7 @@ void fill_pathname_application_path(char *buf, size_t size)
char link_path[PATH_MAX_LENGTH] = {0};
*buf = '\0';
- pid = getpid();
+ pid = getpid();
/* Linux, BSD and Solaris paths. Not standardized. */
for (i = 0; i < ARRAY_SIZE(exts); i++)
@@ -203,6 +193,7 @@ void fill_pathname_application_path(char *buf, size_t size)
snprintf(link_path, sizeof(link_path), "/proc/%u/%s",
(unsigned)pid, exts[i]);
ret = readlink(link_path, buf, size - 1);
+
if (ret >= 0)
{
buf[ret] = '\0';
diff --git a/frontend/drivers/platform_android.c b/frontend/drivers/platform_android.c
deleted file mode 100644
index 8f4b760429..0000000000
--- a/frontend/drivers/platform_android.c
+++ /dev/null
@@ -1,1073 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2015 - 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 .
- */
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "platform_android.h"
-
-#include "../frontend.h"
-#include "../../general.h"
-#include "../../msg_hash.h"
-#include "../../runloop_data.h"
-
-#define SDCARD_ROOT_WRITABLE 1
-#define SDCARD_EXT_DIR_WRITABLE 2
-#define SDCARD_NOT_WRITABLE 3
-
-struct android_app *g_android;
-static pthread_key_t thread_key;
-
-char screenshot_dir[PATH_MAX_LENGTH];
-char downloads_dir[PATH_MAX_LENGTH];
-char apk_path[PATH_MAX_LENGTH];
-char sdcard_dir[PATH_MAX_LENGTH];
-char app_dir[PATH_MAX_LENGTH];
-char ext_dir[PATH_MAX_LENGTH];
-
-static INLINE void android_app_write_cmd(void *data, int8_t cmd)
-{
- struct android_app *android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd))
- RARCH_ERR("Failure writing android_app cmd: %s\n", strerror(errno));
-}
-
-static void android_app_set_input(void *data, AInputQueue* inputQueue)
-{
- struct android_app *android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- slock_lock(android_app->mutex);
- android_app->pendingInputQueue = inputQueue;
- android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
-
- while (android_app->inputQueue != android_app->pendingInputQueue)
- scond_wait(android_app->cond, android_app->mutex);
-
- slock_unlock(android_app->mutex);
-}
-
-static void android_app_set_window(void *data, ANativeWindow* window)
-{
- struct android_app *android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- slock_lock(android_app->mutex);
- if (android_app->pendingWindow)
- android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
-
- android_app->pendingWindow = window;
-
- if (window)
- android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
-
- while (android_app->window != android_app->pendingWindow)
- scond_wait(android_app->cond, android_app->mutex);
-
- slock_unlock(android_app->mutex);
-}
-
-static void android_app_set_activity_state(void *data, int8_t cmd)
-{
- struct android_app *android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- slock_lock(android_app->mutex);
- android_app_write_cmd(android_app, cmd);
- while (android_app->activityState != cmd
- && android_app->activityState != APP_CMD_DEAD)
- scond_wait(android_app->cond, android_app->mutex);
- slock_unlock(android_app->mutex);
-
- if (android_app->activityState == APP_CMD_DEAD)
- RARCH_LOG("RetroArch native thread is dead.\n");
-}
-
-static void onDestroy(ANativeActivity* activity)
-{
- struct android_app *android_app = (struct android_app*)activity->instance;
-
- if (!android_app)
- return;
-
- RARCH_LOG("onDestroy: %p\n", activity);
- sthread_join(android_app->thread);
- RARCH_LOG("Joined with RetroArch native thread.\n");
-
- close(android_app->msgread);
- close(android_app->msgwrite);
- scond_free(android_app->cond);
- slock_free(android_app->mutex);
-
- free(android_app);
-}
-
-static void onStart(ANativeActivity* activity)
-{
- RARCH_LOG("Start: %p\n", activity);
- android_app_set_activity_state((struct android_app*)
- activity->instance, APP_CMD_START);
-}
-
-static void onResume(ANativeActivity* activity)
-{
- RARCH_LOG("Resume: %p\n", activity);
- android_app_set_activity_state((struct android_app*)
- activity->instance, APP_CMD_RESUME);
-}
-
-static void onPause(ANativeActivity* activity)
-{
- RARCH_LOG("Pause: %p\n", activity);
- android_app_set_activity_state((struct android_app*)
- activity->instance, APP_CMD_PAUSE);
-}
-
-static void onStop(ANativeActivity* activity)
-{
- RARCH_LOG("Stop: %p\n", activity);
- android_app_set_activity_state((struct android_app*)
- activity->instance, APP_CMD_STOP);
-}
-
-static void onConfigurationChanged(ANativeActivity *activity)
-{
- struct android_app* android_app = (struct android_app*)
- activity->instance;
-
- if (!android_app)
- return;
-
- RARCH_LOG("ConfigurationChanged: %p\n", activity);
- android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
-}
-
-static void onWindowFocusChanged(ANativeActivity* activity, int focused)
-{
- RARCH_LOG("WindowFocusChanged: %p -- %d\n", activity, focused);
- android_app_write_cmd((struct android_app*)activity->instance,
- focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
-}
-
-static void onNativeWindowCreated(ANativeActivity* activity,
- ANativeWindow* window)
-{
- RARCH_LOG("NativeWindowCreated: %p -- %p\n", activity, window);
- android_app_set_window((struct android_app*)activity->instance, window);
-}
-
-static void onNativeWindowDestroyed(ANativeActivity* activity,
- ANativeWindow* window)
-{
- RARCH_LOG("NativeWindowDestroyed: %p -- %p\n", activity, window);
- android_app_set_window((struct android_app*)activity->instance, NULL);
-}
-
-static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue)
-{
- RARCH_LOG("InputQueueCreated: %p -- %p\n", activity, queue);
- android_app_set_input((struct android_app*)activity->instance, queue);
-}
-
-static void onInputQueueDestroyed(ANativeActivity* activity,
- AInputQueue* queue)
-{
- RARCH_LOG("InputQueueDestroyed: %p -- %p\n", activity, queue);
- android_app_set_input((struct android_app*)activity->instance, NULL);
-}
-
-JNIEnv *jni_thread_getenv(void)
-{
- JNIEnv *env;
- struct android_app* android_app = (struct android_app*)g_android;
- int status = (*android_app->activity->vm)->
- AttachCurrentThread(android_app->activity->vm, &env, 0);
-
- if (status < 0)
- {
- RARCH_ERR("jni_thread_getenv: Failed to attach current thread.\n");
- return NULL;
- }
- pthread_setspecific(thread_key, (void*)env);
-
- return env;
-}
-
-static void jni_thread_destruct(void *value)
-{
- JNIEnv *env = (JNIEnv*)value;
- struct android_app *android_app = (struct android_app*)g_android;
- RARCH_LOG("jni_thread_destruct()\n");
-
- if (!env)
- return;
-
- if (android_app)
- (*android_app->activity->vm)->
- DetachCurrentThread(android_app->activity->vm);
- pthread_setspecific(thread_key, NULL);
-}
-
-static void android_app_entry(void *data)
-{
- char *argv[1];
- int argc = 0;
- int ret = 0;
-
- if (rarch_main(argc, argv, data) != 0)
- goto end;
-#ifndef HAVE_MAIN
- do
- {
- unsigned sleep_ms = 0;
- ret = rarch_main_iterate(&sleep_ms);
-
- if (ret == 1 && sleep_ms > 0)
- rarch_sleep(sleep_ms);
- rarch_main_data_iterate();
- }while (ret != -1);
-
- main_exit(data);
-#endif
-
-end:
- exit(0);
-}
-
-/*
- * Native activity interaction (called from main thread)
- **/
-
-void ANativeActivity_onCreate(ANativeActivity* activity,
- void* savedState, size_t savedStateSize)
-{
- int msgpipe[2];
- struct android_app* android_app;
-
- (void)savedState;
- (void)savedStateSize;
-
- RARCH_LOG("Creating Native Activity: %p\n", activity);
- activity->callbacks->onDestroy = onDestroy;
- activity->callbacks->onStart = onStart;
- activity->callbacks->onResume = onResume;
- activity->callbacks->onSaveInstanceState = NULL;
- activity->callbacks->onPause = onPause;
- activity->callbacks->onStop = onStop;
- activity->callbacks->onConfigurationChanged = onConfigurationChanged;
- activity->callbacks->onLowMemory = NULL;
- activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
- activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
- activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
- activity->callbacks->onInputQueueCreated = onInputQueueCreated;
- activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
-
- /* These are set only for the native activity,
- * and are reset when it ends. */
- ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON
- | AWINDOW_FLAG_FULLSCREEN, 0);
-
- if (pthread_key_create(&thread_key, jni_thread_destruct))
- RARCH_ERR("Error initializing pthread_key\n");
-
- android_app = (struct android_app*)calloc(1, sizeof(*android_app));
- if (!android_app)
- {
- RARCH_ERR("Failed to initialize android_app\n");
- return;
- }
-
- memset(android_app, 0, sizeof(struct android_app));
-
- android_app->activity = activity;
- android_app->mutex = slock_new();
- android_app->cond = scond_new();
-
- if (pipe(msgpipe))
- {
- RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
- activity->instance = NULL;
- }
- android_app->msgread = msgpipe[0];
- android_app->msgwrite = msgpipe[1];
-
- android_app->thread = sthread_create(android_app_entry, android_app);
-
- /* Wait for thread to start. */
- slock_lock(android_app->mutex);
- while (!android_app->running)
- scond_wait(android_app->cond, android_app->mutex);
- slock_unlock(android_app->mutex);
-
- activity->instance = android_app;
-}
-
-
-int system_property_get(const char *name, char *value)
-{
- FILE *pipe;
- int length = 0;
- char buffer[PATH_MAX_LENGTH] = {0};
- char cmd[PATH_MAX_LENGTH] = {0};
- char *curpos = NULL;
-
- snprintf(cmd, sizeof(cmd), "getprop %s", name);
-
- pipe = popen(cmd, "r");
-
- if (!pipe)
- {
- RARCH_ERR("Could not create pipe.\n");
- return 0;
- }
-
- curpos = value;
-
- while (!feof(pipe))
- {
- if (fgets(buffer, 128, pipe) != NULL)
- {
- int curlen = strlen(buffer);
-
- memcpy(curpos, buffer, curlen);
-
- curpos += curlen;
- length += curlen;
- }
- }
-
- *curpos = '\0';
-
- pclose(pipe);
-
- return length;
-}
-
-static void frontend_android_get_name(char *s, size_t len)
-{
- system_property_get("ro.product.model", s);
-}
-
-static void frontend_android_get_version(int32_t *major,
- int32_t *minor, int32_t *rel)
-{
- char os_version_str[PROP_VALUE_MAX] = {0};
- system_property_get("ro.build.version.release", os_version_str);
-
- *major = 0;
- *minor = 0;
- *rel = 0;
-
- /* Parse out the OS version numbers from the system properties. */
- if (os_version_str[0])
- {
- /* Try to parse out the version numbers from the string. */
- int num_read = sscanf(os_version_str, "%d.%d.%d", major, minor, rel);
-
- if (num_read > 0)
- {
- if (num_read < 2)
- *minor = 0;
- if (num_read < 3)
- *rel = 0;
- return;
- }
- }
-}
-
-static void frontend_android_get_os(char *s, size_t len, int *major, int *minor)
-{
- int rel;
-
- frontend_android_get_version(major, minor, &rel);
-
- strlcpy(s, "Android", len);
-}
-
-static void frontend_android_get_version_sdk(int32_t *sdk)
-{
- char os_version_str[PROP_VALUE_MAX] = {0};
- system_property_get("ro.build.version.sdk", os_version_str);
-
- *sdk = 0;
- if (os_version_str[0])
- {
- int num_read = sscanf(os_version_str, "%d", sdk);
- (void) num_read;
- }
-}
-
-static bool device_is_xperia_play(const char *name)
-{
- if (
- !strcmp(name, "R800x") ||
- !strcmp(name, "R800at") ||
- !strcmp(name, "R800i") ||
- !strcmp(name, "R800a") ||
- !strcmp(name, "SO-01D")
- )
- return true;
-
- return false;
-}
-
-static bool device_is_game_console(const char *name)
-{
- if (
- !strcmp(name, "OUYA Console") ||
- device_is_xperia_play(name) ||
- !strcmp(name, "GAMEMID_BT") ||
- !strcmp(name, "S7800") ||
- !strcmp(name, "SHIELD")
- )
- return true;
-
- return false;
-}
-
-bool test_permissions(const char *path)
-{
- char buf[PATH_MAX_LENGTH];
- bool ret;
-
- RARCH_LOG("Testing permissions for %s\n",path);
-
- fill_pathname_join(buf, path, ".retroarch", sizeof(buf));
- ret = path_mkdir(buf);
-
- RARCH_LOG("Create %s %s\n", buf, ret ? "true" : "false");
-
- if(ret)
- rmdir(buf);
-
- return ret;
-}
-
-static void frontend_android_get_environment_settings(int *argc,
- char *argv[], void *data, void *params_data)
-{
- int32_t major, minor, rel;
- int perms = 0;
- char device_model[PROP_VALUE_MAX] = {0};
- char device_id[PROP_VALUE_MAX] = {0};
- struct rarch_main_wrap *args = NULL;
- JNIEnv *env = NULL;
- jobject obj = NULL;
- jstring jstr = NULL;
- struct android_app *android_app = (struct android_app*)data;
- char buf[PATH_MAX_LENGTH] = {0};
-
- if (!android_app)
- return;
-
- env = jni_thread_getenv();
- if (!env)
- return;
-
- args = (struct rarch_main_wrap*)params_data;
-
- if (args)
- {
- args->touched = true;
- args->no_content = false;
- args->verbose = false;
- args->sram_path = NULL;
- args->state_path = NULL;
- }
-
- frontend_android_get_version(&major, &minor, &rel);
-
- RARCH_LOG("Android OS version (major : %d, minor : %d, rel : %d)\n",
- major, minor, rel);
-
- CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
- android_app->getIntent);
- RARCH_LOG("Checking arguments passed from intent ...\n");
-
- /* Config file. */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "CONFIGFILE"));
-
- if (android_app->getStringExtra && jstr)
- {
- static char config_path[PATH_MAX_LENGTH] = {0};
- const char *argv = NULL;
-
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(config_path, argv, sizeof(config_path));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- RARCH_LOG("Config file: [%s].\n", config_path);
- if (args && *config_path)
- args->config_path = config_path;
- }
-
- /* Current IME. */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "IME"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- strlcpy(android_app->current_ime, argv,
- sizeof(android_app->current_ime));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- RARCH_LOG("Current IME: [%s].\n", android_app->current_ime);
- }
-
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "USED"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
- bool used = (!strcmp(argv, "false")) ? false : true;
-
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- RARCH_LOG("USED: [%s].\n", used ? "true" : "false");
- }
-
- /* LIBRETRO. */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "LIBRETRO"));
-
- if (android_app->getStringExtra && jstr)
- {
- static char core_path[PATH_MAX_LENGTH];
- const char *argv = NULL;
-
- *core_path = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
- if (argv && *argv)
- strlcpy(core_path, argv, sizeof(core_path));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- RARCH_LOG("Libretro path: [%s]\n", core_path);
- if (args && *core_path)
- args->libretro_path = core_path;
- }
-
- /* Content. */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "ROM"));
-
- if (android_app->getStringExtra && jstr)
- {
- static char path[PATH_MAX_LENGTH];
- const char *argv = NULL;
-
- *path = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(path, argv, sizeof(path));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*path)
- {
- RARCH_LOG("Auto-start game %s.\n", path);
- if (args && *path)
- args->content_path = path;
- }
- }
-
- /* External Storage */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "SDCARD"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *sdcard_dir = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(sdcard_dir, argv, sizeof(sdcard_dir));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*sdcard_dir)
- {
- RARCH_LOG("External storage location [%s]\n", sdcard_dir);
- /* TODO base dir handler */
- }
- }
-
- /* Screenshots */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "SCREENSHOTS"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *screenshot_dir = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(screenshot_dir, argv, sizeof(screenshot_dir));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*screenshot_dir)
- {
- RARCH_LOG("Picture folder location [%s]\n", screenshot_dir);
- /* TODO: screenshot handler */
- }
- }
-
- /* Downloads */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "DOWNLOADS"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *downloads_dir = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(downloads_dir, argv, sizeof(downloads_dir));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*downloads_dir)
- {
- RARCH_LOG("Download folder location [%s].\n", downloads_dir);
- /* TODO: downloads handler */
- }
- }
-
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "APK"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *apk_path = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(apk_path, argv, sizeof(apk_path));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*apk_path)
- {
- RARCH_LOG("APK location [%s].\n", apk_path);
- }
- }
-
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "EXTERNAL"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *ext_dir = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(ext_dir, argv, sizeof(ext_dir));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- if (*ext_dir)
- {
- RARCH_LOG("External files location [%s]\n", ext_dir);
- }
- }
-
- /* Content. */
- CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
- (*env)->NewStringUTF(env, "DATADIR"));
-
- if (android_app->getStringExtra && jstr)
- {
- const char *argv = NULL;
-
- *app_dir = '\0';
- argv = (*env)->GetStringUTFChars(env, jstr, 0);
-
- if (argv && *argv)
- strlcpy(app_dir, argv, sizeof(app_dir));
- (*env)->ReleaseStringUTFChars(env, jstr, argv);
-
- //set paths depending on the ability to write to sdcard_dir
-
- if(*sdcard_dir)
- {
- if(test_permissions(sdcard_dir))
- perms = SDCARD_ROOT_WRITABLE;
- }
- else if(*ext_dir)
- {
- if(test_permissions(ext_dir))
- perms = SDCARD_EXT_DIR_WRITABLE;
- }
- else
- perms = SDCARD_NOT_WRITABLE;
-
- RARCH_LOG("SD permissions: %d",perms);
-
- if (*app_dir)
- {
- RARCH_LOG("Application location: [%s].\n", app_dir);
- if (args && *app_dir)
- {
- fill_pathname_join(g_defaults.dir.assets, app_dir,
- "assets", sizeof(g_defaults.dir.assets));
- fill_pathname_join(g_defaults.dir.extraction, app_dir,
- "tmp", sizeof(g_defaults.dir.extraction));
- fill_pathname_join(g_defaults.dir.shader, app_dir,
- "shaders", sizeof(g_defaults.dir.shader));
- fill_pathname_join(g_defaults.dir.overlay, app_dir,
- "overlays", sizeof(g_defaults.dir.overlay));
- fill_pathname_join(g_defaults.dir.osk_overlay, app_dir,
- "overlays", sizeof(g_defaults.dir.osk_overlay));
- fill_pathname_join(g_defaults.dir.core, app_dir,
- "cores", sizeof(g_defaults.dir.core));
- fill_pathname_join(g_defaults.dir.core_info,
- app_dir, "info", sizeof(g_defaults.dir.core_info));
- fill_pathname_join(g_defaults.dir.autoconfig,
- app_dir, "autoconfig", sizeof(g_defaults.dir.autoconfig));
- fill_pathname_join(g_defaults.dir.audio_filter,
- app_dir, "audio_filters", sizeof(g_defaults.dir.audio_filter));
- fill_pathname_join(g_defaults.dir.video_filter,
- app_dir, "video_filters", sizeof(g_defaults.dir.video_filter));
- strlcpy(g_defaults.dir.content_history,
- app_dir, sizeof(g_defaults.dir.content_history));
- fill_pathname_join(g_defaults.dir.database,
- app_dir, "database/rdb", sizeof(g_defaults.dir.database));
- fill_pathname_join(g_defaults.dir.cursor,
- app_dir, "database/cursors", sizeof(g_defaults.dir.cursor));
- fill_pathname_join(g_defaults.dir.cheats,
- app_dir, "cheats", sizeof(g_defaults.dir.cheats));
- fill_pathname_join(g_defaults.dir.playlist,
- app_dir, "playlists", sizeof(g_defaults.dir.playlist));
- fill_pathname_join(g_defaults.dir.remap,
- app_dir, "remaps", sizeof(g_defaults.dir.remap));
- fill_pathname_join(g_defaults.dir.wallpapers,
- app_dir, "wallpapers", sizeof(g_defaults.dir.wallpapers));
- if(*downloads_dir && test_permissions(downloads_dir))
- {
- fill_pathname_join(g_defaults.dir.core_assets,
- downloads_dir, "", sizeof(g_defaults.dir.core_assets));
- }
- else
- {
- fill_pathname_join(g_defaults.dir.core_assets,
- app_dir, "downloads", sizeof(g_defaults.dir.core_assets));
- path_mkdir(g_defaults.dir.core_assets);
- }
-
- RARCH_LOG("Default download folder: [%s]", g_defaults.dir.core_assets);
-
- if(*screenshot_dir && test_permissions(screenshot_dir))
- {
- fill_pathname_join(g_defaults.dir.screenshot,
- screenshot_dir, "", sizeof(g_defaults.dir.screenshot));
- }
- else
- {
- fill_pathname_join(g_defaults.dir.screenshot,
- app_dir, "screenshots", sizeof(g_defaults.dir.screenshot));
- path_mkdir(g_defaults.dir.screenshot);
- }
-
- RARCH_LOG("Default screenshot folder: [%s]", g_defaults.dir.screenshot);
-
- switch (perms)
- {
- case SDCARD_EXT_DIR_WRITABLE:
- fill_pathname_join(g_defaults.dir.sram,
- ext_dir, "saves", sizeof(g_defaults.dir.sram));
- path_mkdir(g_defaults.dir.sram);
-
- fill_pathname_join(g_defaults.dir.savestate,
- ext_dir, "states", sizeof(g_defaults.dir.savestate));
- path_mkdir(g_defaults.dir.savestate);
-
- fill_pathname_join(g_defaults.dir.system,
- ext_dir, "system", sizeof(g_defaults.dir.system));
- path_mkdir(g_defaults.dir.system);
- break;
- case SDCARD_NOT_WRITABLE:
- fill_pathname_join(g_defaults.dir.sram,
- app_dir, "saves", sizeof(g_defaults.dir.sram));
- path_mkdir(g_defaults.dir.sram);
- fill_pathname_join(g_defaults.dir.savestate,
- app_dir, "states", sizeof(g_defaults.dir.savestate));
- path_mkdir(g_defaults.dir.savestate);
- fill_pathname_join(g_defaults.dir.system,
- app_dir, "system", sizeof(g_defaults.dir.system));
- path_mkdir(g_defaults.dir.system);
- break;
- case SDCARD_ROOT_WRITABLE:
- default:
- break;
- }
-
- /* create save and system directories in the internal dir too */
- fill_pathname_join(buf,
- app_dir, "saves", sizeof(buf));
- path_mkdir(buf);
-
- fill_pathname_join(buf,
- app_dir, "states", sizeof(buf));
- path_mkdir(buf);
-
- fill_pathname_join(buf,
- app_dir, "system", sizeof(buf));
- path_mkdir(buf);
-
- /* create save and system directories in the internal sd too */
-
- fill_pathname_join(buf,
- ext_dir, "saves", sizeof(buf));
- path_mkdir(buf);
-
- fill_pathname_join(buf,
- ext_dir, "states", sizeof(buf));
- path_mkdir(buf);
-
- fill_pathname_join(buf,
- ext_dir, "system", sizeof(buf));
- path_mkdir(buf);
-
- RARCH_LOG("Default savefile folder: [%s]", g_defaults.dir.sram);
- RARCH_LOG("Default savestate folder: [%s]", g_defaults.dir.savestate);
- RARCH_LOG("Default system folder: [%s]", g_defaults.dir.system);
- }
- }
- }
-
- frontend_android_get_name(device_model, sizeof(device_model));
- system_property_get("ro.product.id", device_id);
-
- g_defaults.settings.video_threaded_enable = true;
-
- /* Set automatic default values per device */
- if (device_is_xperia_play(device_model))
- {
- g_defaults.settings.out_latency = 128;
- g_defaults.settings.video_refresh_rate = 59.19132938771038;
- g_defaults.settings.video_threaded_enable = false;
- }
- else if (!strcmp(device_model, "GAMEMID_BT"))
- g_defaults.settings.out_latency = 160;
- else if (!strcmp(device_model, "SHIELD"))
- g_defaults.settings.video_refresh_rate = 60.0;
- else if (!strcmp(device_model, "JSS15J"))
- g_defaults.settings.video_refresh_rate = 59.65;
-
-#if 0
- /* Explicitly disable input overlay by default
- * for gamepad-like/console devices. */
- if (device_is_game_console(device_model))
- g_defaults.settings.input_overlay_enable = false;
-#endif
-}
-
-static void frontend_android_deinit(void *data)
-{
- JNIEnv *env = NULL;
- struct android_app *android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- RARCH_LOG("Deinitializing RetroArch ...\n");
- android_app->activityState = APP_CMD_DEAD;
-
- env = jni_thread_getenv();
-
- if (env && android_app->onRetroArchExit)
- CALL_VOID_METHOD(env, android_app->activity->clazz,
- android_app->onRetroArchExit);
-
- if (android_app->inputQueue)
- {
- RARCH_LOG("Detaching Android input queue looper ...\n");
- AInputQueue_detachLooper(android_app->inputQueue);
- }
-}
-
-static void frontend_android_shutdown(bool unused)
-{
- (void)unused;
- /* Cleaner approaches don't work sadly. */
- exit(0);
-}
-
-bool android_run_events(void *data);
-
-static void frontend_android_init(void *data)
-{
- JNIEnv *env = NULL;
- ALooper *looper = NULL;
- jclass class = NULL;
- jobject obj = NULL;
- struct android_app* android_app = (struct android_app*)data;
-
- if (!android_app)
- return;
-
- looper = (ALooper*)ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
- ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN,
- ALOOPER_EVENT_INPUT, NULL, NULL);
- android_app->looper = looper;
-
- slock_lock(android_app->mutex);
- android_app->running = 1;
- scond_broadcast(android_app->cond);
- slock_unlock(android_app->mutex);
-
- memset(&g_android, 0, sizeof(g_android));
- g_android = (struct android_app*)android_app;
-
- RARCH_LOG("Waiting for Android Native Window to be initialized ...\n");
-
- while (!android_app->window)
- {
- if (!android_run_events(android_app))
- {
- frontend_android_deinit(android_app);
- frontend_android_shutdown(android_app);
- return;
- }
- }
-
- RARCH_LOG("Android Native Window initialized.\n");
-
- env = jni_thread_getenv();
- if (!env)
- return;
-
- GET_OBJECT_CLASS(env, class, android_app->activity->clazz);
- GET_METHOD_ID(env, android_app->getIntent, class,
- "getIntent", "()Landroid/content/Intent;");
- GET_METHOD_ID(env, android_app->onRetroArchExit, class,
- "onRetroArchExit", "()V");
- CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
- android_app->getIntent);
-
- GET_OBJECT_CLASS(env, class, obj);
- GET_METHOD_ID(env, android_app->getStringExtra, class,
- "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
-}
-
-static int frontend_android_get_rating(void)
-{
- char device_model[PROP_VALUE_MAX] = {0};
- frontend_android_get_name(device_model, sizeof(device_model));
-
- RARCH_LOG("ro.product.model: (%s).\n", device_model);
-
- if (device_is_xperia_play(device_model))
- return 6;
- else if (!strcmp(device_model, "GT-I9505"))
- return 12;
- else if (!strcmp(device_model, "SHIELD"))
- return 13;
- return -1;
-}
-
-#define ANDROID_ARCH_ARMV7 0x26257a91U
-#define ANDROID_ARCH_ARM 0x406a3516U
-#define ANDROID_ARCH_MIPS 0x7c9aa25eU
-#define ANDROID_ARCH_X86 0x0b88b8cbU
-
-static enum frontend_architecture frontend_android_get_architecture(void)
-{
- uint32_t abi_hash;
- char abi[PROP_VALUE_MAX] = {0};
- system_property_get("ro.product.cpu.abi", abi);
-
- abi_hash = msg_hash_calculate(abi);
-
- switch (abi_hash)
- {
- case ANDROID_ARCH_ARMV7:
- return FRONTEND_ARCH_ARM;
- case ANDROID_ARCH_ARM:
- return FRONTEND_ARCH_ARM;
- case ANDROID_ARCH_MIPS:
- return FRONTEND_ARCH_MIPS;
- case ANDROID_ARCH_X86:
- return FRONTEND_ARCH_X86;
- }
-
- return FRONTEND_ARCH_NONE;
-}
-
-static int frontend_android_parse_drive_list(void *data)
-{
- file_list_t *list = (file_list_t*)data;
-
- // MENU_FILE_DIRECTORY is not working with labels, placeholders for now
- menu_list_push(list,
- app_dir, "Application Dir", MENU_FILE_DIRECTORY, 0, 0);
- menu_list_push(list,
- ext_dir, "External Application Dir", MENU_FILE_DIRECTORY, 0, 0);
- menu_list_push(list,
- sdcard_dir, "Internal Memory", MENU_FILE_DIRECTORY, 0, 0);
-
- menu_list_push(list, "/", "",
- MENU_FILE_DIRECTORY, 0, 0);
-
- return 0;
-}
-
-frontend_ctx_driver_t frontend_ctx_android = {
- frontend_android_get_environment_settings,
- frontend_android_init,
- frontend_android_deinit,
- NULL, /* exitspawn */
- NULL, /* process_args */
- NULL, /* exec */
- NULL, /* set_fork */
- frontend_android_shutdown,
- frontend_android_get_name,
- frontend_android_get_os,
- frontend_android_get_rating,
- NULL, /* load_content */
- frontend_android_get_architecture,
- NULL, /* get_powerstate */
- frontend_android_parse_drive_list,
- "android",
-};
diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c
index dc415f52bc..a2412b4243 100644
--- a/frontend/drivers/platform_ctr.c
+++ b/frontend/drivers/platform_ctr.c
@@ -13,13 +13,14 @@
* If not, see .
*/
-#include <3ds.h>
-
#include
-#include
#include
#include
+#include
+
+#include <3ds.h>
+
#include
#ifndef IS_SALAMANDER
#include
@@ -35,15 +36,77 @@
#include "../../menu/menu_list.h"
#endif
-
-int __stacksize__ = 1*1024*1024;
-
const char* elf_path_cst = "sdmc:/retroarch/test.3dsx";
void wait_for_input(void);
#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
+#ifndef CTR_STACK_SIZE
+#define CTR_STACK_SIZE 0x100000
+#endif
+
+#ifndef CTR_LINEAR_HEAP_SIZE
+#define CTR_LINEAR_HEAP_SIZE 0x600000
+#endif
+
+int __stacksize__ = CTR_STACK_SIZE;
+
+extern char* fake_heap_start;
+extern char* fake_heap_end;
+u32 __linear_heap;
+u32 __heapBase;
+static u32 __heap_size_local, __linear_heap_size_local;
+
+extern void (*__system_retAddr)(void);
+
+void __destroy_handle_list(void);
+void __appExit();
+void __libc_fini_array(void);
+
+void __system_allocateHeaps() {
+ u32 tmp=0;
+ int64_t mem_used;
+ svcGetSystemInfo(&mem_used, 0, 1);
+
+ __linear_heap_size_local = CTR_LINEAR_HEAP_SIZE;
+ __heap_size_local = (0x4000000 - mem_used - __linear_heap_size_local - 0x1000) & 0xFFFFF000;
+
+ // Allocate the application heap
+ __heapBase = 0x08000000;
+ svcControlMemory(&tmp, __heapBase, 0x0, __heap_size_local, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
+
+ // Allocate the linear heap
+ svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size_local, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
+ // Set up newlib heap
+ fake_heap_start = (char*)__heapBase;
+ fake_heap_end = fake_heap_start + __heap_size_local;
+
+}
+
+void __attribute__((noreturn)) __libctru_exit(int rc)
+{
+ u32 tmp=0;
+
+ // Unmap the linear heap
+ svcControlMemory(&tmp, __linear_heap, 0x0, __linear_heap_size_local, MEMOP_FREE, 0x0);
+
+ // Unmap the application heap
+ svcControlMemory(&tmp, __heapBase, 0x0, __heap_size_local, MEMOP_FREE, 0x0);
+
+ // Close some handles
+ __destroy_handle_list();
+
+ // Jump to the loader if it provided a callback
+ if (__system_retAddr)
+ __system_retAddr();
+
+ // Since above did not jump, end this process
+ svcExitProcess();
+}
+
+
+
static void frontend_ctr_get_environment_settings(int *argc, char *argv[],
void *args, void *params_data)
{
@@ -77,6 +140,8 @@ static void frontend_ctr_get_environment_settings(int *argc, char *argv[],
"system", sizeof(g_defaults.dir.system));
fill_pathname_join(g_defaults.dir.playlist, g_defaults.dir.core,
"playlists", sizeof(g_defaults.dir.playlist));
+ fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port,
+ "remaps", sizeof(g_defaults.dir.remap));
fill_pathname_join(g_defaults.path.config, g_defaults.dir.port,
"retroarch.cfg", sizeof(g_defaults.path.config));
@@ -199,12 +264,32 @@ void wait_for_input(void)
break;
if (kDown & KEY_SELECT)
- select_pressed = true;
+ exit(0);
+#if 0
+ select_pressed = true;
+#endif
- rarch_sleep(1);
+ retro_sleep(1);
}
}
+int usleep (useconds_t us)
+{
+ svcSleepThread((int64_t)us * 1000);
+}
+
+long sysconf(int name)
+{
+ switch(name)
+ {
+ case _SC_NPROCESSORS_ONLN:
+ return 2;
+ }
+
+ return -1;
+}
+
+
enum frontend_architecture frontend_ctr_get_architecture(void)
{
return FRONTEND_ARCH_ARM;
diff --git a/frontend/drivers/platform_emscripten.c b/frontend/drivers/platform_emscripten.c
index 764f2ba715..f0e5b894c2 100644
--- a/frontend/drivers/platform_emscripten.c
+++ b/frontend/drivers/platform_emscripten.c
@@ -16,8 +16,10 @@
*/
#include
-#include "../../general.h"
+
#include
+
+#include "../../general.h"
#include "../../content.h"
#include "../frontend.h"
#include "../../retroarch.h"
@@ -30,7 +32,7 @@ static void emscripten_mainloop(void)
unsigned sleep_ms = 0;
int ret = rarch_main_iterate(&sleep_ms);
if (ret == 1 && sleep_ms > 0)
- rarch_sleep(sleep_ms);
+ retro_sleep(sleep_ms);
rarch_main_data_iterate();
if (ret != -1)
return;
diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c
index 77abac8269..65e65899d0 100644
--- a/frontend/drivers/platform_gx.c
+++ b/frontend/drivers/platform_gx.c
@@ -24,7 +24,7 @@
#if defined(HW_RVL) && !defined(IS_SALAMANDER)
#include
#include
-#include "../../wii/mem2_manager.h"
+#include "../../memory/wii/mem2_manager.h"
#endif
#include
diff --git a/frontend/drivers/platform_linux.c b/frontend/drivers/platform_linux.c
index 6f8188c332..dcc3eb3882 100644
--- a/frontend/drivers/platform_linux.c
+++ b/frontend/drivers/platform_linux.c
@@ -2,6 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2015 - Daniel De Matteis
* Copyright (C) 2012-2015 - Jason Fetters
+ * 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-
@@ -16,41 +17,910 @@
#include
#include
-#include
#include
#include
#include
-#include
-#include
+#include
#include
#include
+#include
+#include
+
+#ifdef ANDROID
+#include
+#endif
+#ifdef __arm__
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
#include
#include
+#include
+#include "../frontend.h"
#include "../frontend_driver.h"
+#include "../../general.h"
+#include "platform_linux.h"
+static bool cpu_inited_once;
+static cpu_family g_cpuFamily;
+static uint64_t g_cpuFeatures;
+static int g_cpuCount;
+
+#ifdef __arm__
+# define DEFAULT_CPU_FAMILY CPU_FAMILY_ARM
+#elif defined __i386__
+# define DEFAULT_CPU_FAMILY CPU_FAMILY_X86
+#else
+# define DEFAULT_CPU_FAMILY CPU_FAMILY_UNKNOWN
+#endif
+
+#ifdef __i386__
+static INLINE void cpu_x86_cpuid(int func, int values[4])
+{
+ int a, b, c, d;
+ /* We need to preserve ebx since we're compiling PIC code */
+ /* this means we can't use "=b" for the second output register */
+ __asm__ __volatile__ ( \
+ "push %%ebx\n"
+ "cpuid\n" \
+ "mov %1, %%ebx\n"
+ "pop %%ebx\n"
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "a" (func) \
+ );
+ values[0] = a;
+ values[1] = b;
+ values[2] = c;
+ values[3] = d;
+}
+#endif
+
+#ifdef __ARM_ARCH__
+/* Extract the content of a the first occurence of a given field in
+ * the content of /proc/cpuinfo and return it as a heap-allocated
+ * string that must be freed by the caller.
+ *
+ * Return NULL if not found
+ */
+static char *extract_cpuinfo_field(char* buffer, ssize_t length, const char* field)
+{
+ int len;
+ const char *q;
+ int fieldlen = strlen(field);
+ char* bufend = buffer + length;
+ char* result = NULL;
+ /* Look for first field occurence, and ensures it starts the line. */
+ const char *p = buffer;
+
+ bufend = buffer + length;
+
+ for (;;)
+ {
+ p = memmem(p, bufend-p, field, fieldlen);
+ if (p == NULL)
+ return result;
+
+ if (p == buffer || p[-1] == '\n')
+ break;
+
+ p += fieldlen;
+ }
+
+ /* Skip to the first column followed by a space */
+ p += fieldlen;
+ p = memchr(p, ':', bufend-p);
+ if (p == NULL || p[1] != ' ')
+ return result;
+
+ /* Find the end of the line */
+ p += 2;
+ q = memchr(p, '\n', bufend-p);
+ if (q == NULL)
+ q = bufend;
+
+ /* Copy the line into a heap-allocated buffer */
+ len = q-p;
+ result = malloc(len+1);
+ if (result == NULL)
+ return result;
+
+ memcpy(result, p, len);
+ result[len] = '\0';
+
+ return result;
+}
+
+/* Checks that a space-separated list of items contains one given 'item'.
+ * Returns 1 if found, 0 otherwise.
+ */
+static int has_list_item(const char* list, const char* item)
+{
+ const char* p = list;
+ int itemlen = strlen(item);
+
+ if (list == NULL)
+ return 0;
+
+ while (*p)
+ {
+ const char* q;
+
+ /* skip spaces */
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ /* find end of current list item */
+ q = p;
+ while (*q && *q != ' ' && *q != '\t')
+ q++;
+
+ if (itemlen == q-p && !memcmp(p, item, itemlen))
+ return 1;
+
+ /* skip to next item */
+ p = q;
+ }
+ return 0;
+}
+#endif
+
+
+/* Parse an decimal integer starting from 'input', but not going further
+ * than 'limit'. Return the value into '*result'.
+ *
+ * NOTE: Does not skip over leading spaces, or deal with sign characters.
+ * NOTE: Ignores overflows.
+ *
+ * The function returns NULL in case of error (bad format), or the new
+ * position after the decimal number in case of success (which will always
+ * be <= 'limit').
+ */
+static const char *parse_decimal(const char* input, const char* limit, int* result)
+{
+ const char* p = input;
+ int val = 0;
+
+ while (p < limit)
+ {
+ int d = (*p - '0');
+ if ((unsigned)d >= 10U)
+ break;
+ val = val*10 + d;
+ p++;
+ }
+ if (p == input)
+ return NULL;
+
+ *result = val;
+ return p;
+}
+
+/* This small data type is used to represent a CPU list / mask, as read
+ * from sysfs on Linux. See http://www.kernel.org/doc/Documentation/cputopology.txt
+ *
+ * For now, we don't expect more than 32 cores on mobile devices, so keep
+ * everything simple.
+ */
+typedef struct
+{
+ uint32_t mask;
+} CpuList;
+
+/* Parse a textual list of cpus and store the result inside a CpuList object.
+ * Input format is the following:
+ * - comma-separated list of items (no spaces)
+ * - each item is either a single decimal number (cpu index), or a range made
+ * of two numbers separated by a single dash (-). Ranges are inclusive.
+ *
+ * Examples: 0
+ * 2,4-127,128-143
+ * 0-1
+ */
+static void cpulist_parse(CpuList* list, char **buf, ssize_t length)
+{
+ const char* p = (const char*)buf;
+ const char* end = p + length;
+
+ /* NOTE: the input line coming from sysfs typically contains a
+ * trailing newline, so take care of it in the code below
+ */
+ while (p < end && *p != '\n')
+ {
+ int val, start_value, end_value;
+ /* Find the end of current item, and put it into 'q' */
+ const char *q = (const char*)memchr(p, ',', end-p);
+
+ if (!q)
+ q = end;
+
+ /* Get first value */
+ p = parse_decimal(p, q, &start_value);
+ if (p == NULL)
+ return;
+
+ end_value = start_value;
+
+ /* If we're not at the end of the item, expect a dash and
+ * and integer; extract end value.
+ */
+ if (p < q && *p == '-')
+ {
+ p = parse_decimal(p+1, q, &end_value);
+ if (p == NULL)
+ return;
+ }
+
+ /* Set bits CPU list bits */
+ for (val = start_value; val <= end_value; val++)
+ {
+ if ((unsigned)val < 32)
+ list->mask |= (uint32_t)(1U << val);
+ }
+
+ /* Jump to next item */
+ p = q;
+ if (p < end)
+ p++;
+ }
+}
+
+/* Read a CPU list from one sysfs file */
+static void cpulist_read_from(CpuList* list, const char* filename)
+{
+ ssize_t length;
+ char *buf = NULL;
+
+ list->mask = 0;
+
+ if (retro_read_file(filename, (void**)&buf, &length) != 1)
+ {
+ RARCH_ERR("Could not read %s: %s\n", filename, strerror(errno));
+ return;
+ }
+
+ cpulist_parse(list, &buf, length);
+ if (buf)
+ free(buf);
+ buf = NULL;
+}
+
+/* Return the number of cpus present on a given device.
+ *
+ * To handle all weird kernel configurations, we need to compute the
+ * intersection of the 'present' and 'possible' CPU lists and count
+ * the result.
+ */
+static int get_cpu_count(void)
+{
+ CpuList cpus_present[1];
+ CpuList cpus_possible[1];
+
+ cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
+ cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
+
+ /* Compute the intersection of both sets to get the actual number of
+ * CPU cores that can be used on this device by the kernel.
+ */
+ cpus_present->mask &= cpus_possible->mask;
+
+ return __builtin_popcount(cpus_present->mask);
+}
+
+static void linux_cpu_init(void)
+{
+ ssize_t length;
+ void *buf = NULL;
+
+ g_cpuFamily = DEFAULT_CPU_FAMILY;
+ g_cpuFeatures = 0;
+ g_cpuCount = 1;
+
+ if (retro_read_file("/proc/cpuinfo", &buf, &length) != 1)
+ return;
+
+ /* Count the CPU cores, the value may be 0 for single-core CPUs */
+ g_cpuCount = get_cpu_count();
+ if (g_cpuCount == 0)
+ g_cpuCount = 1;
+
+ RARCH_LOG("found cpuCount = %d\n", g_cpuCount);
+
+#ifdef __ARM_ARCH__
+ /* Extract architecture from the "CPU Architecture" field.
+ * The list is well-known, unlike the the output of
+ * the 'Processor' field which can vary greatly.
+ *
+ * See the definition of the 'proc_arch' array in
+ * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
+ * same file.
+ */
+ char* cpu_arch = extract_cpuinfo_field(buf, length, "CPU architecture");
+
+ if (cpu_arch)
+ {
+ char* end;
+ int has_armv7 = 0;
+ /* read the initial decimal number, ignore the rest */
+ long arch_number = strtol(cpu_arch, &end, 10);
+
+ RARCH_LOG("Found CPU architecture = '%s'\n", cpu_arch);
+
+ /* Here we assume that ARMv8 will be upwards compatible with v7
+ * in the future. Unfortunately, there is no 'Features' field to
+ * indicate that Thumb-2 is supported.
+ */
+ if (end > cpu_arch && arch_number >= 7)
+ has_armv7 = 1;
+
+ /* Unfortunately, it seems that certain ARMv6-based CPUs
+ * report an incorrect architecture number of 7!
+ *
+ * See http://code.google.com/p/android/issues/detail?id=10812
+ *
+ * We try to correct this by looking at the 'elf_format'
+ * field reported by the 'Processor' field, which is of the
+ * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
+ * an ARMv6-one.
+ */
+ if (has_armv7)
+ {
+ char *cpu_proc = extract_cpuinfo_field(buf, length,
+ "Processor");
+
+ if (cpu_proc != NULL)
+ {
+ RARCH_LOG("found cpu_proc = '%s'\n", cpu_proc);
+ if (has_list_item(cpu_proc, "(v6l)"))
+ {
+ RARCH_ERR("CPU processor and architecture mismatch!!\n");
+ has_armv7 = 0;
+ }
+ free(cpu_proc);
+ }
+ }
+
+ if (has_armv7)
+ g_cpuFeatures |= CPU_ARM_FEATURE_ARMv7;
+
+ /* The LDREX / STREX instructions are available from ARMv6 */
+ if (arch_number >= 6)
+ g_cpuFeatures |= CPU_ARM_FEATURE_LDREX_STREX;
+
+ free(cpu_arch);
+ }
+
+ /* Extract the list of CPU features from 'Features' field */
+ char* cpu_features = extract_cpuinfo_field(buf, length, "Features");
+
+ if (cpu_features)
+ {
+ RARCH_LOG("found cpu_features = '%s'\n", cpu_features);
+
+ if (has_list_item(cpu_features, "vfpv3"))
+ g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
+
+ else if (has_list_item(cpu_features, "vfpv3d16"))
+ g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
+
+ /* Note: Certain kernels only report NEON but not VFPv3
+ * in their features list. However, ARM mandates
+ * that if NEON is implemented, so must be VFPv3
+ * so always set the flag.
+ */
+ if (has_list_item(cpu_features, "neon"))
+ g_cpuFeatures |= CPU_ARM_FEATURE_NEON | CPU_ARM_FEATURE_VFPv3;
+ free(cpu_features);
+ }
+#endif /* __ARM_ARCH__ */
+
+#ifdef __i386__
+ g_cpuFamily = CPU_FAMILY_X86;
+
+ int regs[4];
+
+ /* According to http://en.wikipedia.org/wiki/CPUID */
+#define VENDOR_INTEL_b 0x756e6547
+#define VENDOR_INTEL_c 0x6c65746e
+#define VENDOR_INTEL_d 0x49656e69
+
+ cpu_x86_cpuid(0, regs);
+ int vendorIsIntel = (regs[1] == VENDOR_INTEL_b &&
+ regs[2] == VENDOR_INTEL_c &&
+ regs[3] == VENDOR_INTEL_d);
+
+ cpu_x86_cpuid(1, regs);
+ if ((regs[2] & (1 << 9)) != 0)
+ g_cpuFeatures |= CPU_X86_FEATURE_SSSE3;
+ if ((regs[2] & (1 << 23)) != 0)
+ g_cpuFeatures |= CPU_X86_FEATURE_POPCNT;
+ if (vendorIsIntel && (regs[2] & (1 << 22)) != 0)
+ g_cpuFeatures |= CPU_X86_FEATURE_MOVBE;
+#endif
+
+#ifdef _MIPS_ARCH
+ g_cpuFamily = CPU_FAMILY_MIPS;
+#endif
+
+ if (buf)
+ free(buf);
+ buf = NULL;
+}
+
+cpu_family linux_get_cpu_platform(void)
+{
+ return g_cpuFamily;
+}
+
+uint64_t linux_get_cpu_features(void)
+{
+ return g_cpuFeatures;
+}
+
+int linux_get_cpu_count(void)
+{
+ return g_cpuCount;
+}
+
+#ifdef ANDROID
+#define SDCARD_ROOT_WRITABLE 1
+#define SDCARD_EXT_DIR_WRITABLE 2
+#define SDCARD_NOT_WRITABLE 3
+
+struct android_app *g_android;
+static pthread_key_t thread_key;
+
+char screenshot_dir[PATH_MAX_LENGTH];
+char downloads_dir[PATH_MAX_LENGTH];
+char apk_path[PATH_MAX_LENGTH];
+char sdcard_dir[PATH_MAX_LENGTH];
+char app_dir[PATH_MAX_LENGTH];
+char ext_dir[PATH_MAX_LENGTH];
+
+
+/* forward declaration */
+bool android_run_events(void *data);
+
+static INLINE void android_app_write_cmd(void *data, int8_t cmd)
+{
+ struct android_app *android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd))
+ RARCH_ERR("Failure writing android_app cmd: %s\n", strerror(errno));
+}
+
+static void android_app_set_input(void *data, AInputQueue* inputQueue)
+{
+ struct android_app *android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ slock_lock(android_app->mutex);
+ android_app->pendingInputQueue = inputQueue;
+ android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
+
+ while (android_app->inputQueue != android_app->pendingInputQueue)
+ scond_wait(android_app->cond, android_app->mutex);
+
+ slock_unlock(android_app->mutex);
+}
+
+static void android_app_set_window(void *data, ANativeWindow* window)
+{
+ struct android_app *android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ slock_lock(android_app->mutex);
+ if (android_app->pendingWindow)
+ android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
+
+ android_app->pendingWindow = window;
+
+ if (window)
+ android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
+
+ while (android_app->window != android_app->pendingWindow)
+ scond_wait(android_app->cond, android_app->mutex);
+
+ slock_unlock(android_app->mutex);
+}
+
+static void android_app_set_activity_state(void *data, int8_t cmd)
+{
+ struct android_app *android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ slock_lock(android_app->mutex);
+ android_app_write_cmd(android_app, cmd);
+ while (android_app->activityState != cmd
+ && android_app->activityState != APP_CMD_DEAD)
+ scond_wait(android_app->cond, android_app->mutex);
+ slock_unlock(android_app->mutex);
+
+ if (android_app->activityState == APP_CMD_DEAD)
+ RARCH_LOG("RetroArch native thread is dead.\n");
+}
+
+static void onDestroy(ANativeActivity* activity)
+{
+ struct android_app *android_app = (struct android_app*)activity->instance;
+
+ if (!android_app)
+ return;
+
+ RARCH_LOG("onDestroy: %p\n", activity);
+ sthread_join(android_app->thread);
+ RARCH_LOG("Joined with RetroArch native thread.\n");
+
+ close(android_app->msgread);
+ close(android_app->msgwrite);
+ scond_free(android_app->cond);
+ slock_free(android_app->mutex);
+
+ free(android_app);
+}
+
+static void onStart(ANativeActivity* activity)
+{
+ RARCH_LOG("Start: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)
+ activity->instance, APP_CMD_START);
+}
+
+static void onResume(ANativeActivity* activity)
+{
+ RARCH_LOG("Resume: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)
+ activity->instance, APP_CMD_RESUME);
+}
+
+static void onPause(ANativeActivity* activity)
+{
+ RARCH_LOG("Pause: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)
+ activity->instance, APP_CMD_PAUSE);
+}
+
+static void onStop(ANativeActivity* activity)
+{
+ RARCH_LOG("Stop: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)
+ activity->instance, APP_CMD_STOP);
+}
+
+static void onConfigurationChanged(ANativeActivity *activity)
+{
+ struct android_app* android_app = (struct android_app*)
+ activity->instance;
+
+ if (!android_app)
+ return;
+
+ RARCH_LOG("ConfigurationChanged: %p\n", activity);
+ android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
+}
+
+static void onWindowFocusChanged(ANativeActivity* activity, int focused)
+{
+ RARCH_LOG("WindowFocusChanged: %p -- %d\n", activity, focused);
+ android_app_write_cmd((struct android_app*)activity->instance,
+ focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
+}
+
+static void onNativeWindowCreated(ANativeActivity* activity,
+ ANativeWindow* window)
+{
+ RARCH_LOG("NativeWindowCreated: %p -- %p\n", activity, window);
+ android_app_set_window((struct android_app*)activity->instance, window);
+}
+
+static void onNativeWindowDestroyed(ANativeActivity* activity,
+ ANativeWindow* window)
+{
+ RARCH_LOG("NativeWindowDestroyed: %p -- %p\n", activity, window);
+ android_app_set_window((struct android_app*)activity->instance, NULL);
+}
+
+static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue)
+{
+ RARCH_LOG("InputQueueCreated: %p -- %p\n", activity, queue);
+ android_app_set_input((struct android_app*)activity->instance, queue);
+}
+
+static void onInputQueueDestroyed(ANativeActivity* activity,
+ AInputQueue* queue)
+{
+ RARCH_LOG("InputQueueDestroyed: %p -- %p\n", activity, queue);
+ android_app_set_input((struct android_app*)activity->instance, NULL);
+}
+
+JNIEnv *jni_thread_getenv(void)
+{
+ JNIEnv *env;
+ struct android_app* android_app = (struct android_app*)g_android;
+ int status = (*android_app->activity->vm)->
+ AttachCurrentThread(android_app->activity->vm, &env, 0);
+
+ if (status < 0)
+ {
+ RARCH_ERR("jni_thread_getenv: Failed to attach current thread.\n");
+ return NULL;
+ }
+ pthread_setspecific(thread_key, (void*)env);
+
+ return env;
+}
+
+static void jni_thread_destruct(void *value)
+{
+ JNIEnv *env = (JNIEnv*)value;
+ struct android_app *android_app = (struct android_app*)g_android;
+ RARCH_LOG("jni_thread_destruct()\n");
+
+ if (!env)
+ return;
+
+ if (android_app)
+ (*android_app->activity->vm)->
+ DetachCurrentThread(android_app->activity->vm);
+ pthread_setspecific(thread_key, NULL);
+}
+
+static void android_app_entry(void *data)
+{
+ char *argv[1];
+ int argc = 0;
+ int ret = 0;
+
+ if (rarch_main(argc, argv, data) != 0)
+ goto end;
+#ifndef HAVE_MAIN
+ do
+ {
+ unsigned sleep_ms = 0;
+ ret = rarch_main_iterate(&sleep_ms);
+
+ if (ret == 1 && sleep_ms > 0)
+ retro_sleep(sleep_ms);
+ rarch_main_data_iterate();
+ }while (ret != -1);
+
+ main_exit(data);
+#endif
+
+end:
+ exit(0);
+}
+
+/*
+ * Native activity interaction (called from main thread)
+ **/
+
+void ANativeActivity_onCreate(ANativeActivity* activity,
+ void* savedState, size_t savedStateSize)
+{
+ int msgpipe[2];
+ struct android_app* android_app;
+
+ (void)savedState;
+ (void)savedStateSize;
+
+ RARCH_LOG("Creating Native Activity: %p\n", activity);
+ activity->callbacks->onDestroy = onDestroy;
+ activity->callbacks->onStart = onStart;
+ activity->callbacks->onResume = onResume;
+ activity->callbacks->onSaveInstanceState = NULL;
+ activity->callbacks->onPause = onPause;
+ activity->callbacks->onStop = onStop;
+ activity->callbacks->onConfigurationChanged = onConfigurationChanged;
+ activity->callbacks->onLowMemory = NULL;
+ activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
+ activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
+ activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
+ activity->callbacks->onInputQueueCreated = onInputQueueCreated;
+ activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
+
+ /* These are set only for the native activity,
+ * and are reset when it ends. */
+ ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_KEEP_SCREEN_ON
+ | AWINDOW_FLAG_FULLSCREEN, 0);
+
+ if (pthread_key_create(&thread_key, jni_thread_destruct))
+ RARCH_ERR("Error initializing pthread_key\n");
+
+ android_app = (struct android_app*)calloc(1, sizeof(*android_app));
+ if (!android_app)
+ {
+ RARCH_ERR("Failed to initialize android_app\n");
+ return;
+ }
+
+ memset(android_app, 0, sizeof(struct android_app));
+
+ android_app->activity = activity;
+ android_app->mutex = slock_new();
+ android_app->cond = scond_new();
+
+ if (pipe(msgpipe))
+ {
+ RARCH_ERR("could not create pipe: %s.\n", strerror(errno));
+ activity->instance = NULL;
+ }
+ android_app->msgread = msgpipe[0];
+ android_app->msgwrite = msgpipe[1];
+
+ android_app->thread = sthread_create(android_app_entry, android_app);
+
+ /* Wait for thread to start. */
+ slock_lock(android_app->mutex);
+ while (!android_app->running)
+ scond_wait(android_app->cond, android_app->mutex);
+ slock_unlock(android_app->mutex);
+
+ activity->instance = android_app;
+}
+
+
+int system_property_get(const char *name, char *value)
+{
+ FILE *pipe;
+ int length = 0;
+ char buffer[PATH_MAX_LENGTH] = {0};
+ char cmd[PATH_MAX_LENGTH] = {0};
+ char *curpos = NULL;
+
+ snprintf(cmd, sizeof(cmd), "getprop %s", name);
+
+ pipe = popen(cmd, "r");
+
+ if (!pipe)
+ {
+ RARCH_ERR("Could not create pipe.\n");
+ return 0;
+ }
+
+ curpos = value;
+
+ while (!feof(pipe))
+ {
+ if (fgets(buffer, 128, pipe) != NULL)
+ {
+ int curlen = strlen(buffer);
+
+ memcpy(curpos, buffer, curlen);
+
+ curpos += curlen;
+ length += curlen;
+ }
+ }
+
+ *curpos = '\0';
+
+ pclose(pipe);
+
+ return length;
+}
+
+static void frontend_android_get_name(char *s, size_t len)
+{
+ system_property_get("ro.product.model", s);
+}
+
+static void frontend_android_get_version(int32_t *major,
+ int32_t *minor, int32_t *rel)
+{
+ char os_version_str[PROP_VALUE_MAX] = {0};
+ system_property_get("ro.build.version.release", os_version_str);
+
+ *major = 0;
+ *minor = 0;
+ *rel = 0;
+
+ /* Parse out the OS version numbers from the system properties. */
+ if (os_version_str[0])
+ {
+ /* Try to parse out the version numbers from the string. */
+ int num_read = sscanf(os_version_str, "%d.%d.%d", major, minor, rel);
+
+ if (num_read > 0)
+ {
+ if (num_read < 2)
+ *minor = 0;
+ if (num_read < 3)
+ *rel = 0;
+ return;
+ }
+ }
+}
+
+static void frontend_android_get_version_sdk(int32_t *sdk)
+{
+ char os_version_str[PROP_VALUE_MAX] = {0};
+ system_property_get("ro.build.version.sdk", os_version_str);
+
+ *sdk = 0;
+ if (os_version_str[0])
+ {
+ int num_read = sscanf(os_version_str, "%d", sdk);
+ (void) num_read;
+ }
+}
+
+static bool device_is_xperia_play(const char *name)
+{
+ if (
+ !strcmp(name, "R800x") ||
+ !strcmp(name, "R800at") ||
+ !strcmp(name, "R800i") ||
+ !strcmp(name, "R800a") ||
+ !strcmp(name, "SO-01D")
+ )
+ return true;
+
+ return false;
+}
+
+static bool device_is_game_console(const char *name)
+{
+ if (
+ !strcmp(name, "OUYA Console") ||
+ device_is_xperia_play(name) ||
+ !strcmp(name, "GAMEMID_BT") ||
+ !strcmp(name, "S7800") ||
+ !strcmp(name, "SHIELD")
+ )
+ return true;
+
+ return false;
+}
+
+bool test_permissions(const char *path)
+{
+ char buf[PATH_MAX_LENGTH];
+ bool ret;
+
+ RARCH_LOG("Testing permissions for %s\n",path);
+
+ fill_pathname_join(buf, path, ".retroarch", sizeof(buf));
+ ret = path_mkdir(buf);
+
+ RARCH_LOG("Create %s %s\n", buf, ret ? "true" : "false");
+
+ if(ret)
+ rmdir(buf);
+
+ return ret;
+}
+
+static void frontend_android_shutdown(bool unused)
+{
+ (void)unused;
+ /* Cleaner approaches don't work sadly. */
+ exit(0);
+}
+
+#else
static const char *proc_apm_path = "/proc/apm";
static const char *proc_acpi_battery_path = "/proc/acpi/battery";
-static const char *proc_acpi_sys_ac_adapter_path= "/sys/class/power_supply/ACAD";
-static const char *proc_acpi_sys_battery_path= "/sys/class/power_supply";
+static const char *proc_acpi_sysfs_ac_adapter_path= "/sys/class/power_supply/ACAD";
+static const char *proc_acpi_sysfs_battery_path= "/sys/class/power_supply";
static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter";
-static bool load_power_file(const char *path, char *buf, size_t buflen)
-{
- ssize_t br = 0;
- const int fd = open(path, O_RDONLY);
- if (fd == -1)
- return false;
- br = read(fd, buf, buflen-1);
- close(fd);
- if (br < 0)
- return false;
- buf[br] = '\0'; /* null-terminate the string. */
-
- return true;
-}
static bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val)
{
@@ -101,15 +971,15 @@ static bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val)
#define ACPI_VAL_YES 0x0b88c316U
#define ACPI_VAL_ONLINE 0x6842bf17U
-static void
-check_proc_acpi_battery(const char * node, bool * have_battery,
+static void check_proc_acpi_battery(const char * node, bool * have_battery,
bool * charging, int *seconds, int *percent)
{
const char *base = proc_acpi_battery_path;
char path[1024];
- char info[1024] = {0};
- char state[1024] = {0};
+ ssize_t length = 0;
char *ptr = NULL;
+ char *buf = NULL;
+ char *buf_info = NULL;
char *key = NULL;
char *val = NULL;
bool charge = false;
@@ -121,14 +991,14 @@ check_proc_acpi_battery(const char * node, bool * have_battery,
snprintf(path, sizeof(path), "%s/%s/%s", base, node, "state");
- if (!load_power_file(path, state, sizeof (state)))
- return;
+ if (!retro_read_file(path, (void**)&buf, &length))
+ goto end;
snprintf(path, sizeof(path), "%s/%s/%s", base, node, "info");
- if (!load_power_file(path, info, sizeof (info)))
- return;
+ if (!retro_read_file(path, (void**)&buf_info, &length))
+ goto end;
- ptr = &state[0];
+ ptr = &buf[0];
while (make_proc_acpi_key_val(&ptr, &key, &val))
{
@@ -162,7 +1032,7 @@ check_proc_acpi_battery(const char * node, bool * have_battery,
}
}
- ptr = &info[0];
+ ptr = &buf_info[0];
while (make_proc_acpi_key_val(&ptr, &key, &val))
{
@@ -213,20 +1083,29 @@ check_proc_acpi_battery(const char * node, bool * have_battery,
*percent = pct;
*charging = charge;
}
+
+end:
+ if (buf_info)
+ free(buf_info);
+ if (buf)
+ free(buf);
+ buf = NULL;
+ buf_info = NULL;
}
-static void
-check_proc_acpi_sys_battery(const char * node, bool * have_battery,
+static void check_proc_acpi_sysfs_battery(const char * node, bool * have_battery,
bool * charging, int *seconds, int *percent)
{
unsigned capacity;
- char path[1024], info[1024], state[1024];
- const char *base = proc_acpi_sys_battery_path;
+ char path[1024], info[1024];
+ const char *base = proc_acpi_sysfs_battery_path;
+ char *buf = NULL;
char *ptr = NULL;
char *key = NULL;
char *val = NULL;
bool charge = false;
bool choose = false;
+ ssize_t length = 0;
int maximum = -1;
int remaining = -1;
int secs = -1;
@@ -236,39 +1115,43 @@ check_proc_acpi_sys_battery(const char * node, bool * have_battery,
return;
snprintf(path, sizeof(path), "%s/%s/%s", base, node, "status");
- if (!load_power_file(path, state, sizeof (state)))
+ if (retro_read_file(path, (void**)&buf, &length) != 1)
return;
- if (strstr(state, "Discharging"))
+ if (strstr((char*)buf, "Discharging"))
*have_battery = true;
- else if (strstr(state, "Full"))
+ else if (strstr((char*)buf, "Full"))
*have_battery = true;
snprintf(path, sizeof(path), "%s/%s/%s", base, node, "capacity");
- if (!load_power_file(path, state, sizeof (state)))
- return;
+ if (retro_read_file(path, (void**)&buf, &length) != 1)
+ goto end;
- capacity = atoi(state);
+ capacity = atoi(buf);
*percent = capacity;
+
+end:
+ if (buf)
+ free(buf);
+ buf = NULL;
}
-
-static void
-check_proc_acpi_ac_adapter(const char * node, bool *have_ac)
+static void check_proc_acpi_ac_adapter(const char * node, bool *have_ac)
{
char path[1024];
const char *base = proc_acpi_ac_adapter_path;
- char state[256] = {0};
+ char *buf = NULL;
char *ptr = NULL;
char *key = NULL;
char *val = NULL;
+ ssize_t length = 0;
snprintf(path, sizeof(path), "%s/%s/%s", base, node, "state");
- if (!load_power_file(path, state, sizeof (state)))
+ if (retro_read_file(path, (void**)&buf, &length) != 1)
return;
- ptr = &state[0];
+ ptr = &buf[0];
while (make_proc_acpi_key_val(&ptr, &key, &val))
{
uint32_t key_hash = djb2_calculate(key);
@@ -278,20 +1161,29 @@ check_proc_acpi_ac_adapter(const char * node, bool *have_ac)
val_hash == ACPI_VAL_ONLINE)
*have_ac = true;
}
+
+ if (buf)
+ free(buf);
+ buf = NULL;
}
-static void
-check_proc_acpi_sys_ac_adapter(const char * node, bool *have_ac)
+static void check_proc_acpi_sysfs_ac_adapter(const char * node, bool *have_ac)
{
- char state[256], path[1024];
- const char *base = proc_acpi_sys_ac_adapter_path;
+ char path[1024];
+ ssize_t length = 0;
+ char *buf = NULL;
+ const char *base = proc_acpi_sysfs_ac_adapter_path;
- snprintf(path, sizeof(path), "%s/%s/%s", base, node, "online");
- if (!load_power_file(path, state, sizeof (state)))
+ snprintf(path, sizeof(path), "%s/%s", base, "online");
+ if (retro_read_file(path, (void**)&buf, &length) != 1)
return;
- if (strstr(state, "1"))
+ if (strstr((char*)buf, "1"))
*have_ac = true;
+
+ if (buf)
+ free(buf);
+ buf = NULL;
}
static bool next_string(char **_ptr, char **_str)
@@ -328,54 +1220,56 @@ static bool frontend_linux_powerstate_check_apm(
enum frontend_powerstate *state,
int *seconds, int *percent)
{
- char buf[128], *ptr;
+ char *ptr;
int ac_status = 0;
int battery_status = 0;
int battery_flag = 0;
int battery_percent = 0;
int battery_time = 0;
+ ssize_t length = 0;
+ char *buf = NULL;
char *str = NULL;
- if (!load_power_file(proc_apm_path, buf, sizeof(buf)))
- return false;
+ if (retro_read_file(proc_apm_path, (void**)&buf, &length) != 1)
+ goto error;
ptr = &buf[0];
if (!next_string(&ptr, &str)) /* driver version */
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* BIOS version */
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* APM flags */
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* AC line status */
- return false;
+ goto error;
else if (!int_string(str, &ac_status))
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* battery status */
- return false;
+ goto error;
else if (!int_string(str, &battery_status))
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* battery flag */
- return false;
+ goto error;
else if (!int_string(str, &battery_flag))
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* remaining battery life percent */
- return false;
+ goto error;
if (str[strlen(str) - 1] == '%')
str[strlen(str) - 1] = '\0';
if (!int_string(str, &battery_percent))
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* remaining battery life time */
- return false;
+ goto error;
else if (!int_string(str, &battery_time))
- return false;
+ goto error;
if (!next_string(&ptr, &str)) /* remaining battery life time units */
- return false;
+ goto error;
else if (!strcmp(str, "min"))
battery_time *= 60;
@@ -395,7 +1289,18 @@ static bool frontend_linux_powerstate_check_apm(
if (battery_time >= 0) /* -1 == unknown */
*seconds = battery_time;
+ if (buf)
+ free(buf);
+ buf = NULL;
+
return true;
+
+error:
+ if (buf)
+ free(buf);
+ buf = NULL;
+
+ return false;
}
static bool frontend_linux_powerstate_check_acpi(
@@ -448,8 +1353,7 @@ end:
return ret;
}
-static bool frontend_linux_powerstate_check_acpi_sys(
- enum frontend_powerstate *state,
+static bool frontend_linux_powerstate_check_acpi_sysfs(enum frontend_powerstate *state,
int *seconds, int *percent)
{
bool ret = false;
@@ -460,7 +1364,7 @@ static bool frontend_linux_powerstate_check_acpi_sys(
*state = FRONTEND_POWERSTATE_NONE;
- entry = retro_opendir(proc_acpi_sys_battery_path);
+ entry = retro_opendir(proc_acpi_sysfs_battery_path);
if (!entry)
goto error;
@@ -468,17 +1372,16 @@ static bool frontend_linux_powerstate_check_acpi_sys(
goto error;
while (retro_readdir(entry))
- check_proc_acpi_sys_battery(retro_dirent_get_name(entry),
+ check_proc_acpi_sysfs_battery(retro_dirent_get_name(entry),
&have_battery, &charging, seconds, percent);
retro_closedir(entry);
- entry = retro_opendir(proc_acpi_sys_ac_adapter_path);
+ entry = retro_opendir(proc_acpi_sysfs_ac_adapter_path);
if (!entry)
goto error;
- while (retro_readdir(entry))
- check_proc_acpi_sys_ac_adapter(retro_dirent_get_name(entry), &have_ac);
+ check_proc_acpi_sysfs_ac_adapter(retro_dirent_get_name(entry), &have_ac);
if (!have_battery)
{
@@ -499,22 +1402,42 @@ error:
return false;
}
+#endif
-static enum frontend_powerstate
-frontend_linux_get_powerstate(int *seconds, int *percent)
+static int frontend_linux_get_rating(void)
+{
+#ifdef ANDROID
+ char device_model[PROP_VALUE_MAX] = {0};
+ frontend_android_get_name(device_model, sizeof(device_model));
+
+ RARCH_LOG("ro.product.model: (%s).\n", device_model);
+
+ if (device_is_xperia_play(device_model))
+ return 6;
+ else if (!strcmp(device_model, "GT-I9505"))
+ return 12;
+ else if (!strcmp(device_model, "SHIELD"))
+ return 13;
+#endif
+ return -1;
+}
+
+static enum frontend_powerstate frontend_linux_get_powerstate(int *seconds, int *percent)
{
enum frontend_powerstate ret = FRONTEND_POWERSTATE_NONE;
- if (frontend_linux_powerstate_check_apm(&ret, seconds, percent))
+#ifndef ANDROID
+ if (frontend_linux_powerstate_check_acpi_sysfs(&ret, seconds, percent))
return ret;
if (frontend_linux_powerstate_check_acpi(&ret, seconds, percent))
return ret;
- if (frontend_linux_powerstate_check_acpi_sys(&ret, seconds, percent))
+ if (frontend_linux_powerstate_check_apm(&ret, seconds, percent))
return ret;
+#endif
- return FRONTEND_POWERSTATE_NONE;
+ return ret;
}
#define LINUX_ARCH_X86_64 0x23dea434U
@@ -524,18 +1447,35 @@ frontend_linux_get_powerstate(int *seconds, int *percent)
#define LINUX_ARCH_MIPS 0x7c9aa25eU
#define LINUX_ARCH_TILE 0x7c9e7873U
+#define ANDROID_ARCH_ARMV7 0x26257a91U
+#define ANDROID_ARCH_ARM 0x406a3516U
+
static enum frontend_architecture frontend_linux_get_architecture(void)
{
uint32_t buffer_hash;
+ const char *val;
+#ifdef ANDROID
+ char abi[PROP_VALUE_MAX] = {0};
+ system_property_get("ro.product.cpu.abi", abi);
+ val = abi;
+#else
struct utsname buffer;
if (uname(&buffer) != 0)
return FRONTEND_ARCH_NONE;
- buffer_hash = djb2_calculate(buffer.machine);
+ val = buffer.machine;
+#endif
+ buffer_hash = djb2_calculate(val);
switch (buffer_hash)
{
+#ifdef ANDROID
+ case ANDROID_ARCH_ARMV7:
+ return FRONTEND_ARCH_ARM;
+ case ANDROID_ARCH_ARM:
+ return FRONTEND_ARCH_ARM;
+#endif
case LINUX_ARCH_X86_64:
return FRONTEND_ARCH_X86_64;
case LINUX_ARCH_X86:
@@ -555,6 +1495,12 @@ static enum frontend_architecture frontend_linux_get_architecture(void)
static void frontend_linux_get_os(char *s, size_t len, int *major, int *minor)
{
+#ifdef ANDROID
+ int rel;
+ frontend_android_get_version(major, minor, &rel);
+
+ strlcpy(s, "Android", len);
+#else
unsigned krel;
struct utsname buffer;
@@ -563,23 +1509,616 @@ static void frontend_linux_get_os(char *s, size_t len, int *major, int *minor)
sscanf(buffer.release, "%d.%d.%u", major, minor, &krel);
strlcpy(s, "Linux", len);
+#endif
}
+static void frontend_linux_get_env(int *argc,
+ char *argv[], void *data, void *params_data)
+{
+#ifdef ANDROID
+ int32_t major, minor, rel;
+ int perms = 0;
+ char device_model[PROP_VALUE_MAX] = {0};
+ char device_id[PROP_VALUE_MAX] = {0};
+ struct rarch_main_wrap *args = NULL;
+ JNIEnv *env = NULL;
+ jobject obj = NULL;
+ jstring jstr = NULL;
+ struct android_app *android_app = (struct android_app*)data;
+ char buf[PATH_MAX_LENGTH] = {0};
+
+ if (!android_app)
+ return;
+
+ env = jni_thread_getenv();
+ if (!env)
+ return;
+
+ args = (struct rarch_main_wrap*)params_data;
+
+ if (args)
+ {
+ args->touched = true;
+ args->no_content = false;
+ args->verbose = false;
+ args->sram_path = NULL;
+ args->state_path = NULL;
+ }
+
+ frontend_android_get_version(&major, &minor, &rel);
+
+ RARCH_LOG("Android OS version (major : %d, minor : %d, rel : %d)\n",
+ major, minor, rel);
+
+ CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
+ android_app->getIntent);
+ RARCH_LOG("Checking arguments passed from intent ...\n");
+
+ /* Config file. */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "CONFIGFILE"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ static char config_path[PATH_MAX_LENGTH] = {0};
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ if (argv && *argv)
+ strlcpy(config_path, argv, sizeof(config_path));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ RARCH_LOG("Config file: [%s].\n", config_path);
+ if (args && *config_path)
+ args->config_path = config_path;
+ }
+
+ /* Current IME. */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "IME"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ strlcpy(android_app->current_ime, argv,
+ sizeof(android_app->current_ime));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ RARCH_LOG("Current IME: [%s].\n", android_app->current_ime);
+ }
+
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "USED"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+ bool used = (!strcmp(argv, "false")) ? false : true;
+
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ RARCH_LOG("USED: [%s].\n", used ? "true" : "false");
+ }
+
+ /* LIBRETRO. */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "LIBRETRO"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ static char core_path[PATH_MAX_LENGTH];
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *core_path = '\0';
+ if (argv && *argv)
+ strlcpy(core_path, argv, sizeof(core_path));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ RARCH_LOG("Libretro path: [%s]\n", core_path);
+ if (args && *core_path)
+ args->libretro_path = core_path;
+ }
+
+ /* Content. */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "ROM"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ static char path[PATH_MAX_LENGTH];
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *path = '\0';
+
+ if (argv && *argv)
+ strlcpy(path, argv, sizeof(path));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*path)
+ {
+ RARCH_LOG("Auto-start game %s.\n", path);
+ if (args && *path)
+ args->content_path = path;
+ }
+ }
+
+ /* External Storage */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "SDCARD"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *sdcard_dir = '\0';
+
+ if (argv && *argv)
+ strlcpy(sdcard_dir, argv, sizeof(sdcard_dir));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*sdcard_dir)
+ {
+ RARCH_LOG("External storage location [%s]\n", sdcard_dir);
+ /* TODO base dir handler */
+ }
+ }
+
+ /* Screenshots */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "SCREENSHOTS"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *screenshot_dir = '\0';
+
+ if (argv && *argv)
+ strlcpy(screenshot_dir, argv, sizeof(screenshot_dir));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*screenshot_dir)
+ {
+ RARCH_LOG("Picture folder location [%s]\n", screenshot_dir);
+ /* TODO: screenshot handler */
+ }
+ }
+
+ /* Downloads */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "DOWNLOADS"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *downloads_dir = '\0';
+
+ if (argv && *argv)
+ strlcpy(downloads_dir, argv, sizeof(downloads_dir));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*downloads_dir)
+ {
+ RARCH_LOG("Download folder location [%s].\n", downloads_dir);
+ /* TODO: downloads handler */
+ }
+ }
+
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "APK"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *apk_path = '\0';
+
+ if (argv && *argv)
+ strlcpy(apk_path, argv, sizeof(apk_path));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*apk_path)
+ {
+ RARCH_LOG("APK location [%s].\n", apk_path);
+ }
+ }
+
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "EXTERNAL"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *ext_dir = '\0';
+
+ if (argv && *argv)
+ strlcpy(ext_dir, argv, sizeof(ext_dir));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ if (*ext_dir)
+ {
+ RARCH_LOG("External files location [%s]\n", ext_dir);
+ }
+ }
+
+ /* Content. */
+ CALL_OBJ_METHOD_PARAM(env, jstr, obj, android_app->getStringExtra,
+ (*env)->NewStringUTF(env, "DATADIR"));
+
+ if (android_app->getStringExtra && jstr)
+ {
+ const char *argv = (*env)->GetStringUTFChars(env, jstr, 0);
+
+ *app_dir = '\0';
+
+ if (argv && *argv)
+ strlcpy(app_dir, argv, sizeof(app_dir));
+ (*env)->ReleaseStringUTFChars(env, jstr, argv);
+
+ //set paths depending on the ability to write to sdcard_dir
+
+ if(*sdcard_dir)
+ {
+ if(test_permissions(sdcard_dir))
+ perms = SDCARD_ROOT_WRITABLE;
+ }
+ else if(*ext_dir)
+ {
+ if(test_permissions(ext_dir))
+ perms = SDCARD_EXT_DIR_WRITABLE;
+ }
+ else
+ perms = SDCARD_NOT_WRITABLE;
+
+ RARCH_LOG("SD permissions: %d",perms);
+
+ if (*app_dir)
+ {
+ RARCH_LOG("Application location: [%s].\n", app_dir);
+ if (args && *app_dir)
+ {
+ fill_pathname_join(g_defaults.dir.assets, app_dir,
+ "assets", sizeof(g_defaults.dir.assets));
+ fill_pathname_join(g_defaults.dir.extraction, app_dir,
+ "tmp", sizeof(g_defaults.dir.extraction));
+ fill_pathname_join(g_defaults.dir.shader, app_dir,
+ "shaders", sizeof(g_defaults.dir.shader));
+ fill_pathname_join(g_defaults.dir.overlay, app_dir,
+ "overlays", sizeof(g_defaults.dir.overlay));
+ fill_pathname_join(g_defaults.dir.osk_overlay, app_dir,
+ "overlays", sizeof(g_defaults.dir.osk_overlay));
+ fill_pathname_join(g_defaults.dir.core, app_dir,
+ "cores", sizeof(g_defaults.dir.core));
+ fill_pathname_join(g_defaults.dir.core_info,
+ app_dir, "info", sizeof(g_defaults.dir.core_info));
+ fill_pathname_join(g_defaults.dir.autoconfig,
+ app_dir, "autoconfig", sizeof(g_defaults.dir.autoconfig));
+ fill_pathname_join(g_defaults.dir.audio_filter,
+ app_dir, "audio_filters", sizeof(g_defaults.dir.audio_filter));
+ fill_pathname_join(g_defaults.dir.video_filter,
+ app_dir, "video_filters", sizeof(g_defaults.dir.video_filter));
+ strlcpy(g_defaults.dir.content_history,
+ app_dir, sizeof(g_defaults.dir.content_history));
+ fill_pathname_join(g_defaults.dir.database,
+ app_dir, "database/rdb", sizeof(g_defaults.dir.database));
+ fill_pathname_join(g_defaults.dir.cursor,
+ app_dir, "database/cursors", sizeof(g_defaults.dir.cursor));
+ fill_pathname_join(g_defaults.dir.cheats,
+ app_dir, "cheats", sizeof(g_defaults.dir.cheats));
+ fill_pathname_join(g_defaults.dir.playlist,
+ app_dir, "playlists", sizeof(g_defaults.dir.playlist));
+ fill_pathname_join(g_defaults.dir.remap,
+ app_dir, "remaps", sizeof(g_defaults.dir.remap));
+ fill_pathname_join(g_defaults.dir.wallpapers,
+ app_dir, "wallpapers", sizeof(g_defaults.dir.wallpapers));
+ if(*downloads_dir && test_permissions(downloads_dir))
+ {
+ fill_pathname_join(g_defaults.dir.core_assets,
+ downloads_dir, "", sizeof(g_defaults.dir.core_assets));
+ }
+ else
+ {
+ fill_pathname_join(g_defaults.dir.core_assets,
+ app_dir, "downloads", sizeof(g_defaults.dir.core_assets));
+ path_mkdir(g_defaults.dir.core_assets);
+ }
+
+ RARCH_LOG("Default download folder: [%s]", g_defaults.dir.core_assets);
+
+ if(*screenshot_dir && test_permissions(screenshot_dir))
+ {
+ fill_pathname_join(g_defaults.dir.screenshot,
+ screenshot_dir, "", sizeof(g_defaults.dir.screenshot));
+ }
+ else
+ {
+ fill_pathname_join(g_defaults.dir.screenshot,
+ app_dir, "screenshots", sizeof(g_defaults.dir.screenshot));
+ path_mkdir(g_defaults.dir.screenshot);
+ }
+
+ RARCH_LOG("Default screenshot folder: [%s]", g_defaults.dir.screenshot);
+
+ switch (perms)
+ {
+ case SDCARD_EXT_DIR_WRITABLE:
+ fill_pathname_join(g_defaults.dir.sram,
+ ext_dir, "saves", sizeof(g_defaults.dir.sram));
+ path_mkdir(g_defaults.dir.sram);
+
+ fill_pathname_join(g_defaults.dir.savestate,
+ ext_dir, "states", sizeof(g_defaults.dir.savestate));
+ path_mkdir(g_defaults.dir.savestate);
+
+ fill_pathname_join(g_defaults.dir.system,
+ ext_dir, "system", sizeof(g_defaults.dir.system));
+ path_mkdir(g_defaults.dir.system);
+ break;
+ case SDCARD_NOT_WRITABLE:
+ fill_pathname_join(g_defaults.dir.sram,
+ app_dir, "saves", sizeof(g_defaults.dir.sram));
+ path_mkdir(g_defaults.dir.sram);
+ fill_pathname_join(g_defaults.dir.savestate,
+ app_dir, "states", sizeof(g_defaults.dir.savestate));
+ path_mkdir(g_defaults.dir.savestate);
+ fill_pathname_join(g_defaults.dir.system,
+ app_dir, "system", sizeof(g_defaults.dir.system));
+ path_mkdir(g_defaults.dir.system);
+ break;
+ case SDCARD_ROOT_WRITABLE:
+ default:
+ break;
+ }
+
+ /* create save and system directories in the internal dir too */
+ fill_pathname_join(buf,
+ app_dir, "saves", sizeof(buf));
+ path_mkdir(buf);
+
+ fill_pathname_join(buf,
+ app_dir, "states", sizeof(buf));
+ path_mkdir(buf);
+
+ fill_pathname_join(buf,
+ app_dir, "system", sizeof(buf));
+ path_mkdir(buf);
+
+ /* create save and system directories in the internal sd too */
+
+ fill_pathname_join(buf,
+ ext_dir, "saves", sizeof(buf));
+ path_mkdir(buf);
+
+ fill_pathname_join(buf,
+ ext_dir, "states", sizeof(buf));
+ path_mkdir(buf);
+
+ fill_pathname_join(buf,
+ ext_dir, "system", sizeof(buf));
+ path_mkdir(buf);
+
+ RARCH_LOG("Default savefile folder: [%s]", g_defaults.dir.sram);
+ RARCH_LOG("Default savestate folder: [%s]", g_defaults.dir.savestate);
+ RARCH_LOG("Default system folder: [%s]", g_defaults.dir.system);
+ }
+ }
+ }
+
+ frontend_android_get_name(device_model, sizeof(device_model));
+ system_property_get("ro.product.id", device_id);
+
+ g_defaults.settings.video_threaded_enable = true;
+
+ /* Set automatic default values per device */
+ if (device_is_xperia_play(device_model))
+ {
+ g_defaults.settings.out_latency = 128;
+ g_defaults.settings.video_refresh_rate = 59.19132938771038;
+ g_defaults.settings.video_threaded_enable = false;
+ }
+ else if (!strcmp(device_model, "GAMEMID_BT"))
+ g_defaults.settings.out_latency = 160;
+ else if (!strcmp(device_model, "SHIELD"))
+ g_defaults.settings.video_refresh_rate = 60.0;
+ else if (!strcmp(device_model, "JSS15J"))
+ g_defaults.settings.video_refresh_rate = 59.65;
+
+#if 0
+ /* Explicitly disable input overlay by default
+ * for gamepad-like/console devices. */
+ if (device_is_game_console(device_model))
+ g_defaults.settings.input_overlay_enable = false;
+#endif
+#else
+ char base_path[PATH_MAX];
+ const char *xdg = getenv("XDG_CONFIG_HOME");
+ const char *home = getenv("HOME");
+
+ if (xdg)
+ snprintf(base_path, sizeof(base_path), "%s/retroarch", xdg);
+ else if (home)
+ snprintf(base_path, sizeof(base_path), "%s/.config/retroarch", home);
+ else
+ snprintf(base_path, sizeof(base_path), "retroarch");
+
+ fill_pathname_join(g_defaults.dir.core, base_path,
+ "cores", sizeof(g_defaults.dir.core));
+ fill_pathname_join(g_defaults.dir.core_info, base_path,
+ "cores", sizeof(g_defaults.dir.core_info));
+ fill_pathname_join(g_defaults.dir.autoconfig, base_path,
+ "autoconf", sizeof(g_defaults.dir.autoconfig));
+ fill_pathname_join(g_defaults.dir.assets, base_path,
+ "assets", sizeof(g_defaults.dir.assets));
+ fill_pathname_join(g_defaults.dir.remap, base_path,
+ "remap", sizeof(g_defaults.dir.remap));
+ fill_pathname_join(g_defaults.dir.playlist, base_path,
+ "playlists", sizeof(g_defaults.dir.playlist));
+ fill_pathname_join(g_defaults.dir.cursor, base_path,
+ "database/cursors", sizeof(g_defaults.dir.cursor));
+ fill_pathname_join(g_defaults.dir.database, base_path,
+ "database/rdb", sizeof(g_defaults.dir.database));
+ fill_pathname_join(g_defaults.dir.shader, base_path,
+ "shaders", sizeof(g_defaults.dir.shader));
+ fill_pathname_join(g_defaults.dir.cheats, base_path,
+ "cheats", sizeof(g_defaults.dir.cheats));
+ fill_pathname_join(g_defaults.dir.overlay, base_path,
+ "overlay", sizeof(g_defaults.dir.overlay));
+ fill_pathname_join(g_defaults.dir.osk_overlay, base_path,
+ "overlay", sizeof(g_defaults.dir.osk_overlay));
+
+ if(home)
+ {
+ fill_pathname_join(g_defaults.dir.screenshot, home,
+ "Pictures", sizeof(g_defaults.dir.screenshot));
+ fill_pathname_join(g_defaults.dir.core_assets, home,
+ "Downloads", sizeof(g_defaults.dir.core_assets));
+ }
+ else
+ {
+ fill_pathname_join(g_defaults.dir.screenshot, home,
+ "retroArch/screenshots", sizeof(g_defaults.dir.screenshot));
+ fill_pathname_join(g_defaults.dir.core_assets, home,
+ "retroarch/downloads", sizeof(g_defaults.dir.core_assets));
+ }
+#endif
+}
+
+static void frontend_linux_deinit(void *data)
+{
+#ifdef ANDROID
+ JNIEnv *env = NULL;
+ struct android_app *android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ RARCH_LOG("Deinitializing RetroArch ...\n");
+ android_app->activityState = APP_CMD_DEAD;
+
+ env = jni_thread_getenv();
+
+ if (env && android_app->onRetroArchExit)
+ CALL_VOID_METHOD(env, android_app->activity->clazz,
+ android_app->onRetroArchExit);
+
+ if (android_app->inputQueue)
+ {
+ RARCH_LOG("Detaching Android input queue looper ...\n");
+ AInputQueue_detachLooper(android_app->inputQueue);
+ }
+#endif
+}
+
+static void frontend_linux_init(void *data)
+{
+#ifdef ANDROID
+ JNIEnv *env = NULL;
+ ALooper *looper = NULL;
+ jclass class = NULL;
+ jobject obj = NULL;
+ struct android_app* android_app = (struct android_app*)data;
+
+ if (!android_app)
+ return;
+
+ looper = (ALooper*)ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+ ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN,
+ ALOOPER_EVENT_INPUT, NULL, NULL);
+ android_app->looper = looper;
+
+ slock_lock(android_app->mutex);
+ android_app->running = 1;
+ scond_broadcast(android_app->cond);
+ slock_unlock(android_app->mutex);
+
+ memset(&g_android, 0, sizeof(g_android));
+ g_android = (struct android_app*)android_app;
+
+ RARCH_LOG("Waiting for Android Native Window to be initialized ...\n");
+
+ while (!android_app->window)
+ {
+ if (!android_run_events(android_app))
+ {
+ frontend_linux_deinit(android_app);
+ frontend_android_shutdown(android_app);
+ return;
+ }
+ }
+
+ RARCH_LOG("Android Native Window initialized.\n");
+
+ env = jni_thread_getenv();
+ if (!env)
+ return;
+
+ GET_OBJECT_CLASS(env, class, android_app->activity->clazz);
+ GET_METHOD_ID(env, android_app->getIntent, class,
+ "getIntent", "()Landroid/content/Intent;");
+ GET_METHOD_ID(env, android_app->onRetroArchExit, class,
+ "onRetroArchExit", "()V");
+ CALL_OBJ_METHOD(env, obj, android_app->activity->clazz,
+ android_app->getIntent);
+
+ GET_OBJECT_CLASS(env, class, obj);
+ GET_METHOD_ID(env, android_app->getStringExtra, class,
+ "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
+#endif
+
+ if (!cpu_inited_once)
+ {
+ linux_cpu_init();
+ cpu_inited_once = true;
+ }
+}
+
+#ifdef ANDROID
+static int frontend_android_parse_drive_list(void *data)
+{
+ file_list_t *list = (file_list_t*)data;
+
+ // MENU_FILE_DIRECTORY is not working with labels, placeholders for now
+ menu_list_push(list,
+ app_dir, "Application Dir", MENU_FILE_DIRECTORY, 0, 0);
+ menu_list_push(list,
+ ext_dir, "External Application Dir", MENU_FILE_DIRECTORY, 0, 0);
+ menu_list_push(list,
+ sdcard_dir, "Internal Memory", MENU_FILE_DIRECTORY, 0, 0);
+
+ menu_list_push(list, "/", "",
+ MENU_FILE_DIRECTORY, 0, 0);
+
+ return 0;
+}
+#endif
+
frontend_ctx_driver_t frontend_ctx_linux = {
- NULL, /* environment_get */
- NULL, /* init */
- NULL, /* deinit */
+ frontend_linux_get_env, /* environment_get */
+ frontend_linux_init, /* init */
+ frontend_linux_deinit, /* deinit */
NULL, /* exitspawn */
NULL, /* process_args */
NULL, /* exec */
NULL, /* set_fork */
+#ifdef ANDROID
+ frontend_android_shutdown, /* shutdown */
+ frontend_android_get_name, /* get_name */
+#else
NULL, /* shutdown */
NULL, /* get_name */
+#endif
frontend_linux_get_os,
- NULL, /* get_rating */
+ frontend_linux_get_rating, /* get_rating */
NULL, /* load_content */
frontend_linux_get_architecture,
frontend_linux_get_powerstate,
+#ifdef ANDROID
+ frontend_android_parse_drive_list, /* parse_drive_list */
+ "android",
+#else
NULL, /* parse_drive_list */
"linux",
+#endif
};
diff --git a/frontend/drivers/platform_android.h b/frontend/drivers/platform_linux.h
similarity index 90%
rename from frontend/drivers/platform_android.h
rename to frontend/drivers/platform_linux.h
index c310b6b4eb..e507f34327 100644
--- a/frontend/drivers/platform_android.h
+++ b/frontend/drivers/platform_linux.h
@@ -15,9 +15,44 @@
* If not, see .
*/
-#ifndef _PLATFORM_ANDROID_H
-#define _PLATFORM_ANDROID_H
+#ifndef _PLATFORM_LINUX_H
+#define _PLATFORM_LINUX_H
+#include
+#include
+
+typedef enum
+{
+ CPU_FAMILY_UNKNOWN = 0,
+ CPU_FAMILY_ARM,
+ CPU_FAMILY_X86,
+ CPU_FAMILY_MIPS,
+
+ CPU_FAMILY_MAX /* do not remove */
+} cpu_family;
+
+enum
+{
+ CPU_ARM_FEATURE_ARMv7 = (1 << 0),
+ CPU_ARM_FEATURE_VFPv3 = (1 << 1),
+ CPU_ARM_FEATURE_NEON = (1 << 2),
+ CPU_ARM_FEATURE_LDREX_STREX = (1 << 3)
+};
+
+enum
+{
+ CPU_X86_FEATURE_SSSE3 = (1 << 0),
+ CPU_X86_FEATURE_POPCNT = (1 << 1),
+ CPU_X86_FEATURE_MOVBE = (1 << 2)
+};
+
+cpu_family linux_get_cpu_family(void);
+
+uint64_t linux_get_cpu_features(void);
+
+int linux_get_cpu_count(void);
+
+#ifdef ANDROID
#include
#include
#include
@@ -237,5 +272,7 @@ enum
extern JNIEnv *jni_thread_getenv(void);
extern struct android_app *g_android;
+#else
+#endif
-#endif /* _PLATFORM_ANDROID_H */
+#endif
diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c
index 45eb218cb9..0c54eb2574 100644
--- a/frontend/drivers/platform_psp.c
+++ b/frontend/drivers/platform_psp.c
@@ -15,7 +15,6 @@
*/
#include
-#include
#include
#include
@@ -32,6 +31,7 @@ int scePowerSetArmClockFrequency(int freq);
#include
#endif
+#include
#include
#include
#ifndef IS_SALAMANDER
@@ -43,12 +43,13 @@ int scePowerSetArmClockFrequency(int freq);
#if defined(HAVE_KERNEL_PRX) || defined(IS_SALAMANDER)
#ifndef VITA
-#include "../../psp1/kernel_functions.h"
+#include "../../bootstrap/psp1/kernel_functions.h"
#endif
#endif
#ifdef VITA
PSP2_MODULE_INFO(0, 0, "RetroArch");
+int _newlib_heap_size_user = 64 * 1024 * 1024;
#else
PSP_MODULE_INFO("RetroArch", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER|THREAD_ATTR_VFPU);
@@ -71,6 +72,7 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[],
void *args, void *params_data)
{
struct rarch_main_wrap *params = NULL;
+ char buf[PATH_MAX_LENGTH] = {0};
(void)args;
@@ -110,9 +112,9 @@ static void frontend_psp_get_environment_settings(int *argc, char *argv[],
"playlists", sizeof(g_defaults.dir.playlist));
fill_pathname_join(g_defaults.path.config, g_defaults.dir.port,
"retroarch.cfg", sizeof(g_defaults.path.config));
- fill_pathname_join(g_defaults.dir.cheats, g_defaults.dir.cheats,
+ fill_pathname_join(g_defaults.dir.cheats, g_defaults.dir.port,
"cheats", sizeof(g_defaults.dir.cheats));
- fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.remap,
+ fill_pathname_join(g_defaults.dir.remap, g_defaults.dir.port,
"remaps", sizeof(g_defaults.dir.remap));
#ifdef VITA
diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c
index fe48376906..b0ce0e00f7 100644
--- a/frontend/drivers/platform_qnx.c
+++ b/frontend/drivers/platform_qnx.c
@@ -14,12 +14,14 @@
* If not, see .
*/
-#include
-
#include
-#include
#include
#include
+
+#include
+
+#include
+
#include "../../dynamic.h"
#include "../../libretro_private.h"
diff --git a/frontend/drivers/platform_wii.c b/frontend/drivers/platform_wii.c
index 609b6279ad..9a6a2c4bd7 100644
--- a/frontend/drivers/platform_wii.c
+++ b/frontend/drivers/platform_wii.c
@@ -18,18 +18,21 @@
#include
#include
#include
+
#include
#include
#include
-#include "../../gfx/drivers/ppc_asm.h"
#include
#include
#include
#include
+#include
#include
#include
+#include "../../gfx/drivers/ppc_asm.h"
+
#define EXECUTE_ADDR ((uint8_t *) 0x91800000)
#define BOOTER_ADDR ((uint8_t *) 0x93000000)
#define ARGS_ADDR ((uint8_t *) 0x93200000)
@@ -46,10 +49,9 @@ char gx_rom_path[PATH_MAX_LENGTH];
static void dol_copy_argv_path(const char *dolpath, const char *argpath)
{
char tmp[PATH_MAX_LENGTH];
- size_t t_len;
+ size_t t_len, len = 0;
struct __argv *argv = (struct __argv *)ARGS_ADDR;
char *cmdline = NULL;
- size_t len = 0;
memset(ARGS_ADDR, 0, sizeof(struct __argv));
@@ -113,13 +115,13 @@ static void dol_copy_argv_path(const char *dolpath, const char *argpath)
* heap memory and are restricted to the stack only. */
void system_exec_wii(const char *_path, bool should_load_game)
{
- FILE *fp;
- size_t size, booter_size;
- void *dol;
+ size_t booter_size;
+ ssize_t length;
char path[PATH_MAX_LENGTH];
char game_path[PATH_MAX_LENGTH];
+ void *dol = NULL;
#ifndef IS_SALAMANDER
- global_t *global = global_get_ptr();
+ global_t *global = global_get_ptr();
bool original_verbose = global->verbosity;
global->verbosity = true;
#endif
@@ -137,30 +139,12 @@ void system_exec_wii(const char *_path, bool should_load_game)
}
RARCH_LOG("Attempt to load executable: [%s]\n", path);
-
- fp = fopen(path, "rb");
- if (fp == NULL)
+ if (retro_read_file(path, dol, &length) != 1)
{
RARCH_ERR("Could not open DOL file %s.\n", path);
goto exit;
}
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- /* try to allocate a buffer for it. if we can't, fail. */
- dol = malloc(size);
- if (!dol)
- {
- RARCH_ERR("Could not execute DOL file %s.\n", path);
- fclose(fp);
- goto exit;
- }
-
- fread(dol, 1, size, fp);
- fclose(fp);
-
fatUnmount("carda:");
fatUnmount("cardb:");
fatUnmount("sd:");
@@ -169,8 +153,8 @@ void system_exec_wii(const char *_path, bool should_load_game)
__io_usbstorage.shutdown();
/* don't use memcpy, there might be an overlap. */
- memmove(EXECUTE_ADDR, dol, size);
- DCFlushRange(EXECUTE_ADDR, size);
+ memmove(EXECUTE_ADDR, dol, length);
+ DCFlushRange(EXECUTE_ADDR, length);
dol_copy_argv_path(path, should_load_game ? game_path : NULL);
diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c
index c25459ae08..0d05c3aa4a 100644
--- a/frontend/drivers/platform_win32.c
+++ b/frontend/drivers/platform_win32.c
@@ -13,12 +13,12 @@
*/
#include
-#include
#include
#include
#include
+#include
#include
#include
#include
diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.cpp
similarity index 66%
rename from frontend/drivers/platform_xdk.c
rename to frontend/drivers/platform_xdk.cpp
index b13b81ccdc..1c0945a5bf 100644
--- a/frontend/drivers/platform_xdk.c
+++ b/frontend/drivers/platform_xdk.cpp
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#ifndef IS_SALAMANDER
@@ -33,7 +34,6 @@ static bool exit_spawn;
static bool exitspawn_start_game;
#ifdef _XBOX360
-
typedef struct _STRING
{
USHORT Length;
@@ -425,3 +425,264 @@ frontend_ctx_driver_t frontend_ctx_xdk = {
frontend_xdk_parse_drive_list,
"xdk",
};
+
+#ifdef _XBOX360
+struct XPR_HEADER
+{
+ DWORD dwMagic;
+ DWORD dwHeaderSize;
+ DWORD dwDataSize;
+};
+#endif
+
+#define XPR0_MAGIC_VALUE 0x30525058
+#define XPR1_MAGIC_VALUE 0x31525058
+#define XPR2_MAGIC_VALUE 0x58505232
+
+PackedResource::PackedResource()
+{
+ m_pSysMemData = NULL;
+ m_dwSysMemDataSize = 0L;
+ m_pVidMemData = NULL;
+ m_dwVidMemDataSize = 0L;
+ m_pResourceTags = NULL;
+ m_dwNumResourceTags = 0L;
+ m_bInitialized = FALSE;
+}
+
+
+PackedResource::~PackedResource()
+{
+ Destroy();
+}
+
+void *PackedResource::GetData(const char *strName) const
+{
+ if (m_pResourceTags == NULL || strName == NULL)
+ return NULL;
+
+#if defined(_XBOX1)
+ for (DWORD i=0; m_pResourceTags[i].strName; i++)
+#elif defined(_XBOX360)
+ for (DWORD i = 0; i < m_dwNumResourceTags; i++)
+#endif
+ {
+ if (!strcasecmp(strName, m_pResourceTags[i].strName))
+ return &m_pSysMemData[m_pResourceTags[i].dwOffset];
+ }
+
+ return NULL;
+}
+
+static INLINE void* AllocateContiguousMemory(DWORD Size, DWORD Alignment)
+{
+#if defined(_XBOX1)
+ return D3D_AllocContiguousMemory(Size, Alignment);
+#elif defined(_XBOX360)
+ return XMemAlloc(Size, MAKE_XALLOC_ATTRIBUTES(0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
+ Alignment, XALLOC_MEMPROTECT_WRITECOMBINE, 0, XALLOC_MEMTYPE_PHYSICAL));
+#endif
+}
+
+static INLINE void FreeContiguousMemory(void* pData)
+{
+#if defined(_XBOX1)
+ return D3D_FreeContiguousMemory(pData);
+#elif defined(_XBOX360)
+ return XMemFree(pData, MAKE_XALLOC_ATTRIBUTES(0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
+ 0, 0, 0, XALLOC_MEMTYPE_PHYSICAL));
+#endif
+}
+
+#ifdef _XBOX1
+char g_strMediaPath[512] = "D:\\Media\\";
+
+static HRESULT FindMediaFile(char *strPath, const char *strFilename, size_t strPathsize)
+{
+ if(strFilename == NULL || strPath == NULL)
+ return E_INVALIDARG;
+
+ strlcpy(strPath, strFilename, strPathsize);
+
+ if(strFilename[1] != ':')
+ snprintf(strPath, strPathsize, "%s%s", g_strMediaPath, strFilename);
+
+ HANDLE hFile = CreateFile(strPath, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ return 0x82000004;
+
+ CloseHandle(hFile);
+
+ return S_OK;
+}
+
+#endif
+
+#if defined(_XBOX1)
+HRESULT PackedResource::Create(const char *strFilename,
+ DWORD dwNumResourceTags, XBRESOURCE* pResourceTags)
+#elif defined(_XBOX360)
+HRESULT PackedResource::Create(const char *strFilename)
+#endif
+{
+ HANDLE hFile;
+ DWORD dwNumBytesRead;
+ XPR_HEADER xprh;
+ bool retval;
+#ifdef _XBOX1
+ BOOL bHasResourceOffsetsTable = FALSE;
+ char strResourcePath[512];
+
+ if (FAILED(FindMediaFile(strResourcePath, strFilename, sizeof(strResourcePath))))
+ return E_FAIL;
+ strFilename = strResourcePath;
+#endif
+
+ hFile = CreateFile(strFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return E_FAIL;
+
+ retval = ReadFile(hFile, &xprh, sizeof(XPR_HEADER), &dwNumBytesRead, NULL);
+
+#if defined(_XBOX1)
+ if(xprh.dwMagic == XPR0_MAGIC_VALUE)
+ bHasResourceOffsetsTable = FALSE;
+ else if(xprh.dwMagic == XPR1_MAGIC_VALUE)
+ bHasResourceOffsetsTable = TRUE;
+ else
+#elif defined(_XBOX360)
+ if(!retval)
+ {
+ CloseHandle(hFile);
+ return E_FAIL;
+ }
+
+ if (xprh.dwMagic != XPR2_MAGIC_VALUE)
+#endif
+ {
+ CloseHandle(hFile);
+ return E_FAIL;
+ }
+
+ // Compute memory requirements
+#if defined(_XBOX1)
+ m_dwSysMemDataSize = xprh.dwHeaderSize - sizeof(XPR_HEADER);
+ m_dwVidMemDataSize = xprh.dwTotalSize - xprh.dwHeaderSize;
+#elif defined(_XBOX360)
+ m_dwSysMemDataSize = xprh.dwHeaderSize;
+ m_dwVidMemDataSize = xprh.dwDataSize;
+#endif
+
+ // Allocate memory
+ m_pSysMemData = (BYTE*)malloc(m_dwSysMemDataSize);
+ if (m_pSysMemData == NULL)
+ {
+ m_dwSysMemDataSize = 0;
+ return E_FAIL;
+ }
+
+ m_pVidMemData = (BYTE*)AllocateContiguousMemory(m_dwVidMemDataSize,
+#if defined(_XBOX1)
+ D3DTEXTURE_ALIGNMENT
+#elif defined(_XBOX360)
+ XALLOC_PHYSICAL_ALIGNMENT_4K
+#endif
+ );
+
+ if(m_pVidMemData == NULL)
+ {
+ m_dwSysMemDataSize = 0;
+ m_dwVidMemDataSize = 0;
+ free(m_pSysMemData);
+ m_pSysMemData = NULL;
+ return E_FAIL;
+ }
+
+ // Read in the data from the file
+ if( !ReadFile( hFile, m_pSysMemData, m_dwSysMemDataSize, &dwNumBytesRead, NULL) ||
+ !ReadFile( hFile, m_pVidMemData, m_dwVidMemDataSize, &dwNumBytesRead, NULL))
+ {
+ CloseHandle( hFile);
+ return E_FAIL;
+ }
+
+ // Done with the file
+ CloseHandle( hFile);
+
+#ifdef _XBOX1
+ if (bHasResourceOffsetsTable)
+ {
+#endif
+
+ // Extract resource table from the header data
+ m_dwNumResourceTags = *(DWORD*)(m_pSysMemData + 0);
+ m_pResourceTags = (XBRESOURCE*)(m_pSysMemData + 4);
+
+ // Patch up the resources
+ for(DWORD i = 0; i < m_dwNumResourceTags; i++)
+ {
+ m_pResourceTags[i].strName = (char*)(m_pSysMemData + (DWORD)m_pResourceTags[i].strName);
+#ifdef _XBOX360
+ if((m_pResourceTags[i].dwType & 0xffff0000) == (RESOURCETYPE_TEXTURE & 0xffff0000))
+ {
+ D3DTexture *pTexture = (D3DTexture*)&m_pSysMemData[m_pResourceTags[i].dwOffset];
+ XGOffsetBaseTextureAddress(pTexture, m_pVidMemData, m_pVidMemData);
+ }
+#endif
+ }
+
+#ifdef _XBOX1
+ }
+#endif
+
+#ifdef _XBOX1
+ // Use user-supplied number of resources and the resource tags
+ if(dwNumResourceTags != 0 || pResourceTags != NULL)
+ {
+ m_pResourceTags = pResourceTags;
+ m_dwNumResourceTags = dwNumResourceTags;
+ }
+#endif
+
+ m_bInitialized = TRUE;
+
+ return S_OK;
+}
+
+#ifdef _XBOX360
+void PackedResource::GetResourceTags(DWORD* pdwNumResourceTags,
+ XBRESOURCE** ppResourceTags)
+{
+ if (pdwNumResourceTags)
+ (*pdwNumResourceTags) = m_dwNumResourceTags;
+
+ if (ppResourceTags)
+ (*ppResourceTags) = m_pResourceTags;
+}
+#endif
+
+void PackedResource::Destroy()
+{
+ free(m_pSysMemData);
+ m_pSysMemData = NULL;
+ m_dwSysMemDataSize = 0L;
+
+ if (m_pVidMemData != NULL)
+ FreeContiguousMemory(m_pVidMemData);
+
+ m_pVidMemData = NULL;
+ m_dwVidMemDataSize = 0L;
+
+ m_pResourceTags = NULL;
+ m_dwNumResourceTags = 0L;
+
+ m_bInitialized = FALSE;
+}
+
+BOOL PackedResource::Initialized() const
+{
+ return m_bInitialized;
+}
diff --git a/frontend/drivers/platform_xdk.h b/frontend/drivers/platform_xdk.h
index 0805554ab6..05de53dcc0 100644
--- a/frontend/drivers/platform_xdk.h
+++ b/frontend/drivers/platform_xdk.h
@@ -988,4 +988,111 @@ extern "C"
#endif
+DWORD XBResource_SizeOf( LPDIRECT3DRESOURCE pResource );
+
+//structure member offsets matter
+struct XBRESOURCE
+{
+#if defined(_XBOX1)
+ char *strName;
+ DWORD dwOffset;
+#elif defined(_XBOX360)
+ DWORD dwType;
+ DWORD dwOffset;
+ DWORD dwSize;
+ char *strName;
+#endif
+};
+
+enum
+{
+ RESOURCETYPE_USERDATA = ( ( 'U' << 24 ) | ( 'S' << 16 ) | ( 'E' << 8 ) | ( 'R' ) ),
+ RESOURCETYPE_TEXTURE = ( ( 'T' << 24 ) | ( 'X' << 16 ) | ( '2' << 8 ) | ( 'D' ) ),
+ RESOURCETYPE_VERTEXBUFFER = ( ( 'V' << 24 ) | ( 'B' << 16 ) | ( 'U' << 8 ) | ( 'F' ) ),
+ RESOURCETYPE_INDEXBUFFER = ( ( 'I' << 24 ) | ( 'B' << 16 ) | ( 'U' << 8 ) | ( 'F' ) ),
+ RESOURCETYPE_EOF = 0xffffffff
+};
+
+class PackedResource
+{
+ protected:
+ BYTE* m_pSysMemData; // Alloc'ed memory for resource headers etc.
+ DWORD m_dwSysMemDataSize;
+
+ BYTE* m_pVidMemData; // Alloc'ed memory for resource data, etc.
+ DWORD m_dwVidMemDataSize;
+
+ XBRESOURCE* m_pResourceTags; // Tags to associate names with the resources
+ DWORD m_dwNumResourceTags; // Number of resource tags
+ BOOL m_bInitialized; // Resource is fully initialized
+
+ public:
+ // Loads the resources out of the specified bundle
+#if defined(_XBOX1)
+ HRESULT Create( const char *strFilename, DWORD dwNumResourceTags = 0L,
+ XBRESOURCE* pResourceTags = NULL );
+#elif defined(_XBOX360)
+ HRESULT Create( const char * strFilename );
+#endif
+
+ void Destroy();
+
+ BOOL Initialized() const;
+
+#ifdef _XBOX360
+ // Retrieves the resource tags
+ void GetResourceTags( DWORD* pdwNumResourceTags, XBRESOURCE** ppResourceTags );
+#endif
+
+ // Helper function to make sure a resource is registered
+ LPDIRECT3DRESOURCE RegisterResource( LPDIRECT3DRESOURCE pResource ) const
+ {
+#ifdef _XBOX1
+ // Register the resource, if it has not yet been registered. We mark
+ // a resource as registered by upping it's reference count.
+ if( pResource && ( pResource->Common & D3DCOMMON_REFCOUNT_MASK ) == 1 )
+ {
+ // Special case CPU-copy push buffers (which live in system memory)
+ if( ( pResource->Common & D3DCOMMON_TYPE_PUSHBUFFER ) &&
+ ( pResource->Common & D3DPUSHBUFFER_RUN_USING_CPU_COPY ) )
+ pResource->Data += (DWORD)m_pSysMemData;
+ else
+ pResource->Register( m_pVidMemData );
+
+ pResource->AddRef();
+ }
+#endif
+ return pResource;
+ }
+
+ // Functions to retrieve resources by their offset
+ void *GetData( DWORD dwOffset ) const
+ { return &m_pSysMemData[dwOffset]; }
+
+ LPDIRECT3DRESOURCE GetResource( DWORD dwOffset ) const
+ { return RegisterResource( (LPDIRECT3DRESOURCE)GetData(dwOffset) ); }
+
+ LPDIRECT3DTEXTURE GetTexture( DWORD dwOffset ) const
+ { return (LPDIRECT3DTEXTURE)GetResource( dwOffset ); }
+
+ LPDIRECT3DVERTEXBUFFER GetVertexBuffer( DWORD dwOffset ) const
+ { return (LPDIRECT3DVERTEXBUFFER)GetResource( dwOffset ); }
+
+ // Functions to retrieve resources by their name
+ void *GetData( const char* strName ) const;
+
+ LPDIRECT3DRESOURCE GetResource( const char* strName ) const
+ { return RegisterResource( (LPDIRECT3DRESOURCE)GetData( strName ) ); }
+
+ LPDIRECT3DTEXTURE GetTexture( const char* strName ) const
+ { return (LPDIRECT3DTEXTURE)GetResource( strName ); }
+
+ LPDIRECT3DVERTEXBUFFER GetVertexBuffer( const char* strName ) const
+ { return (LPDIRECT3DVERTEXBUFFER)GetResource( strName ); }
+
+ // Constructor/destructor
+ PackedResource();
+ ~PackedResource();
+};
+
#endif // __XBOX_INTERNAL_H__
diff --git a/frontend/drivers/platform_xenon.c b/frontend/drivers/platform_xenon.c
index 21337841b6..678116d522 100644
--- a/frontend/drivers/platform_xenon.c
+++ b/frontend/drivers/platform_xenon.c
@@ -15,21 +15,23 @@
*/
#include
-#include
#include
#include
+#include