Initial commit

This commit is contained in:
TwinAphex51224 2011-09-11 19:46:17 +02:00
commit b124117124
575 changed files with 182729 additions and 0 deletions

231
Makefile Normal file
View File

@ -0,0 +1,231 @@
#options, set 1 to enable
CELL_DEBUG = 0
CELL_DEBUG_CONSOLE = 0
CELL_DEBUG_FPS = 0
NO_FRAMESKIP = 0
MULTIMAN_SUPPORT = 0
TOC_LOG = 0
SDK_340 = 1
#which compiler to build with - GCC or SNC
#set to GCC for debug builds for use with debugger
CELL_BUILD_TOOLS = SNC
ifeq ($(CELL_DEBUG),1)
PPU_OPTIMIZE_LV := -O0
else
PPU_OPTIMIZE_LV := -O2
endif
# specify build tools
#explicitly set some cell sdk defaults
CELL_SDK ?= /usr/local/cell
# CELL_GPU_TYPE (currently RSX is only one option)
CELL_GPU_TYPE = RSX
#CELL_PSGL_VERSION is debug, dpm or opt
CELL_PSGL_VERSION = opt
#Python binary - only useful for PSL1ght scripts
PYTHONBIN = python2.7
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
include $(CELL_MK_DIR)/sdk.makedef.mk
# Geohot CFW defines
MKSELF_GEOHOT = make_self_npdrm
MKPKG_PSLIGHT = buildtools/PS3Py/pkg.py
PKG_FINALIZE = package_finalize
STRIP = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-strip
C = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-gcc
CC = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-g++
UTILS_DIR = ./utils
SRC_DIR = ./src
SNES9X_API_DIR = ./src/snes9x
CELL_FRAMEWORK_DIR = ./src/cellframework
CELL_FRAMEWORK2_DIR = ./src/cellframework2
EBOOT_LAUNCHER_DIR = eboot-launcher
EMULATOR_VERSION = 1.0
PPU_SRCS += $(SNES9X_API_DIR)/tile.cpp \
$(SNES9X_API_DIR)/cpu.cpp \
$(SNES9X_API_DIR)/dma.cpp \
$(SNES9X_API_DIR)/ppu.cpp \
$(SNES9X_API_DIR)/sa1.cpp \
$(SNES9X_API_DIR)/sa1cpu.cpp \
$(SNES9X_API_DIR)/fxdbg.cpp \
$(SNES9X_API_DIR)/fxemu.cpp \
$(SNES9X_API_DIR)/fxinst.cpp \
$(SNES9X_API_DIR)/cpuexec.cpp \
$(SNES9X_API_DIR)/cpuops.cpp \
$(SNES9X_API_DIR)/srtc.cpp \
$(SNES9X_API_DIR)/memmap.cpp \
$(SNES9X_API_DIR)/apu/apu.cpp \
$(SNES9X_API_DIR)/apu/SNES_SPC.cpp \
$(foreach dir,$(SNES9X_API_DIR)/jma/,$(wildcard $(dir)/*.cpp)) \
$(SNES9X_API_DIR)/bsx.cpp \
$(SNES9X_API_DIR)/c4.cpp \
$(SNES9X_API_DIR)/c4emu.cpp \
$(SNES9X_API_DIR)/cheats.cpp \
$(SNES9X_API_DIR)/cheats2.cpp \
$(SNES9X_API_DIR)/controls.cpp \
$(SNES9X_API_DIR)/crosshairs.cpp \
$(SNES9X_API_DIR)/dsp.cpp \
$(SNES9X_API_DIR)/dsp1.cpp \
$(SNES9X_API_DIR)/dsp2.cpp \
$(SNES9X_API_DIR)/dsp3.cpp \
$(SNES9X_API_DIR)/dsp4.cpp \
$(SNES9X_API_DIR)/globals.cpp \
$(SNES9X_API_DIR)/loadzip.cpp \
$(SNES9X_API_DIR)/netplay.cpp \
$(SNES9X_API_DIR)/obc1.cpp \
$(SNES9X_API_DIR)/reader.cpp \
$(SNES9X_API_DIR)/sdd1.cpp \
$(SNES9X_API_DIR)/sdd1emu.cpp \
$(SNES9X_API_DIR)/server.cpp \
$(SNES9X_API_DIR)/seta.cpp \
$(SNES9X_API_DIR)/seta010.cpp \
$(SNES9X_API_DIR)/seta011.cpp \
$(SNES9X_API_DIR)/seta018.cpp \
$(SNES9X_API_DIR)/snapshot.cpp \
$(SNES9X_API_DIR)/snes9x.cpp \
$(SNES9X_API_DIR)/spc7110.cpp
PPU_SRCS += $(UTILS_DIR)/zlib/adler32.c \
$(UTILS_DIR)/zlib/compress.c \
$(UTILS_DIR)/zlib/crc32.c \
$(UTILS_DIR)/zlib/deflate.c \
$(UTILS_DIR)/zlib/gzclose.c \
$(UTILS_DIR)/zlib/gzlib.c \
$(UTILS_DIR)/zlib/gzread.c \
$(UTILS_DIR)/zlib/gzwrite.c \
$(UTILS_DIR)/zlib/infback.c \
$(UTILS_DIR)/zlib/inffast.c \
$(UTILS_DIR)/zlib/inflate.c \
$(UTILS_DIR)/zlib/inftrees.c \
$(UTILS_DIR)/zlib/trees.c \
$(UTILS_DIR)/zlib/uncompr.c \
$(UTILS_DIR)/zlib/zutil.c \
$(UTILS_DIR)/zlib/contrib/minizip/ioapi.c \
$(UTILS_DIR)/zlib/contrib/minizip/mztools.c \
$(UTILS_DIR)/zlib/contrib/minizip/zip.c \
$(UTILS_DIR)/zlib/contrib/minizip/unzip.c
PPU_SRCS += $(CELL_FRAMEWORK2_DIR)/audio/rsound.c \
$(CELL_FRAMEWORK2_DIR)/audio/librsound.c \
$(CELL_FRAMEWORK2_DIR)/audio/buffer.c \
$(CELL_FRAMEWORK2_DIR)/input/pad_input.c \
$(CELL_FRAMEWORK2_DIR)/input/mouse_input.c \
PPU_SRCS += $(SRC_DIR)/ps3video.cpp \
$(SRC_DIR)/snes_state/snes_state.c \
$(SRC_DIR)/snes_state/config_file.c \
$(SRC_DIR)/menu.cpp \
$(CELL_FRAMEWORK2_DIR)/audio/resampler.c \
$(CELL_FRAMEWORK2_DIR)/audio/audioport.c \
$(SRC_DIR)/ps3input.c \
$(SRC_DIR)/emu-ps3.cpp \
$(CELL_FRAMEWORK2_DIR)/utility/oskutil.c \
$(CELL_FRAMEWORK_DIR)/fileio/FileBrowser.cpp
PPU_TARGET = snes9x-ps3.ppu.elf
ifeq ($(CELL_DEBUG),1)
DEBUGFLAGS = -D_DEBUG -g
else
DEBUGFLAGS =
endif
PPU_CFLAGS += -I. -DUSE_FILE32API -Dunix -DPSGL -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -DSN_TARGET_PS3 -DNDEBUG=1 -DWORDS_BIGENDIAN -DBLARGG_BIG_ENDIAN=1 -DNO_LOGGER -D__POWERPC__ -D__ppc__ $(DEBUGFLAGS)
PPU_CXXFLAGS += -I./src/ -I./src/snes9x/ -DZLIB -DUNZIP_SUPPORT -DJMA_SUPPORT -DPSGL -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -DNO_LOGGER -DSN_TARGET_PS3 -DNDEBUG=1 -DWORDS_BIGENDIAN -DBLARGG_BIG_ENDIAN=1 -D__POWERPC__ -D__ppc__ $(DEBUGFLAGS)
ifeq ($(CELL_BUILD_TOOLS),SNC)
PARAMS = -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 -Xunroll=1 -Xautovecreg=1 -Xnotocrestore=2 -Xc-=rtti
PPU_CFLAGS += $(PARAMS)
PPU_CXXFLAGS += $(PARAMS)
NOTOCRESTORE = --notocrestore
else
PPU_CFLAGS += -funroll-loops -fno-rtti
PPU_CXXFLAGS += -funroll-loops -fno-rtti
NOTOCRESTORE =
endif
ifeq ($(CELL_DEBUG_CONSOLE),1)
PPU_CFLAGS += -DCELL_DEBUG_CONSOLE
PPU_CXXFLAGS += -DCELL_DEBUG_CONSOLE
L_CONTROL_CONSOLE_LDLIBS = -lcontrol_console_ppu
L_NET_CTL_LDLIBS = -lnetctl_stub
endif
ifeq ($(CELL_DEBUG_FPS),1)
PPU_CFLAGS += -DCELL_DEBUG_FPS
PPU_CXXFLAGS += -DCELL_DEBUG_FPS
endif
ifeq ($(NO_FRAMESKIP),1)
PPU_CFLAGS += -DNO_FRAMESKIP=1
PPU_CXXFLAGS += -DNO_FRAMESKIP=1
endif
ifeq ($(MULTIMAN_SUPPORT),1)
PPU_CFLAGS += -DMULTIMAN_SUPPORT=1
PPU_CXXFLAGS += -DMULTIMAN_SUPPORT=1
ifeq ($(shell uname), Linux)
MKFSELF_WC = $(HOME)/bin/make_self_wc
else
MKFSELF_WC = $(CELL_SDK)/../bin/make_self_wc
endif
endif
ifeq ($(TOC_LOG),1)
TOC_INFO = --print-toc-info
else
TOC_INFO =
endif
ifeq ($(SDK_340),1)
L_SYSUTIL_SCREENSHOT = -lsysutil_screenshot_stub
else
L_SYSUTIL_SCREENSHOT =
endif
PPU_LDLIBS += -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/opt -ldbgfont -lPSGL -lPSGLcgc -lcgc \
-lgcm_cmd -lgcm_sys_stub -lresc_stub -lm -lio_stub -lfs_stub -lsysutil_stub -lsysutil_game_stub $(L_SYSUTIL_SCREENSHOT) $(L_CONTROL_CONSOLE_LDLIBS) -lpngdec_stub -ljpgdec_stub \
-lsysmodule_stub -laudio_stub -lpthread -lnet_stub $(L_NET_CTL_LDLIBS) $(TOC_INFO) $(NOTOCRESTORE)
include $(CELL_MK_DIR)/sdk.target.mk
.PHONY: pkg
#standard pkg packaging
pkg: $(PPU_TARGET)
ifeq ($(MULTIMAN_SUPPORT),1)
$(MKFSELF_WC) $(PPU_TARGET) pkg/USRDIR/RELOAD.SELF
else
$(MAKE_FSELF_NPDRM) $(PPU_TARGET) pkg/USRDIR/EBOOT.BIN
endif
$(MAKE_PACKAGE_NPDRM) pkg/package.conf pkg
#massively reduced filesize using MKSELF_GEOHOT - use this for normal jailbreak builds
.PHONY: pkg-signed
pkg-signed: $(PPU_TARGET)
ifeq ($(MULTIMAN_SUPPORT),1)
$(MKFSELF_WC) $(PPU_TARGET) pkg/USRDIR/RELOAD.SELF
else
$(MKSELF_GEOHOT) $(PPU_TARGET) pkg/USRDIR/EBOOT.BIN SNES900000
endif
$(PYTHONBIN) $(MKPKG_PSLIGHT) --contentid IV0002-SNES90000_00-SAMPLE0000000001 pkg/ snes9xnext-ps3-v$(EMULATOR_VERSION)-fw3.41.pkg
#use this to create a PKG for use with Geohot CFW 3.55
.PHONY: pkg-signed-cfw
pkg-signed-cfw:
ifeq ($(MULTIMAN_SUPPORT),1)
$(MKFSELF_WC) $(PPU_TARGET) pkg/USRDIR/RELOAD.SELF
else
$(MKSELF_GEOHOT) $(PPU_TARGET) pkg/USRDIR/EBOOT.BIN SNES900000
endif
$(PYTHONBIN) $(MKPKG_PSLIGHT) --contentid IV0002-SNES90000_00-SAMPLE0000000001 pkg/ snes9xnext-ps3-v$(EMULATOR_VERSION)-cfw3.55.pkg
$(PKG_FINALIZE) snes9xnext-ps3-v$(EMULATOR_VERSION)-cfw3.55.pkg

69
Makefile-eboot-launcher Normal file
View File

@ -0,0 +1,69 @@
# specify build tools
CELL_BUILD_TOOLS = SNC
#explicitly set some cell sdk defaults
CELL_SDK ?= /usr/local/cell
# CELL_GPU_TYPE (currently RSX is only one option)
CELL_GPU_TYPE = RSX
#CELL_PSGL_VERSION is debug, dpm or opt
CELL_PSGL_VERSION = opt
#Python binary - only useful for PSL1ght scripts
PYTHONBIN = python2.7
CELL_MK_DIR ?= $(CELL_SDK)/samples/mk
include $(CELL_MK_DIR)/sdk.makedef.mk
#CELL_HOST_PATH ?= $(CELL_SDK)/host-win32
MKFSELF = $(CELL_HOST_PATH)/bin/make_fself
MKFSELF_NPDRM = $(CELL_HOST_PATH)/bin/make_fself_npdrm
MKPKG_NPDRM = $(CELL_HOST_PATH)/bin/make_package_npdrm
# Geohot CFW defines
MKSELF_GEOHOT = make_self_npdrm
MKPKG_PSLIGHT = buildtools/PS3Py/pkg.py
PKG_FINALIZE = package_finalize
STRIP = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-strip
COPY = cp
MOVE = mv
C = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-gcc
CC = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-g++
EBOOT_LAUNCHER_DIR = eboot-launcher
PPU_SRCS = $(EBOOT_LAUNCHER_DIR)/main.cpp
PPU_TARGET = EBOOT.ELF
PPU_CFLAGS += -I. -DUSE_FILE32API -Dunix -DPSGL -O2 -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -DSN_TARGET_PS3 -DNDEBUG=1 -DWORDS_BIGENDIAN -DBLARGG_BIG_ENDIAN=1 -DNO_LOGGER -D__POWERPC__ -D__ppc__ -g
PPU_CXXFLAGS += -I./src/ -I./src/snes9x/ -DZLIB -DUNZIP_SUPPORT -DJMA_SUPPORT -DPSGL -O2 -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -DNO_LOGGER -DSN_TARGET_PS3 -DNDEBUG=1 -DWORDS_BIGENDIAN -DBLARGG_BIG_ENDIAN=1 -D__POWERPC__ -D__ppc__
ifeq ($(CELL_BUILD_TOOLS),SNC)
PPU_CFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 \
-Xunroll=1 -Xautovecreg=1
PPU_CXXFLAGS += -Xbranchless=1 -Xfastmath=1 -Xassumecorrectsign=1 -Xassumecorrectalignment=1 \
-Xunroll=1 -Xautovecreg=1
else
PPU_CFLAGS += -funroll-loops
PPU_CXXFLAGS += -funroll-loops
endif
PPU_OPTIMIZE_LV := -O2
PPU_LDLIBS += -lfont_stub -lfontFT_stub -lfreetype_stub -lpthread -lmixer -lm -lmstreamSPURSMP3 -ladec_stub -laudio_stub -lnet_stub -lnetctl_stub -lpngdec_stub -lm -ldbgfont_gcm -lgcm_cmd -lgcm_sys_stub -lio_stub -lsysmodule_stub -lsysutil_stub -lfs_stub -lhttp_util_stub -lspurs_stub -ljpgdec_stub -lhttp_stub -lsysutil_music_export_stub -lsysutil_photo_export_stub -lsysutil_video_export_stub -lrtc_stub \
include $(CELL_MK_DIR)/sdk.target.mk
.PHONY: pkg
#standard pkg packaging
pkg: $(PPU_TARGET)
$(MKSELF_GEOHOT) EBOOT.ELF pkg/USRDIR/EBOOT.BIN SNES900000
#massively reduced filesize using MKSELF_GEOHOT - use this for normal jailbreak builds
.PHONY: pkg-signed
pkg-signed: $(PPU_TARGET)
$(MKSELF_GEOHOT) EBOOT.ELF pkg/USRDIR/EBOOT.BIN SNES900000
#use this to create a PKG for use with Geohot CFW 3.55
.PHONY: pkg-signed-cfw
pkg-signed-cfw:
$(MKSELF_GEOHOT) EBOOT.ELF pkg/USRDIR/EBOOT.BIN SNES900000

314
Makefile-profile Normal file
View File

@ -0,0 +1,314 @@
# set build tools
CELL_BUILD_TOOLS = GCC
ifeq ($(shell uname), Linux)
CELL_HOST_PATH = $(CELL_SDK)/host-linux
else
CELL_HOST_PATH = $(CELL_SDK)/host-win32
endif
# CELL_GPU_TYPE (currently RSX is only one option)
CELL_GPU_TYPE = RSX
# CELL_PSGL_VERSION is debug, dpm or opt
CELL_PSGL_VERSION = opt
# set path to important executables
MKFSELF_NPDRM = $(CELL_HOST_PATH)/bin/make_fself_npdrm
MKFSELF = $(CELL_HOST_PATH)/bin/make_fself
MKPKG_NPDRM = $(CELL_HOST_PATH)/bin/make_package_npdrm
STRIP = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-strip
COPY = cp
C = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-gcc
CC = $(CELL_HOST_PATH)/ppu/bin/ppu-lv2-g++
# set path to all relevants directories
SRC_DIR = src
CELL_FRAMEWORK_DIR = src/cellframework
CELL_FRAMEWORK2_DIR = src/cellframework2
SNES9X_API_DIR = src/snes9x
UTIL_DIR = utils
BUILD_DIR = objs
# build list of source directories
SNES9X_SRC_DIR := $(SNES9X_API_DIR)/ $(SNES9X_API_DIR)/unzip $(SNES9X_API_DIR)/apu $(SNES9X_API_DIR)/jma
PS3_SRC_DIR := $(CELL_FRAMEWORK_DIR)/graphics $(CELL_FRAMEWORK2_DIR)/input $(CELL_FRAMEWORK2_DIR)/audio \
$(CELL_FRAMEWORK_DIR)/threads $(CELL_FRAMEWORK_DIR)/logger $(CELL_FRAMEWORK_DIR)/network \
$(CELL_FRAMEWORK_DIR)/fileio \
$(CELL_FRAMEWORK_DIR)/utility \
$(SRC_DIR)/ $(SRC_DIR)/conf
UTIL_SRC_DIR := $(UTIL_DIR)/ $(UTIL_DIR)/zlib $(UTIL_DIR)/zlib/contrib/minizip
# build src lists and object file lists
SNES9X_CPPSRCS = $(SNES9X_API_DIR)/cpu.cpp \
$(SNES9X_API_DIR)/cpuexec.cpp \
$(SNES9X_API_DIR)/cpuops.cpp \
$(SNES9X_API_DIR)/srtc.cpp \
$(SNES9X_API_DIR)/dma.cpp \
$(SNES9X_API_DIR)/memmap.cpp \
$(SNES9X_API_DIR)/sa1.cpp \
$(SNES9X_API_DIR)/sa1cpu.cpp \
$(SNES9X_API_DIR)/apu/apu.cpp \
$(SNES9X_API_DIR)/apu/SNES_SPC.cpp \
$(SNES9X_API_DIR)/apu/SNES_SPC_misc.cpp \
$(SNES9X_API_DIR)/apu/SNES_SPC_state.cpp \
$(SNES9X_API_DIR)/apu/SPC_DSP.cpp \
$(SNES9X_API_DIR)/apu/SPC_Filter.cpp \
$(SNES9X_API_DIR)/fxdbg.cpp \
$(SNES9X_API_DIR)/fxemu.cpp \
$(SNES9X_API_DIR)/fxinst.cpp \
$(SNES9X_API_DIR)/gfx.cpp \
$(SNES9X_API_DIR)/ppu.cpp \
$(foreach dir,$(SNES9X_API_DIR)/jma/,$(wildcard $(dir)/*.cpp)) \
$(SNES9X_API_DIR)/bsx.cpp \
$(SNES9X_API_DIR)/c4.cpp \
$(SNES9X_API_DIR)/c4emu.cpp \
$(SNES9X_API_DIR)/cheats.cpp \
$(SNES9X_API_DIR)/cheats2.cpp \
$(SNES9X_API_DIR)/clip.cpp \
$(SNES9X_API_DIR)/conffile.cpp \
$(SNES9X_API_DIR)/controls.cpp \
$(SNES9X_API_DIR)/crosshairs.cpp \
$(SNES9X_API_DIR)/debug.cpp \
$(SNES9X_API_DIR)/dsp.cpp \
$(SNES9X_API_DIR)/dsp1.cpp \
$(SNES9X_API_DIR)/dsp2.cpp \
$(SNES9X_API_DIR)/dsp3.cpp \
$(SNES9X_API_DIR)/dsp4.cpp \
$(SNES9X_API_DIR)/globals.cpp \
$(SNES9X_API_DIR)/loadzip.cpp \
$(SNES9X_API_DIR)/logger.cpp \
$(SNES9X_API_DIR)/movie.cpp \
$(SNES9X_API_DIR)/netplay.cpp \
$(SNES9X_API_DIR)/obc1.cpp \
$(SNES9X_API_DIR)/reader.cpp \
$(SNES9X_API_DIR)/screenshot.cpp \
$(SNES9X_API_DIR)/sdd1.cpp \
$(SNES9X_API_DIR)/sdd1emu.cpp \
$(SNES9X_API_DIR)/server.cpp \
$(SNES9X_API_DIR)/seta.cpp \
$(SNES9X_API_DIR)/seta010.cpp \
$(SNES9X_API_DIR)/seta011.cpp \
$(SNES9X_API_DIR)/seta018.cpp \
$(SNES9X_API_DIR)/snapshot.cpp \
$(SNES9X_API_DIR)/snes9x.cpp \
$(SNES9X_API_DIR)/spc7110.cpp \
$(SNES9X_API_DIR)/tile.cpp
#SNES9X_CPPSRCS = $(foreach dir,$(SNES9X_SRC_DIR),$(wildcard $(dir)/*.cpp))
SNES9X_CPPOBJS = $(SNES9X_CPPSRCS:.cpp=.ppu.o)
SNES9X_CSRCS = $(foreach dir,$(SNES9X_SRC_DIR),$(wildcard $(dir)/*.c))
SNES9X_COBJS = $(SNES9X_CSRCS:.c=.ppu.o)
PS3_CPPSRCS = $(foreach dir,$(PS3_SRC_DIR),$(wildcard $(dir)/*.cpp))
PS3_CPPOBJS = $(PS3_CPPSRCS:.cpp=.ppu.o)
PS3_CSRCS = $(foreach dir,$(PS3_SRC_DIR),$(wildcard $(dir)/*.c))
PS3_COBJS = $(PS3_CSRCS:.c=.ppu.o)
UTIL_CPPSRCS = $(foreach dir,$(UTIL_SRC_DIR),$(wildcard $(dir)/*.cpp))
UTIL_CPPOBJS = $(UTIL_CPPSRCS:.cpp=.ppu.o)
#UTIL_CSRCS = $(foreach dir,$(UTIL_SRC_DIR),$(wildcard $(dir)/*.c))
UTIL_CSRCS += $(UTIL_DIR)/zlib/adler32.c \
$(UTIL_DIR)/zlib/compress.c \
$(UTIL_DIR)/zlib/crc32.c \
$(UTIL_DIR)/zlib/deflate.c \
$(UTIL_DIR)/zlib/gzclose.c \
$(UTIL_DIR)/zlib/gzlib.c \
$(UTIL_DIR)/zlib/gzread.c \
$(UTIL_DIR)/zlib/gzwrite.c \
$(UTIL_DIR)/zlib/infback.c \
$(UTIL_DIR)/zlib/inffast.c \
$(UTIL_DIR)/zlib/inflate.c \
$(UTIL_DIR)/zlib/inftrees.c \
$(UTIL_DIR)/zlib/trees.c \
$(UTIL_DIR)/zlib/uncompr.c \
$(UTIL_DIR)/zlib/zutil.c
UTIL_COBJS = $(UTIL_CSRCS:.c=.ppu.o)
PPU_CPPOBJS = $(SNES9X_CPPOBJS:%=$(BUILD_DIR)/%) $(PS3_CPPOBJS:%=$(BUILD_DIR)/%) $(UTIL_CPPOBJS:%=$(BUILD_DIR)/%)
PPU_COBJS = $(SNES9X_COBJS:%=$(BUILD_DIR)/%) $(PS3_COBJS:%=$(BUILD_DIR)/%) $(UTIL_COBJS:%=$(BUILD_DIR)/%)
# Output file
PPU_TARGET = snes9x.ppu.elf
# default flags from sony
PPU_CXXFLAGS = -std=c++98 -W -Wall -Wuninitialized -Wcomment -Wchar-subscripts \
-Wdeprecated-declarations -Wendif-labels -Wformat=2 -Wformat-extra-args \
-Wimplicit -Wimport -Winline -Wmissing-braces -Wparentheses -Wpointer-arith \
-Wredundant-decls -Wreturn-type -Wshadow -Wsign-compare -Wswitch \
-Wunknown-pragmas -Wunused -Wwrite-strings
PPU_CFLAGS = -W -Wall -Wuninitialized -Wcomment -Wchar-subscripts \
-Wdeprecated-declarations -Wendif-labels -Wformat=2 -Wformat-extra-args \
-Wimplicit -Wimport -Winline -Wmissing-braces -Wparentheses -Wpointer-arith \
-Wredundant-decls -Wreturn-type -Wshadow -Wsign-compare -Wswitch \
-Wunknown-pragmas -Wunused -Wwrite-strings
# PLATFORM
PPU_CXXFLAGS += -D__CELLOS_LV2__
PPU_CFLAGS += -D__CELLOS_LV2__
# include flags
PPU_CXXFLAGS += -I. -I$(SNES9X_API_DIR) -I./utils/ -I./utils/zlib
PPU_CFLAGS += -I. -I$(SNES9X_API_DIR) -I./utils/ -I./utils/zlib
# compiler optimizations
PPU_CXXFLAGS += -O3 \
-ffast-math \
-finline-functions \
-funit-at-a-time \
--param inline-unit-growth=200 \
--param large-function-growth=1000 \
--param max-inline-insns-single=450
PPU_CFLAGS += -O3 \
-ffast-math \
-finline-functions \
-funit-at-a-time \
--param inline-unit-growth=200 \
--param large-function-growth=1000 \
--param max-inline-insns-single=450
# port must define
PPU_CXXFLAGS += -DPSGL -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -DUNZIP_SUPPORT -DJMA_SUPPORT -DZLIB
PPU_CFLAGS += -DPSGL -DCORRECT_VRAM_READS -DRIGHTSHIFT_IS_SAR -Dunix -DUSE_FILE32API -DUNZIP_SUPPORT -DJMA_SUPPORT
# DISABLE DEBUG, to enabled add -g
PPU_CXXFLAGS +=
PPU_CFLAGS +=
# enable debug netlogger
PPU_CXXFLAGS += -DCELL_DEBUG -DPS3_DEBUG_IP=\"192.168.1.7\" -DPS3_DEBUG_PORT=9002
PPU_CFLAGS += -DCELL_DEBUG -DPS3_DEBUG_IP=\"192.168.1.7\" -DPS3_DEBUG_PORT=9002
# enable screen debugger
#PPU_CXXFLAGS += -DEMUDEBUG -DEMU_DBG_DELAY=500000
#PPU_CFLAGS += -DEMUDEBUG -DEMU_DBG_DELAY=500000
# enable telnet control console
#PPU_CSTDFLAGS += -DCONTROL_CONSOLE -D__PPU__
#PPU_CSTDFLAGS += -DCONSOLE_USE_NETWORK
#PPU_CXXSTDFLAGS += -DCONTROL_CONSOLE -D__PPU__
#PPU_CXXSTDFLAGS += -DCONSOLE_USE_NETWORK
# default SNES9x file libs
PPU_CXXSNES9XFLAGS = $(PPU_CXXFLAGS)
PPU_CSNES9XFLAGS = $(PPU_CFLAGS)
# libs, order matters!
PPU_LDLIBS += -L. -L$(CELL_SDK)/target/ppu/lib/PSGL/RSX/opt -ldbgfont -lPSGL -lPSGLcgc -lcgc \
-lgcm_cmd -lgcm_sys_stub -lresc_stub -lm -lio_stub -lfs_stub -lsysutil_stub \
-lcontrol_console_ppu -lsysmodule_stub -laudio_stub -lpthread -lnet_stub -lnetctl_stub
# RULE: ALL
all: $(PPU_TARGET) $(PPU_TARGET:%.elf=%.self)
# RULE: All cpp files, can differentiate for SNES9x dir
$(BUILD_DIR)/%.ppu.o: %.cpp
@mkdir -p $(@D)
$(if $(findstring $@,$(SNES9X_CPPOBJS:%=$(BUILD_DIR)/%)),\
$(CC) $(PPU_CXXSNES9XFLAGS) -o $@ -c $<,\
$(CC) $(PPU_CXXFLAGS) -o $@ -c $<)
# RULE: All c files, can differentiate for SNES9x dir
$(BUILD_DIR)/%.ppu.o: %.c
@mkdir -p $(@D)
$(if $(findstring $@,$(SNES9X_COBJS:%=$(BUILD_DIR)/%)),\
ppu-lv2-gcc $(PPU_CSNES9XFLAGS) -o $@ -c $<,\
ppu-lv2-gcc $(PPU_CFLAGS) -o $@ -c $<)
# RULE: build the elf file
$(PPU_TARGET): $(PPU_CPPOBJS) $(PPU_COBJS)
$(CC) $(PPU_CXXFLAGS) $(PPU_LDLIBS) -o $(PPU_TARGET) $(PPU_CPPOBJS) $(PPU_COBJS)
# RULE: build the self file
$(PPU_TARGET:%.elf=%.self): $(PPU_TARGET)
$(MKFSELF) $(PPU_TARGET) $(PPU_TARGET:%.elf=%.self)
# RULE: generates the compiler and linker flags for profile-arcs
genProfile: set_genProfile_flags all
set_genProfile_flags: $(BUILD_DIR)/$(CELL_FRAMEWORK_DIR)/network-stdio/net_stdio.ppu.o
touch ./src/main.cpp
$(eval PS3_SRC_DIR += $(CELL_FRAMEWORK_DIR)/network-stdio)
$(eval PPU_CXXFLAGS += -DPS3_PROFILING -DPS3_PROFILING_IP=\"192.168.1.7\" -DPS3_PROFILING_PORT=9001)
$(eval PPU_CFLAGS += -DPS3_PROFILING -DPS3_PROFILING_IP=\"192.168.1.7\" -DPS3_PROFILING_PORT=9001)
$(eval PPU_CXXSNES9XFLAGS = $(PPU_CXXFLAGS) -fprofile-generate -fprofile-arcs)
$(eval PPU_CSNES9XFLAGS = $(PPU_CFLAGS) -fprofile-generate -fprofile-arcs)
$(eval PPU_LDLIBS += -lgcov -fprofile-generate)
$(eval PPU_LDLIBS += -Wl,-wrap,fopen -Wl,-wrap,fclose -Wl,-wrap,fwrite -Wl,-wrap,fread -Wl,-wrap,fseek -Wl,-wrap,ftell -Wl,-wrap,fflush -Wl,-wrap,rewind -Wl,-wrap,fgetpos -Wl,-wrap,fsetpos -Wl,-wrap,setbuf -Wl,-wrap,setvbuf -Wl,-wrap,ungetc -Wl,-wrap,feof)
# RULE: use a generated profile (gcda files)
useProfile: set_useProfile_flags all
set_useProfile_flags:
touch ./src/main.cpp
$(eval PPU_CXXSNES9XFLAGS = $(PPU_CXXFLAGS) -fprofile-use)
$(eval PPU_CSNES9XFLAGS = $(PPU_CFLAGS) -fprofile-use)
$(eval PPU_LDLIBS += -fprofile-use)
# RULE: build the package
pkg: $(PPU_TARGET)
$(STRIP) $(PPU_TARGET)
$(MKFSELF_NPDRM) $(PPU_TARGET) pkg/USRDIR/EBOOT.BIN
$(COPY) -r ./src/cellframework/extra/shaders pkg/USRDIR/
$(MKPKG_NPDRM) pkg/package.conf pkg
# RULE: testing...
echo:
echo $(PPU_CPPOBJS)
echo $(BUILD_DIR)/$(CELL_FRAMEWORK_DIR)/network-stdio/net_stdio.ppu.o
# RULE - force, for empty dependency
force: ;
# RULE - clean SNES9x or ps3 or utils or all
clean_snes9x:
@rm $(SNES9X_CPPOBJS:%=$(BUILD_DIR)/%) -f
@rm $(SNES9X_CPPOBJS:%.o=$(BUILD_DIR)/%.d) -f
@rm $(SNES9X_COBJS:%=$(BUILD_DIR)/%) -f
@rm $(SNES9X_COBJS:%.o=$(BUILD_DIR)/%.d) -f
clean_ps3:
@rm $(PS3_CPPOBJS:%=$(BUILD_DIR)/%) -f
@rm $(PS3_CPPOBJS:%.o=$(BUILD_DIR)/%.d) -f
@rm $(PS3_COBJS:%=$(BUILD_DIR)/%) -f
@rm $(PS3_COBJS:%.o=$(BUILD_DIR)/%.d) -f
@rm $(BUILD_DIR)/$(CELL_FRAMEWORK_DIR)/network-stdio/net_stdio.ppu.o -f
clean_util:
@rm $(UTIL_CPPOBJS:%=$(BUILD_DIR)/%) -f
@rm $(UTIL_CPPOBJS:%.o=$(BUILD_DIR)/%.d) -f
@rm $(UTIL_COBJS:%=$(BUILD_DIR)/%) -f
@rm $(UTIL_COBJS:%.o=$(BUILD_DIR)/%.d) -f
clean: clean_snes9x clean_ps3 clean_util
@rm $(PPU_TARGET) $(PPU_TARGET:%.elf=%.self) -f
.PHONY: pkg
pkg: $(PPU_TARGET)
$(STRIP) $(PPU_TARGET)
$(MKFSELF_NPDRM) $(PPU_TARGET) pkg/USRDIR/EBOOT.BIN
$(COPY) -r src/cellframework/extra/shaders pkg/USRDIR/
$(MKPKG_NPDRM) pkg/package.conf pkg

623
PS3-SNES9x-CHANGELOG.txt Normal file
View File

@ -0,0 +1,623 @@
*******************************************************************************
SNES9x PS3
CHANGELOG
*******************************************************************************
===============================================================================
Build 4.4.9 (12-04-2011)
===============================================================================
* Custom Soundtrack support - select a song/album/playlist from the XMB
Music category - music can be played both in-game and from within the menu.
* Added USB/Bluetooth headset support - sound gets output through the
headset.
* Fixed Super Mario RPG level-up freeze.
* Fixed Super Mario World 2: Yoshi's Island save file selection screen graphical
glitch.
* Some filebrowser fixes
* Added 5x scale option.
* Updated Maister Pong - now with sound effects, scoring, two-player support,
nice gameplay mechanics, etc.
===============================================================================
Build 4.4.8 (03-04-2011)
===============================================================================
* Very big performance and lag reduction optimizations. The previous builds
were indeed very laggy - this should be a very big improvement on that front.
* You can now use two shaders at once - we call this 'Custom Scaling/ Dual
Shader' mode. A scaling factor (from 1 to 4x) can be specified.
Some great graphical effects can be achieved by combining shaders.
* Shader presets have been added. Shader presets are configuration files that
automatically configure the settings for 'Shader 1', 'Shader 2', 'Hardware
Filtering Shader 1', 'Hardware Filtering Shader 2', 'Scaling Factor' and
'Overscan'. You can create your own shader presets - they are just
plain-text files stored in USRDIR/presets.
* Controllers can now be individually configured - you can specifically
configure the controls for a controller connected to a specific port/
number.
* Cheat input has been made less buggy. With the 'New' control scheme -
L2 + Analog Stick Right Down will still input cheats with the OSK, but
it will add a generic label (simply the cheatcode itself as a label)
until you rename this generic label by triggering the action 'Input
Cheatlabel'. The 'New' control scheme has this hooked up to 'L2 + R2 +
Analog Stick Right - Down'. This can of course be reconfigured to any
button / button-combo you see fit.
* Fixed interlaced games like Rise Of The Robots - were displaying
glitched graphics before in version 4.4.7.
* Added a homebrew SNES game by Themaister. Game logic is semi-hooked
up - paddle works, ball bounces off the paddle, just scoring has to
be added. Anyway, this has mostly been a 3-day exercise in SNES ASM -
there will be a more useful/fun homebrew game in the future. This is
just for illustrative purposes.
* Added some shader variations and some new shaders - HQ4x, BR4x -
courtesy of Jacaraca.
===============================================================================
Build 4.4.7 (13-03-2011)
===============================================================================
- Added new shaders (waterpaint-normalcontrast, waterpaint-normalcontrast-scanline,
waterpaint-highcontrast, waterpaint-highcontrast-scanline, crt-highgamma)
- Optimized crt, crt-highgamma shaders - both run now at 60fps at 1920x1080.
- Reduced lag.
- Fixed Turbo Mode toggling - works the same now as in 4.4.4.
- Fixed RSound bug with Windows OSes.
- Fixed L2 button mapping issue.
===============================================================================
Build 4.4.6 (16-02-2011)
===============================================================================
- HD version and Normal version merged into one - there are now HD shaders that
do the same as the previous HD version.
* HD shaders (which upscale the resolution to 512x448) instead of hacked
HD version. '4xSoft-HD' is currently the best out of the HD shaders - more to
come.
* The HD version in version 4.4.5 ran in interlaced mode - with the HD
shaders, you can run in either progressive or interlaced mode.
- Fixed PAL50/PAL60 automatic activation in 576i/p mode.
- Fixed Rise Of The Robots interlacing issues - other games which use
interlaced mode also corrected.
- Fixed Multiplayer controls - only player 1 worked.
===============================================================================
Build 4.4.5 (14-02-2010)
===============================================================================
- New HD Version - every game runs at the SNES' high-resolution mode (512x448
interlaced mode). Try this with the right shader on (4xSoft) and this can make
the games look beautiful. Both progressive (1080p/720p/480p/576p) and interlaced
modes (480i/576i/1080i) work with this - try interlaced for best results.
4xSoft combined with this HD version also beautifies the pseudo hi-res
transparent background layers in Kirby's Dreamland 3.
- Triple Buffering option added - enabled by default. Faster graphics/shader
performance with triple buffering turned on - some potential input lag with
triple buffering on - turn it off in case you experience problems of this
nature.
- USB/Bluetooth mouse can be used now for Mouse/Super Scope games.
- Primal Rage works again.
===============================================================================
Build 4.4.4 (19-01-2010)
===============================================================================
- FIXED: (CHRONO TRIGGER SCREEN HEIGHT JUMPING BUG)
===============================================================================
Chrono Trigger would jump from 256x224 to 256x239 for one odd frame when
transitioning from normal mode to battle mode - this caused an undesirable
screen hiccup to occur everytime. This issue has been fixed.
===============================================================================
- FIXED: Player 2 - Buttons X/Y didn't work
===============================================================================
This bug was introduced in v4.4.3 due to an improper macro. It has now been
fixed as of v4.4.4.
===============================================================================
- FIXED: Loading a ROM with a cheatfile loaded and then loading another ROM
with no cheatfile will not clear out the previous game's cheats
===============================================================================
This bug was introduced in v4.4.0, and has now been fixed as of v4.4.4. Also
note that games which do not have a cheatfile will create a new cheatfile
automatically.
===============================================================================
- FIXED: Super Scope controls auto-centered when let go of thumbstick
- ADDED: Better Super Scope controls
===============================================================================
Previously in v4.4.3, the Super Scope crosshair would center back to the middle
of the screen as soon as you let go of the thumbstick on the left analog stick.
Now it controls much more closely to the mouse. Note that there might be an
option to toggle the Super Scope controls in the future (to either auto-center
when let go of the thumbstick or let the cursor stay at the current position).
===============================================================================
- FIXED: Some games were hooked up with patchy controls (Doom)
- ADDED: Accessory Autodetection
===============================================================================
The accessory autodetection in v4.4.2/4.4.3 left some things to be desired.
A new setting has been added to the SNES9x Settings screen - 'Accessory Auto-
detection'.
SNES9x PS3 auto-detects most games that feature support for these peripherals.
This setting will control how SNES9x PS3 will deal with these games when it
detects them.
CONFIRM - When detecting a Mouse/Scope/Multitap-compatible game, a dialog
screen is presented to the user asking him/her if the accessory
should be enabled. If you select 'No', normal 2 joypad controls
will be used instead.
ON - Games which support Mouse/Scope/Multitap will be automatically
detected and the accessory will be automatically enabled without
any input from the user.
OFF - Accessories will not be detected or enabled - standard 2 joypad
controls for all games.
===============================================================================
- ADDED: Control Schemes
===============================================================================
There are now three [Control Schemes] - 'Default', 'New', and 'Custom'.
DEFAULT - Controls are the same as they were before.
NEW - A new control scheme. See below:
R3 + L3 - [Exit to Menu] - go back to the ROM Browser
menu.
Right analog stick - Up - SNES9x pause (supersedes regular SNES pause).
Right analog stick - Left - Decrement fastforward speed by one (-1).
Right analog stick - Right - Increment fastforward speed by one (+1).
Right analog stick - Down - Toggle [Fastforwarding] on/off.
Right analog stick - Left + L2 - Decrement cheat position by one (-1).
Right analog stick - Right + L2 - Increment cheat position by one (+1).
Right analog stick - Up + L2 - Toggle the currently selected cheat on/off.
Right analog stick - Down + L2 - Input a cheat with an on-screen keyboard.
Right analog stick - Left + R2 - Decrement save state slot by one (-1).
Right analog stick - Right + R2 - Increment save state slot by one (+1).
Right analog stick - Up + R2 - Load from currently selected save state slot.
Right analog stick - Down + R2 - Save to currently selected save state slot.
R2 + R3 - Toggle [SRAM Write Protection] on/off.
L2 + R3 - Toggle [Record Movie] on/off.
L2 + L3 - Load Movie
CUSTOM - Custom control scheme. All buttons/button combos can be
customized.
===============================================================================
- ADDED: Savestate SRAM Overwrite Protect
===============================================================================
Implemented by request - see Issue 8: Loading a save state also load the
associated save ram file and write it to disk right away.
(URL: https://code.google.com/p/snes9x-ps3/issues/detail?id=8&can=1)
Normally, when SNES9x loads a savestate, the SRAM contents are automatically
overwritten. The ugly side-effect of this is that this can unknowingly
delete your normal saved game progress.
ON - SNES9x will write-protect SRAM - this means that if you load a save-
state, it will not overwrite the SRAM save(s). However, SRAM is not
saved at all in this mode.
OFF - SRAM is writable - this means that if you load a savestate, it will
overwrite the SRAM save(s).
NOTE: This option can be toggled in-game with the 'New' control scheme by
pressing button combo [R2 + R3].
===============================================================================
- ADDED: Cheat Code Input In-game with Onscreen Keyboard
===============================================================================
Cheatcodes can now be inserted with an onscreen keyboard in-game. A new
action has been added called 'Cheat Input'.
Cheatcodes that you add will be saved to your cheatfile. Currently, the cheat
code will be added in order.
NOTE: This option can be toggled in-game with the 'New' control scheme by
pressing button combo [L2 + Analog Stick Right - Down].
NOTE: There is still a bug that happens after inserting 15/16 cheat codes
in a row.
When this bug happens, you will no longer be presented with the option to
input a label after correctly inputting a cheat. Instead, the label will be
the cheat code itself. This is a memory shortage bug that we hope to fix soon.
===============================================================================
- ADDED: Resolution saving
===============================================================================
Implemented by request - see Issue 18: Screen resolution does not save upon
exit
(URL: https://code.google.com/p/snes9x-ps3/issues/detail?id=18&can=1)
The resolution you had previously played in will now be automatically selected
when you start SNES9x the next time.
There are also sane fallbacks. If SNES9x saved the resolution at 1080p and the
next time you want to play SNES9x you happen to have your PS3 connected to a
screen that doesn't support 1080p - it will fall back to a lower resolution
that your TV does support.
===============================================================================
- ADDED: Throttle Mode
===============================================================================
This is a performance benchmarking feature that might or might not be useful
to users. Turn this 'Off', and VSync and audio will be disabled - the game
will then run at the maximum amount of frames per second (FPS) that the PS3
can manage.
NOTE: There seems to be a hardware/software cap of 124/125fps that appears to
be prevalent even in menus.
===============================================================================
Build 4.4.3 (11-01-2010)
===============================================================================
- Autodetection of Super Scope/Mouse/Multitap had a bug in it - after you
loaded a Super Scope/mouse game and then tried to load a multitap-compatible
game, the game would attempt to hook up the Mouse/Scope instead due to an error
in a switch/case statement. Fixed this.
Autodetection now works as expected. Please upgrade to 4.4.3 as soon as possible
to avoid inconvenient problems.
-==============================================================================
Build 4.4.2 (09-01-2011) - rev. number ?
===============================================================================
* Super Scope and SNES Mouse support. The Super Scope and the Mouse are currently
mapped to the left analog stick - the controls are -
- Circle Button - Scope Toggle Turbo
- Cross Button - Scope Cursor Button
- Triangle Button - Mouse R Button - Scope Aim Off Screen
- Square Button - Mouse L Button -Scope Fire
- Start Button - Scope Pause Button
* Automatic Super Scope/Mouse support detection (works for most games)
* Automatic multitap detection (for most games)
* Automatic PAL50/PAL60 switching (for 576p PAL resolution only)
* Only shows toggleable resolutions now in the Settings menu that your TV supports.
* Fixed Syvalion/R.P.M. Racing/Power Drive (games use 512x448 - flickered
like mad before)
* Added .GD3 ROM extension.
* Added configurable controls - nearly any button/button combo can be
configured. All of the configurable settings are saved of course.
* Some of the new things you can 'bind' buttons to:
- Record movie
- Stop movie
- Playback movie
- Fast forward
- Increase fast-forward speed
- Decrease fast-forward speed
- Reset
- Soft Reset
- Some more shaders (Lanzcos12/Lanzcos16/SuperScale2x - you've probably seen
them already in Genesis Plus/FBA et al - that's because they all use the
same shaders from Cellframework.)
- Sane parental control defaults (you can use this when parental control is
enabled at highest level).
- You can set the SRAM path directory now.
===============================================================================
Build 4.4.1 (15-11-2010) - rev. number da152b168e
===============================================================================
* Added pixel shaders - select them in General Settings.
The following pixel shaders have been added:
- Stock (Default shader)
- 2xSaI
- Blur
- Curved CRT
- HQ2x
- Quad interpolation
- Scanlines
- Sharpen
- Super2xSaI
- SuperEagle
all but SuperEagle, Super2xSaI and Curved CRT run at fullspeed at 1080p 16:9 -
the highest resolution. If a shader doesn't run at fullspeed on that
resolution, 720p resolution will run it just fine at fullspeed.
* PAL60 option works with 1.92 version
* Added a 'Force NTSC ROM to PAL' option in SNES9x Settings
===============================================================================
Build 4.4.0 (12-11-2010) - rev. number 0cb00f8c86
===============================================================================
* PAL issues are fixed at all resolutions - ghosting is gone
* It's now possible to run NTSC ROMs and PAL ROMs alike correctly at 576p PAL
mode. When the setting 'PAL60' is set to ON, a trick will be applied to get
NTSC ROMs to run correctly at 50Hz mode. If set to OFF, it will run PAL ROMs
correctly. Even though PAL ROMs will play normally now at 480p/720p/1080p,
576p still seems to run PAL ROMs slightly better - but it's probably
unnoticeable to the user.
* Cheatcode files can now be loaded and selected/enabled ingame. Note that
all zSNES and SNES9x cheatcode files are supported - everything with the .CHT
extension. You can also set a Cheatfile directory. If you don't set a
Cheatfile directory, the default will be USRDIR.
Cheatfiles must have the same filename as the ROM. Here is how selecting
and enabling cheats works in-game:
Right analog stick - Left + L2 - Move cheat position back by one (-1)
Right analog stick - Right + L2 - Move cheat position forwards by one (+1)
Right analog stick - Up - Enable the currently selected cheat
Right analog stick - Down - Disable the currently selected cheat
Here are two links with some quite useful cheatfiles:
https://code.google.com/p/snes9x-gx/downloads/detail?name=Snes9x%20GX%20Cheat%20Files.zip&can=2&q=
http://zsnes.zophar.net/cht/
===============================================================================
Build 4.3.9 (03-11-2010) - rev. number 49d11492e2
===============================================================================
* Updated to new SNES9x version - now runs the following games that didn't
work before:
- The Mask
* Fixed 16:9 aspect ratio issue - this seems to be a common issue with PS3s
on modern HDTVs. There is now an 'Overscan' option inside the Settings menu
that you can use to get the stretched screen fit just right on your TV screen.
* Settings are saved when exiting the emulator.
* The garbage on the right side of the screen has been fixed
* Two sound modes are now available: Normal (same as it was before) and RSound.
RSound is a networked audio client/server program - with this, you can route
the music from the PS3 (SNES audio in this case) to any laptop/PC/settopbox that
has a media player with either the RSound plugin, or a dedicated RSound server
application (Rsd/Rsdplay). There is a documentation file and a Youtube video
provided to help people to set it up. Latency is as low as it possibly can be -
definitely try it out.
* Major restructuring to the Settings screen.
* The default ROM directory, default savestate directory can now be set inside
the Settings screen.
* 5-player Multitap support (was previously just 4-player)
===============================================================================
Build 4.3.8 (23-10-2010) - rev. number 768cf9df52
===============================================================================
* Updated to new SNES9x version - now runs the following games that didn't
work previously (or had noise instead of sound):
- Earthworm Jim 2
- NBA Hangtime
- MS Pac Man
* PSGL driver built and in use - speed is now better at 1080p than it was
previously at 480p. There's still a resolution switch, but there's no need
anymore to switch to 480p - speed is the same at 1080p as it is on 480p, and
it's damn good for the record. Enjoy.
* All resolutions supported now
* Added simple hardware filtering settings - Linear Interpolation and Point
Filtering. Shaders will come later.
* Added Aspect Ratio settings - 4:3 and 16:10 (HDTVs with 16:9 aspect ratio
might experience that on 16:10, the screen might be slightly cut-off. We're
working on a proper aspect ratio setting for 16:9)
* Can now load configurable settings from snes9x.conf file stored in the
USRDIR folder. Saving of this file will come in the next release.
* Will now select the highest resolution your TV/monitor can support - so is
no longer set to default at 480p.
* No more performance difference between 1.92 pkg and 3.41 pkg.
===============================================================================
Build 4.3.7 (19-10-2010) - rev. number f2e3e0bef2
===============================================================================
* There's now a build for PS3s with firmwares below 3.41 (basically bigger than
or equal to FW 1.92) and a build for PS3s with firmwares 3.41 or higher.
* You can now switch resolutions inside the Settings screen - go from 480p to
720p or vice versa, hence the need for two builds (480p and 720p) eliminated.
* Zipped ROM support (ZIP/JMA)
* Savestates are now compressed as well (NOTE: I don't know what this will
do to your pre-existing savestates. Try to back them up first - they're
inside the USRDIR folder of /dev_hdd0/game/SNES90000/)
* Menu looks a whole lot better now at both 480p and 720p; crappy font has
been put out of commission. It's now actually readable
* Games that switch between SNES resolutions (Seiken Densetsu 3/Secret of
Mana) are now both vertically scaled correctly - you don't even notice the
resolution switch anymore. This is only at 480p mode - in 720p mode you will
notice the same effect as you did previously. This will be worked on. (Halsafar)
* A lot of settings got added to the Settings screen. For instance, it's now
possible (on most PAL games) to run them at 60fps by setting 'Force PAL ROM
to NTSC' to ON. This won't work for every game, however (most games after
1993 came with region protection), and it might even result in a crash
because you're doing something that is not deemed appropriate by either the
SNES hardware or the emulator. A solution for PAL ROMs is worked on.
* You can return to a previous folder inside the ROM menu by pressing the
CIRCLE button.
===============================================================================
Build 4.3.6 (11-10-2010) - rev. number 61ecb6e1c9:
===============================================================================
* Savestates implemented (cmonkey69)
* Settings screen implemented (cmonkey69)
* Some performance improvements noticeable due to switch to more recent
SDK - Jikkyou Oshaberi Parodius now has only a minor frame drop to 57fps on
the character select screen but runs fine everywhere else (at 480p)
===============================================================================
Build 4.3.5 (8-10-2010):
===============================================================================
* Fixed the 'green ROM' loading/crashing bug - it was due to a mistake made
when 'sorting' the file names inside a directory - the variable array that
checked if a file was a directory was not updated. Credit goes to cmonkey69
for fixing his own code :)
* Moved all display code into its own file - celldisplay.cpp /
celldisplayutil.h
* Upgraded to latest SNES9x - git repository:
http://board.byuu.org/viewtopic.php?f=3&t=881
- Contains the following patches/improvements:
- Cx4 improvement (Mega Man X2) -
http://board.byuu.org/viewtopic.php?f=3&t=881
- Fix Dual Orb 2 sound glitch (byuu)
- Updated to latest WIP
- Improvements noticed by myself (mostly APU related):
- Jikkyou Oshaberi Parodius - far better performance - far less sound
pops (this was one of the few games except for SuperFX ones that did
not run perfectly)
- Star Fox/Star Fox 2 have far less sound pops (though still there)
- Super Mario World 2: Yoshi's Island - the spots where framerate dips
and sound pops could usually be noticed have also been improved
* NOTE: These games (SuperFX games - Jikkyou Oshaberi Parodius - SA-1 -
are best played at 480p - the fps stays at 60, but the sound pops are
very irritating at 720p with these few games)
===============================================================================
Build 4.3.4 (3-10-2010):
===============================================================================
* Removed the hack that caused the emulator to exit to the XMB after loading
the fourth ROM - this was to disguise a really bad crashing bug. This hack
no longer seems to be needed.
* If you exit a ROM with L3+R3, you can return back to the game while inside
the ROM Browser menu by pressing L2+R2 simultaneously.
===============================================================================
Build 4.3.3 (2-10-2010):
===============================================================================
* Multitap support. Start a ROM with the Triangle button inside the ROM browser
menu.
- This works on all controllers - PS3/USB joypads - you name it. You can
hotswap them on the fly - you don't have to have them all inserted at the
start of the game - you can insert them later and it will instantly recognize
the second/third/fourth pad as that controller
* Changed SoundInputRate from 31942 to 31960 - I heard a lot of static/
distortion with games like Demon's Crest and Super Metroid at 31942, and
31960 seems to be a huge improvement to that end. 31942 was a SoundInputRate
that I had decided upon back when the emulator was still running at a 60Hz
refresh rate instead of 59.94Hz - now that we're at 59.94Hz, we can increase
the SoundInputRate and get better sound/video synchronization overall. Might
increase this even more in the future - have to do some more tests.
- In any case, as a result of changing this, most games should have improved
sound now.
===============================================================================
Build 4.3.2 (1-10-2010):
===============================================================================
* Totally rewritten controller/input code (check cellpad.cpp/cellpadutil.h).
Theoretically, input lag should be less now since the read_pad loop was
previously hardcoded to do a pass at least two times - now it will check how
many controllers are actually connected. So for instance, if only one
controller is connected, it will only go through this loop where it checks
for button input one time instead of twice - thus reducing clock cycles.
Also there are now function calls available such as cellPadUtilButtonPressed
and cellPadUtilButtonReleased, which could be used in various ways.
* The left analog stick is now mapped to the directional pad.
* The left analog stick now works at the ROM browser menu and is a lot
faster than the D-pad - so use this for browsing in case you have a big ROM
list and the D-pad takes a while to browse through it.
* Files in ROM directories are now alphabetically sorted (cmonkey69)
* ROM browser will return to the last entered directory after quitting ROM
* 'Quit ROM' shortcut changed to R3+L3
* The 480p build in the last version (4.3.1) did not output at 480p but at
576p, because the 576p mode was ticked in the PARAM.SFO. The 480p build
will now display at 480p like it's supposed to.
* Removed the 'Load PAL ROM' option by pressing Triangle at the ROM browser
menu since it serves no purpose at the moment and doesn't do what it's
supposed to.
===============================================================================
Build 4.3.1 (27-9-2010):
===============================================================================
* There's now a 720p build and a 480p one. This is only temporary until I
find a way to manually set resolutions without the PS3 making its own
inferences as to what resolution I would like based on the display settings
toggled in PARAM.SFO.
* Got rid of a duplicate cellGcmFlush(); at the very start of the flip
function - it should not be at the start of the function according to
examples shown. cellGcmFlush basically forces the RSX to process all the
GCM commands buffered in the command buffer - however, in the
same method, this function is already called after resetting the flip
status.
* Made preliminary steps to sort out the PAL problems by allowing the user
to load a ROM with the Triangle button that sets ForcePAL and the refresh
rate to 50Hz. However, there should be a way to get at the region of the
ROM using some sort of Snes9x function call without having to start the
actual ROM that has been loaded. This way, I could set this automatically.
===============================================================================
Build 4.3 (26-9-2010)
===============================================================================
* Aspect ratio set to 4:3 - doesn't yet output at 4:3 though - still big
borders at left and right of the screen
* Better colors
* Runs now at native 480p resolution @ 59.94Hz refresh rate - together with
SoundInputrate (31942), takes care of all audio/video glitches. Basically
runs and performs like a native SNES now - or at least close.
===============================================================================
Build 4.2.2
===============================================================================
* Exits the emulator and returns back to the XMB after having loaded the
fourth ROM to prevent known crashing bug/black screen upon trying to load the
fifth ROM from the ROM browser menu.
===============================================================================
Build 4.2.1
===============================================================================
* Added a 'Quit ROM' shortcut - press R2 + L2 simultaneously in-game to go
back to the ROM browser menu.
===============================================================================
Build 4.2
===============================================================================
* Set SoundInputRate at 31942 (previous setting was 31968), seems to remove
the sound pops. Sound seems to be pretty much perfect now - perhaps later
on return to this and find the ideal value somewhere inbetween 31942 - 31950.
===============================================================================
Build 4
===============================================================================
* Started from scratch - redownloaded 1.52, took everything from eisz to make
it compile for PS3
* Set SoundSync to TRUE
* Set AutoSaveDelay to 0
* Applied the following patches from snes9x-gtk:
- Revision r258 - Add a fixed-point linear resampler option.
- Revision r259 - Use the APU_DEFAULT_RESAMPLER macro.
- Revision r260 - Optimize the linear interpolation macro.
- Revision r272 - Merge zones' timing stuff.
- Revision r282 - Use APU clock that yields 32040hz output instead of 32000.
- Revision r283 - Integrate timing hack variables into the clock ratios to
allow integers in all cases.
- Revision r287 - Don't push samples if there aren't any.
* Finally, the sound scratching is gone as a result of applying all the patches
one after another. People will still want to fiddle around with the
SoundInputRate to get it totally perfect - the crackling is gone, that is no
longer a problem, but if you focus really hard, you will hear a slight pop -
SoundInputRate is now set at 31968 - try lowering it, subtract by 10.
In case this writeup makes it sound like the sound is bad, you will probably
not even notice what I'm talking about here - the sound is pretty much perfect
now.
===============================================================================
Build 3
===============================================================================
* Patch r287 from snes9x-gtk - 'Don't push samples if there aren't any'
* Patch r260 from snes9x-gtk - 'Optimize the linear interpolation macro'
* Patch r272 from snes9x-gtk - 'Merge zones' timing stuff' (bSNES'
SA-1 core integrated in SNES9x + Seiken Densetsu 2/Secret of Mana gamehack)
* Patch r283 from snes9x-gtk - 'Integrate timing hack variables into the clock
ratios to allow integers in all cases.'
* Patch r282 from snes9x-gtk - 'Use APU clock that yields 32040hz output
instead of 32000.' - Together, these two patches seem to fix the sound lag
and pops (but crackling remains).
* Settings.AutoSaveDelay changed from 5 to 0 - SRAM lag fix.
* Settings.SyncSound set to TRUE.
* SFC file support in rudimentary file browser.
===============================================================================
Build 2
===============================================================================
* Patch r283 from snes9x-gtk - 'Integrate timing hack variables into the
clock ratios to allow integers in all cases.'
* Patch r282 from snes9x-gtk - 'Use APU clock that yields 32040hz output
instead of 32000.' - Together, these two patches seem to fix the sound lag
and pops (but crackling remains).

1133
PS3-SNES9x-README.txt Normal file

File diff suppressed because it is too large Load Diff

10
build-all Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
echo ""
echo "EBOOT - make $1"
echo ""
make -f Makefile-eboot-launcher $1
echo ""
echo "SNES9x - make $1"
echo ""
make -f Makefile $1

2
buildtools/PS3Py/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.pyc

BIN
buildtools/PS3Py/ICON0.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,9 @@
all: pkgcrypt.so
pkgcrypt.so: crypt.c setup.py
@python setup.py build --compiler=mingw32
@cp build/lib.*/pkgcrypt.so .
clean:
rm -rf build pkgcrypt.so

282
buildtools/PS3Py/Struct.py Normal file
View File

@ -0,0 +1,282 @@
import struct, sys
class StructType(tuple):
def __getitem__(self, value):
return [self] * value
def __call__(self, value, endian='<'):
if isinstance(value, str):
return struct.unpack(endian + tuple.__getitem__(self, 0), value[:tuple.__getitem__(self, 1)])[0]
else:
return struct.pack(endian + tuple.__getitem__(self, 0), value)
class StructException(Exception):
pass
class Struct(object):
__slots__ = ('__attrs__', '__baked__', '__defs__', '__endian__', '__next__', '__sizes__', '__values__')
int8 = StructType(('b', 1))
uint8 = StructType(('B', 1))
int16 = StructType(('h', 2))
uint16 = StructType(('H', 2))
int32 = StructType(('l', 4))
uint32 = StructType(('L', 4))
int64 = StructType(('q', 8))
uint64 = StructType(('Q', 8))
float = StructType(('f', 4))
def string(cls, len, offset=0, encoding=None, stripNulls=False, value=''):
return StructType(('string', (len, offset, encoding, stripNulls, value)))
string = classmethod(string)
LE = '<'
BE = '>'
__endian__ = '<'
def __init__(self, func=None, unpack=None, **kwargs):
self.__defs__ = []
self.__sizes__ = []
self.__attrs__ = []
self.__values__ = {}
self.__next__ = True
self.__baked__ = False
if func == None:
self.__format__()
else:
sys.settrace(self.__trace__)
func()
for name in func.func_code.co_varnames:
value = self.__frame__.f_locals[name]
self.__setattr__(name, value)
self.__baked__ = True
if unpack != None:
if isinstance(unpack, tuple):
self.unpack(*unpack)
else:
self.unpack(unpack)
if len(kwargs):
for name in kwargs:
self.__values__[name] = kwargs[name]
def __trace__(self, frame, event, arg):
self.__frame__ = frame
sys.settrace(None)
def __setattr__(self, name, value):
if name in self.__slots__:
return object.__setattr__(self, name, value)
if self.__baked__ == False:
if not isinstance(value, list):
value = [value]
attrname = name
else:
attrname = '*' + name
self.__values__[name] = None
for sub in value:
if isinstance(sub, Struct):
sub = sub.__class__
try:
if issubclass(sub, Struct):
sub = ('struct', sub)
except TypeError:
pass
type_, size = tuple(sub)
if type_ == 'string':
self.__defs__.append(Struct.string)
self.__sizes__.append(size)
self.__attrs__.append(attrname)
self.__next__ = True
if attrname[0] != '*':
self.__values__[name] = size[3]
elif self.__values__[name] == None:
self.__values__[name] = [size[3] for val in value]
elif type_ == 'struct':
self.__defs__.append(Struct)
self.__sizes__.append(size)
self.__attrs__.append(attrname)
self.__next__ = True
if attrname[0] != '*':
self.__values__[name] = size()
elif self.__values__[name] == None:
self.__values__[name] = [size() for val in value]
else:
if self.__next__:
self.__defs__.append('')
self.__sizes__.append(0)
self.__attrs__.append([])
self.__next__ = False
self.__defs__[-1] += type_
self.__sizes__[-1] += size
self.__attrs__[-1].append(attrname)
if attrname[0] != '*':
self.__values__[name] = 0
elif self.__values__[name] == None:
self.__values__[name] = [0 for val in value]
else:
try:
self.__values__[name] = value
except KeyError:
raise AttributeError(name)
def __getattr__(self, name):
if self.__baked__ == False:
return name
else:
try:
return self.__values__[name]
except KeyError:
raise AttributeError(name)
def __len__(self):
ret = 0
arraypos, arrayname = None, None
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size] + offset
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arrayname = attrs
arraypos = 0
size = len(self.__values__[attrs[1:]][arraypos])
size = len(self.__values__[attrs])
ret += size
return ret
def unpack(self, data, pos=0):
for name in self.__values__:
if not isinstance(self.__values__[name], Struct):
self.__values__[name] = None
elif self.__values__[name].__class__ == list and len(self.__values__[name]) != 0:
if not isinstance(self.__values__[name][0], Struct):
self.__values__[name] = None
arraypos, arrayname = None, None
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size] + offset
temp = data[pos:pos+size]
if len(temp) != size:
raise StructException('Expected %i byte string, got %i' % (size, len(temp)))
if encoding != None:
temp = temp.decode(encoding)
if stripNulls:
temp = temp.rstrip('\0')
if attrs[0] == '*':
name = attrs[1:]
if self.__values__[name] == None:
self.__values__[name] = []
self.__values__[name].append(temp)
else:
self.__values__[attrs] = temp
pos += size
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arrayname = attrs
arraypos = 0
name = attrs[1:]
self.__values__[attrs][arraypos].unpack(data, pos)
pos += len(self.__values__[attrs][arraypos])
arraypos += 1
else:
self.__values__[attrs].unpack(data, pos)
pos += len(self.__values__[attrs])
else:
values = struct.unpack(self.__endian__+sdef, data[pos:pos+size])
pos += size
j = 0
for name in attrs:
if name[0] == '*':
name = name[1:]
if self.__values__[name] == None:
self.__values__[name] = []
self.__values__[name].append(values[j])
else:
self.__values__[name] = values[j]
j += 1
return self
def pack(self):
arraypos, arrayname = None, None
ret = ''
for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
if sdef == Struct.string:
size, offset, encoding, stripNulls, value = size
if isinstance(size, str):
size = self.__values__[size]+offset
if attrs[0] == '*':
if arrayname != attrs:
arraypos = 0
arrayname = attrs
temp = self.__values__[attrs[1:]][arraypos]
arraypos += 1
else:
temp = self.__values__[attrs]
if encoding != None:
temp = temp.encode(encoding)
temp = temp[:size]
ret += temp + ('\0' * (size - len(temp)))
elif sdef == Struct:
if attrs[0] == '*':
if arrayname != attrs:
arraypos = 0
arrayname = attrs
ret += self.__values__[attrs[1:]][arraypos].pack()
arraypos += 1
else:
ret += self.__values__[attrs].pack()
else:
values = []
for name in attrs:
if name[0] == '*':
if arrayname != name:
arraypos = 0
arrayname = name
values.append(self.__values__[name[1:]][arraypos])
arraypos += 1
else:
values.append(self.__values__[name])
ret += struct.pack(self.__endian__+sdef, *values)
return ret
def __getitem__(self, value):
return [('struct', self.__class__)] * value

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
LIBRARY pkgcrypt.pyd
EXPORTS
initpkgcrypt

97
buildtools/PS3Py/crypt.c Normal file
View File

@ -0,0 +1,97 @@
#include <Python.h>
static PyObject *sha1_callback = NULL;
static void manipulate(uint8_t *key) {
uint64_t temp = key[0x38] << 56|
key[0x39] << 48|
key[0x3a] << 40|
key[0x3b] << 32|
key[0x3c] << 24|
key[0x3d] << 16|
key[0x3e] << 8|
key[0x3f];
temp++;
key[0x38] = (temp >> 56) & 0xff;
key[0x39] = (temp >> 48) & 0xff;
key[0x3a] = (temp >> 40) & 0xff;
key[0x3b] = (temp >> 32) & 0xff;
key[0x3c] = (temp >> 24) & 0xff;
key[0x3d] = (temp >> 16) & 0xff;
key[0x3e] = (temp >> 8) & 0xff;
key[0x3f] = (temp >> 0) & 0xff;
}
static PyObject* pkg_crypt(PyObject *self, PyObject *args) {
uint8_t *key, *input, *ret;
int key_length, input_length, length;
int remaining, i, offset=0;
PyObject *arglist;
PyObject *result;
if (!PyArg_ParseTuple(args, "s#s#i", &key, &key_length, &input, &input_length, &length))
return NULL;
ret = malloc(length);
remaining = length;
while (remaining > 0) {
int bytes_to_dump = remaining;
if (bytes_to_dump > 0x10)
bytes_to_dump = 0x10;
// outhash = SHA1(listToString(key)[0:0x40])
uint8_t *outHash;
{
arglist = Py_BuildValue("(s#)", key, 0x40);
result = PyObject_CallObject(sha1_callback, arglist);
Py_DECREF(arglist);
if (!result) return NULL;
int outHash_length;
if (!PyArg_Parse(result, "s#", &outHash, &outHash_length)) return NULL;
}
for(i = 0; i < bytes_to_dump; i++) {
ret[offset] = outHash[i] ^ input[offset];
offset++;
}
Py_DECREF(result);
manipulate(key);
remaining -= bytes_to_dump;
}
// Return the encrypted data
PyObject *py_ret = Py_BuildValue("s#", ret, length);
free(ret);
return py_ret;
}
static PyObject *register_sha1_callback(PyObject *self, PyObject *args) {
PyObject *result = NULL;
PyObject *temp;
if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
if (!PyCallable_Check(temp)) {
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}
Py_XINCREF(temp); /* Add a reference to new callback */
Py_XDECREF(sha1_callback); /* Dispose of previous callback */
sha1_callback = temp; /* Remember new callback */
/* Boilerplate to return "None" */
Py_INCREF(Py_None);
result = Py_None;
}
return result;
}
static PyMethodDef cryptMethods[] = {
{"pkgcrypt", pkg_crypt, METH_VARARGS, "C implementation of pkg.py's crypt function"},
{"register_sha1_callback", register_sha1_callback, METH_VARARGS, "Register a callback to python's SHA1 function, so we don't have to bother with creating our own implementation."},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initpkgcrypt(void) {
(void) Py_InitModule("pkgcrypt", cryptMethods);
}

275
buildtools/PS3Py/fself.py Normal file
View File

@ -0,0 +1,275 @@
#!/usr/bin/env python
from __future__ import with_statement
from Struct import Struct
import struct
import getopt
import sys
"""
This is a quick and dirty implementation of make_fself based on the
documentation collected here:
http://ps3wiki.lan.st/index.php/Self_file_format
It's not ment to look pretty, or be well documented but just provide
an alternative to using the illegal Sony SDK until a better solution
is released. (Such as a propper ELF loader built into lv2)
-- phiren
"""
class SelfHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.headerVer = Struct.uint32
self.flags = Struct.uint16
self.type = Struct.uint16
self.meta = Struct.uint32
self.headerSize = Struct.uint64
self.encryptedSize = Struct.uint64
self.unknown = Struct.uint64
self.AppInfo = Struct.uint64
self.elf = Struct.uint64
self.phdr = Struct.uint64
self.shdr = Struct.uint64
self.phdrOffsets = Struct.uint64
self.sceversion = Struct.uint64
self.digest = Struct.uint64
self.digestSize = Struct.uint64
class AppInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.authid = Struct.uint64
self.unknown = Struct.uint32
self.appType = Struct.uint32
self.appVersion = Struct.uint64
class phdrOffset(Struct):
__endian__ = Struct.BE
def __format__(self):
self.offset = Struct.uint64
self.size = Struct.uint64
self.unk1 = Struct.uint32
self.unk2 = Struct.uint32
self.unk3 = Struct.uint32
self.unk4 = Struct.uint32
class DigestSubHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.type = Struct.uint32
self.size = Struct.uint32
self.cont = Struct.uint64
class DigestType2(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magicBits = Struct.uint8[0x14]
self.digest = Struct.uint8[0x14]
self.padding = Struct.uint8[0x08]
class DigestTypeNPDRM(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.unk1 = Struct.uint32
self.drmType = Struct.uint32
self.unk2 = Struct.uint32
self.contentID = Struct.uint8[0x30]
self.fileSHA1 = Struct.uint8[0x10]
self.notSHA1 = Struct.uint8[0x10]
self.notXORKLSHA1 = Struct.uint8[0x10]
class Elf64_ehdr(Struct):
__endian__ = Struct.BE
def __format__(self):
self.ident = Struct.uint8[16]
self.type = Struct.uint16
self.machine = Struct.uint16
self.version = Struct.uint32
self.entry = Struct.uint64
self.phoff = Struct.uint64
self.shoff = Struct.uint64
self.flags = Struct.uint32
self.ehsize = Struct.uint16
self.phentsize = Struct.uint16
self.phnum = Struct.uint16
self.shentsize = Struct.uint16
self.shnum = Struct.uint16
self.shstrndx = Struct.uint16
class Elf64_phdr(Struct):
__endian__ = Struct.BE
def __format__(self):
self.type = Struct.uint32
self.flags = Struct.uint32
self.offset = Struct.uint64
self.vaddr = Struct.uint64
self.paddr = Struct.uint64
self.filesz = Struct.uint64
self.memsz = Struct.uint64
self.align = Struct.uint64
def align(address, alignment):
padding = alignment - (address % alignment)
return address + padding
def padding(address, alignment):
padding = alignment - (address % alignment)
return "\0" * padding
def readElf(infile):
with open(infile, 'rb') as fp:
data = fp.read()
ehdr = Elf64_ehdr()
ehdr.unpack(data[0:len(ehdr)])
phdrs = []
offset = ehdr.phoff
for i in range(ehdr.phnum):
phdr = Elf64_phdr()
phdr.unpack(data[offset:offset+len(phdr)])
offset += len(phdr)
phdrs.append(phdr)
return data, ehdr, phdrs
def genDigest(out, npdrm):
digestSubHeader = DigestSubHeader()
digestType2 = DigestType2()
digestTypeNPDRM = DigestTypeNPDRM()
digestSubHeader.type = 2
digestSubHeader.size = 0x40
if npdrm:
digestSubHeader.cont = 1
out.write(digestSubHeader.pack())
digestType2.magicBits = (0x62, 0x7c, 0xb1, 0x80, 0x8a, 0xb9, 0x38, 0xe3, 0x2c, 0x8c, 0x09, 0x17, 0x08, 0x72, 0x6a, 0x57, 0x9e, 0x25, 0x86, 0xe4)
out.write(digestType2.pack())
if not npdrm:
return
digestSubHeader.type = 3
digestSubHeader.size = 0x90
digestSubHeader.cont = 0
out.write(digestSubHeader.pack())
digestTypeNPDRM.magic = 0x4e504400
digestTypeNPDRM.unk1 = 1
digestTypeNPDRM.drmType = 2
digestTypeNPDRM.unk2 = 1
digestTypeNPDRM.contentID = [0x30] * 0x2f + [0]
digestTypeNPDRM.fileSHA1 = (0x42, 0x69, 0x74, 0x65, 0x20, 0x4d, 0x65, 0x2c, 0x20, 0x53, 0x6f, 0x6e, 0x79, 0x00, 0xde, 0x07)
digestTypeNPDRM.notSHA1 = [0xab] * 0x10
digestTypeNPDRM.notXORKLSHA1 = [0x01] * 0x0f + [0x02]
out.write(digestTypeNPDRM.pack())
def createFself(npdrm, infile, outfile="EBOOT.BIN"):
elf, ehdr, phdrs = readElf(infile)
header = SelfHeader()
appinfo = AppInfo()
digestSubHeader = DigestSubHeader()
digestType2 = DigestType2()
digestTypeNPDRM = DigestTypeNPDRM()
phdr = Elf64_phdr()
phdrOffsets = phdrOffset()
header.magic = 0x53434500
header.headerVer = 2
header.flags = 0x8000
header.type = 1
header.encryptedSize = len(elf)
header.unknown = 3
header.AppInfo = align(len(header), 0x10)
header.elf = align(header.AppInfo + len(appinfo), 0x10)
header.phdr = header.elf + len(ehdr)
phdrOffsetsOffset = header.phdr + len(phdr) * len(phdrs)
header.phdrOffsets = align(phdrOffsetsOffset, 0x10);
header.sceVersion = 0
digestOffset = header.phdrOffsets + len(phdrs) * len(phdrOffsets)
header.digest = align(digestOffset, 0x10)
header.digestSize = len(digestSubHeader) + len(digestType2
)
if npdrm:
header.digestSize += len(digestSubHeader) + len(digestTypeNPDRM)
endofHeader = header.digest + header.digestSize
elfOffset = align(endofHeader, 0x80)
header.shdr = elfOffset + ehdr.shoff
header.headerSize = elfOffset
header.meta = endofHeader - 0x10
appinfo.authid = 0x1010000001000003
appinfo.unknown = 0x1000002
if npdrm:
appinfo.appType = 0x8
else:
appinfo.appType = 0x4
appinfo.appVersion = 0x0001000000000000
offsets = []
for phdr in phdrs:
offset = phdrOffset()
offset.offset = phdr.offset + elfOffset
offset.size = phdr.filesz
offset.unk1 = 1
offset.unk2 = 0
offset.unk3 = 0
if phdr.type == 1:
offset.unk4 = 2
else:
offset.unk4 = 0
offsets.append(offset)
out = open(outfile, 'wb')
out.write(header.pack())
out.write(padding(len(header), 0x10))
out.write(appinfo.pack())
out.write(padding(header.AppInfo + len(appinfo), 0x10))
out.write(ehdr.pack())
for phdr in phdrs:
out.write(phdr.pack())
out.write(padding(phdrOffsetsOffset, 0x10))
for offset in offsets:
out.write(offset.pack())
out.write(padding(digestOffset, 0x10))
genDigest(out, npdrm)
out.write(padding(endofHeader, 0x80))
out.write(elf)
def usage():
print """fself.py usage:
fself.py [options] input.elf output.self
If output file is not specified, fself.py will default to EBOOT.BIN
Options:
--npdrm: will output a file for use with pkg.py."""
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "hn", ["help", "npdrm"])
except getopt.GetoptError:
usage()
sys.exit(2)
npdrm = False
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit(2)
elif opt in ("-n", "--npdrm"):
npdrm = True
else:
usage()
if len(args) == 1:
createFself(npdrm, args[0])
elif len(args) == 2:
createFself(npdrm, args[0], args[1])
else:
usage()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,2 @@
make.exe
pause

601
buildtools/PS3Py/pkg.py Normal file
View File

@ -0,0 +1,601 @@
#!/usr/bin/env python
from __future__ import with_statement
from Struct import Struct
from fself import SelfHeader, AppInfo
import struct
import sys
import hashlib
import os
import getopt
import ConfigParser
import io
import glob
TYPE_NPDRMSELF = 0x1
TYPE_RAW = 0x3
TYPE_DIRECTORY = 0x4
TYPE_OVERWRITE_ALLOWED = 0x80000000
debug = False
class EbootMeta(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.unk1 = Struct.uint32
self.drmType = Struct.uint32
self.unk2 = Struct.uint32
self.contentID = Struct.uint8[0x30]
self.fileSHA1 = Struct.uint8[0x10]
self.notSHA1 = Struct.uint8[0x10]
self.notXORKLSHA1 = Struct.uint8[0x10]
self.nulls = Struct.uint8[0x10]
class MetaHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.unk1 = Struct.uint32
self.unk2 = Struct.uint32
self.drmType = Struct.uint32
self.unk4 = Struct.uint32
self.unk21 = Struct.uint32
self.unk22 = Struct.uint32
self.unk23 = Struct.uint32
self.unk24 = Struct.uint32
self.unk31 = Struct.uint32
self.unk32 = Struct.uint32
self.unk33 = Struct.uint32
self.secondaryVersion = Struct.uint16
self.unk34 = Struct.uint16
self.dataSize = Struct.uint32
self.unk42 = Struct.uint32
self.unk43 = Struct.uint32
self.packagedBy = Struct.uint16
self.packageVersion = Struct.uint16
class DigestBlock(Struct):
__endian__ = Struct.BE
def __format__(self):
self.type = Struct.uint32
self.size = Struct.uint32
self.isNext = Struct.uint64
class FileHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.fileNameOff = Struct.uint32
self.fileNameLength = Struct.uint32
self.fileOff = Struct.uint64
self.fileSize = Struct.uint64
self.flags = Struct.uint32
self.padding = Struct.uint32
def __str__(self):
out = ""
out += "[X] File Name: %s [" % self.fileName
if self.flags & 0xFF == TYPE_NPDRMSELF:
out += "NPDRM Self]"
elif self.flags & 0xFF == TYPE_DIRECTORY:
out += "Directory]"
elif self.flags & 0xFF == TYPE_RAW:
out += "Raw Data]"
else:
out += "Unknown]"
if (self.flags & TYPE_OVERWRITE_ALLOWED ) != 0:
out += " Overwrite allowed.\n"
else:
out += " Overwrite NOT allowed.\n"
out += "\n"
out += "[X] File Name offset: %08x\n" % self.fileNameOff
out += "[X] File Name Length: %08x\n" % self.fileNameLength
out += "[X] Offset To File Data: %016x\n" % self.fileOff
out += "[X] File Size: %016x\n" % self.fileSize
out += "[X] Flags: %08x\n" % self.flags
out += "[X] Padding: %08x\n\n" % self.padding
assert self.padding == 0, "I guess I was wrong, this is not padding."
return out
def __repr__(self):
return self.fileName + ("<FileHeader> Size: 0x%016x" % self.fileSize)
def __init__(self):
Struct.__init__(self)
self.fileName = ""
def doWork(self, decrypteddata, context = None):
if context == None:
self.fileName = nullterm(decrypteddata[self.fileNameOff:self.fileNameOff+self.fileNameLength])
else:
self.fileName = nullterm(crypt(context, decrypteddata[self.fileNameOff:self.fileNameOff+self.fileNameLength], self.fileNameLength))
def dump(self, directory, data, header):
if self.flags & 0xFF == 0x4:
try:
os.makedirs(directory + "/" + self.fileName)
except Exception, e:
print
else:
tFile = open(directory + "/" + self.fileName, "wb")
tFile.write(data[self.fileOff:self.fileOff+self.fileSize])
class Header(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.type = Struct.uint32
self.pkgInfoOff = Struct.uint32
self.unk1 = Struct.uint32
self.headSize = Struct.uint32
self.itemCount = Struct.uint32
self.packageSize = Struct.uint64
self.dataOff = Struct.uint64
self.dataSize = Struct.uint64
self.contentID = Struct.uint8[0x30]
self.QADigest = Struct.uint8[0x10]
self.KLicensee = Struct.uint8[0x10]
def __str__(self):
context = keyToContext(self.QADigest)
setContextNum(context, 0xFFFFFFFFFFFFFFFF)
licensee = crypt(context, listToString(self.KLicensee), 0x10)
out = ""
out += "[X] Magic: %08x\n" % self.magic
out += "[X] Type: %08x\n" % self.type
out += "[X] Offset to package info: %08x\n" % self.pkgInfoOff
out += "[ ] unk1: %08x\n" % self.unk1
out += "[X] Head Size: %08x\n" % self.headSize
out += "[X] Item Count: %08x\n" % self.itemCount
out += "[X] Package Size: %016x\n" % self.packageSize
out += "[X] Data Offset: %016x\n" % self.dataOff
out += "[X] Data Size: %016x\n" % self.dataSize
out += "[X] ContentID: '%s'\n" % (nullterm(self.contentID))
out += "[X] QA_Digest: %s\n" % (nullterm(self.QADigest, True))
out += "[X] K Licensee: %s\n" % licensee.encode('hex')
return out
def listToString(inlist):
if isinstance(inlist, list):
return ''.join(["%c" % el for el in inlist])
else:
return ""
def nullterm(str_plus, printhex=False):
if isinstance(str_plus, list):
if printhex:
str_plus = ''.join(["%X" % el for el in str_plus])
else:
str_plus = listToString(str_plus)
z = str_plus.find('\0')
if z != -1:
return str_plus[:z]
else:
return str_plus
def keyToContext(key):
if isinstance(key, list):
key = listToString(key)
key = key[0:16]
largekey = []
for i in range(0, 8):
largekey.append(ord(key[i]))
for i in range(0, 8):
largekey.append(ord(key[i]))
for i in range(0, 8):
largekey.append(ord(key[i+8]))
for i in range(0, 8):
largekey.append(ord(key[i+8]))
for i in range(0, 0x20):
largekey.append(0)
return largekey
#Thanks to anonymous for the help with the RE of this part,
# the x86 mess of ands and ors made my head go BOOM headshot.
def manipulate(key):
if not isinstance(key, list):
return
tmp = listToString(key[0x38:])
tmpnum = struct.unpack('>Q', tmp)[0]
tmpnum += 1
tmpnum = tmpnum & 0xFFFFFFFFFFFFFFFF
setContextNum(key, tmpnum)
def setContextNum(key, tmpnum):
tmpchrs = struct.pack('>Q', tmpnum)
key[0x38] = ord(tmpchrs[0])
key[0x39] = ord(tmpchrs[1])
key[0x3a] = ord(tmpchrs[2])
key[0x3b] = ord(tmpchrs[3])
key[0x3c] = ord(tmpchrs[4])
key[0x3d] = ord(tmpchrs[5])
key[0x3e] = ord(tmpchrs[6])
key[0x3f] = ord(tmpchrs[7])
import pkgcrypt
def crypt(key, inbuf, length):
if not isinstance(key, list):
return ""
# Call our ultra fast c implemetation
return pkgcrypt.pkgcrypt(listToString(key), inbuf, length);
# Original python (slow) implementation
ret = ""
offset = 0
while length > 0:
bytes_to_dump = length
if length > 0x10:
bytes_to_dump = 0x10
outhash = SHA1(listToString(key)[0:0x40])
for i in range(0, bytes_to_dump):
ret += chr(ord(outhash[i]) ^ ord(inbuf[offset]))
offset += 1
manipulate(key)
length -= bytes_to_dump
return ret
def SHA1(data):
m = hashlib.sha1()
m.update(data)
return m.digest()
pkgcrypt.register_sha1_callback(SHA1)
def listPkg(filename):
with open(filename, 'rb') as fp:
data = fp.read()
offset = 0
header = Header()
header.unpack(data[offset:offset+len(header)])
print header
print
assert header.type == 0x00000001, 'Unsupported Type'
if header.itemCount > 0:
print 'Listing: "' + filename + '"'
print "+) overwrite, -) no overwrite"
print
dataEnc = data[header.dataOff:header.dataOff+header.dataSize]
context = keyToContext(header.QADigest)
decData = crypt(context, dataEnc, len(FileHeader())*header.itemCount)
fileDescs = []
for i in range(0, header.itemCount):
fileD = FileHeader()
fileD.unpack(decData[0x20 * i:0x20 * i + 0x20])
fileDescs.append(fileD)
for fileD in fileDescs:
fileD.doWork(dataEnc, context)
out = ""
if fileD.flags & 0xFF == TYPE_NPDRMSELF:
out += " NPDRM SELF:"
elif fileD.flags & 0xFF == TYPE_DIRECTORY:
out += " directory:"
elif fileD.flags & 0xFF == TYPE_RAW:
out += " raw data:"
else:
out += " unknown:"
if (fileD.flags & TYPE_OVERWRITE_ALLOWED ) != 0:
out += "+"
else:
out += "-"
out += "%11d: " % fileD.fileSize
out += fileD.fileName
print out,
print
#print fileD
def unpack(filename):
with open(filename, 'rb') as fp:
data = fp.read()
offset = 0
header = Header()
header.unpack(data[offset:offset+len(header)])
if debug:
print header
print
assert header.type == 0x00000001, 'Unsupported Type'
if header.itemCount > 0:
dataEnc = data[header.dataOff:header.dataOff+header.dataSize]
context = keyToContext(header.QADigest)
decData = crypt(context, dataEnc, header.dataSize)
directory = nullterm(header.contentID)
try:
os.makedirs(directory)
except Exception, e:
pass
fileDescs = []
for i in range(0, header.itemCount):
fileD = FileHeader()
fileD.unpack(decData[0x20 * i:0x20 * i + 0x20])
fileD.doWork(decData)
fileDescs.append(fileD)
if debug:
print fileD
fileD.dump(directory, decData, header)
def getFiles(files, folder, original):
oldfolder = folder
foundFiles = glob.glob( os.path.join(folder, '*') )
sortedList = []
for filepath in foundFiles:
if not os.path.isdir(filepath):
sortedList.append(filepath)
for filepath in foundFiles:
if os.path.isdir(filepath):
sortedList.append(filepath)
for filepath in sortedList:
newpath = filepath.replace("\\", "/")
newpath = newpath[len(original):]
if os.path.isdir(filepath):
folder = FileHeader()
folder.fileName = newpath
folder.fileNameOff = 0
folder.fileNameLength = len(folder.fileName)
folder.fileOff = 0
folder.fileSize = 0
folder.flags = TYPE_OVERWRITE_ALLOWED | TYPE_DIRECTORY
folder.padding = 0
files.append(folder)
getFiles(files, filepath, original)
else:
file = FileHeader()
file.fileName = newpath
file.fileNameOff = 0
file.fileNameLength = len(file.fileName)
file.fileOff = 0
file.fileSize = os.path.getsize(filepath)
file.flags = TYPE_OVERWRITE_ALLOWED | TYPE_RAW
if newpath == "USRDIR/EBOOT.BIN":
file.fileSize = ((file.fileSize - 0x30 + 63) & ~63) + 0x30
file.flags = TYPE_OVERWRITE_ALLOWED | TYPE_NPDRMSELF
file.padding = 0
files.append(file)
def pack(folder, contentid, outname=None):
qadigest = hashlib.sha1()
header = Header()
header.magic = 0x7F504B47
header.type = 0x01
header.pkgInfoOff = 0xC0
header.unk1 = 0x05
header.headSize = 0x80
header.itemCount = 0
header.packageSize = 0
header.dataOff = 0x140
header.dataSize = 0
for i in range(0, 0x30):
header.contentID[i] = 0
for i in range(0,0x10):
header.QADigest[i] = 0
header.KLicensee[i] = 0
metaBlock = MetaHeader()
metaBlock.unk1 = 1 #doesnt change output of --extract
metaBlock.unk2 = 4 #doesnt change output of --extract
metaBlock.drmType = 3 #1 = Network, 2 = Local, 3 = Free, anything else = unknown
metaBlock.unk4 = 2
metaBlock.unk21 = 4
metaBlock.unk22 = 5 #5 == gameexec, 4 == gamedata
metaBlock.unk23 = 3
metaBlock.unk24 = 4
metaBlock.unk31 = 0xE #packageType 0x10 == patch, 0x8 == Demo&Key, 0x0 == Demo&Key (AND UserFiles = NotOverWrite), 0xE == normal, use 0xE for gamexec, and 8 for gamedata
metaBlock.unk32 = 4 #when this is 5 secondary version gets used??
metaBlock.unk33 = 8 #doesnt change output of --extract
metaBlock.secondaryVersion = 0
metaBlock.unk34 = 0
metaBlock.dataSize = 0
metaBlock.unk42 = 5
metaBlock.unk43 = 4
metaBlock.packagedBy = 0x1061
metaBlock.packageVersion = 0
files = []
getFiles(files, folder, folder)
header.itemCount = len(files)
dataToEncrypt = ""
fileDescLength = 0
fileOff = 0x20 * len(files)
for file in files:
alignedSize = (file.fileNameLength + 0x0F) & ~0x0F
file.fileNameOff = fileOff
fileOff += alignedSize
for file in files:
file.fileOff = fileOff
fileOff += (file.fileSize + 0x0F) & ~0x0F
dataToEncrypt += file.pack()
for file in files:
alignedSize = (file.fileNameLength + 0x0F) & ~0x0F
dataToEncrypt += file.fileName
dataToEncrypt += "\0" * (alignedSize-file.fileNameLength)
fileDescLength = len(dataToEncrypt)
for file in files:
if not file.flags & 0xFF == TYPE_DIRECTORY:
path = os.path.join(folder, file.fileName)
fp = open(path, 'rb')
fileData = fp.read()
qadigest.update(fileData)
fileSHA1 = SHA1(fileData)
fp.close()
if fileData[0:9] == "SCE\0\0\0\0\x02\x80":
fselfheader = SelfHeader()
fselfheader.unpack(fileData[0:len(fselfheader)])
appheader = AppInfo()
appheader.unpack(fileData[fselfheader.AppInfo:fselfheader.AppInfo+len(appheader)])
found = False
digestOff = fselfheader.digest
while not found:
digest = DigestBlock()
digest.unpack(fileData[digestOff:digestOff+len(digest)])
if digest.type == 3:
found = True
else:
digestOff += digest.size
if digest.isNext != 1:
break
digestOff += len(digest)
if appheader.appType == 8 and found:
dataToEncrypt += fileData[0:digestOff]
meta = EbootMeta()
meta.magic = 0x4E504400
meta.unk1 = 1
meta.drmType = metaBlock.drmType
meta.unk2 = 1
for i in range(0,min(len(contentid), 0x30)):
meta.contentID[i] = ord(contentid[i])
for i in range(0,0x10):
meta.fileSHA1[i] = ord(fileSHA1[i])
meta.notSHA1[i] = (~meta.fileSHA1[i]) & 0xFF
if i == 0xF:
meta.notXORKLSHA1[i] = (1 ^ meta.notSHA1[i] ^ 0xAA) & 0xFF
else:
meta.notXORKLSHA1[i] = (0 ^ meta.notSHA1[i] ^ 0xAA) & 0xFF
meta.nulls[i] = 0
dataToEncrypt += meta.pack()
dataToEncrypt += fileData[digestOff + 0x80:]
else:
dataToEncrypt += fileData
else:
dataToEncrypt += fileData
dataToEncrypt += '\0' * (((file.fileSize + 0x0F) & ~0x0F) - len(fileData))
header.dataSize = len(dataToEncrypt)
metaBlock.dataSize = header.dataSize
header.packageSize = header.dataSize + 0x1A0
head = header.pack()
qadigest.update(head)
qadigest.update(dataToEncrypt[0:fileDescLength])
QA_Digest = qadigest.digest()
for i in range(0, 0x10):
header.QADigest[i] = ord(QA_Digest[i])
for i in range(0, min(len(contentid), 0x30)):
header.contentID[i] = ord(contentid[i])
context = keyToContext(header.QADigest)
setContextNum(context, 0xFFFFFFFFFFFFFFFF)
licensee = crypt(context, listToString(header.KLicensee), 0x10)
for i in range(0, min(len(contentid), 0x10)):
header.KLicensee[i] = ord(licensee[i])
if outname != None:
outFile = open(outname, 'wb')
else:
outFile = open(contentid + ".pkg", 'wb')
outFile.write(header.pack())
headerSHA = SHA1(header.pack())[3:19]
outFile.write(headerSHA)
metaData = metaBlock.pack()
metaBlockSHA = SHA1(metaData)[3:19]
metaBlockSHAPad = '\0' * 0x30
context = keyToContext([ord(c) for c in metaBlockSHA])
metaBlockSHAPadEnc = crypt(context, metaBlockSHAPad, 0x30)
context = keyToContext([ord(c) for c in headerSHA])
metaBlockSHAPadEnc2 = crypt(context, metaBlockSHAPadEnc, 0x30)
outFile.write(metaBlockSHAPadEnc2)
outFile.write(metaData)
outFile.write(metaBlockSHA)
outFile.write(metaBlockSHAPadEnc)
context = keyToContext(header.QADigest)
encData = crypt(context, dataToEncrypt, header.dataSize)
outFile.write(encData)
outFile.write('\0' * 0x60)
outFile.close()
print header
def usage():
print """usage: [based on revision 1061]
python pkg.py target-directory [out-file]
python pkg.py [options] npdrm-package
-l | --list list packaged files.
-x | --extract extract package.
python pkg.py [options]
--version print revision.
--help print this message."""
def version():
print """pky.py 0.5"""
def main():
global debug
extract = False
list = False
contentid = None
try:
opts, args = getopt.getopt(sys.argv[1:], "hx:dvl:c:", ["help", "extract=", "debug","version", "list=", "contentid="])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit(2)
elif opt in ("-v", "--version"):
version()
sys.exit(2)
elif opt in ("-x", "--extract"):
fileToExtract = arg
extract = True
elif opt in ("-l", "--list"):
fileToList = arg
list = True
elif opt in ("-d", "--debug"):
debug = True
elif opt in ("-c", "--contentid"):
contentid = arg
else:
usage()
sys.exit(2)
if extract:
unpack(fileToExtract)
elif list:
listPkg(fileToList)
else:
if len(args) == 1 and contentid != None:
pack(args[0], contentid)
elif len(args) == 2 and contentid != None:
pack(args[0], contentid, args[1])
else:
usage()
sys.exit(2)
if __name__ == "__main__":
main()

Binary file not shown.

View File

@ -0,0 +1,8 @@
from distutils.core import setup, Extension
module1 = Extension('pkgcrypt', sources = ['crypt.c'])
setup (name = 'pkgcrypt',
version = '1.0',
description = 'C implementation of the crypt function from pkg.py',
ext_modules = [module1])

307
buildtools/PS3Py/sfo.py Normal file
View File

@ -0,0 +1,307 @@
#!/usr/bin/env python
from __future__ import with_statement
from xml.dom.minidom import Document, parse, parseString
from Struct import Struct
import struct
import sys
import getopt
debug = None
pretty = None
SFO_MAGIC = 0x46535000
SFO_STRING = 2
SFO_INT = 4
def nullterm(str_plus):
z = str_plus.find('\0')
if z != -1:
return str_plus[:z]
else:
return str_plus
class Header(Struct):
__endian__ = Struct.LE
def __format__(self):
self.magic = Struct.uint32
self.unk1 = Struct.uint32
self.KeyOffset = Struct.uint32
self.ValueOffset = Struct.uint32
self.PairCount = Struct.uint32
def __str__(self):
out = ""
out += "[X] Magic: %08x\n" % self.magic
out += "[ ] Unk1: %08x\n" % self.unk1
out += "[X] Key Offset: %08x\n" % self.KeyOffset
out += "[X] Value Offset: %08x\n" % self.ValueOffset
out += "[X] Pair Count: %08x" % self.PairCount
return out
class Entry(Struct):
__endian__ = Struct.LE
def __format__(self):
self.key_off = Struct.uint16
self.unk1 = Struct.uint8
self.value_type = Struct.uint8
self.value_len = Struct.uint32
self.padded_len = Struct.uint32
self.value_off = Struct.uint32
def __str__(self):
out = ""
out += "[X] Key Offset: %04x\n" % self.key_off
out += "[ ] Unk1: %02x\n" % self.unk1
out += "[/] Value Type: %02x\n" % self.value_type
out += "[X] Value Length: %08x\n" % self.value_len
out += "[X] Padded Length: %08x\n" % self.padded_len
out += "[X] Value Offset: %08x" % self.value_off
return out
def PrettyPrint(self, data, key_off, value_off):
out = ""
out += "[X] Key: '%s'[%04x]\n" % (nullterm(data[self.key_off + key_off:]), self.key_off)
out += "[/] Unk: %02x\n" % (self.unk1)
out += "[/] Value Type: %02x\n" % self.value_type
out += "[X] Value Length: %08x\n" % self.value_len
out += "[X] Padded Length: %08x\n" % self.padded_len
out += "[X] Value Offset: %08x" % self.value_off
if self.value_type == SFO_STRING:
out += "[X] Value: '%s'[%08x]" % (nullterm(data[self.value_off + value_off:]), self.value_off+value_off)
elif self.value_type == SFO_INT:
out += "[X] Value: %d[%08x]" % (struct.unpack('<I', data[self.value_off + value_off:self.value_off + value_off + 4])[0], self.value_off+value_off)
else:
out += "[X] Value Type Unknown"
return out
def usage():
print """usage:
python sfo.py"""
def version():
print """sfo.py 0.2"""
def listSFO(file):
global debug
global pretty
with open(file, 'rb') as fp:
stuff = {}
data = fp.read()
offset = 0
header = Header()
header.unpack(data[offset:offset+len(header)])
if debug:
print header
print
assert header.magic == SFO_MAGIC
assert header.unk1 == 0x00000101
offset += len(header)
off1 = header.KeyOffset
off2 = header.ValueOffset
for x in xrange(header.PairCount):
entry = Entry()
entry.unpack(data[offset:offset+len(entry)])
if debug and not pretty:
print entry
print
if debug and pretty:
print entry.PrettyPrint(data, off1, off2)
print
key = nullterm(data[off1+entry.key_off:])
if entry.value_type == SFO_STRING:
value = nullterm(data[off2+entry.value_off:])
else:
value = struct.unpack('<I', data[entry.value_off + off2:entry.value_off + off2 + 4])[0]
stuff[key] = value
offset += len(entry)
if not debug:
print stuff
def convertToXml(sfofile, xml):
doc = Document()
sfo = doc.createElement("sfo")
with open(sfofile, 'rb') as fp:
stuff = {}
data = fp.read()
offset = 0
header = Header()
header.unpack(data[offset:offset+len(header)])
if debug:
print header
print
assert header.magic == SFO_MAGIC
assert header.unk1 == 0x00000101
offset += len(header)
off1 = header.KeyOffset
off2 = header.ValueOffset
for x in xrange(header.PairCount):
entry = Entry()
entry.unpack(data[offset:offset+len(entry)])
if debug and not pretty:
print entry
print
if debug and pretty:
print entry.PrettyPrint(data, off1, off2)
print
key = nullterm(data[off1+entry.key_off:])
valuenode = doc.createElement("value")
valuenode.setAttribute("name", key)
if entry.value_type == SFO_STRING:
value = nullterm(data[off2+entry.value_off:])
valuenode.setAttribute("type", "string")
valuenode.appendChild(doc.createTextNode(value))
else:
value = struct.unpack('<I', data[entry.value_off + off2:entry.value_off + off2 + 4])[0]
valuenode.setAttribute("type", "integer")
valuenode.appendChild(doc.createTextNode("%d" % value))
sfo.appendChild(valuenode)
stuff[key] = value
offset += len(entry)
if not debug:
print stuff
doc.appendChild(sfo)
file = open(xml, "wb" )
doc.writexml(file, '', '\t', '\n' )
file.close()
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return (''.join(rc)).strip()
def align(num, alignment):
return (num + alignment - 1) & ~(alignment-1)
def convertToSFO(xml, sfofile, forcetitle, forceappid):
dom = parse(xml)
nodes = dom.getElementsByTagName("value")
kvs = []
for node in nodes:
if node.hasAttributes():
type = None
name = None
for i in range(node.attributes.length):
if(node.attributes.item(i).name == "type"):
type = node.attributes.item(i).value
if(node.attributes.item(i).name == "name"):
name = node.attributes.item(i).value
if name != None and type != None:
if name == "TITLE" and forcetitle != None:
kvs.append((name, forcetitle))
elif name == "TITLE_ID" and forceappid != None:
kvs.append((name, forceappid))
elif type == "string":
kvs.append((name, getText(node.childNodes)))
elif type == "integer":
kvs.append((name, int(getText(node.childNodes))))
header = Header()
header.magic = SFO_MAGIC
header.unk1 = 0x00000101
header.PairCount = len(kvs)
entries = []
keyoff = 0
valueoff = 0
for (k,v) in kvs:
entry = Entry()
entry.key_off = keyoff
entry.unk1 = 4
if isinstance(v, int):
entry.value_type = SFO_INT
entry.value_len = 4
entry.padded_len = 4
else:
entry.value_type = SFO_STRING
entry.value_len = len(v) + 1
alignment = 4
if k == "TITLE":
alignment = 0x80
elif k == "LICENSE":
alignment = 0x200
elif k == "TITLE_ID":
alignment = 0x10
entry.padded_len = align(entry.value_len, alignment)
entry.value_off = valueoff
keyoff += len(k)+1
valueoff += entry.padded_len
entries.append(entry)
header.KeyOffset = len(Header()) + 0x10 * header.PairCount
header.ValueOffset = align(header.KeyOffset + keyoff, 4)
keypad = header.ValueOffset - (header.KeyOffset + keyoff)
valuepad = header.ValueOffset - (header.KeyOffset + keyoff)
file = open(sfofile, "wb")
file.write(header.pack())
for entry in entries:
file.write(entry.pack())
for k,v in kvs:
file.write(k + '\0')
file.write('\0' * keypad)
for k,v in kvs:
if isinstance(v, int):
file.write(struct.pack('<I', v))
else:
alignment = 4
if k == "TITLE":
alignment = 0x80
elif k == "LICENSE":
alignment = 0x200
elif k == "TITLE_ID":
alignment = 0x10
file.write(v + '\0')
file.write('\0' * (align(len(v) + 1, alignment) - (len(v) +1)))
file.close()
def main():
global debug
global pretty
debug = False
pretty = False
list = False
fileToList = None
toxml = False
fromxml = False
forcetitle = None
forceappid = None
if len(sys.argv) < 1:
return
if "python" in sys.argv[0]:
sys.argv = sys.argv[1:]
try:
opts, args = getopt.getopt(sys.argv[1:], "hdvpl:tf", ["help", "debug","version", "pretty", "list=", "toxml", "fromxml", "title=", "appid="])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit(2)
elif opt in ("-v", "--version"):
version()
sys.exit(2)
elif opt in ("-l", "--list"):
fileToList = arg
list = True
elif opt in ("-d", "--debug"):
debug = True
elif opt in ("-p", "--pretty"):
pretty = True
elif opt in ("-t", "--toxml"):
toxml = True
elif opt in ("-f", "--fromxml"):
fromxml = True
elif opt in ("--title"):
forcetitle = arg
elif opt in ("--appid"):
forceappid = arg
else:
usage()
sys.exit(2)
if list:
listSFO(fileToList)
elif toxml and not fromxml and len(args) == 2:
convertToXml(args[0], args[1])
elif fromxml and not toxml and len(args) == 2:
convertToSFO(args[0], args[1], forcetitle, forceappid)
else:
usage()
if __name__ == "__main__":
main()

39
buildtools/PS3Py/sfo.xml Normal file
View File

@ -0,0 +1,39 @@
<?xml version="1.0" ?>
<sfo>
<value name="APP_VER" type="string">
01.00
</value>
<value name="ATTRIBUTE" type="integer">
0
</value>
<value name="BOOTABLE" type="integer">
1
</value>
<value name="CATEGORY" type="string">
HG
</value>
<value name="LICENSE" type="string">
This application was created with the official non-official SDK called PSL1GHT, for more information visit http://www.psl1ght.com/ . This is in no way associated with Sony Computer Entertainment Inc., please do not contact them for help, they will not be able to provide it.
</value>
<value name="PARENTAL_LEVEL" type="integer">
0
</value>
<value name="PS3_SYSTEM_VER" type="string">
01.8000
</value>
<value name="RESOLUTION" type="integer">
63
</value>
<value name="SOUND_FORMAT" type="integer">
279
</value>
<value name="TITLE" type="string">
Test - PSL1GHT
</value>
<value name="TITLE_ID" type="string">
TEST00000
</value>
<value name="VERSION" type="string">
01.00
</value>
</sfo>

2387
docs/changes.txt Normal file

File diff suppressed because it is too large Load Diff

68
docs/control-inputs.txt Normal file
View File

@ -0,0 +1,68 @@
Control input names are completely defined by the individual ports. This
document is intended to collect the rules for all ports.
The various meta-characters in the rules are:
# - A number. The range is detemined by the context
## - A two-digit number (i.e. with leading zeros)
[...] - Something optional
(...) - For grouping with |
| - "or", choose one of the options.
<...> - A named field
{...} - A list of possible values. Multiple values may be used, but they
must be in the order listed and joined with +-signs.
"" - 'ditto', used to indicate the same list as the above line.
================================================================================
Unix
================================================================================
Input names:
Jxx:Axis# Axis # on joystick xx. Axis0 may be
Up/Down, and Axis1 Left/Right.
Jxx:B# Button # on joystick xx.
Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+B# Used with the 'JSx Meta#' port
Jxx:{M1,M2,M3,M4,M5,M6,M7,M8}+Axis# command.
Jxx:X+B# Used to 'define' this key for all
Jxx:X+Axis# combinations of JS Meta.
Port-specific Commands:
JSx Meta# Used to specify modifier keys (i.e. Shift, Control) to
affect the specified joystick. For example, you could
map J00:B20 to "JS0 Meta1", then map J00:B0 to "Joypad1
A" and J00:M1+B0 to "Joypad1 Turbo A". '#' may range
from 1-8.
Jsx ToggleMeta# Like the above, but toggles the meta-state each time
the button is pressed.
================================================================================
Unix/X11
================================================================================
Keyboard Input:
Note that only one keyboard (K00) is currently supported. If you know how
to support multiple keyboards (and can test it!), feel free to fix x11.cpp
and delete this note.
Keyboard modifiers are S=Shift, C=Control, A=Alt, M=Meta. Combine them in
order, i.e. all 4 would be "SCAM".
Kxx:<keyname> Key names are as recognized by XStringToKeysym.
Kxx:<mods>+<keyname> Note however that keys are mapped by keycode,
so for example on a standard qwerty keyboard
"K00:colon" and "K00:semicolon" are identical.
Pointer Input:
Note that only one mouse (M00) is currently supported. If you know how to
support multiple pointing devices (and can test it!), feel free to fix
x11.cpp and delete this note.
Mxx:Pointer Map the mouse pointer. If someone has a mouse
Mxx:Pointer# device with multiple pointers, fix x11.cpp to
report that and you can use the second syntax.
Mxx:B# Mouse buttons.

97
docs/controls.txt Normal file
View File

@ -0,0 +1,97 @@
This lists the available commands, excluding the ones you get back from
S9xGetAllSnes9xCommands(). The various meta-characters are:
# - A number. The range is detemined by the context
## - A two-digit number (i.e. with leading zeros)
[...] - Something optional
(...) - For grouping with |
| - "or", choose one of the options.
<...> - A named field
{...} - A list of possible values. Multiple values may be used, but they
must be in the order listed and joined with +-signs.
"" - 'ditto', used to indicate the same list as the above line.
Speeds are: Var, Slow, Med, and Fast. 'Var' starts slow and speeds up as the
button is held.
Axes are: Left/Right, Right/Left, Up/Down, Down/Up, Y/A, A/Y, X/B, B/X, L/R,
and R/L. Negative is listed first (i.e. "Y/A" means negative deflection is
towards Y, while "A/Y" means negative deflection is towards A).
AxisToPointer, ButtonToPointer, and AxisToButtons allow for translating
between different input types. There are 8 'pointers' with IDs
PseudoPointerBase+0 to PseudoPointerBase+7, and 256 'buttons' with IDs
PseudoButtonBase+0 to PseudoButtonBase+255. So for example,
"AxisToButtons 0/255 T=50%" would take the axis data, and do
S9xReportButton(PseudoButtonBase+0,1) when said axis goes past 50% in the
negative direction and S9xReportButton(PseudoButtonBase+255,1) when it goes
over 50% deflection in the positive direction. Similarly, it will do
S9xReportButton(...,0) when the deflection drops under 50% in either
direction. "ButtonToPointer 1u Slow" would move the pointer with ID
PseudoPointerBase+0 up one pixel per frame as long as the button is pressed
(reporting this change at the end of each frame).
---------------
Button Commands
---------------
Joypad# {Up, Down, Left, Right, A, B, X, Y, L, R, Start, Select}
Joypad# Turbo ""
Joypad# Sticky ""
Joypad# StickyTurbo ""
Joypad# ToggleTurbo ""
Joypad# ToggleSticky ""
Joypad# ToggleStickyTurbo ""
Mouse# (L|R|LR)
Superscope AimOffscreen
Superscope {Fire, Cursor, ToggleTurbo, Pause}
Superscope AimOffscreen ""
Justifier# AimOffscreen
Justifier# {Trigger, Start}
Justifier# AimOffscreen ""
ButtonToPointer #[u|d][l|r] <speed> ; NOTE: "# <speed>" is invalid
-------------
Axis Commands
-------------
Joypad# Axis <axis> T=#% ; T = 0.1 to 100 by tenths
AxisToButtons #/# T=#% ; neg then pos, range 0-255, T as above
AxisToPointer #(h|v) [-]<speed> ; NOTE: '-' inverts the axis
----------------
Pointer Commands
----------------
Pointer {Mouse1, Mouse2, Superscope, Justifier1, Justifier2}
------
Multis
------
Multis are a type of button command. The basic format of a multi is "{...}",
where the '...' consists of 1 or more valid non-multi button command
strings. The braces are literal, not metacharacters. Subcommands separated
by commas are executed one after the next. Semicolons skip one frame before
continuing subcommand execution. Semicolons may be repeated. When the multi
button is pressed, each subcommand is 'pressed', and when the multi button
is released each subcommand is 'released'.
There are also press-only multis, defined as "+{...}". These act just like
regular multis, with two differences: the multi is only run when you press
the button (release isignored), and each subcommand must be prefixed with
'+' or '-' to indicate whether the the subcommand should be pressed or
released.
For example: {Joypad1 A,Joypad2 A;Joypad3 A;;;;;QuickSave000}
This presses (or releases) A on pads 1 and 2, then waits one frame, then
presses A on pad 3, then waits 5 frames, then saves to snapshot 0 (on press
only).
You may access the multi number in the returned s9xcommand_t structure as
cmd.button.multi_idx. This may be used to assign the same multi to multiple
buttons:
MULTI#<num> ; NOTE: that's a literal octothorpe

339
docs/gpl-2.0.txt Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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 Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

504
docs/lgpl-2.1.txt Normal file
View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

385
docs/porting.html Normal file
View File

@ -0,0 +1,385 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="description" content="How to Port Snes9x to a New Platform">
<style type="text/css">
<!-- ul { list-style-type:none } h2 { margin-top:3em } h3 { margin-top:2em } -->
</style>
<title>Porting Snes9x</title>
</head>
<body>
<h1 style="text-align:center">How to Port Snes9x to a New Platform</h1>
<div style="text-align:right">
Version: 1.52<br>
(c) Copyright 1998 Gary Henderson
</div>
<h2>Introduction</h2>
<p>
This is brief description of the steps to port Snes9x to the new platform. It describes what code you have to write and what functions exist that you can make use of. It also gives some insights as to how Snes9x actually works, although that will be subject of another document yet to be written.
</p>
<h2>System Requirements</h2>
<p>
A C++ compiler. For the most part Snes9x really isn't written in C++, it just uses the C++ compiler as a &ldquo;better C&rdquo; compiler to get inline functions and so on. GCC is good for compiling Snes9x (<a href="http://gcc.gnu.org/">http://gcc.gnu.org/</a>).
</p>
<p>
A fast CPU. SNES emulation is very compute intensive; two, or sometimes three CPUs to emulate, an 8-channel 16-bit stereo sound digital signal processor with real-time sample decompression, filter and echo effects, two custom graphics processor chips that can produce transparency, scaling, rotation and window effects in 32768 colors, and finally hardware DMA all take their toll on the host CPU.
</p>
<p>
Enough RAM. Snes9x uses 8MB to load SNES ROM images and several MB for emulating sound, graphics, custom chips, and so on.
</p>
<p>
A 16-bit color (two bytes per pixel) or deeper display, at least 512*478 pixels in resolution. Pixel format conversion may be required before you place the rendered SNES screen on to the display.
</p>
<p>
Sound output requires spooling 8-bit or 16-bit, mono or stereo digital sound data to the host sound system. Some ports can use interrupts or callbacks from the sound system to know when more sound data is required, most other ports have to periodically poll the host sound system to see if more data is required; if it is then the sound mixing code is called to fill the sound buffer with SNES sound data, which then can be passed on to the host sound system. Sound data is generated as an array of bytes (<code>uint8</code>) for 8-bit sound or shorts (<code>int16</code>) for 16-bit data. Stereo sound data generates twice as many samples, with each channel's samples interleaved, first left's then right's.
</p>
<p>
For the user to be able to control and play SNES games, some form of input device is required, a joypad or keyboard, for example. The real SNES can have 2 eight-button digital joypads connected to it or 5 joypads when an optional multi-player adaptor is connected, although most games only require a single joypad. Access to all eight buttons and the direction pad, of course, are usually required by most games. Snes9x does emulate the multi-player adaptor hardware, if you were wondering, but its still up to you to provide the emulation of the individual joypads.
</p>
<p>
The real SNES also has a SNES mouse, Super Scope and Justifier (light-gun) available as optional extras. Snes9x can emulate all of these using some form of pointing device, usually the host system's mouse.
</p>
<p>
Some SNES game cartridges contains a small amount of extra RAM and a battery, so ROMs could save a player's progress through a game for games that takes many hours to play from start to finish. Snes9x simulates this S-RAM by saving the contents of the area of memory occupied by the S-RAM into a file then automatically restoring it again the next time the user plays the same game. If the hardware you're porting to doesn't have a storage media available then you could be in trouble.
</p>
<p>
Snes9x also implements freeze-game files which can record the state of the SNES hardware and RAM at a particular point in time and can restore it to that exact state at a later date - the result is that users can save a game at any point, not just at save-game or password points provided by the original game coders. Each freeze file is over 400k in size. To help save disk space, Snes9x can be compiled with zlib (<a href="http://www.zlib.net/">http://www.zlib.net/</a>), which is used to GZIP compress the freeze files, reducing the size to typically below 100k. zlib is also used to load GZIP or ZIP compressed ROM images. Additionally, Snes9x supports JMA archives compressed with NSRT (<a href="http://nsrt.edgeemu.com/">http://nsrt.edgeemu.com/</a>).
</p>
<h2>Compile-Time Options</h2>
<h3><code>DEBUGGER</code></h3>
<p>
Enables extra code to assist you in debugging SNES ROMs. The debugger has only ever been a quick-hack and user-interface to debugger facilities is virtually non-existent. Most of the debugger information is output via stdout and enabling the debugger slows the whole emulator down slightly. However, the debugger options available are very powerful; you could use it to help get your port working. You probably still want to ship the finished version with the debugger disabled, it will only confuse non-technical users.
</p>
<h3><code>RIGHTSHIFT_IS_SAR</code></h3>
<p>
Define this if your compiler uses shift right arithmetic for signed values. For example, GCC and Visual C++ use shift right arithmetic.
</p>
<h3><code>CPU_SHUTDOWN</code></h3>
<p>
This is a speed-up hack. When defined and if <code>Settings.ShutdownMaster</code> is <code>true</code>, Snes9x starts watching for when CPU is in a simply loop waiting for a known event to happen - like the end of the current scanline. If Snes9x spots CPU in such a loop, it simply skips the emulation of its instructions until the event happens. It can be a big win with lots of SNES games, but will break a small number of games. In this case, set <code>Settings.ShutdownMaster</code> to <code>false</code> before you load a ROM image. Note that this hack is forcibly disabled in some games. See <code>Memory.ApplyROMFixes</code> function for the list of such games.
</p>
<h3><code>CORRECT_VRAM_READS</code></h3>
<p>
You must define this. It allows correct VRAM reads.
</p>
<h3><code>ZLIB / UNZIP_SUPPORT / JMA_SUPPORT</code></h3>
<p>
Define these if you want to support GZIP/ZIP/JMA compressed ROM images and GZIP compressed freeze-game files.
</p>
<h3><code>ZSNES_FX / ZSNES_C4</code></h3>
<p>
Define these if your CPU is x86 compatible and you're going to use the ZSNES Super FX and C4 assembler codes.
</p>
<h3><code>USE_OPENGL</code></h3>
<p>
Define this and set <code>Settings.OpenGLEnable</code> to <code>true</code>, then you'll get the rendered SNES image as one OpenGL texture.
</p>
<h3>Typical Options Common for Most Platforms</h3>
<p><code>
ZLIB<br>
UNZIP_SUPPORT<br>
JMA_SUPPORT<br>
CPU_SHUTDOWN<br>
RIGHTSHIFT_IS_SAR<br>
CORRECT_VRAM_READS
</code></p>
<h2>Editing port.h</h2>
<p>
You may need to edit <code>port.h</code> to fit Snes9x to your system.
</p>
<p>
If the byte ordering of your system is least significant byte first, make sure <code>LSB_FIRST</code> is defined, otherwise make sure it's not defined.
</p>
<p>
You'll need to make sure what pixel format your system uses for 16-bit colors (<code>RGB565</code>, <code>RGB555</code>, <code>BGR565</code> or <code>BGR555</code>), and if it's not <code>RGB565</code>, define <code>PIXEL_FORMAT</code> to it so that Snes9x will use it to render the SNES screen. For example, Windows uses <code>RGB565</code>, Mac OS X uses <code>RGB555</code>. If your system supports more than one pixel format, you can define <code>GFX_MULTI_FORMAT</code> and change Snes9x's pixel format dynamically by calling <code>S9xSetRenderPixelFormat</code> function. If your system is 24 or 32-bit only, then don't define anything; instead write a conversion routine that will take a complete rendered 16-bit SNES screen in <code>RGB565</code> format and convert to the format required to be displayed on your system.
</p>
<p>
<code>port.h</code> also typedefs some types; <code>uint8</code> for an unsigned 8-bit quantity, <code>uint16</code> for an unsigned 16-bit quantity, <code>uint32</code> for a 32-bit unsigned quantity and <code>bool8</code> for a <code>true</code>/<code>false</code> type. Signed versions are also typedef'ed.
</p>
<h2>Controllers Management</h2>
<p>
Read <code>controls.h</code>, <code>crosshair.h</code>, <code>controls.txt</code> and <code>control-inputs.txt</code> for details. This section is the minimal explanation to get the SNES controls workable.
</p>
<p>
The real SNES allows several different types of devices to be plugged into the game controller ports. The devices Snes9x emulates are a joypad, multi-player adaptor known as the Multi Player 5 or Multi Tap (allowing a further 4 joypads to be plugged in), a 2-button mouse, a light gun known as the Super Scope, and a light gun known as the Justifier.
</p>
<p>
In your initialization code, call <code>S9xUnmapAllControl</code> function.
</p>
<p>
Map any IDs to each SNES controller's buttons and pointers. (ID 249-255 are reserved).
</p>
<p>
Typically, use <code>S9xMapPointer</code> function for the pointer of the SNES mouse, Super Scope and Justifier, <code>S9xMapButton</code> function for other buttons. Set <code>poll</code> to <code>false</code> for the joypad buttons, <code>true</code> for the other buttons and pointers.
</p>
<p>
<code>S9xMapButton(k1P_A_Button, s9xcommand_t cmd = S9xGetCommandT(&quot;Joypad1 A&quot;), false);</code>
</p>
<p>
In your main emulation loop, after <code>S9xMainLoop</code> function is called, check your system's keyboard/joypad, and call <code>S9xReportButton</code> function to report the states of the SNES joypad buttons to Snes9x.
</p>
<p>
<code>void MyMainLoop (void)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;S9xMainLoop();<br>
&nbsp;&nbsp;&nbsp;&nbsp;MyReportButttons();<br>
}</code>
</p>
<p>
<code>void MyReportButtons (void)<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;S9xReportButton(k1P_A_Button, (key_is_pressed ? true : false));<br>
}</code>
</p>
<p>
Prepare your <code>S9xPollButton</code> and <code>S9xPollPointer</code> function to reply Snes9x's request for other buttons/cursors states.
</p>
<p>
Call <code>S9xSetController</code> function. It connects each input device to each SNES input port.<br>
Here's typical controller settings that is used by the real SNES games:
</p>
<p>Joypad<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);</code>
</p>
<p>Mouse (port 1)<br>
<code>S9xSetController(0, CTL_MOUSE, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_JOYPAD, 1, 0, 0, 0);</code>
</p>
<p>Mouse (port 2)<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_MOUSE, 1, 0, 0, 0);</code>
</p>
<p>Super Scope<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_SUPERSCOPE, 0, 0, 0, 0);</code>
</p>
<p>Multi Player 5<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_MP5, 1, 2, 3, 4);</code>
</p>
<p>Justifier<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_JUSTIFIER, 0, 0, 0, 0);</code>
</p>
<p>Justifier (2 players)<br>
<code>S9xSetController(0, CTL_JOYPAD, 0, 0, 0, 0);<br>
S9xSetController(1, CTL_JUSTIFIER, 1, 0, 0, 0);</code>
</p>
<h2>Existing Interface Functions</h2>
<h3><code>bool8 Memory.Init (void)</code></h3>
<p>
Allocates and initializes several major lumps of memory, for example the SNES ROM and RAM arrays, tile cache arrays, etc. Returns <code>false</code> if memory allocation fails.
</p>
<h3><code>void Memory.Deinit (void)</code></h3>
<p>
Deallocates the memory allocations made by <code>Memory.Init</code> function.
</p>
<h3><code>bool8 S9xGraphicsInit (void)</code></h3>
<p>
Allocates and initializes several lookup tables used to speed up SNES graphics rendering. Call after you have initialized the <code>GFX.Screen</code> and <code>GFX.Pitch</code> values. Returns <code>false</code> if memory allocation fails.
</p>
<h3><code>void S9xGraphicsDeinit (void)</code></h3>
<p>
Deallocates the memory allocations made by <code>S9xGraphicsInit</code> function.
</p>
<h3><code>bool8 S9xInitAPU (void)</code></h3>
<p>
Allocates and initializes several arrays used by the sound CPU and sound generation code. Returns <code>false</code> if memory allocation fails.
</p>
<h3><code>void S9xDeinitAPU (void)</code></h3>
<p>
Deallocates the allocations made by <code>S9xInitAPU</code> function.
</p>
<h3><code>bool8 S9xInitSound (int buffer_ms, int lag_ms)</code></h3>
<p>
Allocates memory for mixing and queueing SNES sound data, does more sound code initialization and opens the host system's sound device by calling <code>S9xOpenSoundDevice</code>, a function you must provide. Before calling this function you must set up <code>Settings.SoundSync</code>, <code>Settings.SixteenBitSound</code>, <code>Settings.SoundPlaybackRate</code>, <code>Settings.SoundInputRate</code> (see section below) and <code>Settings.Stereo</code>.<br>
<code>buffer_ms</code>, given in milliseconds, is the memory buffer size for queueing sound data. <code>lag_ms</code> is allowable latency between when a sample is queued and when it is pulled in <code>S9xMixSamples</code>. Set <code>lag_ms</code> to zero if you have your own latency handling code in your port.
</p>
<h3><code>void S9xReset (void)</code></h3>
<p>
Resets the SNES emulated hardware back to the state it was in at &ldquo;switch-on&rdquo; except the S-RAM area is preserved (&ldquo;hardware reset&rdquo;). The effect is it resets the current game back to the start. This function is automatically called by <code>Memory.LoadROM</code> function.
</p>
<h3><code>void S9xSoftReset (void)</code></h3>
<p>
Similar to <code>S9xReset</code> function, but &ldquo;software reset&rdquo; as you press the SNES reset button.
</p>
<h3><code>bool8 Memory.LoadROM (const char *filepath)</code></h3>
<p>
Attempts to load the specified ROM image filename into the emulated ROM area. There are many different SNES ROM image formats and the code attempts to auto-detect as many different types as it can and in a vast majority of the cases gets it right.<br>
There are several ROM image options in the <code>Settings</code>structure; allow the user to set them before calling <code>Memory.LoadROM</code> function, or make sure they are all reset to default values before each call to <code>Memory.LoadROM</code> function. See <code>Settings.ForceXXX</code> in <code>snes9x.h</code>.
</p>
<h3><code>bool8 Memory.LoadMultiCart (const char *cartApath, const char *cartBpath)</code></h3>
<p>
Attempts to load multiple ROM images into the emulated ROM area, for the multiple cartridge systems such as Sufami Turbo, Same Game, etc.
</p>
<h3><code>bool8 Memory.LoadSRAM (const char *filepath)</code></h3>
<p>
Call this function to load the associated S-RAM save file (if any). The filename should be based on the ROM image name to allow easy linkage. The current ports change the directory and the filename extension of the ROM filename to derive the S-RAM filename.
</p>
<h3><code>bool8 Memory.SaveSRAM (const char *filepath)</code></h3>
<p>
Call this function to save the emulated S-RAM area into a file so it can be restored again the next time the user wants to play the game. Remember to call this when just before the emulator exits or when the user has been playing a game and is about to load another one.
</p>
<h3><code>void S9xMainLoop (void)</code></h3>
<p>
The emulator main loop. Call this from your own main loop that calls this function (if a ROM image is loaded and the game is not paused), processes any pending host system events, then goes back around the loop again until the emulator exits. <code>S9xMainLoop</code> function normally returns control to your main loop once every emulated frame, when it reaches the start of scan-line zero. However it may take a few frames when a huge memory transfer is being emulated. The function can return more often if the <code>DEBUGGER</code> compile-time flag is defined and the CPU has hit a break point, or the <code>DEBUG_MODE_FLAG</code> bit is set in <code>CPU.Flags</code> or instruction single-stepping is enabled.
</p>
<h3><code>void S9xMixSamples (uint8 *buffer, int sample_count)</code></h3>
<p>
Call this function from your host sound system handling code to fill <code>buffer</code> with ready-mixed SNES sound data. If 16-bit sound mode is chosen, then the buffer will be filled with an array of <code>sample_count</code> <code>int16</code>, otherwise an array of <code>sample_count</code> <code>uint8</code>. If stereo sound generation is selected the buffer is filled with the same number of samples, but in pairs, first a left channel sample followed by the right channel sample.<br>
If there are less queued samples than you request by <code>sample_count</code>, the function fills <code>buffer</code> with silent sound data and returns <code>false</code>. To avoid this shortage of queued samples, request larger buffer size when calling <code>S9xInitSound</code>, and handle sound latency safely.
</p>
<h3><code>int S9xGetSampleCount (void)</code></h3>
<p>
Returns the number of sound samples available in the buffer for your configured playback settings.
</p>
<h3><code>void S9xSetSamplesAvailableCallback (void (*) samples_available (void *), void *data)</code></h3>
<p>
Call this function to set up a callback that is run when sound samples are made available. <code>samples_available</code> is a function you provide that returns <code>void</code> and takes a pointer as an argument. <code>data</code> is a pointer that you may wish to pass to your callback or can be <code>NULL</code>. If you choose to provide a callback, you must call the provided <code>S9xFinalizeSamples</code> function inside it to actually buffer the samples. If you are using a callback-oriented sound API, it is recommended to set up a function that locks a common mutex during the calls to <code>S9xFinalizeSamples</code> and <code>S9xMixSamples</code> to prevent them from running at the same time and corrupting the sound buffer.<br>
If you wish to disable a callback you have set up or need to temporarily shut down your sound system, you may pass <code>NULL</code> for both arguments to revert to the built-in version.
</p>
<h3><code>bool8 S9xSyncSound (void)</code></h3>
<p>
Call this function to synchronize the sound buffers to the game state. If Snes9x is generating too much sound data, or a buffer-overrun is likely, this function will return <code>false</code>. In this case, you may wish to wait until your host sound system uses the available samples, and <code>S9xSyncSound</code> returns <code>true</code> before continuing to execute <code>S9xMainLoop</code>.
</p>
<h3><code>bool8 S9xSetSoundMute (bool8 mute)</code></h3>
<p>
Call with a <code>true</code> parameter to prevent <code>S9xMixSamples</code> function from processing SNES sample data and instead just filling the return buffer with silent sound data. Useful if your sound system is interrupt or callback driven and the game has been paused either directly or indirectly because the user interacting with the emulator's user interface in some way.
</p>
<h3><code>bool8 S9xFreezeGame (const char *filepath)</code></h3>
<p>
Call this function to record the current SNES hardware state into a file, the file can be loaded back using <code>S9xUnfreezeGame</code> function at a later date effectively restoring the current game to exact same spot. Call this function while you're processing any pending system events when <code>S9xMainLoop</code> function has returned control to you in your main loop.
</p>
<h3><code>bool8 S9xUnfreezeGame (const char *filepath)</code></h3>
<p>
Restore the SNES hardware back to the exactly the state it was in when <code>S9xFreezeGame</code> function was used to generate the file specified. You have to arrange the correct ROM is already loaded using <code>Memory.LoadROM</code> function, an easy way to arrange this is to base freeze-game filenames on the ROM image name. The UNIX/Linux ports load freeze-game files when the user presses a function key, with the names romfilename.000 for F1, romfilename.001 for F2, etc. Games are frozen in the first place when the user presses Shift-function key. You could choose some other scheme.
</p>
<h3><code>void S9xDumpSPCSnapshot (void)</code></h3>
<p>
Call this funtion to make a so-called SPC file, a snapshot of SNES sound state. Actual dump occurs at the first key-on event after this function is called.
</p>
<h3><code>void S9xSetInfoString (const char *string)</code></h3>
<p>
Call this function if you want to show a message onto the SNES screen.
</p>
<h3>Other Available Functions</h3>
<p>
See <code>movie.h</code> and <code>movie.cpp</code> to support the Snes9x movie feature.<br>
See <code>cheats.h</code>, <code>cheats.cpp</code> and <code>cheats2.cpp</code> to support the cheat feature.
</p>
<h2>Interface Functions You Need to Implement</h2>
<h3><code>bool8 S9xOpenSnapshotFile (const char *filepath, bool8 read_only, STREAM *file)</code></h3>
<p>
This function opens a freeze-game file. <code>STREAM</code> is defined as a <code>gzFile</code> if <code>ZLIB</code> is defined else it's defined as <code>FILE *</code>. The <code>read_only</code> parameter is set to <code>true</code> when reading a freeze-game file and <code>false</code> when writing a freeze-game file. Open the file <code>filepath</code> and return its pointer <code>file</code>.
</p>
<h3><code>void S9xCloseSnapshotFile (STREAM file)</code></h3>
<p>
This function closes the freeze-game file opened by <code>S9xOpenSnapshotFile</code> function.
</p>
<h3><code>void S9xExit (void)</code></h3>
<p>
Called when some fatal error situation arises or when the &ldquo;q&rdquo; debugger command is used.
</p>
<h3><code>bool8 S9xInitUpdate (void)</code></h3>
<p>
Called just before Snes9x begins to render an SNES screen. Use this function if you should prepare before drawing, otherwise let it empty.
</p>
<h3><code>bool8 S9xDeinitUpdate (int width, int height)</code></h3>
<p>
Called once a complete SNES screen has been rendered into the <code>GFX.Screen</code> memory buffer, now is your chance to copy the SNES rendered screen to the host computer's screen memory. The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478.
</p>
<h3><code>void S9xMessage (int type, int number, const char *message)</code></h3>
<p>
When Snes9x wants to display an error, information or warning message, it calls this function. Check in <code>messages.h</code> for the types and individual message numbers that Snes9x currently passes as parameters.<br>
The idea is display the message string so the user can see it, but you choose not to display anything at all, or change the message based on the message number or message type.<br>
Eventually all debug output will also go via this function, trace information already does.
</p>
<h3><code>bool8 S9xOpenSoundDevice (void)</code></h3>
<p>
<code>S9xInitSound</code> function calls this function to actually open the host sound device.
</p>
<h3><code>const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype)</code></h3>
<p>
When Snes9x needs to know the name of the cheat/IPS file and so on, this function is called. Check <code>extension</code> and <code>dirtype</code>, and return the appropriate filename. The current ports return the ROM file path with the given extension.
</p>
<h3><code>const char *S9xGetFilenameInc (const char *extension, enum s9x_getdirtype dirtype)</code></h3>
<p>
Almost the same as <code>S9xGetFilename</code> function, but used for saving SPC files etc. So you have to take care not to delete the previously saved file, by increasing the number of the filename; romname.000.spc, romname.001.spc, ...
</p>
<h3><code>const char *S9xGetDirectory (enum s9x_getdirtype dirtype)</code></h3>
<p>
Called when Snes9x wants to know the directory <code>dirtype</code>.
</p>
<h3><code>const char *S9xChooseFilename (bool8 read_only)</code></h3>
<p>
If your port can match Snes9x's built-in <code>LoadFreezeFile</code>/<code>SaveFreezeFile</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>.
</p>
<h3><code>const char *S9xChooseMovieFilename (bool8 read_only)</code></h3>
<p>
If your port can match Snes9x's built-in <code>BeginRecordingMovie</code>/<code>LoadMovie</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>.
</p>
<h3><code>const char *S9xBasename (const char *path)</code></h3>
<p>
Called when Snes9x wants to know the name of the ROM image. Typically, extract the filename from <code>path</code> and return it.
</p>
<h3><code>void S9xAutoSaveSRAM (void)</code></h3>
<p>
If <code>Settings.AutoSaveDelay</code> is not zero, Snes9x calls this function when the contents of the S-RAM has been changed. Typically, call <code>Memory.SaveSRAM</code> function from this function.
</p>
<h3><code>void S9xToggleSoundChannel (int c)</code></h3>
<p>
If your port can match Snes9x's built-in <code>SoundChannelXXX</code> command (see <code>controls.cpp</code>), you may choose to use this function. Otherwise return <code>NULL</code>. Basically, turn on/off the sound channel <code>c</code> (0-7), and turn on all channels if <code>c</code> is 8.
</p>
<h3><code>void S9xSetPalette (void)</code></h3>
<p>
Called when the SNES color palette has changed. Use this function if your system should change its color palette to match the SNES's. Otherwise let it empty.
</p>
<h3><code>void S9xSyncSpeed (void)</code></h3>
<p>
Called at the end of <code>S9xMainLoop</code> function, when emulating one frame has been done. You should adjust the frame rate in this function.
</p>
<h2>Global Variables</h2>
<h3><code>uint16 *GFX.Screen</code></h3>
<p>
A <code>uint16</code> array pointer to (at least) 2*512*478 bytes buffer where Snes9x puts the rendered SNES screen. However, if your port will not support hires mode (<code>Settings.SupportHiRes = false</code>), then a 2*256*239 bytes buffer is allowed. You should allocate the space by yourself. As well you can change the <code>GFX.Screen</code> value after <code>S9xDeinitUpdate</code> function is called so that double-buffering will be easy.
</p>
<h3><code>uint32 GFX.Pitch</code></h3>
<p>
Bytes per line (not pixels per line) of the <code>GFX.Screen</code> buffer. Typically set it to 1024. When the SNES screen is 256 pixels width and <code>Settings.OpenGLEnable</code> is <code>false</code>, last half 512 bytes per line are unused. When <code>Settings.OpenGLEnable</code> is <code>true</code>, <code>GFX.Pitch</code> is ignored.
</p>
<h3>Settings structure</h3>
<p>
There are various switches in the <code>Settings</code> structure. See <code>snes9x.h</code> for details. At least the settings below are required for good emulation.
</p>
<p><code>
memset(&amp;Settings, 0, sizeof(Settings));<br>
Settings.MouseMaster = true;<br>
Settings.SuperScopeMaster = true;<br>
Settings.JustifierMaster = true;<br>
Settings.MultiPlayer5Master = true;<br>
Settings.FrameTimePAL = 20000;<br>
Settings.FrameTimeNTSC = 16667;<br>
Settings.SixteenBitSound = true;<br>
Settings.Stereo = true;<br>
Settings.SoundPlaybackRate = 32000;<br>
Settings.SoundInputRate = 32000;<br>
Settings.SupportHiRes = true;<br>
Settings.Transparency = true;<br>
Settings.AutoDisplayMessages = true;<br>
Settings.InitialInfoStringTimeout = 120;<br>
Settings.HDMATimingHack = 100;<br>
Settings.BlockInvalidVRAMAccessMaster = true;
</code></p>
<h3><code>Settings.SoundInputRate</code></h3>
<p>
Adjusts the sound rate through resampling. For every <code>Settings.SoundInputRate</code> samples generated by the SNES, <code>Settings.SoundPlaybackRate</code> samples will be produced.<br>
The sound generation rate on a SNES is directly proportional to the video output rate. Displays that synchronize with the vertical refresh but have a slightly lower refresh-rate than the emulated system can experience sound drop-outs. It may be beneficial to provide an option for users to configure <code>Settings.SoundInputRate</code> to suit their own systems. Setting <code>Settings.SoundInputRate</code> to a value that matches the actual output rate (i.e. 31977hz for 59.96hz) or lower will allow the users to eliminate crackling. A range of 31000hz to 33000hz should be inclusive enough for all displays. Use of this setting paired with the <code>S9xSyncSound</code> function can eliminate sound discontinuity.
</p>
<div style="text-align:right; margin-top:3em">
Updated most recently by: 2009/12/20 zones
</div>
</body>
</html>

84
docs/snapshots.txt Normal file
View File

@ -0,0 +1,84 @@
***** Important notice ********************************************************
This document describes the snapshot file format for Snes9x 1.52 and later,
not compatible with 1.51.
*******************************************************************************
Snes9x snapshot file format: (may be gzip-compressed)
Begins with fixed length signature, consisting of a string, ':', a 4-digit
decimal version, and a '\n'.
#!s9xsnp:0006 <-- '\n' after the 6
Then we have various blocks. The block format is: 3-character block name,
':', 6-digit length, ':', then the data. Blocks are written in a defined
order. Structs are written packed with their members in a defined order, in
big-endian order where applicable.
NAM:000019:Chrono Trigger.zip
Currently defined blocks (in order) are:
Essential parts:
NAM - ROM filename, from Memory.ROMFilename. 0-terminated string.
CPU - struct SCPUState, CPU internal state variables.
REG - struct SRegisters, emulated CPU registers.
PPU - struct SPPU, PPU internal variables. Note that IPPU is never saved.
DMA - struct SDMA, DMA/HDMA state variables.
VRA - Memory.VRAM, 0x10000 bytes.
RAM - Memory.RAM, 0x20000 bytes (WRAM).
SRA - Memory.SRAM, 0x20000 bytes.
FIL - Memory.FillRAM, 0x8000 bytes (register backing store).
SND - All of sound emulated registers and state valiables.
CTL - struct SControlSnapshot, controller emulation.
TIM - struct STimings, variables about timings between emulated events.
Optional parts:
SFX - struct FxRegs_s, Super FX.
SA1 - struct SSA1, SA1 internal state variables.
SAR - struct SSA1Registers, SA1 emulated registers.
DP1 - struct SDSP1, DSP-1.
DP2 - struct SDSP2, DSP-2.
DP4 - struct SDSP4, DSP-4.
CX4 - Memory.C4RAM, 0x2000 bytes.
ST0 - struct SST010, ST-010.
OBC - struct SOBC1, OBC1 internal state variables.
OBM - Memory.OBC1RAM, 0x2000 byts.
S71 - struct SSPC7110Snapshot, SPC7110.
SRT - struct SSRTCSnapshot, S-RTC internal state variables.
CLK - struct SRTCData, S-RTC emulated registers.
BSX - struct SBSX, BS-X.
SHO - rendered SNES screen.
MOV - struct SnapshotMovieInfo.
MID - Some block of data the movie subsystem.
==================
Without changing the snapshot version number:
---------------------------------------------
Blocks may be safely added at the END of the file, as anything after the last
block is ignored. Blocks may not be moved or removed.
Blocks may not decrease in size. Say you decrease from 10 bytes to 5. Then
later you increase back to 8. The only way you could safely do this is if
bytes 5-7 still mean the same thing they meant when the block was 10 bytes
long.
Blocks may increase in size as you wish, as long as you can handle old
savestates with the old shorter size.
Struct members may not change in interpretation. New struct members may be
added (at the END!) only if you can cope with them being binary-0 in older
savestates. Struct members may not be removed or changed in size/type.
With changing the snapshot version number:
------------------------------------------
Blocks may be added, moved, or removed at will.
Blocks may decrease in size.
Struct members may be added, moved, or deleted, and their
interpretations/types may be changed. Use the 'debuted_in' and 'deleted_in'
fields to indicate when the new member debuted or the old member went away.

173
docs/snes9x-license.txt Normal file
View File

@ -0,0 +1,173 @@
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
Jerremy Koot (jkoot@snes9x.com)
(c) Copyright 2002 - 2004 Matthew Kendora
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
Kris Bleakley (codeviolation@hotmail.com)
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
Nach (n-a-c-h@users.sourceforge.net),
zones (kasumitokoduck@yahoo.com)
(c) Copyright 2006 - 2007 nitsuja
(c) Copyright 2009 - 2010 BearOso,
OV2
BS-X C emulator code
(c) Copyright 2005 - 2006 Dreamer Nom,
zones
C4 x86 assembler and some C emulation code
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
Nach,
zsKnight (zsknight@zsnes.com)
C4 C++ code
(c) Copyright 2003 - 2006 Brad Jorsch,
Nach
DSP-1 emulator code
(c) Copyright 1998 - 2006 _Demo_,
Andreas Naive (andreasnaive@gmail.com),
Gary Henderson,
Ivar (ivar@snes9x.com),
John Weidman,
Kris Bleakley,
Matthew Kendora,
Nach,
neviksti (neviksti@hotmail.com)
DSP-2 emulator code
(c) Copyright 2003 John Weidman,
Kris Bleakley,
Lord Nightmare (lord_nightmare@users.sourceforge.net),
Matthew Kendora,
neviksti
DSP-3 emulator code
(c) Copyright 2003 - 2006 John Weidman,
Kris Bleakley,
Lancer,
z80 gaiden
DSP-4 emulator code
(c) Copyright 2004 - 2006 Dreamer Nom,
John Weidman,
Kris Bleakley,
Nach,
z80 gaiden
OBC1 emulator code
(c) Copyright 2001 - 2004 zsKnight,
pagefault (pagefault@zsnes.com),
Kris Bleakley
Ported from x86 assembler to C by sanmaiwashi
SPC7110 and RTC C++ emulator code used in 1.39-1.51
(c) Copyright 2002 Matthew Kendora with research by
zsKnight,
John Weidman,
Dark Force
SPC7110 and RTC C++ emulator code used in 1.52+
(c) Copyright 2009 byuu,
neviksti
S-DD1 C emulator code
(c) Copyright 2003 Brad Jorsch with research by
Andreas Naive,
John Weidman
S-RTC C emulator code
(c) Copyright 2001 - 2006 byuu,
John Weidman
ST010 C++ emulator code
(c) Copyright 2003 Feather,
John Weidman,
Kris Bleakley,
Matthew Kendora
Super FX x86 assembler emulator code
(c) Copyright 1998 - 2003 _Demo_,
pagefault,
zsKnight
Super FX C emulator code
(c) Copyright 1997 - 1999 Ivar,
Gary Henderson,
John Weidman
Sound emulator code used in 1.5-1.51
(c) Copyright 1998 - 2003 Brad Martin
(c) Copyright 1998 - 2006 Charles Bilyue'
Sound emulator code used in 1.52+
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
SH assembler code partly based on x86 assembler code
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
2xSaI filter
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
HQ2x, HQ3x, HQ4x filters
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
NTSC filter
(c) Copyright 2006 - 2007 Shay Green
GTK+ GUI code
(c) Copyright 2004 - 2010 BearOso
Win32 GUI code
(c) Copyright 2003 - 2006 blip,
funkyass,
Matthew Kendora,
Nach,
nitsuja
(c) Copyright 2009 - 2010 OV2
Mac OS GUI code
(c) Copyright 1998 - 2001 John Stiles
(c) Copyright 2001 - 2010 zones
Specific ports contains the works of other authors. See headers in
individual files.
Snes9x homepage: http://www.snes9x.com/
Permission to use, copy, modify and/or distribute Snes9x in both binary
and source form, for non-commercial purposes, is hereby granted without
fee, providing that this license information and copyright notice appear
with all copies and any derived work.
This software is provided 'as-is', without any express or implied
warranty. In no event shall the authors be held liable for any damages
arising from the use of this software or it's derivatives.
Snes9x is freeware for PERSONAL USE only. Commercial users should
seek permission of the copyright holders first. Commercial use includes,
but is not limited to, charging money for Snes9x or software derived from
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
using Snes9x as a promotion for your commercial product.
The copyright holders request that bug fixes and improvements to the code
should be forwarded to them so everyone can benefit from the modifications
in future versions.
Super NES and Super Nintendo Entertainment System are trademarks of
Nintendo Co., Limited and its subsidiary companies.

241
docs/snes9x.conf.default Normal file
View File

@ -0,0 +1,241 @@
#-----------------------------------------
# snes9x.conf : Snes9x Configuration file
#-----------------------------------------
[ROM]
# Filename =
LoROM = FALSE
HiROM = FALSE
PAL = FALSE
NTSC = FALSE
# Header = TRUE/FALSE to ForceHeader or ForceNoHeader
# Interleaved = TRUE/FALSE to ForceInterleaved or ForceNoInterleaved
Interleaved2 = FALSE
InterleaveGD24 = FALSE
Cheat = FALSE
Patch = TRUE
[Sound]
Sync = FALSE
16BitSound = TRUE
Stereo = TRUE
ReverseStereo = FALSE
Rate = 32000
InputRate = 32000
Mute = FALSE
[Display]
HiRes = TRUE
Transparency = TRUE
GraphicWindows = TRUE
DisplayFrameRate = FALSE
DisplayWatchedAddresses = FALSE
DisplayInput = FALSE
DisplayFrameCount = FALSE
MessagesInImage = TRUE
MessageDisplayTime = 120
[Settings]
BSXBootup = FALSE
# FrameTime =
FrameSkip = Auto
TurboMode = FALSE
TurboFrameSkip = 15
MovieTruncateAtEnd = FALSE
MovieNotifyIgnored = FALSE
WrongMovieStateProtection = TRUE
StretchScreenshots = 1
SnapshotScreenshots = TRUE
DontSaveOopsSnapshot = FALSE
AutoSaveDelay = 0
[Controls]
MouseMaster = TRUE
SuperscopeMaster = TRUE
JustifierMaster = TRUE
MP5Master = TRUE
AllowLeftRight = FALSE
Port1 = pad1
Port2 = none
Mouse1Crosshair = 1 White/Black
Mouse2Crosshair = 1 White/Black
SuperscopeCrosshair = 2 White/Black
Justifier1Crosshair = 4 Blue/Black
Justifier2Crosshair = 4 MagicPink/Black
[Hack]
EnableGameSpecificHacks = TRUE
AllowInvalidVRAMAccess = FALSE
SpeedHacks = FALSE
DisableIRQ = FALSE
DisableHDMA = FALSE
HDMATiming = 100
[Netplay]
Enable = FALSE
Port = 6096
Server = ""
[DEBUG]
Debugger = FALSE
Trace = FALSE
[Unix]
# BaseDir = ~/.snes9x
# SnapshotFilename =
# PlayMovieFilename =
# RecordMovieFilename =
EnableGamePad = TRUE
PadDevice1 = (null)
PadDevice2 = (null)
PadDevice3 = (null)
PadDevice4 = (null)
PadDevice5 = (null)
PadDevice6 = (null)
PadDevice7 = (null)
PadDevice8 = (null)
ThreadSound = FALSE
SoundBufferSize = 100
SoundFragmentSize = 2048
# SoundDevice =
ClearAllControls = FALSE
[Unix/X11]
SetKeyRepeat = TRUE
VideoMode = 1
[Unix/X11 Controls]
J00:Axis1 = Joypad1 Axis Up/Down T=50%
J00:Axis0 = Joypad1 Axis Left/Right T=50%
J00:B1 = Joypad1 A
J00:B2 = Joypad1 B
J00:B0 = Joypad1 X
J00:B3 = Joypad1 Y
J00:B6 = Joypad1 L
J00:B7 = Joypad1 R
J00:B8 = Joypad1 Select
J00:B11 = Joypad1 Start
K00:u = Joypad1 Up
K00:Up = Joypad1 Up
K00:j = Joypad1 Down
K00:n = Joypad1 Down
K00:Down = Joypad1 Down
K00:h = Joypad1 Left
K00:Left = Joypad1 Left
K00:k = Joypad1 Right
K00:Right = Joypad1 Right
K00:d = Joypad1 A
K00:S+d = Joypad1 ToggleTurbo A
K00:C+d = Joypad1 ToggleSticky A
K00:c = Joypad1 B
K00:S+c = Joypad1 ToggleTurbo B
K00:C+c = Joypad1 ToggleSticky B
K00:s = Joypad1 X
K00:S+s = Joypad1 ToggleTurbo X
K00:C+s = Joypad1 ToggleSticky X
K00:x = Joypad1 Y
K00:S+x = Joypad1 ToggleTurbo Y
K00:C+x = Joypad1 ToggleSticky Y
K00:a = Joypad1 L
K00:v = Joypad1 L
K00:S+a = Joypad1 ToggleTurbo L
K00:S+v = Joypad1 ToggleTurbo L
K00:C+a = Joypad1 ToggleSticky L
K00:C+v = Joypad1 ToggleSticky L
K00:z = Joypad1 R
K00:S+z = Joypad1 ToggleTurbo R
K00:C+z = Joypad1 ToggleSticky R
K00:space = Joypad1 Select
K00:Return = Joypad1 Start
K00:KP_Up = Joypad2 Up
K00:KP_Down = Joypad2 Down
K00:KP_Left = Joypad2 Left
K00:KP_Right = Joypad2 Right
K00:Prior = Joypad2 A
K00:Next = Joypad2 B
K00:Home = Joypad2 X
K00:End = Joypad2 Y
K00:Insert = Joypad2 L
K00:Delete = Joypad2 R
K00:KP_Add = Joypad2 Select
K00:KP_Enter = Joypad2 Start
K00:Escape = ExitEmu
K00:Pause = Pause
K00:Scroll_Lock = Pause
K00:CS+Escape = Reset
K00:S+Escape = SoftReset
K00:F12 = SaveFreezeFile
K00:A+F3 = SaveFreezeFile
K00:C+F3 = SaveFreezeFile
K00:F11 = LoadFreezeFile
K00:A+F2 = LoadFreezeFile
K00:C+F2 = LoadFreezeFile
K00:S+F1 = QuickSave000
K00:S+F2 = QuickSave001
K00:S+F3 = QuickSave002
K00:S+F4 = QuickSave003
K00:S+F5 = QuickSave004
K00:S+F6 = QuickSave005
K00:S+F7 = QuickSave006
K00:S+F8 = QuickSave007
K00:S+F9 = QuickSave008
K00:F1 = QuickLoad000
K00:F2 = QuickLoad001
K00:F3 = QuickLoad002
K00:F4 = QuickLoad003
K00:F5 = QuickLoad004
K00:F6 = QuickLoad005
K00:F7 = QuickLoad006
K00:F8 = QuickLoad007
K00:F9 = QuickLoad008
K00:F10 = LoadOopsFile
K00:A+F1 = SaveSPC
K00:C+F1 = SaveSPC
K00:Print = Screenshot
K00:S+1 = BeginRecordingMovie
K00:S+2 = EndRecordingMovie
K00:S+3 = LoadMovie
K00:Tab = EmuTurbo
K00:S+Tab = ToggleEmuTurbo
K00:equal = IncFrameRate
K00:minus = DecFrameRate
K00:S+equal = IncFrameTime
K00:S+minus = DecFrameTime
K00:A+equal = IncEmuTurbo
K00:A+minus = DecEmuTurbo
K00:C+equal = IncTurboSpeed
K00:C+minus = DecTurboSpeed
K00:6 = SwapJoypads
K00:A+F4 = SoundChannel0
K00:C+F4 = SoundChannel0
K00:A+F5 = SoundChannel1
K00:C+F5 = SoundChannel1
K00:A+F6 = SoundChannel2
K00:C+F6 = SoundChannel2
K00:A+F7 = SoundChannel3
K00:C+F7 = SoundChannel3
K00:A+F8 = SoundChannel4
K00:C+F8 = SoundChannel4
K00:A+F9 = SoundChannel5
K00:C+F9 = SoundChannel5
K00:A+F10 = SoundChannel6
K00:C+F10 = SoundChannel6
K00:A+F11 = SoundChannel7
K00:C+F11 = SoundChannel7
K00:A+F12 = SoundChannelsOn
K00:C+F12 = SoundChannelsOn
K00:1 = ToggleBG0
K00:2 = ToggleBG1
K00:3 = ToggleBG2
K00:4 = ToggleBG3
K00:5 = ToggleSprites
K00:9 = ToggleTransparency
K00:BackSpace = ClipWindows
K00:0 = ToggleHDMA
K00:A+Escape = Debugger
M00:Pointer = Pointer Mouse1+Superscope+Justifier1
M00:B0 = {Mouse1 L,Superscope Fire,Justifier1 Trigger}
M00:B2 = {Mouse1 R,Superscope Cursor,Justifier1 Start}
M00:B1 = {Justifier1 AimOffscreen Trigger,Superscope AimOffscreen}
K00:grave = Superscope ToggleTurbo
K00:slash = Superscope Pause

44
eboot-launcher/main.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <math.h>
#include <stddef.h>
#include <sys/return_code.h>
#include <sys/process.h>
#include <sys/memory.h>
#include <sys/timer.h>
#include <sys/paths.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cell/sysmodule.h>
#include <cell/cell_fs.h>
#include <sysutil/sysutil_sysparam.h>
//#include <sysutil/sysutil_discgame.h>
#include <sysutil/sysutil_common.h>
SYS_PROCESS_PARAM(1001, 0x100000)
int main(int argc, char **argv)
{
(void) argc;
char tn[128];
char filename[128];
sprintf(tn, "%s", argv[0]);
char *pch=tn;
char *pathpos=strrchr(pch,'/');
pathpos[0]=0;
sprintf(filename, "%s/RELOAD.SELF", tn);
sys_game_process_exitspawn2(filename, NULL, NULL, NULL, 0, 1001, SYS_PROCESS_PRIMARY_STACK_SIZE_1M);
}

BIN
pkg/ICON0.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
pkg/PARAM.SFO Executable file

Binary file not shown.

BIN
pkg/PIC1.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

0
pkg/USRDIR/.empty Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -0,0 +1,43 @@
shaders = 1
shader0 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/manual-reader.cg"
filter_linear0 = true
imports = "press_count_l;press_time_l;press_time_prev_l;press_count_r;press_time_r;press_time_prev_r"
press_count_l_input_slot = 1
press_time_l_input_slot = 1
press_time_prev_l_input_slot = 1
press_count_l_mask = 20
press_time_l_mask = 20
press_time_prev_l_mask = 20
press_count_r_input_slot = 1
press_time_r_input_slot = 1
press_time_prev_r_input_slot = 1
press_count_r_mask = 10
press_time_r_mask = 10
press_time_prev_r_mask = 10
press_count_l_semantic = transition_count
press_time_l_semantic = transition
press_time_prev_l_semantic = transition_previous
press_count_r_semantic = transition_count
press_time_r_semantic = transition
press_time_prev_r_semantic = transition_previous
textures = "border;page1;page2;page3;page4;page5;page6"
border = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/manual-reader-border.png"
page1 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_1.jpg"
page2 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_2.jpg"
page3 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_3.jpg"
page4 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_4.jpg"
page5 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_5.jpg"
page6 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/manualshaders/page_6.jpg"
border_linear = true
page1_linear = true
page2_linear = true
page3_linear = true
page4_linear = true
page5_linear = true
page6_linear = true

View File

@ -0,0 +1,255 @@
/*
Author: Themaister
License: Public domain
*/
// Border shader. 4x input scale, 1920x1080 border. :)
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
};
struct VERT
{
float2 menu_pos;
float2 menu_pos_alt;
float alpha0;
float alpha0_alt;
float alpha1;
float alpha1_alt;
float alpha2;
float alpha2_alt;
float alpha3;
float alpha3_alt;
float alpha4;
float alpha4_alt;
float alpha5;
float alpha5_alt;
};
#define MENU_PAGE_RES float2(569, 1016.0)
#define PAGE_GEOM float2(4.0, 2.0)
const float box_scale_ = 4.0; // 4x scale.
const float2 out_res_ = float2(1920.0, 1080.0); // Output target size.
// Output resolution on screen for the menu pages. The .jpg/.png can be whatever size.
const float2 menu_page_res_ = MENU_PAGE_RES;
const float2 page_geom = PAGE_GEOM;
const float2 menu_res_ = PAGE_GEOM * MENU_PAGE_RES;
// Depends on border. :)
const float2 shift_ = float2(-270.0, -54.0);
const float2 page_shift_ = float2(588.0, 10.0);
const float pages = 48.0; // Tweakable.
float2 pixel_shift(float2 middle, float2 show_size)
{
return float2(-2.0, 2.0) * middle / show_size;
}
void main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 modelViewProj,
float4 color : COLOR,
out float4 oColor : COLOR,
float2 tex : TEXCOORD,
out float2 oTex : TEXCOORD,
float2 tex_border : TEXCOORD1,
out float2 otex_border : TEXCOORD1,
out VERT vout,
uniform float press_count_l,
uniform float press_time_l,
uniform float press_time_prev_l,
uniform float press_count_r,
uniform float press_time_r,
uniform float press_time_prev_r,
uniform input IN
)
{
const float2 out_res = IN.output_size;
const float2 scaling_coeff = out_res / out_res_;
const float2 box_scale = box_scale_ * scaling_coeff;
const float2 menu_page_res = menu_page_res_ * scaling_coeff;
const float2 menu_res = menu_res_ * scaling_coeff;
const float2 shift = shift_ * scaling_coeff;
const float2 page_shift = page_shift_ * scaling_coeff;
oPosition = mul(modelViewProj, position);
oColor = color;
float2 scale = (IN.output_size / IN.video_size) / box_scale;
float2 middle = 0.5 * IN.video_size / IN.texture_size;
float2 diff = tex.xy - middle;
oTex = middle + (diff * scale + shift * pixel_shift(middle, IN.video_size * box_scale)) * IN.video_size / float2(256.0, 224.0);
middle = float2(0.5, 0.5);
float2 dist = tex_border - middle;
otex_border = middle + dist * IN.output_size / out_res;
// Calculate blend time.
float time;
if (press_time_l > press_time_r)
{
if (floor(fmod(press_count_l, 2.0)) > 0.0)
time = (IN.frame_count - press_time_l) / 20.0;
else
time = (IN.frame_count - press_time_prev_l) / 20.0;
}
else
{
if (floor(fmod(press_count_r, 2.0)) > 0.0)
time = (IN.frame_count - press_time_r) / 20.0;
else
time = (IN.frame_count - press_time_prev_r) / 20.0;
}
float alpha_0 = 0.0;
float alpha_0_alt = 0.0;
float alpha_1 = 0.0;
float alpha_1_alt = 0.0;
float alpha_2 = 0.0;
float alpha_2_alt = 0.0;
float alpha_3 = 0.0;
float alpha_3_alt = 0.0;
float alpha_4 = 0.0;
float alpha_4_alt = 0.0;
float alpha_5 = 0.0;
float alpha_5_alt = 0.0;
// Calculate blend coeffs.
float page_index = floor(fmod((press_count_r + 1.0) / 2.0, pages)) - floor(fmod((press_count_l + 1.0) / 2.0, pages));
if (page_index < 0.0)
page_index = pages + page_index;
float page_index_prev;
if (press_time_l > press_time_r)
{
page_index_prev = fmod(page_index + 1.0, pages);
}
else
{
if (page_index == 0.0)
page_index_prev = pages - 1.0;
else
page_index_prev = page_index - 1.0;
}
float abs_page_index = floor(page_index / 8.0);
float abs_page_index_prev = floor(page_index_prev / 8.0);
float full_alpha = 1.0 - exp(-time);
float prev_alpha = exp(-time);
if (abs_page_index >= 5.0)
alpha_5 = full_alpha;
else if (abs_page_index >= 4.0)
alpha_4 = full_alpha;
else if (abs_page_index >= 3.0)
alpha_3 = full_alpha;
else if (abs_page_index >= 2.0)
alpha_2 = full_alpha;
else if (abs_page_index >= 1.0)
alpha_1 = full_alpha;
else
alpha_0 = full_alpha;
if (abs_page_index_prev >= 5.0)
alpha_5_alt = prev_alpha;
else if (abs_page_index_prev >= 4.0)
alpha_4_alt = prev_alpha;
else if (abs_page_index_prev >= 3.0)
alpha_3_alt = prev_alpha;
else if (abs_page_index_prev >= 2.0)
alpha_2_alt = prev_alpha;
else if (abs_page_index_prev >= 1.0)
alpha_1_alt = prev_alpha;
else
alpha_0_alt = prev_alpha;
float2 abs_shift = float2(0.5, -0.5) * (page_geom - float2(1.0));
abs_shift += float2(-fmod(page_index, page_geom.x), floor(fmod(page_index, page_geom.x * page_geom.y) / page_geom.x));
abs_shift *= menu_page_res;
float2 abs_shift_alt = float2(0.5, -0.5) * (page_geom - float2(1.0));
abs_shift_alt += float2(-fmod(page_index_prev, page_geom.x), floor(fmod(page_index_prev, page_geom.x * page_geom.y) / page_geom.x));
abs_shift_alt *= menu_page_res;
float2 menu_pos =
middle +
dist * IN.output_size / menu_res +
(page_shift + abs_shift) * pixel_shift(middle, menu_res);
float2 menu_pos_alt =
middle +
dist * IN.output_size / menu_res +
(page_shift + abs_shift_alt) * pixel_shift(middle, menu_res);
vout = VERT(menu_pos, menu_pos_alt,
alpha_0, alpha_0_alt,
alpha_1, alpha_1_alt,
alpha_2, alpha_2_alt,
alpha_3, alpha_3_alt,
alpha_4, alpha_4_alt,
alpha_5, alpha_5_alt
);
}
float4 main_fragment (
float2 tex : TEXCOORD0, float2 tex_border : TEXCOORD1,
uniform sampler2D s0 : TEXUNIT0,
uniform sampler2D border,
uniform sampler2D page1,
uniform sampler2D page2,
uniform sampler2D page3,
uniform sampler2D page4,
uniform sampler2D page5,
uniform sampler2D page6,
in VERT vout) : COLOR
{
float4 frame = tex2D(s0, tex);
float4 background = tex2D(border, tex_border);
float alpha_mask = 1.0;
if (tex_border.x >= 0.999 || tex_border.x < 0.65 || tex_border.y >= 0.999 || tex_border.y <= 0.001)
alpha_mask = 0.0;
return
alpha_mask *
(
tex2D(page1, vout.menu_pos) * vout.alpha0 +
tex2D(page1, vout.menu_pos_alt) * vout.alpha0_alt +
tex2D(page2, vout.menu_pos) * vout.alpha1 +
tex2D(page2, vout.menu_pos_alt) * vout.alpha1_alt +
tex2D(page3, vout.menu_pos) * vout.alpha2 +
tex2D(page3, vout.menu_pos_alt) * vout.alpha2_alt +
tex2D(page4, vout.menu_pos) * vout.alpha3 +
tex2D(page4, vout.menu_pos_alt) * vout.alpha3_alt +
tex2D(page5, vout.menu_pos) * vout.alpha4 +
tex2D(page5, vout.menu_pos_alt) * vout.alpha4_alt +
tex2D(page6, vout.menu_pos) * vout.alpha5 +
tex2D(page6, vout.menu_pos_alt) * vout.alpha5_alt
)
+ lerp(frame, background, background.a);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

View File

@ -0,0 +1,11 @@
imports = "mario_water;mario_water_time"
mario_water_semantic = capture
mario_water_time_semantic = transition
mario_water_wram = 0085
mario_water_time_wram = 0085
shaders = 2
shader0 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/mario-water.cg"
shader1 = "/dev_hdd0/game/SNES90000/USRDIR/shaders/stock.cg"
textures = rain
rain = "/dev_hdd0/game/SNES90000/USRDIR/borders/Centered-1080p/overlays/none-overlay.png"
rain_linear = true

View File

@ -0,0 +1,11 @@
imports = "mario_water;mario_water_time"
mario_water_semantic = capture
mario_water_time_semantic = transition
mario_water_wram = 0075
mario_water_time_wram = 0075
shaders = 2
shader0 = "/dev_hdd0/game/SNES90000/USRDIR/gameaware/mario-water.cg"
shader1 = "/dev_hdd0/game/SNES90000/USRDIR/shaders/stock.cg"
textures = rain
rain = "/dev_hdd0/game/SNES90000/USRDIR/borders/Centered-1080p/overlays/none-overlay.png"
rain_linear = true

View File

@ -0,0 +1,107 @@
/*
Author: Themaister
License: Public domain
*/
struct input
{
float2 video_size;
float2 texture_size;
float2 output_size;
float frame_count;
};
struct prev_in
{
float2 tex_coord;
sampler2D texture;
};
struct vertex_out
{
float water;
};
void main_vertex
(
float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 modelViewProj,
float4 color : COLOR,
out float4 oColor : COLOR,
float2 tex : TEXCOORD0,
out float2 oTex : TEXCOORD0,
float2 tex1 : TEXCOORD1,
out float2 oTex1 : TEXCOORD1,
out vertex_out VERT,
uniform float mario_water,
uniform float mario_water_time,
uniform input IN
)
{
oPosition = mul(modelViewProj, position);
oColor = color;
oTex = tex;
oTex1 = tex1;
float transition_time = (IN.frame_count - mario_water_time) / 120.0;
float water_coeff;
if (mario_water > 0.0)
water_coeff = 1.0;
else
water_coeff = exp(-transition_time);
VERT = vertex_out(water_coeff);
}
const float2 src0 = float2(0.6, 0.7);
const float2 src1 = float2(0.9, 0.9);
const float2 src2 = float2(-0.6, 0.3);
const float2 src3 = float2(0.1, 0.4);
const float2 src4 = float2(0.1, 0.4);
const float2 src5 = float2(0.5, 0.5);
const float2 src6 = float2(-1.0, 1.0);
float apply_wave(float2 pos, float2 src, float cnt)
{
float2 diff = pos - src;
float dist = 300.0 * sqrt(dot(diff, diff));
dist -= 0.15 * cnt;
return sin(dist);
}
float4 water_texture(float4 output, float2 scale, float cnt)
{
float res = apply_wave(scale, src0, cnt);
res += apply_wave(scale, src1, cnt);
res += apply_wave(scale, src2, cnt);
res += apply_wave(scale, src3, cnt);
res += apply_wave(scale, src4, cnt);
res += apply_wave(scale, src5, cnt);
res += apply_wave(scale, src6, cnt);
return output * (0.95 + 0.012 * res);
}
float4 main_fragment
(
uniform input IN,
float2 tex : TEXCOORD0, uniform sampler2D s0 : TEXUNIT0,
uniform sampler2D rain, float2 tex1 : TEXCOORD1,
in vertex_out VERT
) : COLOR
{
float4 water_tex = water_texture(tex2D(s0, tex),
tex * IN.texture_size / IN.video_size, IN.frame_count);
float4 normal_tex = tex2D(s0, tex);
float4 rain_tex = tex2D(rain, tex1);
return lerp(lerp(normal_tex, water_tex, VERT.water), rain_tex, rain_tex.a * VERT.water * 0.5);
}

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2 + 4xSoft-variation"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.cg"
PS3CurrentShader2 = "xSoft/4xSoft-variation-1.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2 + Bicubic-sharper"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xBR/2xBR-v2.cg"
PS3CurrentShader2 = "Bicubic/Bicubic-sharper.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2 + Lanczos16"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xBR/2xBR-v2.cg"
PS3CurrentShader2 = "Lanczos/Lanczos16.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2 + Lanczos4"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xBR/2xBR-v2.cg"
PS3CurrentShader2 = "Lanczos/Lanczos4.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2.1 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.1.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2.2 + Quilez"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.2.cg"
PS3CurrentShader2 = "Quilez.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2.2 + advAA aspect 10:7"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.2.cg"
PS3CurrentShader2 = "2x-boxed/AdvancedAA-box-2x-aspect-10-7.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2.2 + advancedAA box"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.2.cg"
PS3CurrentShader2 = "2x-boxed/AdvancedAA-box-2.5x.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xBR-v2.2 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/2xBR-v2.2.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xSaI + 4xSoft-variation-1 (Sharp)"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xSaL/2xSaI.cg"
PS3CurrentShader2 = "xSoft/4xSoft-variation-1.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "2xSaI + 4xSoft-variation-1"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xSaL/2xSaI.cg"
PS3CurrentShader2 = "xSoft/4xSoft-variation-1.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "3xBR-v2 + Quilez"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/3xBR-v2.cg"
PS3CurrentShader2 = "Quilez.cg"
ScaleEnabled = 1
ScaleFactor = 3

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "3xBR-v2 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/3xBR-v2.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 3

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "3xBR-v2.1 + Quilez"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/3xBR-v2.1.cg"
PS3CurrentShader2 = "Quilez.cg"
ScaleEnabled = 1
ScaleFactor = 3

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "3xBR-v2.1 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/3xBR-v2.1.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 3

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xBR + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/4xBR.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xBR-v1.1 + Quilez"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/4xBR-v1.1.cg"
PS3CurrentShader2 = "Quilez.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xBR-v1.1 + stock"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xBR/4xBR-v1.1.cg"
PS3CurrentShader2 = "stock.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xSoftHD + 4xSoft (x4)"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xSoft/4xSoft-HD.cg"
PS3CurrentShader2 = "xSoft/4xSoft.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xSoftHD + 4xSoftHD-1152x672"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xSoft/4xSoft-HD.cg"
PS3CurrentShader2 = "xSoft/4xSoft-HD-1152x672.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xSoftHD + 4xSoftHD (960x592)"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "xSoft/4xSoft-HD.cg"
PS3CurrentShader2 = "xSoft/4xSoft-HD-960x592.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "4xSoftHD + 4xSoft-variation-1"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "xSoft/4xSoft-HD.cg"
PS3CurrentShader2 = "xSoft/4xSoft-variation-1.cg"
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD + Anti-aliasing
Smooth = 0
Smooth2 = 0
PS3CurrentShader = /xSoft/4xSoft-HD.cg
PS3CurrentShader2 = /AdvancedAA.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD + CRT
Smooth = 0
Smooth2 = 0
PS3CurrentShader = /xSoft/4xSoft-HD.cg
PS3CurrentShader2 = /CRT/crt.cg
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD + Scanline
Smooth = 0
Smooth2 = 0
PS3CurrentShader = /xSoft/4xSoft-HD.cg
PS3CurrentShader2 = /scanline.cg
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD + Sharpen
Smooth = 1
Smooth2 = 1
PS3CurrentShader = /xSoft/4xSoft-HD.cg
PS3CurrentShader2 = /Sharpen/sharpen-light2.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + 4xSoftHD-1152x672
Smooth = 0
Smooth2 = 1
PS3CurrentShader = /xSoft/4xSoft-HD-variation-1.cg
PS3CurrentShader2 = /xSoft/4xSoft-HD-1152x672.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + 4xSoft-HD-960x592
Smooth = 0
Smooth2 = 0
PS3CurrentShader = /xSoft/4xSoft-HD-variation-1.cg
PS3CurrentShader2 = /xSoft/4xSoft-HD-960x592.cg
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + 4xSoft-variation-1
Smooth = 0
Smooth2 = 1
PS3CurrentShader = /xSoft/4xSoft-HD-variation-1.cg
PS3CurrentShader2 = /xSoft/4xSoft-variation-1.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + Anti-aliasing
Smooth = 0
Smooth2 = 0
PS3CurrentShader = /xSoft/4xSoft-HD-variation-1.cg
PS3CurrentShader2 = /AdvancedAA.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + HQ2x
Smooth = 0
Smooth2 = 0
PS3CurrentShader = //4xSoft-HD-variation-1.cg
PS3CurrentShader2 = //hq2x.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 4xSoftHD-variation-1 + Scanlines
Smooth = 0
Smooth2 = 1
PS3CurrentShader = /xSoft/4xSoft-HD-variation-1.cg
PS3CurrentShader2 = /scanline.cg
ScaleEnabled = 1
ScaleFactor = 4

View File

@ -0,0 +1,8 @@
[PS3General]
ShaderPresetTitle = 5xBR-v2.1 plus AdvancedAA
Smooth = 0
Smooth2 = 1
PS3CurrentShader = /xBR/5xBR-v2.1.cg
PS3CurrentShader2 = /1x-boxed/AdvancedAA-box-1x.cg
ScaleEnabled = 1
ScaleFactor = 5

View File

@ -0,0 +1,8 @@
KeepAspect = 3
ShaderPresetTitle = "Borders Centered (2x scale - 1080p)"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "Borders/Border-Centered/border-centered-fbo-scale-2x.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,8 @@
KeepAspect = 3
ShaderPresetTitle = "Borders Centered + Water (2x scale - 1080p)"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "Borders/Border-Centered/border-centered-water-fbo-scale-2x.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,8 @@
KeepAspect = 3
ShaderPresetTitle = "Borders Left Portrait (2x scale - 1080p)"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "Borders/Border-Left-Portrait/border-left-portrait-fbo-scale-2x.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "Anti-Aliasing + Bicubic Anti-Aliasing (sharper)"
Smooth = 0
Smooth2 = 1
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "Bicubic/Bicubic-sharper.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "Anti-Aliasing + Bloom"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "Bloom/bloom-HD.cg"
ScaleEnabled = 1
ScaleFactor = 2

View File

@ -0,0 +1,7 @@
ShaderPresetTitle = "Anti-Aliasing + CRT High Gamma"
Smooth = 0
Smooth2 = 0
PS3CurrentShader = "AdvancedAA.cg"
PS3CurrentShader2 = "CRT/crt-highgamma.cg"
ScaleEnabled = 1
ScaleFactor = 2

Some files were not shown because too many files have changed in this diff Show More