mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-21 19:45:10 +00:00
merge PC port onto the decompile
This commit is contained in:
parent
9a40d86f6a
commit
e87c070517
474 changed files with 212357 additions and 135 deletions
242
Makefile
242
Makefile
|
@ -18,13 +18,35 @@ COMPARE ?= 1
|
|||
# If NON_MATCHING is 1, define the NON_MATCHING and AVOID_UB macros when building (recommended)
|
||||
NON_MATCHING ?= 0
|
||||
# Build for the N64 (turn this off for ports)
|
||||
TARGET_N64 ?= 1
|
||||
TARGET_N64 ?= 0
|
||||
# Compiler to use (ido or gcc)
|
||||
COMPILER ?= ido
|
||||
|
||||
ifeq ($(COMPILER),gcc)
|
||||
NON_MATCHING := 1
|
||||
endif
|
||||
# Build for Emscripten/WebGL
|
||||
TARGET_WEB ?= 0
|
||||
# Specify the target you are building for, 0 means native
|
||||
TARGET_ARCH ?= native
|
||||
TARGET_BITS ?= 0
|
||||
|
||||
ifneq ($(TARGET_BITS),0)
|
||||
BITS := -m$(TARGET_BITS)
|
||||
else
|
||||
BITS :=
|
||||
endif
|
||||
|
||||
# Automatic settings only for ports
|
||||
ifeq ($(TARGET_N64),0)
|
||||
NON_MATCHING := 1
|
||||
GRUCODE := f3dex2e
|
||||
WINDOWS_BUILD := 0
|
||||
ifeq ($(TARGET_WEB),0)
|
||||
ifeq ($(OS),Windows_NT)
|
||||
WINDOWS_BUILD := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
# Release
|
||||
|
||||
|
@ -79,6 +101,11 @@ ifeq ($(GRUCODE), f3dex2) # Fast3DEX2
|
|||
TARGET := $(TARGET).f3dex2
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE), f3dex2e) # Fast3DEX2 Extended (for PC)
|
||||
GRUCODE_CFLAGS := -DF3DEX_GBI_2E
|
||||
TARGET := $(TARGET).f3dex2e
|
||||
COMPARE := 0
|
||||
else
|
||||
ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
|
||||
GRUCODE_CFLAGS := -DF3D_NEW
|
||||
GRUCODE_ASFLAGS := --defsym F3D_NEW=1
|
||||
|
@ -95,6 +122,7 @@ endif
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_N64),0)
|
||||
NON_MATCHING := 1
|
||||
|
@ -106,6 +134,10 @@ ifeq ($(NON_MATCHING),1)
|
|||
COMPARE := 0
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
VERSION_CFLAGS := $(VERSION_CFLAGS) -DTARGET_WEB
|
||||
endif
|
||||
|
||||
################### Universal Dependencies ###################
|
||||
|
||||
# (This is a bit hacky, but a lot of rules implicitly depend
|
||||
|
@ -137,9 +169,26 @@ endif
|
|||
|
||||
# BUILD_DIR is location where all build artifacts are placed
|
||||
BUILD_DIR_BASE := build
|
||||
ifeq ($(TARGET_N64),1)
|
||||
BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)
|
||||
else
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_web
|
||||
else
|
||||
BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)_pc
|
||||
endif
|
||||
endif
|
||||
|
||||
LIBULTRA := $(BUILD_DIR)/libultra.a
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).html
|
||||
else
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
EXE := $(BUILD_DIR)/$(TARGET).exe
|
||||
else
|
||||
EXE := $(BUILD_DIR)/$(TARGET)
|
||||
endif
|
||||
endif
|
||||
ROM := $(BUILD_DIR)/$(TARGET).z64
|
||||
ELF := $(BUILD_DIR)/$(TARGET).elf
|
||||
LD_SCRIPT := sm64.ld
|
||||
|
@ -151,7 +200,13 @@ LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
|
|||
|
||||
# Directories containing source files
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets
|
||||
ASM_DIRS := asm lib
|
||||
ASM_DIRS := lib
|
||||
ifeq ($(TARGET_N64),1)
|
||||
ASM_DIRS := asm $(ASM_DIRS)
|
||||
else
|
||||
SRC_DIRS := $(SRC_DIRS) src/pc src/pc/gfx src/pc/audio src/pc/controller
|
||||
ASM_DIRS :=
|
||||
endif
|
||||
BIN_DIRS := bin bin/$(VERSION)
|
||||
|
||||
ULTRA_SRC_DIRS := lib/src lib/src/math
|
||||
|
@ -177,6 +232,15 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_N64),0)
|
||||
OPT_FLAGS += $(BITS)
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
OPT_FLAGS := -O2 -g4 --source-map-base http://localhost:8080/
|
||||
endif
|
||||
endif
|
||||
|
||||
# Use a default opt flag for gcc
|
||||
ifeq ($(COMPILER),gcc)
|
||||
OPT_FLAGS := -O2
|
||||
|
@ -188,11 +252,80 @@ include Makefile.split
|
|||
# Source code files
|
||||
LEVEL_C_FILES := $(wildcard levels/*/leveldata.c) $(wildcard levels/*/script.c) $(wildcard levels/*/geo.c)
|
||||
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) $(LEVEL_C_FILES)
|
||||
CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
|
||||
S_FILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s))
|
||||
ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c))
|
||||
GODDARD_C_FILES := $(foreach dir,$(GODDARD_SRC_DIRS),$(wildcard $(dir)/*.c))
|
||||
ifeq ($(TARGET_N64),1)
|
||||
ULTRA_S_FILES := $(foreach dir,$(ULTRA_ASM_DIRS),$(wildcard $(dir)/*.s))
|
||||
GENERATED_C_FILES := $(BUILD_DIR)/assets/mario_anim_data.c $(BUILD_DIR)/assets/demo_data.c
|
||||
endif
|
||||
GENERATED_C_FILES := $(BUILD_DIR)/assets/mario_anim_data.c $(BUILD_DIR)/assets/demo_data.c \
|
||||
$(addprefix $(BUILD_DIR)/bin/,$(addsuffix _skybox.c,$(notdir $(basename $(wildcard textures/skyboxes/*.png)))))
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),0)
|
||||
CXX_FILES :=
|
||||
endif
|
||||
|
||||
ifneq ($(TARGET_N64),1)
|
||||
ULTRA_C_FILES_SKIP := \
|
||||
sqrtf.c \
|
||||
string.c \
|
||||
sprintf.c \
|
||||
_Printf.c \
|
||||
kdebugserver.c \
|
||||
osInitialize.c \
|
||||
func_802F7140.c \
|
||||
func_802F71F0.c \
|
||||
func_802F4A20.c \
|
||||
EU_D_802f4330.c \
|
||||
D_802F4380.c \
|
||||
osLeoDiskInit.c \
|
||||
osCreateThread.c \
|
||||
osDestroyThread.c \
|
||||
osStartThread.c \
|
||||
osSetThreadPri.c \
|
||||
osPiStartDma.c \
|
||||
osPiRawStartDma.c \
|
||||
osPiRawReadIo.c \
|
||||
osPiGetCmdQueue.c \
|
||||
osJamMesg.c \
|
||||
osSendMesg.c \
|
||||
osRecvMesg.c \
|
||||
osSetEventMesg.c \
|
||||
osTimer.c \
|
||||
osSetTimer.c \
|
||||
osSetTime.c \
|
||||
osCreateViManager.c \
|
||||
osViSetSpecialFeatures.c \
|
||||
osVirtualToPhysical.c \
|
||||
osViBlack.c \
|
||||
osViSetEvent.c \
|
||||
osViSetMode.c \
|
||||
osViSwapBuffer.c \
|
||||
osSpTaskLoadGo.c \
|
||||
osCreatePiManager.c \
|
||||
osGetTime.c \
|
||||
osEepromProbe.c \
|
||||
osEepromWrite.c \
|
||||
osEepromLongWrite.c \
|
||||
osEepromRead.c \
|
||||
osEepromLongRead.c \
|
||||
osContInit.c \
|
||||
osContStartReadData.c \
|
||||
osAiGetLength.c \
|
||||
osAiSetFrequency.c \
|
||||
osAiSetNextBuffer.c \
|
||||
__osViInit.c \
|
||||
__osSyncPutChars.c \
|
||||
__osAtomicDec.c \
|
||||
__osSiRawStartDma.c \
|
||||
__osViSwapContext.c \
|
||||
__osViGetCurrentContext.c \
|
||||
__osDevMgrMain.c
|
||||
|
||||
C_FILES := $(filter-out src/game/main.c,$(C_FILES))
|
||||
ULTRA_C_FILES := $(filter-out $(addprefix lib/src/,$(ULTRA_C_FILES_SKIP)),$(ULTRA_C_FILES))
|
||||
endif
|
||||
|
||||
ifeq ($(VERSION),sh)
|
||||
SOUND_BANK_FILES := $(wildcard sound/sound_banks/*.json)
|
||||
|
@ -220,6 +353,7 @@ SOUND_OBJ_FILES := $(SOUND_BIN_DIR)/sound_data.ctl.o \
|
|||
|
||||
# Object files
|
||||
O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
|
||||
$(foreach file,$(CXX_FILES),$(BUILD_DIR)/$(file:.cpp=.o)) \
|
||||
$(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
|
||||
$(foreach file,$(GENERATED_C_FILES),$(file:.c=.o))
|
||||
|
||||
|
@ -232,21 +366,27 @@ GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
|
|||
DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d
|
||||
|
||||
# Files with GLOBAL_ASM blocks
|
||||
ifneq ($(NON_MATCHING),1)
|
||||
GLOBAL_ASM_C_FILES != grep -rl 'GLOBAL_ASM(' $(wildcard src/**/*.c)
|
||||
GLOBAL_ASM_O_FILES = $(foreach file,$(GLOBAL_ASM_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
|
||||
GLOBAL_ASM_DEP = $(BUILD_DIR)/src/audio/non_matching_dep
|
||||
endif
|
||||
|
||||
# Segment elf files
|
||||
SEG_FILES := $(SEGMENT_ELF_FILES) $(ACTOR_ELF_FILES) $(LEVEL_ELF_FILES)
|
||||
|
||||
##################### Compiler Options #######################
|
||||
INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I $(BUILD_DIR)/include -I src -I .
|
||||
ENDIAN_BITWIDTH := $(BUILD_DIR)/endian-and-bitwidth
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
IRIX_ROOT := tools/ido5.3_compiler
|
||||
|
||||
ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0)
|
||||
CROSS := mips-linux-gnu-
|
||||
else ifeq ($(shell type mips64-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0)
|
||||
CROSS := mips64-linux-gnu-
|
||||
else
|
||||
else ifeq ($(shell type mips64-elf-ld >/dev/null 2>/dev/null; echo $$?), 0)
|
||||
CROSS := mips64-elf-
|
||||
endif
|
||||
|
||||
|
@ -277,8 +417,6 @@ ifeq ($(TARGET_N64),1)
|
|||
CC_CFLAGS := -fno-builtin
|
||||
endif
|
||||
|
||||
INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I $(BUILD_DIR)/include -I src -I .
|
||||
|
||||
# Check code syntax with host compiler
|
||||
CC_CHECK := gcc -fsyntax-only -fsigned-char $(CC_CFLAGS) $(TARGET_CFLAGS) $(INCLUDE_CFLAGS) -std=gnu90 -Wall -Wextra -Wno-format-security -Wno-main -DNON_MATCHING -DAVOID_UB $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
|
||||
|
||||
|
@ -300,7 +438,51 @@ ifeq ($(shell getconf LONG_BIT), 32)
|
|||
export QEMU_GUEST_BASE := 1
|
||||
else
|
||||
# Ensure that gcc treats the code as 32-bit
|
||||
CC_CHECK += -m32
|
||||
CC_CHECK += $(BITS)
|
||||
endif
|
||||
|
||||
else # TARGET_N64
|
||||
|
||||
AS := as
|
||||
ifneq ($(TARGET_WEB),1)
|
||||
CC := $(CROSS)gcc
|
||||
CXX := $(CROSS)g++
|
||||
else
|
||||
CC := emcc
|
||||
endif
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
LD := $(CXX)
|
||||
else
|
||||
LD := $(CC)
|
||||
endif
|
||||
CPP := cpp -P
|
||||
OBJDUMP := objdump
|
||||
OBJCOPY := objcopy
|
||||
PYTHON := python3
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(CROSS)sdl2-config --cflags`
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(CROSS)sdl2-config --cflags`
|
||||
else ifeq ($(TARGET_WEB),1)
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -s USE_SDL=2
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv -s USE_SDL=2
|
||||
else
|
||||
CC_CHECK := $(CC) -fsyntax-only -fsigned-char $(INCLUDE_CFLAGS) -Wall -Wextra -Wno-format-security $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) `$(CROSS)pkg-config --cflags libusb-1.0 glfw3` `$(CROSS)sdl2-config --cflags`
|
||||
CFLAGS := $(OPT_FLAGS) $(INCLUDE_CFLAGS) $(VERSION_CFLAGS) $(GRUCODE_CFLAGS) -fno-strict-aliasing -fwrapv `$(CROSS)pkg-config --cflags libusb-1.0 glfw3` `$(CROSS)sdl2-config --cflags`
|
||||
endif
|
||||
|
||||
ASFLAGS := -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS)
|
||||
|
||||
ifeq ($(TARGET_WEB),1)
|
||||
LDFLAGS := -lm -lGL -lSDL2 -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
|
||||
else
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -Llib -lpthread -lglew32 `$(CROSS)sdl2-config --static-libs` -lm -lglu32 -lsetupapi -ldinput8 -luser32 -lgdi32 -limm32 -lole32 -loleaut32 -lshell32 -lwinmm -lversion -luuid -lopengl32 -no-pie -static
|
||||
else
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm -lGL `$(CROSS)sdl2-config --libs` -no-pie -lpthread `$(CROSS)pkg-config --libs libusb-1.0 glfw3` -lasound -lX11 -lXrandr -lpulse
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# Prevent a crash with -sopt
|
||||
|
@ -333,23 +515,32 @@ endif
|
|||
|
||||
###################### Dependency Check #####################
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
BINUTILS_VER_MAJOR := $(shell $(LD) --version | grep ^GNU | sed 's/^.* //; s/\..*//g')
|
||||
BINUTILS_VER_MINOR := $(shell $(LD) --version | grep ^GNU | sed 's/^[^.]*\.//; s/\..*//g')
|
||||
BINUTILS_DEPEND := $(shell expr $(BINUTILS_VER_MAJOR) \>= 2 \& $(BINUTILS_VER_MINOR) \>= 27)
|
||||
ifeq ($(BINUTILS_DEPEND),0)
|
||||
$(error binutils version 2.27 required, version $(BINUTILS_VER_MAJOR).$(BINUTILS_VER_MINOR) detected)
|
||||
endif
|
||||
endif
|
||||
|
||||
######################## Targets #############################
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
all: $(ROM)
|
||||
ifeq ($(COMPARE),1)
|
||||
@$(SHA1SUM) -c $(TARGET).sha1 || (echo 'The build succeeded, but did not match the official ROM. This is expected if you are making changes to the game.\nTo silence this message, use "make COMPARE=0"'. && false)
|
||||
endif
|
||||
else
|
||||
all: $(EXE)
|
||||
endif
|
||||
|
||||
clean:
|
||||
$(RM) -r $(BUILD_DIR_BASE)
|
||||
|
||||
cleantools:
|
||||
$(MAKE) -s -C tools clean
|
||||
|
||||
distclean:
|
||||
$(RM) -r $(BUILD_DIR_BASE)
|
||||
./extract_assets.py --clean
|
||||
|
@ -402,6 +593,7 @@ $(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/$(VERSION)/define_text.inc.c
|
|||
endif
|
||||
endif
|
||||
|
||||
|
||||
$(BUILD_DIR)/text/%/define_courses.inc.c: text/define_courses.inc.c text/%/courses.h
|
||||
$(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/
|
||||
$(TEXTCONV) charmap.txt $@ $@
|
||||
|
@ -410,6 +602,8 @@ $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h t
|
|||
$(CPP) $(VERSION_CFLAGS) $< -o $@ -I text/$*/
|
||||
$(TEXTCONV) charmap.txt $@ $@
|
||||
|
||||
O_FILES += $(wildcard $(BUILD_DIR)/bin/$(VERSION)/*.o)
|
||||
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
|
||||
|
||||
# Make sure build directory exists before compiling anything
|
||||
|
@ -444,6 +638,7 @@ $(BUILD_DIR)/%.ci4: %.ci4.png
|
|||
|
||||
# compressed segment generation
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
# TODO: ideally this would be `-Trodata-segment=0x07000000` but that doesn't set the address
|
||||
|
||||
$(BUILD_DIR)/bin/%.elf: $(BUILD_DIR)/bin/%.o
|
||||
|
@ -473,6 +668,7 @@ $(BUILD_DIR)/%.mio0.o: $(BUILD_DIR)/%.mio0.s
|
|||
|
||||
$(BUILD_DIR)/%.mio0.s: $(BUILD_DIR)/%.mio0
|
||||
printf ".section .data\n\n.incbin \"$<\"\n" > $@
|
||||
endif
|
||||
|
||||
$(BUILD_DIR)/%.table: %.aiff
|
||||
$(AIFF_EXTRACT_CODEBOOK) $< >$@
|
||||
|
@ -510,8 +706,30 @@ $(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o
|
|||
$(SOUND_BIN_DIR)/%.o: $(SOUND_BIN_DIR)/%.s
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
$(SOUND_BIN_DIR)/%.s: $(SOUND_BIN_DIR)/%
|
||||
printf ".section .data\n\n.incbin \"$<\"\n" > $@
|
||||
else
|
||||
$(SOUND_BIN_DIR)/sound_data.ctl.c: $(SOUND_BIN_DIR)/sound_data.ctl
|
||||
echo "unsigned char gSoundDataADSR[] = {" > $@
|
||||
hexdump -v -e '1/1 "0x%X,"' $< >> $@
|
||||
echo "};" >> $@
|
||||
|
||||
$(SOUND_BIN_DIR)/sound_data.tbl.c: $(SOUND_BIN_DIR)/sound_data.tbl
|
||||
echo "unsigned char gSoundDataRaw[] = {" > $@
|
||||
hexdump -v -e '1/1 "0x%X,"' $< >> $@
|
||||
echo "};" >> $@
|
||||
|
||||
$(SOUND_BIN_DIR)/sequences.bin.c: $(SOUND_BIN_DIR)/sequences.bin
|
||||
echo "unsigned char gMusicData[] = {" > $@
|
||||
hexdump -v -e '1/1 "0x%X,"' $< >> $@
|
||||
echo "};" >> $@
|
||||
|
||||
$(SOUND_BIN_DIR)/bank_sets.c: $(SOUND_BIN_DIR)/bank_sets
|
||||
echo "unsigned char gBankSetsData[] = {" > $@
|
||||
hexdump -v -e '1/1 "0x%X,"' $< >> $@
|
||||
echo "};" >> $@
|
||||
endif
|
||||
|
||||
$(BUILD_DIR)/levels/scripts.o: $(BUILD_DIR)/include/level_headers.h
|
||||
|
||||
|
@ -578,6 +796,10 @@ $(GLOBAL_ASM_DEP).$(NON_MATCHING):
|
|||
@rm -f $(GLOBAL_ASM_DEP).*
|
||||
touch $@
|
||||
|
||||
$(BUILD_DIR)/%.o: %.cpp
|
||||
@$(CXX) -fsyntax-only $(CFLAGS) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
|
||||
$(CXX) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c
|
||||
@$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
@ -590,6 +812,7 @@ $(BUILD_DIR)/%.o: $(BUILD_DIR)/%.c
|
|||
$(BUILD_DIR)/%.o: %.s
|
||||
$(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $<
|
||||
|
||||
ifeq ($(TARGET_N64),1)
|
||||
$(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
|
||||
$(CPP) $(VERSION_CFLAGS) -MMD -MP -MT $@ -MF $@.d -I include/ -I . -DBUILD_DIR=$(BUILD_DIR) -o $@ $<
|
||||
|
||||
|
@ -610,6 +833,11 @@ $(ROM): $(ELF)
|
|||
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
|
||||
$(OBJDUMP) -D $< > $@
|
||||
|
||||
else
|
||||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES)
|
||||
$(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
.PHONY: all clean distclean default diff test load libultra
|
||||
|
|
0
asmdiff.jp.sh
Executable file → Normal file
0
asmdiff.jp.sh
Executable file → Normal file
|
@ -2499,6 +2499,7 @@ static const Lights1 segment2_lights_unused = gdSPDefLights1(
|
|||
|
||||
// 0x02014470 - 0x020144B0
|
||||
static const Mtx matrix_identity = {
|
||||
#ifdef TARGET_N64
|
||||
{{0x00010000, 0x00000000,
|
||||
0x00000001, 0x00000000},
|
||||
{0x00000000, 0x00010000,
|
||||
|
@ -2507,19 +2508,32 @@ static const Mtx matrix_identity = {
|
|||
0x00000000, 0x00000000},
|
||||
{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000}}
|
||||
#else
|
||||
{{1.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 1.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 1.0f, 0.0f},
|
||||
{0.0f, 0.0f, 0.0f, 1.0f}}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// 0x020144B0 - 0x020144F0
|
||||
static const Mtx matrix_fullscreen = {
|
||||
#if TARGET_N64
|
||||
{{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000},
|
||||
{0x00000000, 0xffff0000,
|
||||
0xffffffff, 0xffff0001},
|
||||
{0x01990000, 0x00000000,
|
||||
0x00000222, 0x00000000},
|
||||
{((65536 * 2 / SCREEN_WIDTH) << 16) | 0, 0x00000000,
|
||||
(0 << 16) | (65536 * 2 / SCREEN_HEIGHT), 0x00000000},
|
||||
{0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000}}
|
||||
#else
|
||||
{{2.0f / SCREEN_WIDTH, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 2.0f / SCREEN_HEIGHT, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, -1.0f, 0.0f},
|
||||
{-1.0f, -1.0f, -1.0f, 1.0f}}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ def main():
|
|||
input = image[pos : pos + size]
|
||||
os.makedirs(os.path.dirname(asset), exist_ok=True)
|
||||
if asset.endswith(".png"):
|
||||
with tempfile.NamedTemporaryFile(prefix="asset") as png_file:
|
||||
with tempfile.NamedTemporaryFile(prefix="asset", delete=False) as png_file:
|
||||
png_file.write(input)
|
||||
png_file.flush()
|
||||
if asset.startswith("textures/skyboxes/") or asset.startswith("levels/ending/cake"):
|
||||
|
|
2618
include/GL/eglew.h
Normal file
2618
include/GL/eglew.h
Normal file
File diff suppressed because it is too large
Load diff
23686
include/GL/glew.h
Normal file
23686
include/GL/glew.h
Normal file
File diff suppressed because it is too large
Load diff
1775
include/GL/glxew.h
Normal file
1775
include/GL/glxew.h
Normal file
File diff suppressed because it is too large
Load diff
1447
include/GL/wglew.h
Normal file
1447
include/GL/wglew.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -87,6 +87,12 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef F3DEX_GBI_2E
|
||||
# ifndef F3DEX_GBI_2
|
||||
# define F3DEX_GBI_2
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef F3DEX_GBI_2
|
||||
# ifndef F3DEX_GBI
|
||||
# define F3DEX_GBI
|
||||
|
@ -1103,7 +1109,11 @@
|
|||
* Vertex (set up for use with colors)
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef TARGET_N64
|
||||
short ob[3]; /* x, y, z */
|
||||
#else
|
||||
float ob[3]; /* x, y, z */
|
||||
#endif
|
||||
unsigned short flag;
|
||||
short tc[2]; /* texture coord */
|
||||
unsigned char cn[4]; /* color & alpha */
|
||||
|
@ -1113,7 +1123,11 @@ typedef struct {
|
|||
* Vertex (set up for use with normals)
|
||||
*/
|
||||
typedef struct {
|
||||
#ifdef TARGET_N64
|
||||
short ob[3]; /* x, y, z */
|
||||
#else
|
||||
float ob[3]; /* x, y, z */
|
||||
#endif
|
||||
unsigned short flag;
|
||||
short tc[2]; /* texture coord */
|
||||
signed char n[3]; /* normal */
|
||||
|
@ -1162,6 +1176,7 @@ typedef struct {
|
|||
unsigned char v[3];
|
||||
} Tri;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/*
|
||||
* 4x4 matrix, fixed point s15.16 format.
|
||||
* First 8 words are integer portion of the 4x4 matrix
|
||||
|
@ -1173,6 +1188,11 @@ typedef union {
|
|||
Mtx_t m;
|
||||
long long int force_structure_alignment;
|
||||
} Mtx;
|
||||
#else
|
||||
typedef struct {
|
||||
float m[4][4];
|
||||
} Mtx;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Viewport
|
||||
|
@ -4396,6 +4416,26 @@ typedef union {
|
|||
}}
|
||||
|
||||
/* Fraction never used in fill */
|
||||
#ifdef F3DEX_GBI_2E
|
||||
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
||||
{ \
|
||||
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt); \
|
||||
_g0->words.w0 = _SHIFTL(G_FILLRECT, 24, 8) | \
|
||||
_SHIFTL((lrx), 2, 22); \
|
||||
_g0->words.w1 = _SHIFTL((lry), 2, 22); \
|
||||
_g1->words.w0 = _SHIFTL((ulx), 2, 22); \
|
||||
_g1->words.w1 = _SHIFTL((uly), 2, 22); \
|
||||
}
|
||||
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
||||
{{ \
|
||||
(_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 2, 22)), \
|
||||
_SHIFTL((lry), 2, 22), \
|
||||
}}, \
|
||||
{{ \
|
||||
_SHIFTL((ulx), 2, 22), \
|
||||
_SHIFTL((uly), 2, 22), \
|
||||
}}
|
||||
#else
|
||||
#define gDPFillRectangle(pkt, ulx, uly, lrx, lry) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
|
@ -4404,15 +4444,16 @@ typedef union {
|
|||
_SHIFTL((lrx), 14, 10) | _SHIFTL((lry), 2, 10));\
|
||||
_g->words.w1 = (_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10));\
|
||||
}
|
||||
|
||||
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
||||
{{ \
|
||||
(_SHIFTL(G_FILLRECT, 24, 8) | _SHIFTL((lrx), 14, 10) | \
|
||||
_SHIFTL((lry), 2, 10)), \
|
||||
(_SHIFTL((ulx), 14, 10) | _SHIFTL((uly), 2, 10)) \
|
||||
}}
|
||||
#endif
|
||||
|
||||
/* like gDPFillRectangle but accepts negative arguments */
|
||||
#ifndef F3DEX_GBI_2E
|
||||
#define gDPScisFillRectangle(pkt, ulx, uly, lrx, lry) \
|
||||
{ \
|
||||
Gfx *_g = (Gfx *)(pkt); \
|
||||
|
@ -4423,6 +4464,7 @@ typedef union {
|
|||
_g->words.w1 = (_SHIFTL(MAX((ulx),0), 14, 10) | \
|
||||
_SHIFTL(MAX((uly),0), 2, 10)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define gDPSetConvert(pkt, k0, k1, k2, k3, k4, k5) \
|
||||
{ \
|
||||
|
@ -4620,6 +4662,46 @@ typedef union {
|
|||
gImmp1(pkt, G_RDPHALF_2, (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16))); \
|
||||
gImmp1(pkt, G_RDPHALF_CONT, (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16))); \
|
||||
}
|
||||
#elif defined(F3DEX_GBI_2E)
|
||||
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
||||
{ \
|
||||
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt), *_g2 = (Gfx *)(pkt); \
|
||||
\
|
||||
_g0->words.w0 = _SHIFTL(G_TEXRECT, 24, 8) | \
|
||||
_SHIFTL((xh), 0, 24); \
|
||||
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
||||
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
||||
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
||||
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
||||
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||
}
|
||||
|
||||
# define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{{ \
|
||||
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL((xh), 0, 24)), \
|
||||
_SHIFTL((yh), 0, 24), \
|
||||
}}, \
|
||||
{{ \
|
||||
(_SHIFTL((tile), 24, 3) | _SHIFTL((xl), 0, 24)), \
|
||||
_SHIFTL((yl), 0, 24), \
|
||||
}}, \
|
||||
{{ \
|
||||
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
||||
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
||||
}}
|
||||
|
||||
# define gSPTextureRectangleFlip(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||
{ \
|
||||
Gfx *_g0 = (Gfx *)(pkt), *_g1 = (Gfx *)(pkt), *_g2 = (Gfx *)(pkt); \
|
||||
\
|
||||
_g0->words.w0 = _SHIFTL(G_TEXRECTFLIP, 24, 8) | \
|
||||
_SHIFTL((xh), 0, 24); \
|
||||
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
||||
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
||||
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
||||
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
||||
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||
}
|
||||
#else
|
||||
# define gSPTextureRectangle(pkt, xl, yl, xh, yh, tile, s, t, dsdx, dtdy)\
|
||||
{ \
|
||||
|
|
|
@ -53,14 +53,14 @@ extern "C" {
|
|||
typedef struct {
|
||||
u16 type; /* Controller Type */
|
||||
u8 status; /* Controller status */
|
||||
u8 errno;
|
||||
u8 errnum;
|
||||
}OSContStatus;
|
||||
|
||||
typedef struct {
|
||||
u16 button;
|
||||
s8 stick_x; /* -80 <= stick_x <= 80 */
|
||||
s8 stick_y; /* -80 <= stick_y <= 80 */
|
||||
u8 errno;
|
||||
u8 errnum;
|
||||
} OSContPad;
|
||||
|
||||
typedef struct {
|
||||
|
@ -68,7 +68,7 @@ typedef struct {
|
|||
u8 databuffer[32]; /* address of the data buffer */
|
||||
u8 addressCrc; /* CRC code for address */
|
||||
u8 dataCrc; /* CRC code for data */
|
||||
u8 errno;
|
||||
u8 errnum;
|
||||
} OSContRamIo;
|
||||
|
||||
|
||||
|
|
|
@ -81,7 +81,4 @@ void osCreatePiManager(OSPri pri, OSMesgQueue *cmdQ, OSMesg *cmdBuf, s32 cmdMsgC
|
|||
OSMesgQueue *osPiGetCmdQueue(void);
|
||||
s32 osPiWriteIo(uintptr_t devAddr, u32 data);
|
||||
s32 osPiReadIo(uintptr_t devAddr, u32 *data);
|
||||
|
||||
s32 osPiRawStartDma(s32 dir, u32 cart_addr, void *dram_addr, size_t size);
|
||||
s32 osEPiRawStartDma(OSPiHandle *piHandle, s32 dir, u32 cart_addr, void *dram_addr, size_t size);
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,8 @@ typedef s32 intptr_t;
|
|||
typedef s32 ptrdiff_t;
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
typedef ptrdiff_t ssize_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,10 +28,15 @@
|
|||
#define SCREEN_HEIGHT 240
|
||||
|
||||
// Border Height Define for NTSC Versions
|
||||
#ifdef TARGET_N64
|
||||
#ifndef VERSION_EU
|
||||
#define BORDER_HEIGHT 8
|
||||
#else
|
||||
#define BORDER_HEIGHT 1
|
||||
#endif
|
||||
#else
|
||||
// What's the point of having a border?
|
||||
#define BORDER_HEIGHT 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
20
include/gfx_dimensions.h
Normal file
20
include/gfx_dimensions.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef GFX_DIMENSIONS_H
|
||||
#define GFX_DIMENSIONS_H
|
||||
|
||||
#ifndef TARGET_N64
|
||||
#include <math.h>
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
#define GFX_DIMENSIONS_FROM_LEFT_EDGE(v) (SCREEN_WIDTH / 2 - SCREEN_HEIGHT / 2 * gfx_current_dimensions.aspect_ratio + (v))
|
||||
#define GFX_DIMENSIONS_FROM_RIGHT_EDGE(v) (SCREEN_WIDTH / 2 + SCREEN_HEIGHT / 2 * gfx_current_dimensions.aspect_ratio - (v))
|
||||
#define GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(v) floorf(GFX_DIMENSIONS_FROM_LEFT_EDGE(v))
|
||||
#define GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(v) ceilf(GFX_DIMENSIONS_FROM_RIGHT_EDGE(v))
|
||||
#define GFX_DIMENSIONS_ASPECT_RATIO (gfx_current_dimensions.aspect_ratio)
|
||||
#else
|
||||
#define GFX_DIMENSIONS_FROM_LEFT_EDGE(v) (v)
|
||||
#define GFX_DIMENSIONS_FROM_RIGHT_EDGE(v) (SCREEN_WIDTH - (v))
|
||||
#define GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(v) (v)
|
||||
#define GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(v) (SCREEN_WIDTH - (v))
|
||||
#define GFX_DIMENSIONS_ASPECT_RATIO (4.0f / 3.0f)
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -275,4 +275,10 @@
|
|||
#define GET_OR_SET(op, var) \
|
||||
CMD_BBBB(0x3C, 0x04, op, var)
|
||||
|
||||
#define ADV_DEMO() \
|
||||
CMD_BBH(0x3D, 0x04, 0x0000)
|
||||
|
||||
#define CLEAR_DEMO_PTR() \
|
||||
CMD_BBH(0x3E, 0x04, 0x0000)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define LEVEL_MISC_MACROS_H
|
||||
|
||||
#define MACRO_OBJECT_WITH_BEH_PARAM(preset, yaw, posX, posY, posZ, behParam) \
|
||||
(((yaw * 0x10 / 45) << 9) | (preset + 0x1F)), posX, posY, posZ, behParam
|
||||
((s16)((yaw * 0x10 / 45) << 9) | (preset + 0x1F)), posX, posY, posZ, behParam
|
||||
|
||||
#define MACRO_OBJECT(preset, yaw, posX, posY, posZ) \
|
||||
MACRO_OBJECT_WITH_BEH_PARAM(preset, yaw, posX, posY, posZ, 0)
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#define ALIGNED16
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_N64
|
||||
// convert a virtual address to physical.
|
||||
#define VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr) & 0x1FFFFFFF)
|
||||
|
||||
|
@ -54,5 +55,11 @@
|
|||
|
||||
// another way of converting virtual to physical
|
||||
#define VIRTUAL_TO_PHYSICAL2(addr) ((u8 *)(addr) - 0x80000000U)
|
||||
#else
|
||||
// no conversion for pc port other than cast
|
||||
#define VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr))
|
||||
#define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr))
|
||||
#define VIRTUAL_TO_PHYSICAL2(addr) ((void *)(addr))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#ifndef SEGMENT_SYMBOLS_H
|
||||
#define SEGMENT_SYMBOLS_H
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define DECLARE_SEGMENT(name) \
|
||||
extern u8 _##name##SegmentRomStart[]; \
|
||||
extern u8 _##name##SegmentRomEnd[];
|
||||
#else
|
||||
#define DECLARE_SEGMENT(name) \
|
||||
static u8 _##name##SegmentRomStart[1]; \
|
||||
static u8 _##name##SegmentRomEnd[1];
|
||||
#endif
|
||||
|
||||
#define DECLARE_ACTOR_SEGMENT(name) \
|
||||
DECLARE_SEGMENT(name##_mio0) \
|
||||
|
@ -37,7 +43,11 @@ DECLARE_ACTOR_SEGMENT(group17)
|
|||
DECLARE_SEGMENT(behavior)
|
||||
DECLARE_SEGMENT(scripts)
|
||||
DECLARE_SEGMENT(goddard)
|
||||
#ifdef TARGET_N64
|
||||
extern u8 _goddardSegmentStart[];
|
||||
#else
|
||||
static u8 _goddardSegmentStart[1];
|
||||
#endif
|
||||
|
||||
DECLARE_LEVEL_SEGMENT(menu)
|
||||
DECLARE_LEVEL_SEGMENT(intro)
|
||||
|
|
|
@ -44,17 +44,24 @@ const LevelScript level_intro_entry_2[] = {
|
|||
INIT_LEVEL(),
|
||||
BLACKOUT(/*active*/ TRUE),
|
||||
FIXED_LOAD(/*loadAddr*/ _goddardSegmentStart, /*romStart*/ _goddardSegmentRomStart, /*romEnd*/ _goddardSegmentRomEnd),
|
||||
//LOAD_MARIO_HEAD(/*loadHeadID*/ REGULAR_FACE),
|
||||
LOAD_MARIO_HEAD(/*loadHeadID*/ REGULAR_FACE),
|
||||
LOAD_RAW(/*seg*/ 0x13, _behaviorSegmentRomStart, _behaviorSegmentRomEnd),
|
||||
LOAD_MIO0_TEXTURE(/*seg*/ 0x0A, _title_screen_bg_mio0SegmentRomStart, _title_screen_bg_mio0SegmentRomEnd),
|
||||
ALLOC_LEVEL_POOL(),
|
||||
|
||||
//AREA(/*index*/ 1, intro_geo_00035C),
|
||||
//END_AREA(),
|
||||
AREA(/*index*/ 1, intro_geo_00035C),
|
||||
END_AREA(),
|
||||
|
||||
FREE_LEVEL_POOL(),
|
||||
SLEEP(/*frames*/ 2),
|
||||
BLACKOUT(/*active*/ FALSE),
|
||||
//LOAD_AREA(/*area*/ 1),
|
||||
CLEAR_DEMO_PTR(), // we need to do this or else file select will be tainted with inputs
|
||||
GET_OR_SET(/*op*/ OP_GET, /*var*/ 5),
|
||||
JUMP_IF(/*op*/ OP_EQ, /*arg*/ 1, script_intro_L1), // was start pressed when demo ended last time?
|
||||
LOAD_AREA(/*area*/ 1),
|
||||
SET_MENU_MUSIC(/*seq*/ 0x0002),
|
||||
TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_STAR, /*time*/ 20, /*color*/ 0x00, 0x00, 0x00),
|
||||
|
|
|
@ -50,7 +50,7 @@ const LevelScript level_main_menu_entry_1[] = {
|
|||
GET_OR_SET(/*op*/ OP_SET, /*var*/ VAR_CURR_SAVE_FILE_NUM),
|
||||
STOP_MUSIC(/*fadeOutTime*/ 0x00BE),
|
||||
TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF),
|
||||
SLEEP(/*frames*/ 16),
|
||||
SLEEP(/*frames*/ 24),
|
||||
CLEAR_LEVEL(),
|
||||
SLEEP_BEFORE_EXIT(/*frames*/ 1),
|
||||
SET_REG(/*value*/ LEVEL_CASTLE_GROUNDS),
|
||||
|
@ -72,15 +72,24 @@ const LevelScript level_main_menu_entry_2[] = {
|
|||
|
||||
/*25*/ FREE_LEVEL_POOL(),
|
||||
/*26*/ LOAD_AREA(/*area*/ 2),
|
||||
#ifndef TARGET_N64
|
||||
// sVisibleStars is set to 0 during FIXED_LOAD above on N64, but not on PC-port.
|
||||
// lvl_init_act_selector_values_and_stars must be called here otherwise the
|
||||
// previous value is retained and causes incorrect drawing during the 16 transition
|
||||
// frames.
|
||||
CALL(/*arg*/ 0, /*func*/ lvl_init_act_selector_values_and_stars),
|
||||
#endif
|
||||
/*27*/ TRANSITION(/*transType*/ WARP_TRANSITION_FADE_FROM_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF),
|
||||
/*29*/ SLEEP(/*frames*/ 16),
|
||||
/*30*/ SET_MENU_MUSIC(/*seq*/ 0x000D),
|
||||
#ifdef TARGET_N64
|
||||
/*31*/ CALL(/*arg*/ 0, /*func*/ lvl_init_act_selector_values_and_stars),
|
||||
#endif
|
||||
/*33*/ CALL_LOOP(/*arg*/ 0, /*func*/ lvl_update_obj_and_load_act_button_actions),
|
||||
/*35*/ GET_OR_SET(/*op*/ OP_SET, /*var*/ VAR_CURR_ACT_NUM),
|
||||
/*36*/ STOP_MUSIC(/*fadeOutTime*/ 0x00BE),
|
||||
/*37*/ TRANSITION(/*transType*/ WARP_TRANSITION_FADE_INTO_COLOR, /*time*/ 16, /*color*/ 0xFF, 0xFF, 0xFF),
|
||||
/*39*/ SLEEP(/*frames*/ 16),
|
||||
/*39*/ SLEEP(/*frames*/ 24),
|
||||
/*40*/ CLEAR_LEVEL(),
|
||||
/*41*/ SLEEP_BEFORE_EXIT(/*frames*/ 1),
|
||||
// L1:
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "libultra_internal.h"
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
int r, c;
|
||||
s32 tmp1;
|
||||
|
@ -35,6 +39,11 @@ void guMtxL2F(float mf[4][4], Mtx *m) {
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void guMtxF2L(float mf[4][4], Mtx *m) {
|
||||
memcpy(m, mf, sizeof(Mtx));
|
||||
}
|
||||
#endif
|
||||
|
||||
void guMtxIdentF(float mf[4][4]) {
|
||||
int r, c;
|
||||
|
@ -49,7 +58,11 @@ void guMtxIdentF(float mf[4][4]) {
|
|||
}
|
||||
}
|
||||
void guMtxIdent(Mtx *m) {
|
||||
#ifdef TARGET_N64
|
||||
float mf[4][4];
|
||||
guMtxIdentF(mf);
|
||||
guMtxF2L(mf, m);
|
||||
#else
|
||||
guMtxIdentF(m->m);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ void __osContGetInitData(u8 *a0, OSContStatus *status) {
|
|||
sp14 = &(D_80365CE0[0].request);
|
||||
for (i = 0; i < _osCont_numControllers; i++, sp14++, status++) {
|
||||
spc = *(OSContPackedRequest *) sp14;
|
||||
status->errno = (spc.unk02 & 0xc0) >> 4;
|
||||
if (status->errno == 0) {
|
||||
status->errnum = (spc.unk02 & 0xc0) >> 4;
|
||||
if (status->errnum == 0) {
|
||||
status->type = spc.unk05 << 8 | spc.unk04;
|
||||
status->status = spc.unk06;
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ void osContGetReadData(OSContPad *pad) {
|
|||
spc = &D_80365CE0[0].read;
|
||||
for (i = 0; i < _osCont_numControllers; i++, spc++, pad++) {
|
||||
sp4 = *spc;
|
||||
pad->errno = (sp4.unk02 & 0xc0) >> 4;
|
||||
if (pad->errno == 0) {
|
||||
pad->errnum = (sp4.unk02 & 0xc0) >> 4;
|
||||
if (pad->errnum == 0) {
|
||||
pad->button = sp4.button;
|
||||
pad->stick_x = sp4.rawStickX;
|
||||
pad->stick_y = sp4.rawStickY;
|
||||
|
|
4
readme2.txt
Normal file
4
readme2.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
You need audiofile, sdl2, glew, glfw
|
||||
for Windows you also need mingw32
|
||||
>https://packages.msys2.org/base/mingw-w64-SDL2
|
||||
>https://packages.msys2.org/base/mingw-w64-glew
|
|
@ -66,7 +66,7 @@ chan_stereoheadseteffects 1
|
|||
chan_setdyntable .channel59_table
|
||||
chan_jump .main_loop_023589
|
||||
|
||||
# Main loop for standard, non-continuous sound effects
|
||||
|
||||
.main_loop_023589:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
|
@ -80,17 +80,17 @@ chan_iowriteval 5
|
|||
chan_ioreadval 4
|
||||
chan_dyncall
|
||||
|
||||
# keep looping until layer 0 finishes or we are told to stop or to play something else
|
||||
|
||||
.poll_023589:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
chan_bltz .skip_023589 # if we have a signal:
|
||||
chan_beqz .force_stop_023589 # told to stop
|
||||
chan_jump .start_playing_023589 # told to play something else
|
||||
chan_bltz .skip_023589
|
||||
chan_beqz .force_stop_023589
|
||||
chan_jump .start_playing_023589
|
||||
.skip_023589:
|
||||
chan_testlayerfinished 0
|
||||
chan_beqz .poll_023589 # if layer 0 hasn't finished, keep polling
|
||||
chan_jump .main_loop_023589 # otherwise go back to the main loop
|
||||
chan_beqz .poll_023589
|
||||
chan_jump .main_loop_023589
|
||||
.force_stop_023589:
|
||||
chan_freelayer 0
|
||||
chan_freelayer 1
|
||||
|
@ -133,7 +133,7 @@ chan_stereoheadseteffects 1
|
|||
chan_setdyntable .channel6_table
|
||||
chan_jump .main_loop_146
|
||||
|
||||
# Main loop for moving, env and air sound effects, which play continuously
|
||||
|
||||
.main_loop_146:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
|
@ -148,7 +148,7 @@ chan_iowriteval 5
|
|||
chan_ioreadval 4
|
||||
chan_dyncall
|
||||
|
||||
# keep looping until we are told to stop or to play something else
|
||||
|
||||
.poll_146:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
|
@ -170,7 +170,7 @@ chan_iowriteval 5
|
|||
chan_stereoheadseteffects 1
|
||||
chan_setdyntable .channel7_table
|
||||
|
||||
# Loop for menu sound effects
|
||||
|
||||
.main_loop_7:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
|
@ -187,19 +187,19 @@ chan_setpanmix 127
|
|||
chan_ioreadval 4
|
||||
chan_dyncall
|
||||
|
||||
# keep looping until layer 0 finishes or we are told to stop or to play something else
|
||||
|
||||
.poll_7:
|
||||
chan_delay1
|
||||
chan_ioreadval 0
|
||||
chan_bltz .skip_7 # if we have a signal:
|
||||
chan_beqz .force_stop_7 # told to stop
|
||||
chan_bltz .skip_7
|
||||
chan_beqz .force_stop_7
|
||||
chan_unreservenotes
|
||||
chan_jump .start_playing_7 # told to play something else
|
||||
chan_jump .start_playing_7
|
||||
.skip_7:
|
||||
chan_testlayerfinished 0
|
||||
chan_beqz .poll_7 # if layer 0 hasn't finished, keep polling
|
||||
chan_beqz .poll_7
|
||||
chan_unreservenotes
|
||||
chan_jump .main_loop_7 # otherwise go back to the main loop
|
||||
chan_jump .main_loop_7
|
||||
.force_stop_7:
|
||||
chan_freelayer 0
|
||||
chan_freelayer 1
|
||||
|
@ -207,7 +207,7 @@ chan_freelayer 2
|
|||
chan_unreservenotes
|
||||
chan_jump .main_loop_7
|
||||
|
||||
# Delay for a number of ticks (1-255) in an interruptible manner.
|
||||
|
||||
.delay:
|
||||
chan_writeseq_nextinstr 0, 1
|
||||
chan_loop 20
|
||||
|
@ -222,15 +222,15 @@ chan_end
|
|||
chan_setpanmix 127
|
||||
chan_setvolscale 127
|
||||
chan_setvibratoextent 0
|
||||
chan_ioreadval 1 # IO slots 0-3 are reset to -1 when read; restore the value
|
||||
chan_ioreadval 1
|
||||
chan_iowriteval 0
|
||||
chan_break # break out of the loop
|
||||
chan_break # force the caller to return immediately
|
||||
chan_break
|
||||
chan_break
|
||||
chan_end
|
||||
|
||||
# Set reverb in way that takes area echo level and volume into account. This
|
||||
# is done by writing to IO slot 5 and letting get_sound_reverb in external.c
|
||||
# do the necessary math.
|
||||
|
||||
|
||||
|
||||
.set_reverb:
|
||||
chan_writeseq_nextinstr 0, 1
|
||||
chan_setreverb 10
|
||||
|
@ -977,7 +977,7 @@ layer_portamento 0x81, 42, 255
|
|||
layer_note1 37, 0x1e, 105
|
||||
layer_end
|
||||
|
||||
.sound_action_climb_down_tree: # unused
|
||||
.sound_action_climb_down_tree:
|
||||
chan_setbank 0
|
||||
chan_setinstr 1
|
||||
chan_setlayer 0, .layer_579
|
||||
|
@ -988,7 +988,7 @@ layer_portamento 0x81, 44, 255
|
|||
layer_note1 40, 0xb4, 100
|
||||
layer_end
|
||||
|
||||
.chan_582: # unused
|
||||
.chan_582:
|
||||
chan_setbank 0
|
||||
chan_setinstr 2
|
||||
chan_setlayer 0, .layer_58A
|
||||
|
@ -1408,7 +1408,7 @@ layer_note1 42, 0x8, 127
|
|||
layer_end
|
||||
|
||||
.ifndef VERSION_JP
|
||||
.chan_828: # unused
|
||||
.chan_828:
|
||||
chan_setbank 7
|
||||
chan_setinstr 3
|
||||
chan_setlayer 0, .layer_83C
|
||||
|
|
|
@ -765,6 +765,7 @@ void func_eu_802e9bec(s32 player, s32 channel, s32 arg2) {
|
|||
|
||||
#else
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
|
@ -868,6 +869,24 @@ struct SPTask *create_next_audio_frame_task(void) {
|
|||
return gAudioTask;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
return NULL;
|
||||
}
|
||||
void create_next_audio_buffer(s16 *samples, u32 num_samples) {
|
||||
gAudioFrameCount++;
|
||||
if (sGameLoopTicked != 0) {
|
||||
update_game_sound();
|
||||
sGameLoopTicked = 0;
|
||||
}
|
||||
s32 writtenCmds;
|
||||
synthesis_execute(gAudioCmdBuffers[0], &writtenCmds, samples, num_samples);
|
||||
gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
|
||||
decrease_sample_dma_ttls();
|
||||
}
|
||||
#endif
|
||||
|
||||
void play_sound(s32 soundBits, f32 *pos) {
|
||||
sSoundRequests[sSoundRequestCount].soundBits = soundBits;
|
||||
|
|
|
@ -651,10 +651,12 @@ s32 audio_shut_down_and_reset_step(void) {
|
|||
*/
|
||||
void wait_for_audio_frames(s32 frames) {
|
||||
gAudioFrameCount = 0;
|
||||
#ifdef TARGET_N64
|
||||
// Sound thread will update gAudioFrameCount
|
||||
while (gAudioFrameCount < frames) {
|
||||
// spin
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -884,7 +884,7 @@ void audio_init() {
|
|||
s32 lim2, lim3;
|
||||
#endif
|
||||
u32 size;
|
||||
u64 *ptr64;
|
||||
UNUSED u64 *ptr64;
|
||||
void *data;
|
||||
UNUSED s32 pad2;
|
||||
|
||||
|
@ -902,6 +902,7 @@ void audio_init() {
|
|||
((u64 *) gAudioHeap)[i] = 0;
|
||||
}
|
||||
|
||||
#ifndef AVOID_UB
|
||||
i = 0;
|
||||
lim3 = ((uintptr_t) &gAudioGlobalsEndMarker - (uintptr_t) &gAudioGlobalsStartMarker) / 8;
|
||||
ptr64 = &gAudioGlobalsStartMarker - 1;
|
||||
|
@ -909,6 +910,7 @@ void audio_init() {
|
|||
i++;
|
||||
ptr64[i] = 0;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
for (i = 0; i < gAudioHeapSize / 8; i++) {
|
||||
((u64 *) gAudioHeap)[i] = 0;
|
||||
|
|
|
@ -34,6 +34,7 @@ void decrease_sample_dma_ttls(void);
|
|||
s32 audio_shut_down_and_reset_step(void);
|
||||
void func_802ad7ec(u32);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
struct SPTask *create_next_audio_frame_task(void) {
|
||||
u32 samplesRemainingInAI;
|
||||
s32 writtenCmds;
|
||||
|
@ -114,12 +115,14 @@ struct SPTask *create_next_audio_frame_task(void) {
|
|||
task = &gAudioTask->task.t;
|
||||
task->type = M_AUDTASK;
|
||||
task->flags = flags;
|
||||
#if TARGET_N64
|
||||
task->ucode_boot = rspF3DBootStart;
|
||||
task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
|
||||
task->ucode = rspAspMainStart;
|
||||
task->ucode_data = rspAspMainDataStart;
|
||||
task->ucode_size = 0x800; // (this size is ignored)
|
||||
task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
|
||||
#endif
|
||||
task->dram_stack = NULL;
|
||||
task->dram_stack_size = 0;
|
||||
task->output_buff = NULL;
|
||||
|
@ -130,6 +133,7 @@ struct SPTask *create_next_audio_frame_task(void) {
|
|||
task->yield_data_size = 0;
|
||||
return gAudioTask;
|
||||
}
|
||||
#endif
|
||||
|
||||
void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
|
||||
s32 i;
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include "external.h"
|
||||
|
||||
|
||||
#ifndef TARGET_N64
|
||||
#include "../pc/mixer.h"
|
||||
#endif
|
||||
|
||||
#define DMEM_ADDR_TEMP 0x0
|
||||
#define DMEM_ADDR_UNCOMPRESSED_NOTE 0x180
|
||||
#define DMEM_ADDR_ADPCM_RESAMPLED 0x20
|
||||
|
|
|
@ -23,7 +23,7 @@ ALIGNED8 u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE];
|
|||
// 0x200 bytes
|
||||
ALIGNED8 struct SaveBuffer gSaveBuffer;
|
||||
// 0x190a0 bytes
|
||||
struct GfxPool gGfxPools[2];
|
||||
struct GfxPool gGfxPools[GFX_NUM_POOLS];
|
||||
|
||||
|
||||
// Yield buffer for audio, 0x400 bytes. Stubbed out post-JP since the audio
|
||||
|
@ -37,8 +37,3 @@ ALIGNED8 u8 gAudioSPTaskYieldBuffer[OS_YIELD_AUDIO_SIZE];
|
|||
#if !defined(F3DEX_GBI_SHARED) && !defined(VERSION_EU)
|
||||
ALIGNED8 u8 gUnusedThread2Stack[0x1400];
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,11 @@ extern struct SaveBuffer gSaveBuffer;
|
|||
|
||||
extern u8 gGfxSPTaskStack[];
|
||||
|
||||
extern struct GfxPool gGfxPools[2];
|
||||
#ifdef TARGET_N64
|
||||
#define GFX_NUM_POOLS 2
|
||||
#else
|
||||
#define GFX_NUM_POOLS 1
|
||||
#endif
|
||||
extern struct GfxPool gGfxPools[GFX_NUM_POOLS];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "sm64.h"
|
||||
#include "audio/external.h"
|
||||
|
@ -20,6 +23,7 @@
|
|||
#include "math_util.h"
|
||||
#include "surface_collision.h"
|
||||
#include "surface_load.h"
|
||||
#include "level_table.h"
|
||||
|
||||
#define CMD_SIZE_SHIFT (sizeof(void *) >> 3)
|
||||
#define CMD_PROCESS_OFFSET(offset) ((offset & 3) | ((offset & ~3) << CMD_SIZE_SHIFT))
|
||||
|
@ -601,7 +605,17 @@ static void level_cmd_set_gamma(void) {
|
|||
|
||||
static void level_cmd_set_terrain_data(void) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
#ifdef TARGET_N64
|
||||
gAreas[sCurrAreaIndex].terrainData = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
#else
|
||||
Collision *data;
|
||||
u32 size;
|
||||
|
||||
data = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
size = get_area_terrain_size(data) * sizeof(Collision);
|
||||
gAreas[sCurrAreaIndex].terrainData = alloc_only_pool_alloc(sLevelPool, size);
|
||||
memcpy(gAreas[sCurrAreaIndex].terrainData, data, size);
|
||||
#endif
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
@ -615,7 +629,17 @@ static void level_cmd_set_rooms(void) {
|
|||
|
||||
static void level_cmd_set_macro_objects(void) {
|
||||
if (sCurrAreaIndex != -1) {
|
||||
#ifdef TARGET_N64
|
||||
gAreas[sCurrAreaIndex].macroObjects = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
#else
|
||||
MacroObject *data = segmented_to_virtual(CMD_GET(void *, 4));
|
||||
s32 len = 0;
|
||||
while (data[len++] != 0x001E) {
|
||||
len += 4;
|
||||
}
|
||||
gAreas[sCurrAreaIndex].macroObjects = alloc_only_pool_alloc(sLevelPool, len * sizeof(MacroObject));
|
||||
memcpy(gAreas[sCurrAreaIndex].macroObjects, data, len * sizeof(MacroObject));
|
||||
#endif
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
@ -696,6 +720,8 @@ static void level_cmd_38(void) {
|
|||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
extern int gPressedStart;
|
||||
|
||||
static void level_cmd_get_or_set_var(void) {
|
||||
if (CMD_GET(u8, 2) == 0) {
|
||||
switch (CMD_GET(u8, 3)) {
|
||||
|
@ -714,6 +740,9 @@ static void level_cmd_get_or_set_var(void) {
|
|||
case 4:
|
||||
gCurrAreaIndex = sRegister;
|
||||
break;
|
||||
case 5:
|
||||
gPressedStart = sRegister;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (CMD_GET(u8, 3)) {
|
||||
|
@ -732,12 +761,48 @@ static void level_cmd_get_or_set_var(void) {
|
|||
case 4:
|
||||
sRegister = gCurrAreaIndex;
|
||||
break;
|
||||
case 5:
|
||||
sRegister = gPressedStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
int gDemoLevels[7] = {
|
||||
LEVEL_BOWSER_1,
|
||||
LEVEL_WF,
|
||||
LEVEL_CCM,
|
||||
LEVEL_BBH,
|
||||
LEVEL_JRB,
|
||||
LEVEL_HMC,
|
||||
LEVEL_PSS
|
||||
};
|
||||
|
||||
int gDemoLevelID = 0;
|
||||
int gDemoInputListID_2 = 0;
|
||||
|
||||
extern int start_demo(int);
|
||||
|
||||
static void level_cmd_advdemo(void)
|
||||
{
|
||||
start_demo(0);
|
||||
if(gDemoLevelID == 6) {
|
||||
sRegister = gDemoLevels[6];
|
||||
gDemoLevelID = 0;
|
||||
} else {
|
||||
sRegister = gDemoLevels[gDemoLevelID++];
|
||||
}
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
static void level_cmd_cleardemoptr(void)
|
||||
{
|
||||
gCurrDemoInput = NULL;
|
||||
sCurrentCmd = CMD_NEXT;
|
||||
}
|
||||
|
||||
static void (*LevelScriptJumpTable[])(void) = {
|
||||
/*00*/ level_cmd_load_and_execute,
|
||||
/*01*/ level_cmd_exit_and_execute,
|
||||
|
@ -800,6 +865,8 @@ static void (*LevelScriptJumpTable[])(void) = {
|
|||
/*3A*/ level_cmd_3A,
|
||||
/*3B*/ level_cmd_create_whirlpool,
|
||||
/*3C*/ level_cmd_get_or_set_var,
|
||||
/*3D*/ level_cmd_advdemo,
|
||||
/*3E*/ level_cmd_cleardemoptr,
|
||||
};
|
||||
|
||||
struct LevelCommand *level_script_execute(struct LevelCommand *cmd) {
|
||||
|
|
|
@ -533,6 +533,57 @@ void alloc_surface_pools(void) {
|
|||
reset_red_coins_collected();
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
/**
|
||||
* Get the size of the terrain data, to get the correct size when copying later.
|
||||
*/
|
||||
u32 get_area_terrain_size(s16 *data) {
|
||||
s16 *startPos = data;
|
||||
s32 end = FALSE;
|
||||
s16 terrainLoadType;
|
||||
s32 numVertices;
|
||||
s32 numRegions;
|
||||
s32 numSurfaces;
|
||||
s16 hasForce;
|
||||
|
||||
while (!end) {
|
||||
terrainLoadType = *data++;
|
||||
|
||||
switch (terrainLoadType) {
|
||||
case TERRAIN_LOAD_VERTICES:
|
||||
numVertices = *data++;
|
||||
data += 3 * numVertices;
|
||||
break;
|
||||
|
||||
case TERRAIN_LOAD_OBJECTS:
|
||||
data += get_special_objects_size(data);
|
||||
break;
|
||||
|
||||
case TERRAIN_LOAD_ENVIRONMENT:
|
||||
numRegions = *data++;
|
||||
data += 6 * numRegions;
|
||||
break;
|
||||
|
||||
case TERRAIN_LOAD_CONTINUE:
|
||||
continue;
|
||||
|
||||
case TERRAIN_LOAD_END:
|
||||
end = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
numSurfaces = *data++;
|
||||
hasForce = surface_has_force(terrainLoadType);
|
||||
data += (3 + hasForce) * numSurfaces;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return data - startPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Process the level file, loading in vertices, surfaces, some objects, and environmental
|
||||
* boxes (water, gas, JRB fog).
|
||||
|
|
|
@ -28,6 +28,9 @@ extern struct Surface *sSurfacePool;
|
|||
extern s16 sSurfacePoolSize;
|
||||
|
||||
void alloc_surface_pools(void);
|
||||
#ifndef TARGET_N64
|
||||
u32 get_area_terrain_size(s16 *data);
|
||||
#endif
|
||||
void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects);
|
||||
void clear_dynamic_surfaces(void);
|
||||
void load_object_collision_model(void);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "area.h"
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "behavior_data.h"
|
||||
#include "game_init.h"
|
||||
#include "object_list_processor.h"
|
||||
|
@ -20,6 +21,8 @@
|
|||
#include "save_file.h"
|
||||
#include "level_table.h"
|
||||
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
struct SpawnInfo gPlayerSpawnInfos[1];
|
||||
struct GraphNode *D_8033A160[0x100];
|
||||
struct Area gAreaData[8];
|
||||
|
@ -104,6 +107,11 @@ void set_warp_transition_rgb(u8 red, u8 green, u8 blue) {
|
|||
gWarpTransBlue = blue;
|
||||
}
|
||||
|
||||
static int scale_x_to_correct_aspect_center(int x) {
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
return x + (SCREEN_HEIGHT * aspect / 2) - (SCREEN_WIDTH / 2);
|
||||
}
|
||||
|
||||
void print_intro_text(void) {
|
||||
#ifdef VERSION_EU
|
||||
int language = eu_get_language();
|
||||
|
@ -111,9 +119,9 @@ void print_intro_text(void) {
|
|||
if ((gGlobalTimer & 0x1F) < 20) {
|
||||
if (gControllerBits == 0) {
|
||||
#ifdef VERSION_EU
|
||||
print_text_centered(160, 20, gNoControllerMsg[language]);
|
||||
print_text_centered(SCREEN_WIDTH / 2, 20, gNoControllerMsg[language]);
|
||||
#else
|
||||
print_text_centered(160, 20, "NO CONTROLLER");
|
||||
print_text_centered(scale_x_to_correct_aspect_center(SCREEN_WIDTH / 2), 20, "NO CONTROLLER");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef VERSION_EU
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "sm64.h"
|
||||
|
||||
#if defined(VERSION_EU) || defined(VERSION_SH)
|
||||
#if defined(TARGET_N64) && (defined(VERSION_EU) || defined(VERSION_SH))
|
||||
|
||||
s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args);
|
||||
|
||||
|
|
26
src/game/display.h
Normal file
26
src/game/display.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef _DISPLAY_H
|
||||
#define _DISPLAY_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define GFX_POOL_SIZE 6400
|
||||
|
||||
extern u16 frameBufferIndex;
|
||||
extern u32 gGlobalTimer;
|
||||
|
||||
// extern ? my_rdp_init(?);
|
||||
// extern ? my_rsp_init(?);
|
||||
// extern ? clear_z_buffer(?);
|
||||
// extern ? display_frame_buffer(?);
|
||||
extern void clear_frame_buffer(s32);
|
||||
extern void clear_viewport(Vp *, s32);
|
||||
// extern ? draw_screen_borders(?);
|
||||
void make_viewport_clip_rect(Vp *viewport);
|
||||
extern void init_render_image(void);
|
||||
extern void end_master_display_list(void);
|
||||
extern void func_80247D84(void);
|
||||
extern void func_80247ED8(void);
|
||||
extern void func_80247FAC(void);
|
||||
extern void display_and_vsync(void);
|
||||
|
||||
#endif /* _DISPLAY_H */
|
|
@ -212,11 +212,13 @@ void create_task_structure(void) {
|
|||
gGfxSPTask->msgqueue = &D_80339CB8;
|
||||
gGfxSPTask->msg = (OSMesg) 2;
|
||||
gGfxSPTask->task.t.type = M_GFXTASK;
|
||||
#if TARGET_N64
|
||||
gGfxSPTask->task.t.ucode_boot = rspF3DBootStart;
|
||||
gGfxSPTask->task.t.ucode_boot_size = ((u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart);
|
||||
gGfxSPTask->task.t.flags = 0;
|
||||
gGfxSPTask->task.t.ucode = rspF3DStart;
|
||||
gGfxSPTask->task.t.ucode_data = rspF3DDataStart;
|
||||
#endif
|
||||
gGfxSPTask->task.t.ucode_size = SP_UCODE_SIZE; // (this size is ignored)
|
||||
gGfxSPTask->task.t.ucode_data_size = SP_UCODE_DATA_SIZE;
|
||||
gGfxSPTask->task.t.dram_stack = (u64 *) gGfxSPTaskStack;
|
||||
|
@ -578,10 +580,16 @@ void setup_game_memory(void) {
|
|||
load_segment_decompress(2, _segment2_mio0SegmentRomStart, _segment2_mio0SegmentRomEnd);
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
static struct LevelCommand *levelCommandAddr;
|
||||
#endif
|
||||
|
||||
// main game loop thread. runs forever as long as the game
|
||||
// continues.
|
||||
void thread5_game_loop(UNUSED void *arg) {
|
||||
struct LevelCommand *addr;
|
||||
#ifdef TARGET_N64
|
||||
struct LevelCommand *levelCommandAddr;
|
||||
#endif
|
||||
|
||||
setup_game_memory();
|
||||
#ifdef VERSION_SH
|
||||
|
@ -595,18 +603,32 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
|
||||
set_vblank_handler(2, &gGameVblankHandler, &gGameVblankQueue, (OSMesg) 1);
|
||||
|
||||
// point addr to the entry point into the level script data.
|
||||
addr = segmented_to_virtual(level_script_entry);
|
||||
// point levelCommandAddr to the entry point into the level script data.
|
||||
levelCommandAddr = segmented_to_virtual(level_script_entry);
|
||||
|
||||
play_music(SEQ_PLAYER_SFX, SEQUENCE_ARGS(0, SEQ_SOUND_PLAYER), 0);
|
||||
set_sound_mode(save_file_get_sound_mode());
|
||||
|
||||
#ifdef TARGET_N64
|
||||
func_80247ED8();
|
||||
rendering_init();
|
||||
|
||||
while (1) {
|
||||
#else
|
||||
gGlobalTimer++;
|
||||
}
|
||||
|
||||
void game_loop_one_iteration(void) {
|
||||
#endif
|
||||
// if the reset timer is active, run the process to reset the game.
|
||||
if (gResetTimer) {
|
||||
|
||||
#ifdef TARGET_N64
|
||||
draw_reset_bars();
|
||||
continue;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
profiler_log_thread5_time(THREAD5_START);
|
||||
|
||||
|
@ -622,7 +644,7 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
audio_game_loop_tick();
|
||||
config_gfx_pool();
|
||||
read_controller_inputs();
|
||||
addr = level_script_execute(addr);
|
||||
levelCommandAddr = level_script_execute(levelCommandAddr);
|
||||
display_and_vsync();
|
||||
|
||||
// when debug info is enabled, print the "BUF %d" information.
|
||||
|
@ -631,5 +653,7 @@ void thread5_game_loop(UNUSED void *arg) {
|
|||
// amount of free space remaining.
|
||||
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
|
||||
}
|
||||
#ifdef TARGET_N64
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -46,7 +46,11 @@ s8 gFlyingCarpetState;
|
|||
*
|
||||
* Texture coordinates are s10.5 fixed-point, which means you should left-shift the actual coordinates by 5.
|
||||
*/
|
||||
#ifdef TARGET_N64
|
||||
void make_vertex(Vtx *vtx, s32 n, s16 x, s16 y, s16 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a) {
|
||||
#else
|
||||
void make_vertex(Vtx *vtx, s32 n, f32 x, f32 y, f32 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a) {
|
||||
#endif
|
||||
vtx[n].v.ob[0] = x;
|
||||
vtx[n].v.ob[1] = y;
|
||||
vtx[n].v.ob[2] = z;
|
||||
|
|
|
@ -12,9 +12,15 @@ enum FlyingCarpetState
|
|||
|
||||
extern s8 gFlyingCarpetState;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
extern void make_vertex(
|
||||
Vtx *vtx, s32 n, s16 x, s16 y, s16 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a
|
||||
);
|
||||
#else
|
||||
extern void make_vertex(
|
||||
Vtx *vtx, s32 n, f32 x, f32 y, f32 z, s16 tx, s16 ty, u8 r, u8 g, u8 b, u8 a
|
||||
);
|
||||
#endif
|
||||
extern s16 round_float(f32);
|
||||
extern Gfx *geo_exec_inside_castle_light(s32 callContext, struct GraphNode *node, f32 mtx[4][4]);
|
||||
extern Gfx *geo_exec_flying_carpet_timer_update(s32 callContext, struct GraphNode *node,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "game_init.h"
|
||||
#include "level_update.h"
|
||||
#include "camera.h"
|
||||
|
@ -264,9 +265,9 @@ void render_hud_power_meter(void) {
|
|||
* Renders the amount of lives Mario has.
|
||||
*/
|
||||
void render_hud_mario_lives(void) {
|
||||
print_text(22, HUD_TOP_Y, ","); // 'Mario Head' glyph
|
||||
print_text(38, HUD_TOP_Y, "*"); // 'X' glyph
|
||||
print_text_fmt_int(54, HUD_TOP_Y, "%d", gHudDisplay.lives);
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(22), HUD_TOP_Y, ","); // 'Mario Head' glyph
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(38), HUD_TOP_Y, "*"); // 'X' glyph
|
||||
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(54), HUD_TOP_Y, "%d", gHudDisplay.lives);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,9 +280,9 @@ void render_hud_coins(void) {
|
|||
}
|
||||
|
||||
#ifdef VERSION_JP
|
||||
#define HUD_STARS_X 247
|
||||
#define HUD_STARS_X 73
|
||||
#else
|
||||
#define HUD_STARS_X 242
|
||||
#define HUD_STARS_X 78
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -299,11 +300,12 @@ void render_hud_stars(void) {
|
|||
showX = 1;
|
||||
}
|
||||
|
||||
print_text(HUD_STARS_X, HUD_TOP_Y, "-"); // 'Star' glyph
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X), HUD_TOP_Y, "-"); // 'Star' glyph
|
||||
if (showX == 1) {
|
||||
print_text((HUD_STARS_X + 16), HUD_TOP_Y, "*"); // 'X' glyph
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X) + 16, HUD_TOP_Y, "*"); // 'X' glyph
|
||||
}
|
||||
print_text_fmt_int(((showX * 14) + (HUD_STARS_X + 16)), HUD_TOP_Y, "%d", gHudDisplay.stars);
|
||||
print_text_fmt_int((showX * 14) + GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(HUD_STARS_X - 16),
|
||||
HUD_TOP_Y, "%d", gHudDisplay.stars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,13 +335,13 @@ void render_hud_timer(void) {
|
|||
#ifdef VERSION_EU
|
||||
switch (eu_get_language()) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
print_text(170, 185, "TIME");
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME");
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
print_text(165, 185, "TEMPS");
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(155), 185, "TEMPS");
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
print_text(170, 185, "ZEIT");
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "ZEIT");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -348,14 +350,14 @@ void render_hud_timer(void) {
|
|||
|
||||
timerFracSecs = ((timerValFrames - (timerMins * 1800) - (timerSecs * 30)) & 0xFFFF) / 3;
|
||||
#ifndef VERSION_EU
|
||||
print_text(170, 185, "TIME");
|
||||
print_text(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(150), 185, "TIME");
|
||||
#endif
|
||||
print_text_fmt_int(229, 185, "%0d", timerMins);
|
||||
print_text_fmt_int(249, 185, "%02d", timerSecs);
|
||||
print_text_fmt_int(283, 185, "%d", timerFracSecs);
|
||||
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(91), 185, "%0d", timerMins);
|
||||
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(71), 185, "%02d", timerSecs);
|
||||
print_text_fmt_int(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(37), 185, "%d", timerFracSecs);
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_begin);
|
||||
render_hud_tex_lut(239, 32, (*hudLUT)[GLYPH_APOSTROPHE]);
|
||||
render_hud_tex_lut(274, 32, (*hudLUT)[GLYPH_DOUBLE_QUOTE]);
|
||||
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(81), 32, (*hudLUT)[GLYPH_APOSTROPHE]);
|
||||
render_hud_tex_lut(GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(46), 32, (*hudLUT)[GLYPH_DOUBLE_QUOTE]);
|
||||
gSPDisplayList(gDisplayListHead++, dl_hud_img_end);
|
||||
}
|
||||
|
||||
|
@ -377,7 +379,7 @@ void render_hud_camera_status(void) {
|
|||
s32 y;
|
||||
|
||||
cameraLUT = segmented_to_virtual(&main_hud_camera_lut);
|
||||
x = 266;
|
||||
x = GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(54);
|
||||
y = 205;
|
||||
|
||||
if (sCameraHUD.status == CAM_STATUS_NONE) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "memory.h"
|
||||
#include "types.h"
|
||||
#include "audio/external.h"
|
||||
|
@ -127,10 +128,14 @@ void create_dl_identity_matrix(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
matrix->m[0][0] = 0x00010000; matrix->m[1][0] = 0x00000000; matrix->m[2][0] = 0x00000000; matrix->m[3][0] = 0x00000000;
|
||||
matrix->m[0][1] = 0x00000000; matrix->m[1][1] = 0x00010000; matrix->m[2][1] = 0x00000000; matrix->m[3][1] = 0x00000000;
|
||||
matrix->m[0][2] = 0x00000001; matrix->m[1][2] = 0x00000000; matrix->m[2][2] = 0x00000000; matrix->m[3][2] = 0x00000000;
|
||||
matrix->m[0][3] = 0x00000000; matrix->m[1][3] = 0x00000001; matrix->m[2][3] = 0x00000000; matrix->m[3][3] = 0x00000000;
|
||||
#else
|
||||
guMtxIdent(matrix);
|
||||
#endif
|
||||
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(matrix), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
|
@ -1793,13 +1798,26 @@ void render_dialog_entries(void) {
|
|||
|
||||
render_dialog_box_type(dialog, dialog->linesPerBox);
|
||||
|
||||
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE, ensure_nonnegative(dialog->leftOffset),
|
||||
gDPSetScissor(gDisplayListHead++, G_SC_NON_INTERLACE,
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(dialog->leftOffset),
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
ensure_nonnegative(DIAG_VAL2 - dialog->width),
|
||||
#ifdef VERSION_EU
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(dialog->leftOffset + DIAG_VAL3 / gDialogBoxScale),
|
||||
#else
|
||||
SCREEN_WIDTH,
|
||||
#endif
|
||||
ensure_nonnegative((240 - dialog->width) + ((dialog->linesPerBox * 80) / DIAG_VAL4) / gDialogBoxScale));
|
||||
#else
|
||||
#ifdef TARGET_N64
|
||||
ensure_nonnegative(DIAG_VAL3 + dialog->leftOffset),
|
||||
#else
|
||||
SCREEN_WIDTH,
|
||||
#endif
|
||||
ensure_nonnegative(240 + ((dialog->linesPerBox * 80) / DIAG_VAL4) - dialog->width));
|
||||
#endif
|
||||
#if defined(VERSION_JP) || defined(VERSION_SH)
|
||||
|
@ -2108,8 +2126,17 @@ void change_dialog_camera_angle(void) {
|
|||
}
|
||||
|
||||
void shade_screen(void) {
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, 0, 240.0f, 0);
|
||||
create_dl_translation_matrix(MENU_MTX_PUSH, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 240.0f, 0);
|
||||
|
||||
// This is a bit weird. It reuses the dialog text box (width 130, height -80),
|
||||
// so scale to at least fit the screen.
|
||||
#ifdef TARGET_N64
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH, 2.6f, 3.4f, 1.0f);
|
||||
#else
|
||||
create_dl_scale_matrix(MENU_MTX_NOPUSH,
|
||||
GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_HEIGHT / 130.0f, 3.0f, 1.0f);
|
||||
#endif
|
||||
|
||||
gDPSetEnvColor(gDisplayListHead++, 0, 0, 0, 110);
|
||||
gSPDisplayList(gDisplayListHead++, dl_draw_text_bg_box);
|
||||
gSPPopMatrix(gDisplayListHead++, G_MTX_MODELVIEW);
|
||||
|
@ -2145,7 +2172,7 @@ void render_pause_red_coins(void) {
|
|||
s8 x;
|
||||
|
||||
for (x = 0; x < gRedCoinsCollected; x++) {
|
||||
print_animated_red_coin(290 - x * 20, 16);
|
||||
print_animated_red_coin(GFX_DIMENSIONS_FROM_RIGHT_EDGE(30) - x * 20, 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2437,7 +2464,8 @@ void print_hud_pause_colorful_str(void) {
|
|||
gDPSetEnvColor(gDisplayListHead++, 255, 255, 255, gDialogTextAlpha);
|
||||
|
||||
#ifdef VERSION_EU
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, get_str_x_pos_from_center_scale(160, textPause, 12.0f), 81, textPause);
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, get_str_x_pos_from_center_scale(
|
||||
SCREEN_WIDTH / 2, textPause, 12.0f), 81, textPause);
|
||||
#else
|
||||
print_hud_lut_string(HUD_LUT_GLOBAL, 123, 81, textPause);
|
||||
#endif
|
||||
|
|
|
@ -958,6 +958,8 @@ void basic_update(UNUSED s16 *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
int gPressedStart = 0;
|
||||
|
||||
s32 play_mode_normal(void) {
|
||||
if (gCurrDemoInput != NULL) {
|
||||
print_intro_text();
|
||||
|
@ -966,6 +968,7 @@ s32 play_mode_normal(void) {
|
|||
gCurrLevelNum == LEVEL_PSS ? WARP_OP_DEMO_END : WARP_OP_DEMO_NEXT);
|
||||
} else if (!gWarpTransition.isActive && sDelayedWarpOp == WARP_OP_NONE
|
||||
&& (gPlayer1Controller->buttonPressed & START_BUTTON)) {
|
||||
gPressedStart = 1;
|
||||
level_trigger_warp(gMarioState, WARP_OP_DEMO_NEXT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -327,3 +327,49 @@ void spawn_special_objects(s16 areaIndex, s16 **specialObjList) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TARGET_N64
|
||||
u32 get_special_objects_size(s16 *data) {
|
||||
s16 *startPos = data;
|
||||
s32 numOfSpecialObjects;
|
||||
s32 i;
|
||||
u8 presetID;
|
||||
s32 offset;
|
||||
|
||||
numOfSpecialObjects = *data++;
|
||||
|
||||
for (i = 0; i < numOfSpecialObjects; i++) {
|
||||
presetID = (u8) *data++;
|
||||
data += 3;
|
||||
offset = 0;
|
||||
|
||||
while (TRUE) {
|
||||
if (SpecialObjectPresets[offset].preset_id == presetID) {
|
||||
break;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
|
||||
switch (SpecialObjectPresets[offset].type) {
|
||||
case SPTYPE_NO_YROT_OR_PARAMS:
|
||||
break;
|
||||
case SPTYPE_YROT_NO_PARAMS:
|
||||
data++;
|
||||
break;
|
||||
case SPTYPE_PARAMS_AND_YROT:
|
||||
data += 2;
|
||||
break;
|
||||
case SPTYPE_UNKNOWN:
|
||||
data += 3;
|
||||
break;
|
||||
case SPTYPE_DEF_PARAM_AND_YROT:
|
||||
data++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return data - startPos;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -16,5 +16,8 @@ extern void spawn_macro_abs_special(u32 model, const BehaviorScript *behavior, s
|
|||
extern void spawn_macro_objects(s16 areaIndex, s16 * macroObjList);
|
||||
extern void spawn_macro_objects_hardcoded(s16 areaIndex, s16 * macroObjList);
|
||||
extern void spawn_special_objects(s16 areaIndex, s16 ** specialObjList);
|
||||
#ifndef TARGET_N64
|
||||
extern u32 get_special_objects_size(s16 *data);
|
||||
#endif
|
||||
|
||||
#endif /* MACRO_SPECIAL_OBJECTS_H */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <ultra64.h>
|
||||
#include "prevent_bss_reordering.h"
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
//#include "game.h"
|
||||
#include "game_init.h"
|
||||
#include "sound_init.h"
|
||||
#include "level_update.h"
|
||||
|
@ -88,6 +90,10 @@ s32 get_credits_str_width(char *str) {
|
|||
return length;
|
||||
}
|
||||
|
||||
#define CREDIT_TEXT_MARGIN_X ((s32)(GFX_DIMENSIONS_ASPECT_RATIO * 21))
|
||||
#define CREDIT_TEXT_X_LEFT GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(CREDIT_TEXT_MARGIN_X)
|
||||
#define CREDIT_TEXT_X_RIGHT GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(CREDIT_TEXT_MARGIN_X)
|
||||
|
||||
/**
|
||||
* print_displaying_credits_entry: Print the current displaying Credits Entry
|
||||
* Called in render_game. This function checks if sDispCreditsEntry points to a
|
||||
|
@ -122,27 +128,27 @@ void print_displaying_credits_entry(void) {
|
|||
#endif
|
||||
|
||||
dl_rgba16_begin_cutscene_msg_fade();
|
||||
print_credits_str_ascii(28, strY, titleStr);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY, titleStr);
|
||||
|
||||
#ifndef VERSION_JP
|
||||
switch (numLines) {
|
||||
case 4:
|
||||
print_credits_str_ascii(28, strY + 24, *currStrPtr++);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY + 24, *currStrPtr++);
|
||||
numLines = 2;
|
||||
lineHeight = 24;
|
||||
break;
|
||||
case 5:
|
||||
print_credits_str_ascii(28, strY + 16, *currStrPtr++);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY + 16, *currStrPtr++);
|
||||
numLines = 3;
|
||||
break;
|
||||
#ifdef VERSION_EU
|
||||
case 6:
|
||||
print_credits_str_ascii(28, strY + 32, *currStrPtr++);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY + 32, *currStrPtr++);
|
||||
numLines = 3;
|
||||
break;
|
||||
case 7:
|
||||
print_credits_str_ascii(28, strY + 16, *currStrPtr++);
|
||||
print_credits_str_ascii(28, strY + 32, *currStrPtr++);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY + 16, *currStrPtr++);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_LEFT, strY + 32, *currStrPtr++);
|
||||
numLines = 3;
|
||||
break;
|
||||
#endif
|
||||
|
@ -152,7 +158,7 @@ void print_displaying_credits_entry(void) {
|
|||
// smart dev here, thinking ahead for when the cosmic ray hits the rdram
|
||||
// chips 23 years later and nearly causes upwarp 2
|
||||
while (numLines-- > 0) {
|
||||
print_credits_str_ascii((320 - 28) - get_credits_str_width(*currStrPtr), strY, *currStrPtr);
|
||||
print_credits_str_ascii(CREDIT_TEXT_X_RIGHT - get_credits_str_width(*currStrPtr), strY, *currStrPtr);
|
||||
|
||||
#ifdef VERSION_JP
|
||||
strY += 16;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
#ifndef TARGET_N64
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "sm64.h"
|
||||
|
||||
|
@ -75,6 +78,7 @@ void *get_segment_base_addr(s32 segment) {
|
|||
return (void *) (sSegmentTable[segment] | 0x80000000);
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void *segmented_to_virtual(const void *addr) {
|
||||
size_t segment = (uintptr_t) addr >> 24;
|
||||
size_t offset = (uintptr_t) addr & 0x00FFFFFF;
|
||||
|
@ -94,6 +98,18 @@ void move_segment_table_to_dmem(void) {
|
|||
for (i = 0; i < 16; i++)
|
||||
gSPSegment(gDisplayListHead++, i, sSegmentTable[i]);
|
||||
}
|
||||
#else
|
||||
void *segmented_to_virtual(const void *addr) {
|
||||
return (void *) addr;
|
||||
}
|
||||
|
||||
void *virtual_to_segmented(u32 segment, const void *addr) {
|
||||
return (void *) addr;
|
||||
}
|
||||
|
||||
void move_segment_table_to_dmem(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the main memory pool. This pool is conceptually a pair of stacks
|
||||
|
@ -232,7 +248,7 @@ u32 main_pool_pop_state(void) {
|
|||
*/
|
||||
static void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd) {
|
||||
u32 size = ALIGN16(srcEnd - srcStart);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
osInvalDCache(dest, size);
|
||||
while (size != 0) {
|
||||
u32 copySize = (size >= 0x1000) ? 0x1000 : size;
|
||||
|
@ -245,6 +261,9 @@ static void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd) {
|
|||
srcStart += copySize;
|
||||
size -= copySize;
|
||||
}
|
||||
#else
|
||||
memcpy(dest, srcStart, srcEnd - srcStart);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -262,6 +281,7 @@ static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
|
|||
return dest;
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/**
|
||||
* Load data from ROM into a newly allocated block, and set the segment base
|
||||
* address to this block.
|
||||
|
@ -356,6 +376,7 @@ void load_engine_code_segment(void) {
|
|||
osInvalICache(startAddr, totalSize);
|
||||
osInvalDCache(startAddr, totalSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Allocate an allocation-only pool from the main pool. This pool doesn't
|
||||
|
|
|
@ -37,11 +37,19 @@ u32 main_pool_available(void);
|
|||
u32 main_pool_push_state(void);
|
||||
u32 main_pool_pop_state(void);
|
||||
|
||||
#ifdef TARGET_N64
|
||||
void *load_segment(s32 segment, u8 *srcStart, u8 *srcEnd, u32 side);
|
||||
void *load_to_fixed_pool_addr(u8 *destAddr, u8 *srcStart, u8 *srcEnd);
|
||||
void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd);
|
||||
void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd);
|
||||
void load_engine_code_segment(void);
|
||||
#else
|
||||
#define load_segment(...)
|
||||
#define load_to_fixed_pool_addr(...)
|
||||
#define load_segment_decompress(...)
|
||||
#define load_segment_decompress_heap(...)
|
||||
#define load_engine_code_segment(...)
|
||||
#endif
|
||||
|
||||
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side);
|
||||
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
|
||||
|
|
|
@ -1102,7 +1102,6 @@ void move_ddd_painting(struct Painting *painting, f32 frontPos, f32 backPos, f32
|
|||
gDddPaintingStatus = BOWSERS_SUB_BEATEN | DDD_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the painting's node's layer based on its alpha
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "game_init.h"
|
||||
#include "mario.h"
|
||||
#include "memory.h"
|
||||
|
@ -27,7 +28,7 @@ struct TextLabel {
|
|||
* Stores the text to be rendered on screen
|
||||
* and how they are to be rendered.
|
||||
*/
|
||||
struct TextLabel *sTextLabels[52];
|
||||
struct TextLabel *sTextLabels[256];
|
||||
s16 sTextLabelsCount = 0;
|
||||
|
||||
/**
|
||||
|
@ -365,6 +366,7 @@ void add_glyph_texture(s8 glyphIndex) {
|
|||
gSPDisplayList(gDisplayListHead++, dl_hud_img_load_tex_block);
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/**
|
||||
* Clips textrect into the boundaries defined.
|
||||
*/
|
||||
|
@ -385,6 +387,7 @@ void clip_to_bounds(s32 *x, s32 *y) {
|
|||
*y = TEXRECT_MAX_Y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Renders the glyph that's set at the given position.
|
||||
|
@ -395,7 +398,9 @@ void render_textrect(s32 x, s32 y, s32 pos) {
|
|||
s32 rectX;
|
||||
s32 rectY;
|
||||
|
||||
#ifdef TARGET_N64
|
||||
clip_to_bounds(&rectBaseX, &rectBaseY);
|
||||
#endif
|
||||
rectX = rectBaseX;
|
||||
rectY = rectBaseY;
|
||||
gSPTextureRectangle(gDisplayListHead++, rectX << 2, rectY << 2, (rectX + 15) << 2,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "main.h"
|
||||
#include "print.h"
|
||||
#include "engine/math_util.h"
|
||||
|
@ -505,13 +506,18 @@ static void geo_process_background(struct GraphNodeBackground *node) {
|
|||
if (list != 0) {
|
||||
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);
|
||||
} else if (gCurGraphNodeMasterList != NULL) {
|
||||
#ifdef TARGET_N64
|
||||
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 7);
|
||||
#else
|
||||
Gfx *gfxStart = alloc_display_list(sizeof(Gfx) * 8);
|
||||
#endif
|
||||
Gfx *gfx = gfxStart;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetCycleType(gfx++, G_CYC_FILL);
|
||||
gDPSetFillColor(gfx++, node->background);
|
||||
gDPFillRectangle(gfx++, 0, BORDER_HEIGHT, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1 - BORDER_HEIGHT);
|
||||
gDPFillRectangle(gfx++, GFX_DIMENSIONS_RECT_FROM_LEFT_EDGE(0), BORDER_HEIGHT,
|
||||
GFX_DIMENSIONS_RECT_FROM_RIGHT_EDGE(0) - 1, SCREEN_HEIGHT - BORDER_HEIGHT - 1);
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetCycleType(gfx++, G_CYC_1CYCLE);
|
||||
gSPEndDisplayList(gfx++);
|
||||
|
@ -751,6 +757,10 @@ static int obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) {
|
|||
// the amount of units between the center of the screen and the horizontal edge
|
||||
// given the distance from the object to the camera.
|
||||
|
||||
#ifndef TARGET_N64
|
||||
hScreenEdge *= GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
#endif
|
||||
|
||||
if (geo != NULL && geo->type == GRAPH_NODE_TYPE_CULLING_RADIUS) {
|
||||
cullingRadius =
|
||||
(f32)((struct GraphNodeCullingRadius *) geo)->cullingRadius; //! Why is there a f32 cast?
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "area.h"
|
||||
#include "game/game_init.h"
|
||||
#include "engine/math_util.h"
|
||||
|
@ -48,10 +49,10 @@ Vtx *vertex_transition_color(struct WarpTransitionData *transData, u8 alpha) {
|
|||
u8 b = transData->blue;
|
||||
|
||||
if (verts != NULL) {
|
||||
make_vertex(verts, 0, 0, 0, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 1, SCREEN_WIDTH, 0, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 2, SCREEN_WIDTH, SCREEN_HEIGHT, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 3, 0, SCREEN_HEIGHT, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 0, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 0, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 1, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), 0, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 2, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, r, g, b, alpha);
|
||||
make_vertex(verts, 3, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, r, g, b, alpha);
|
||||
} else {
|
||||
}
|
||||
return verts;
|
||||
|
@ -240,8 +241,13 @@ int render_screen_transition(s8 fadeTimer, s8 transType, u8 transTime, struct Wa
|
|||
}
|
||||
|
||||
Gfx *render_cannon_circle_base(void) {
|
||||
#ifdef TARGET_N64
|
||||
Vtx *verts = alloc_display_list(4 * sizeof(*verts));
|
||||
Gfx *dlist = alloc_display_list(16 * sizeof(*dlist));
|
||||
#else
|
||||
Vtx *verts = alloc_display_list(8 * sizeof(*verts));
|
||||
Gfx *dlist = alloc_display_list(20 * sizeof(*dlist));
|
||||
#endif
|
||||
Gfx *g = dlist;
|
||||
|
||||
if (verts != NULL && dlist != NULL) {
|
||||
|
@ -250,6 +256,13 @@ Gfx *render_cannon_circle_base(void) {
|
|||
make_vertex(verts, 2, SCREEN_WIDTH, SCREEN_HEIGHT, -1, 1152, 192, 0, 0, 0, 255);
|
||||
make_vertex(verts, 3, 0, SCREEN_HEIGHT, -1, -1152, 192, 0, 0, 0, 255);
|
||||
|
||||
#ifndef TARGET_N64
|
||||
make_vertex(verts, 4, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 5, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), 0, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 6, GFX_DIMENSIONS_FROM_RIGHT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255);
|
||||
make_vertex(verts, 7, GFX_DIMENSIONS_FROM_LEFT_EDGE(0), SCREEN_HEIGHT, -1, 0, 0, 0, 0, 0, 255);
|
||||
#endif
|
||||
|
||||
gSPDisplayList(g++, dl_proj_mtx_fullscreen);
|
||||
gDPSetCombineMode(g++, G_CC_MODULATEIDECALA, G_CC_MODULATEIDECALA);
|
||||
gDPSetTextureFilter(g++, G_TF_BILERP);
|
||||
|
@ -259,6 +272,12 @@ Gfx *render_cannon_circle_base(void) {
|
|||
gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts), 4, 0);
|
||||
gSPDisplayList(g++, dl_draw_quad_verts_0123);
|
||||
gSPTexture(g++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF);
|
||||
#ifndef TARGET_N64
|
||||
gDPSetCombineMode(g++, G_CC_SHADE, G_CC_SHADE);
|
||||
gSPVertex(g++, VIRTUAL_TO_PHYSICAL(verts + 4), 4, 4);
|
||||
gSP2Triangles(g++, 4, 0, 3, 0, 4, 3, 7, 0);
|
||||
gSP2Triangles(g++, 1, 5, 6, 0, 1, 6, 2, 0);
|
||||
#endif
|
||||
gSPDisplayList(g++, dl_screen_transition_end);
|
||||
gSPEndDisplayList(g);
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "engine/math_util.h"
|
||||
#include "memory.h"
|
||||
#include "area.h"
|
||||
|
@ -241,6 +242,16 @@ void *create_skybox_ortho_matrix(s8 player) {
|
|||
f32 top = sSkyBoxInfo[player].scaledY;
|
||||
Mtx *mtx = alloc_display_list(sizeof(*mtx));
|
||||
|
||||
#ifndef TARGET_N64
|
||||
f32 half_width = (4.0f / 3.0f) / GFX_DIMENSIONS_ASPECT_RATIO * SCREEN_WIDTH / 2;
|
||||
f32 center = (sSkyBoxInfo[player].scaledX + SCREEN_WIDTH / 2);
|
||||
if (half_width < SCREEN_WIDTH / 2) {
|
||||
// A wider screen than 4:3
|
||||
left = center - half_width;
|
||||
right = center + half_width;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mtx != NULL) {
|
||||
guOrtho(mtx, left, right, bottom, top, 0.0f, 3.0f, 1.0f);
|
||||
} else {
|
||||
|
@ -253,7 +264,7 @@ void *create_skybox_ortho_matrix(s8 player) {
|
|||
* Creates the skybox's display list, then draws the 3x3 grid of tiles.
|
||||
*/
|
||||
Gfx *init_skybox_display_list(s8 player, s8 background, s8 colorIndex) {
|
||||
s32 dlCommandCount = 5 + 9 * 7; // 5 for the start and end, plus 9 skybox tiles
|
||||
s32 dlCommandCount = 5 + (3 * 3) * 7; // 5 for the start and end, plus 9 skybox tiles
|
||||
void *skybox = alloc_display_list(dlCommandCount * sizeof(Gfx));
|
||||
Gfx *dlist = skybox;
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ void remove_all_memtrackers(void) {
|
|||
sMemTrackers[i].end = 0.0f;
|
||||
sMemTrackers[i].total = 0.0f;
|
||||
}
|
||||
|
||||
#ifdef AVOID_UB
|
||||
sNumActiveMemTrackers = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 23AE20 -> 23AE44; orig name: func_8018C650 */
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "renderer.h"
|
||||
#include "draw_objects.h"
|
||||
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
/**
|
||||
* @file draw_objects.c
|
||||
* This file contains the functions and helpers for rendering the various
|
||||
|
@ -693,14 +695,19 @@ void func_80179B64(struct ObjGroup *group) {
|
|||
(applyproc_t) Unknown80179ACC, group);
|
||||
}
|
||||
|
||||
/* 22836C -> 228498 */
|
||||
void func_80179B9C(struct GdVec3f *pos, struct ObjCamera *cam, struct ObjView *view) {
|
||||
// plc again
|
||||
void func_80179B9C(struct GdVec3f *pos, struct ObjCamera *cam, struct ObjView *view)
|
||||
{
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
aspect *= 0.75;
|
||||
//func_80196430(pos, &cam->unkE8);
|
||||
gd_rotate_and_translate_vec3f(pos, &cam->unkE8);
|
||||
|
||||
if (pos->z > -256.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
pos->x *= 256.0 / -pos->z;
|
||||
pos->x *= 256.0 / -pos->z / aspect;
|
||||
pos->y *= 256.0 / pos->z;
|
||||
pos->x += view->lowerRight.x / 2.0f;
|
||||
pos->y += view->lowerRight.y / 2.0f;
|
||||
|
|
|
@ -22,12 +22,20 @@
|
|||
#include "gd_math.h"
|
||||
#include "shape_helper.h"
|
||||
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
#define MAX_GD_DLS 1000
|
||||
#define OS_MESG_SI_COMPLETE 0x33333333
|
||||
|
||||
#ifdef TARGET_N64
|
||||
#define GD_VIRTUAL_TO_PHYSICAL(addr) ((uintptr_t)(addr) &0x0FFFFFFF)
|
||||
#define GD_LOWER_24(addr) ((uintptr_t)(addr) &0x00FFFFFF)
|
||||
#define GD_LOWER_29(addr) (((uintptr_t)(addr)) & 0x1FFFFFFF)
|
||||
#else
|
||||
#define GD_VIRTUAL_TO_PHYSICAL(addr) (addr)
|
||||
#define GD_LOWER_24(addr) ((uintptr_t)(addr))
|
||||
#define GD_LOWER_29(addr) (((uintptr_t)(addr)))
|
||||
#endif
|
||||
|
||||
#define MTX_INTPART_PACK(w1, w2) (((w1) &0xFFFF0000) | (((w2) >> 16) & 0xFFFF))
|
||||
#define MTX_FRACPART_PACK(w1, w2) ((((w1) << 16) & 0xFFFF0000) | ((w2) &0xFFFF))
|
||||
|
@ -1683,6 +1691,7 @@ u32 Unknown8019EC88(Gfx *dl, UNUSED s32 arg1) {
|
|||
|
||||
/* 24D4C4 -> 24D63C; orig name: func_8019ECF4 */
|
||||
void mat4_to_mtx(const Mat4f *src, Mtx *dst) {
|
||||
#ifdef TARGET_N64
|
||||
s32 i; // 14
|
||||
s32 j; // 10
|
||||
s32 w1;
|
||||
|
@ -1700,6 +1709,9 @@ void mat4_to_mtx(const Mat4f *src, Mtx *dst) {
|
|||
mtxFrc++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
guMtxF2L(src, dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 24D63C -> 24D6E4; orig name: func_8019EE6C */
|
||||
|
@ -2333,6 +2345,8 @@ void parse_p1_controller(void) {
|
|||
OSContPad *p1contPrev; // 30
|
||||
u8 *gdCtrlBytes; // 2C
|
||||
u8 *prevGdCtrlBytes; // 28
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
aspect *= 0.75;
|
||||
|
||||
gdctrl = &gGdCtrl;
|
||||
gdCtrlBytes = (u8 *) gdctrl;
|
||||
|
@ -2430,14 +2444,14 @@ void parse_p1_controller(void) {
|
|||
gdctrl->csrY -= gdctrl->stickY * 0.1; //? 0.1f
|
||||
}
|
||||
// border checks? is this for the cursor finger movement?
|
||||
if ((f32) gdctrl->csrX < (sScreenView2->parent->upperLeft.x + 16.0f)) {
|
||||
gdctrl->csrX = (s32)(sScreenView2->parent->upperLeft.x + 16.0f);
|
||||
if ((f32) gdctrl->csrX < (sScreenView2->parent->upperLeft.x + (16.0f/aspect))) {
|
||||
gdctrl->csrX = (s32)(sScreenView2->parent->upperLeft.x + (16.0f/aspect));
|
||||
}
|
||||
|
||||
if ((f32) gdctrl->csrX
|
||||
> (sScreenView2->parent->upperLeft.x + sScreenView2->parent->lowerRight.x - 48.0f)) {
|
||||
> (sScreenView2->parent->upperLeft.x + sScreenView2->parent->lowerRight.x - (48.0/aspect))) {
|
||||
gdctrl->csrX =
|
||||
(s32)(sScreenView2->parent->upperLeft.x + sScreenView2->parent->lowerRight.x - 48.0f);
|
||||
(s32)(sScreenView2->parent->upperLeft.x + sScreenView2->parent->lowerRight.x - (48.0/aspect));
|
||||
}
|
||||
|
||||
if ((f32) gdctrl->csrY < (sScreenView2->parent->upperLeft.y + 16.0f)) {
|
||||
|
@ -3425,9 +3439,12 @@ void Unknown801A5FF8(struct ObjGroup *arg0) {
|
|||
}
|
||||
|
||||
/* 254AC0 -> 254DFC; orig name: PutSprite */
|
||||
// thanks to gamemasterplc again for fixing this
|
||||
void gd_put_sprite(u16 *sprite, s32 x, s32 y, s32 wx, s32 wy) {
|
||||
s32 c; // 5c
|
||||
s32 r; // 58
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO * 0.75;
|
||||
x *= aspect;
|
||||
|
||||
gSPDisplayList(next_gfx(), osVirtualToPhysical(gd_dl_sprite_start_tex_block));
|
||||
for (r = 0; r < wy; r += 32) {
|
||||
|
@ -3615,6 +3632,7 @@ void Unknown801A6E30(UNUSED u32 a0) {
|
|||
void Unknown801A6E44(UNUSED u32 a0) {
|
||||
}
|
||||
|
||||
#ifdef TARGET_N64
|
||||
/* 255628 -> 255704; orig name: func_801A6E58 */
|
||||
void gd_block_dma(u32 devAddr, void *vAddr, s32 size) {
|
||||
s32 transfer; // 2c
|
||||
|
@ -3692,6 +3710,11 @@ struct GdObj *load_dynlist(struct DynList *dynlist) {
|
|||
|
||||
return loadedList;
|
||||
}
|
||||
#else
|
||||
struct GdObj *load_dynlist(struct DynList *dynlist) {
|
||||
return proc_dynlist(dynlist);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 255988 -> 25599C */
|
||||
void stub_801A71B8(UNUSED u32 a0) {
|
||||
|
|
|
@ -303,7 +303,9 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
u8 nx, ny, nz; // 24, 25, 26
|
||||
UNUSED u32 pad20;
|
||||
register struct VtxLink *vtxlink; // a1
|
||||
#ifdef TARGET_N64
|
||||
register s16 *vnPos; // a2
|
||||
#endif
|
||||
register s16 x; // a3
|
||||
register s16 y; // t0
|
||||
register s16 z; // t1
|
||||
|
@ -323,11 +325,18 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
nz = (u8)(vtx->normal.z * 255.0f);
|
||||
|
||||
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
|
||||
#ifdef TARGET_N64
|
||||
vnPos = vtxlink->data->n.ob;
|
||||
vn = vtxlink->data;
|
||||
*vnPos++ = x;
|
||||
*vnPos++ = y;
|
||||
*vnPos++ = z;
|
||||
#else
|
||||
vn = vtxlink->data;
|
||||
vn->n.ob[0] = x;
|
||||
vn->n.ob[1] = y;
|
||||
vn->n.ob[2] = z;
|
||||
#endif
|
||||
vn->n.n[0] = nx;
|
||||
vn->n.n[1] = ny;
|
||||
vn->n.n[2] = nz;
|
||||
|
@ -339,7 +348,9 @@ void convert_gd_verts_to_Vn(struct ObjGroup *grp) {
|
|||
void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
|
||||
UNUSED u32 pad24[6];
|
||||
register struct VtxLink *vtxlink; // a1
|
||||
#ifdef TARGET_N64
|
||||
register s16 *vtxcoords; // a2
|
||||
#endif
|
||||
register s16 x; // a3
|
||||
register s16 y; // t0
|
||||
register s16 z; // t1
|
||||
|
@ -355,10 +366,16 @@ void convert_gd_verts_to_Vtx(struct ObjGroup *grp) {
|
|||
z = (s16) vtx->pos.z;
|
||||
|
||||
for (vtxlink = vtx->gbiVerts; vtxlink != NULL; vtxlink = vtxlink->prev) {
|
||||
#ifdef TARGET_N64
|
||||
vtxcoords = vtxlink->data->v.ob;
|
||||
vtxcoords[0] = x;
|
||||
vtxcoords[1] = y;
|
||||
vtxcoords[2] = z;
|
||||
#else
|
||||
vtxlink->data->v.ob[0] = x;
|
||||
vtxlink->data->v.ob[1] = y;
|
||||
vtxlink->data->v.ob[2] = z;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "game/segment7.h"
|
||||
#include "intro_geo.h"
|
||||
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
// frame counts for the zoom in, hold, and zoom out of title model
|
||||
#define INTRO_STEPS_ZOOM_IN 20
|
||||
#define INTRO_STEPS_HOLD_1 75
|
||||
|
@ -167,11 +169,15 @@ Gfx *intro_backdrop_one_image(s32 index, s8 *backgroundTable) {
|
|||
Gfx *displayListIter; // sp54
|
||||
const u8 *const *vIntroBgTable; // sp50
|
||||
s32 i; // sp4c
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
||||
float x_ofs = (SCREEN_WIDTH/2)-(aspect*SCREEN_HEIGHT/2);
|
||||
|
||||
mtx = alloc_display_list(sizeof(*mtx));
|
||||
displayList = alloc_display_list(36 * sizeof(*displayList));
|
||||
displayListIter = displayList;
|
||||
vIntroBgTable = segmented_to_virtual(introBackgroundTextureType[backgroundTable[index]]);
|
||||
guTranslate(mtx, introBackgroundOffsetX[index], introBackgroundOffsetY[index], 0.0f);
|
||||
vIntroBgTable = segmented_to_virtual(introBackgroundTextureType[backgroundTable[0]]);
|
||||
guTranslate(mtx, ((index%num_tiles_h)*80)+x_ofs, (index/num_tiles_h)*80, 0.0f);
|
||||
gSPMatrix(displayListIter++, mtx, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH);
|
||||
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000118);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
|
@ -196,13 +202,16 @@ Gfx *geo_intro_backdrop(s32 sp48, struct GraphNode *sp4c, UNUSED void *context)
|
|||
backgroundTable = introBackgroundTables[index];
|
||||
displayList = NULL;
|
||||
displayListIter = NULL;
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
||||
|
||||
if (sp48 == 1) {
|
||||
displayList = alloc_display_list(16 * sizeof(*displayList));
|
||||
displayList = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*displayList));
|
||||
displayListIter = displayList;
|
||||
graphNode->node.flags = (graphNode->node.flags & 0xFF) | 0x100;
|
||||
gSPDisplayList(displayListIter++, &dl_proj_mtx_fullscreen);
|
||||
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000100);
|
||||
for (i = 0; i < 12; ++i) {
|
||||
for (i = 0; i < num_tiles_h*3; ++i) {
|
||||
gSPDisplayList(displayListIter++, intro_backdrop_one_image(i, backgroundTable));
|
||||
}
|
||||
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000190);
|
||||
|
@ -220,6 +229,9 @@ Gfx *geo_game_over_tile(s32 sp40, struct GraphNode *sp44, UNUSED void *context)
|
|||
graphNode = sp44;
|
||||
displayList = NULL;
|
||||
displayListIter = NULL;
|
||||
f32 aspect = GFX_DIMENSIONS_ASPECT_RATIO;
|
||||
int num_tiles_h = (((aspect*SCREEN_HEIGHT)+79)/80);
|
||||
|
||||
if (sp40 != 1) {
|
||||
gGameOverFrameCounter = 0;
|
||||
gGameOverTableIndex = -2;
|
||||
|
@ -227,7 +239,7 @@ Gfx *geo_game_over_tile(s32 sp40, struct GraphNode *sp44, UNUSED void *context)
|
|||
gameOverBackgroundTable[i] = INTRO_BACKGROUND_GAME_OVER;
|
||||
}
|
||||
} else {
|
||||
displayList = alloc_display_list(16 * sizeof(*displayList));
|
||||
displayList = alloc_display_list(((num_tiles_h*3)+4) * sizeof(*displayList));
|
||||
displayListIter = displayList;
|
||||
if (gGameOverTableIndex == -2) {
|
||||
if (gGameOverFrameCounter == 180) {
|
||||
|
@ -248,7 +260,7 @@ Gfx *geo_game_over_tile(s32 sp40, struct GraphNode *sp44, UNUSED void *context)
|
|||
graphNode->flags = (graphNode->flags & 0xFF) | 0x100;
|
||||
gSPDisplayList(displayListIter++, &dl_proj_mtx_fullscreen);
|
||||
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000100);
|
||||
for (j = 0; j < (s32) sizeof(gameOverBackgroundTable); ++j) {
|
||||
for (j = 0; j < (s32) num_tiles_h*3; ++j) {
|
||||
gSPDisplayList(displayListIter++, intro_backdrop_one_image(j, gameOverBackgroundTable));
|
||||
}
|
||||
gSPDisplayList(displayListIter++, &title_screen_bg_dl_0A000190);
|
||||
|
|
|
@ -69,6 +69,29 @@ int run_press_start_demo_timer(s32 timer) {
|
|||
return timer;
|
||||
}
|
||||
|
||||
extern int gDemoInputListID_2;
|
||||
extern int gPressedStart;
|
||||
|
||||
int start_demo(int timer)
|
||||
{
|
||||
gCurrDemoInput = NULL;
|
||||
gPressedStart = 0;
|
||||
// start the mario demo animation for the demo list.
|
||||
//func_80278AD4(&gDemo, gDemoInputListID_2);
|
||||
|
||||
// if the next demo sequence ID is the count limit, reset it back to
|
||||
// the first sequence.
|
||||
|
||||
if((++gDemoInputListID_2) == gDemo.animDmaTable->count)
|
||||
gDemoInputListID_2 = 0;
|
||||
|
||||
gCurrDemoInput = ((struct DemoInput *) gDemo.targetAnim) + 1; // add 1 (+4) to the pointer to skip the demoID.
|
||||
timer = (s8)((struct DemoInput *) gDemo.targetAnim)->timer; // TODO: see if making timer s8 matches
|
||||
gCurrSaveFileNum = 1;
|
||||
gCurrActNum = 6;
|
||||
return timer;
|
||||
}
|
||||
|
||||
// input loop for the level select menu. updates the selected stage
|
||||
// count if an input was received. signals the stage to be started
|
||||
// or the level select to be exited if start or the quit combo is
|
||||
|
@ -134,28 +157,22 @@ s16 level_select_input_loop(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int intro_default(void) {
|
||||
s32 sp1C = 0;
|
||||
|
||||
#ifndef VERSION_JP
|
||||
if (D_U_801A7C34 == 1) {
|
||||
if (gGlobalTimer < 0x81) {
|
||||
play_sound(SOUND_MARIO_HELLO, gDefaultSoundArgs);
|
||||
} else {
|
||||
play_sound(SOUND_MARIO_PRESS_START_TO_PLAY, gDefaultSoundArgs);
|
||||
}
|
||||
D_U_801A7C34 = 0;
|
||||
}
|
||||
#endif
|
||||
print_intro_text();
|
||||
|
||||
if (gPlayer1Controller->buttonPressed & START_BUTTON) {
|
||||
#ifdef VERSION_JP
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
||||
sp1C = 100 + gDebugLevelSelect;
|
||||
#else
|
||||
play_sound(SOUND_MENU_STAR_SOUND, gDefaultSoundArgs);
|
||||
sp1C = 100 + gDebugLevelSelect;
|
||||
#ifndef VERSION_JP
|
||||
D_U_801A7C34 = 1;
|
||||
#endif
|
||||
}
|
||||
|
|
15
src/pc/audio/audio_api.h
Normal file
15
src/pc/audio/audio_api.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef AUDIO_API_H
|
||||
#define AUDIO_API_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct AudioAPI {
|
||||
bool (*init)(void);
|
||||
int (*buffered)(void);
|
||||
int (*get_desired_buffered)(void);
|
||||
void (*play)(const uint8_t *buf, size_t len);
|
||||
};
|
||||
|
||||
#endif
|
23
src/pc/audio/audio_null.c
Normal file
23
src/pc/audio/audio_null.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "audio_api.h"
|
||||
|
||||
static bool audio_null_init(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int audio_null_buffered(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audio_null_get_desired_buffered(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void audio_null_play(const uint8_t *buf, size_t len) {
|
||||
}
|
||||
|
||||
struct AudioAPI audio_null = {
|
||||
audio_null_init,
|
||||
audio_null_buffered,
|
||||
audio_null_get_desired_buffered,
|
||||
audio_null_play
|
||||
};
|
8
src/pc/audio/audio_null.h
Normal file
8
src/pc/audio/audio_null.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef AUDIO_NULL_H
|
||||
#define AUDIO_NULL_H
|
||||
|
||||
#include "audio_api.h"
|
||||
|
||||
extern struct AudioAPI audio_null;
|
||||
|
||||
#endif
|
48
src/pc/audio/audio_sdl.c
Normal file
48
src/pc/audio/audio_sdl.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "audio_api.h"
|
||||
|
||||
static SDL_AudioDeviceID dev;
|
||||
|
||||
static bool audio_sdl_init(void) {
|
||||
if (SDL_Init(SDL_INIT_AUDIO) != 0) {
|
||||
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
SDL_AudioSpec want, have;
|
||||
SDL_zero(want);
|
||||
want.freq = 32000;
|
||||
want.format = AUDIO_S16;
|
||||
want.channels = 2;
|
||||
want.samples = 512;
|
||||
want.callback = NULL;
|
||||
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
|
||||
if (dev == 0) {
|
||||
fprintf(stderr, "SDL_OpenAudio error: %s\n", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int audio_sdl_buffered(void) {
|
||||
return SDL_GetQueuedAudioSize(dev) / 4;
|
||||
}
|
||||
|
||||
static int audio_sdl_get_desired_buffered(void) {
|
||||
return 1100;
|
||||
}
|
||||
|
||||
static void audio_sdl_play(const uint8_t *buf, size_t len) {
|
||||
if (audio_sdl_buffered() < 6000) {
|
||||
// Don't fill the audio buffer too much in case this happens
|
||||
SDL_QueueAudio(dev, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
struct AudioAPI audio_sdl = {
|
||||
audio_sdl_init,
|
||||
audio_sdl_buffered,
|
||||
audio_sdl_get_desired_buffered,
|
||||
audio_sdl_play
|
||||
};
|
6
src/pc/audio/audio_sdl.h
Normal file
6
src/pc/audio/audio_sdl.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef AUDIO_SDL_H
|
||||
#define AUDIO_SDL_H
|
||||
|
||||
extern struct AudioAPI audio_sdl;
|
||||
|
||||
#endif
|
236
src/pc/configfile.c
Normal file
236
src/pc/configfile.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
// configfile.c - handles loading and saving the configuration options
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "configfile.h"
|
||||
|
||||
#define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
enum ConfigOptionType {
|
||||
CONFIG_TYPE_BOOL,
|
||||
CONFIG_TYPE_UINT,
|
||||
CONFIG_TYPE_FLOAT,
|
||||
};
|
||||
|
||||
struct ConfigOption {
|
||||
const char *name;
|
||||
enum ConfigOptionType type;
|
||||
union {
|
||||
bool *boolValue;
|
||||
unsigned int *uintValue;
|
||||
float *floatValue;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
*Config options and default values
|
||||
*/
|
||||
bool configFullscreen = false;
|
||||
// Keyboard mappings (scancode values)
|
||||
unsigned int configKeyA = 0x26;
|
||||
unsigned int configKeyB = 0x33;
|
||||
unsigned int configKeyStart = 0x39;
|
||||
unsigned int configKeyR = 0x36;
|
||||
unsigned int configKeyZ = 0x25;
|
||||
unsigned int configKeyCUp = 0x148;
|
||||
unsigned int configKeyCDown = 0x150;
|
||||
unsigned int configKeyCLeft = 0x14B;
|
||||
unsigned int configKeyCRight = 0x14D;
|
||||
unsigned int configKeyStickUp = 0x11;
|
||||
unsigned int configKeyStickDown = 0x1F;
|
||||
unsigned int configKeyStickLeft = 0x1E;
|
||||
unsigned int configKeyStickRight = 0x20;
|
||||
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configFullscreen},
|
||||
{.name = "key_a", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyA},
|
||||
{.name = "key_b", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyB},
|
||||
{.name = "key_start", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStart},
|
||||
{.name = "key_r", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyR},
|
||||
{.name = "key_z", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyZ},
|
||||
{.name = "key_cup", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyCUp},
|
||||
{.name = "key_cdown", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyCDown},
|
||||
{.name = "key_cleft", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyCLeft},
|
||||
{.name = "key_cright", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyCRight},
|
||||
{.name = "key_stickup", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickUp},
|
||||
{.name = "key_stickdown", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickDown},
|
||||
{.name = "key_stickleft", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickLeft},
|
||||
{.name = "key_stickright", .type = CONFIG_TYPE_UINT, .uintValue = &configKeyStickRight},
|
||||
};
|
||||
|
||||
// Reads an entire line from a file (excluding the newline character) and returns an allocated string
|
||||
// Returns NULL if no lines could be read from the file
|
||||
static char *read_file_line(FILE *file) {
|
||||
char *buffer;
|
||||
size_t bufferSize = 8;
|
||||
size_t offset = 0; // offset in buffer to write
|
||||
|
||||
buffer = malloc(bufferSize);
|
||||
while (1) {
|
||||
// Read a line from the file
|
||||
if (fgets(buffer + offset, bufferSize - offset, file) == NULL) {
|
||||
free(buffer);
|
||||
return NULL; // Nothing could be read.
|
||||
}
|
||||
offset = strlen(buffer);
|
||||
assert(offset > 0);
|
||||
|
||||
// If a newline was found, remove the trailing newline and exit
|
||||
if (buffer[offset - 1] == '\n') {
|
||||
buffer[offset - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (feof(file)) // EOF was reached
|
||||
break;
|
||||
|
||||
// If no newline or EOF was reached, then the whole line wasn't read.
|
||||
bufferSize *= 2; // Increase buffer size
|
||||
buffer = realloc(buffer, bufferSize);
|
||||
assert(buffer != NULL);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Returns the position of the first non-whitespace character
|
||||
static char *skip_whitespace(char *str) {
|
||||
while (isspace(*str))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
// NULL-terminates the current whitespace-delimited word, and returns a pointer to the next word
|
||||
static char *word_split(char *str) {
|
||||
// Precondition: str must not point to whitespace
|
||||
assert(!isspace(*str));
|
||||
|
||||
// Find either the next whitespace char or end of string
|
||||
while (!isspace(*str) && *str != '\0')
|
||||
str++;
|
||||
if (*str == '\0') // End of string
|
||||
return str;
|
||||
|
||||
// Terminate current word
|
||||
*(str++) = '\0';
|
||||
|
||||
// Skip whitespace to next word
|
||||
return skip_whitespace(str);
|
||||
}
|
||||
|
||||
// Splits a string into words, and stores the words into the 'tokens' array
|
||||
// 'maxTokens' is the length of the 'tokens' array
|
||||
// Returns the number of tokens parsed
|
||||
static unsigned int tokenize_string(char *str, int maxTokens, char **tokens) {
|
||||
int count = 0;
|
||||
|
||||
str = skip_whitespace(str);
|
||||
while (str[0] != '\0' && count < maxTokens) {
|
||||
tokens[count] = str;
|
||||
str = word_split(str);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Loads the config file specified by 'filename'
|
||||
void configfile_load(const char *filename) {
|
||||
FILE *file;
|
||||
char *line;
|
||||
|
||||
printf("Loading configuration from '%s'\n", filename);
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
// Create a new config file and save defaults
|
||||
printf("Config file '%s' not found. Creating it.\n", filename);
|
||||
configfile_save(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
// Go through each line in the file
|
||||
while ((line = read_file_line(file)) != NULL) {
|
||||
char *p = line;
|
||||
char *tokens[2];
|
||||
int numTokens;
|
||||
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
numTokens = tokenize_string(p, 2, tokens);
|
||||
if (numTokens != 0) {
|
||||
if (numTokens == 2) {
|
||||
const struct ConfigOption *option = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LEN(options); i++) {
|
||||
if (strcmp(tokens[0], options[i].name) == 0) {
|
||||
option = &options[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (option == NULL)
|
||||
printf("unknown option '%s'\n", tokens[0]);
|
||||
else {
|
||||
switch (option->type) {
|
||||
case CONFIG_TYPE_BOOL:
|
||||
if (strcmp(tokens[1], "true") == 0)
|
||||
*option->boolValue = true;
|
||||
else if (strcmp(tokens[1], "false") == 0)
|
||||
*option->boolValue = false;
|
||||
break;
|
||||
case CONFIG_TYPE_UINT:
|
||||
sscanf(tokens[1], "%u", option->uintValue);
|
||||
break;
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
sscanf(tokens[1], "%f", option->floatValue);
|
||||
break;
|
||||
default:
|
||||
assert(0); // bad type
|
||||
}
|
||||
printf("option: '%s', value: '%s'\n", tokens[0], tokens[1]);
|
||||
}
|
||||
} else
|
||||
puts("error: expected value");
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
// Writes the config file to 'filename'
|
||||
void configfile_save(const char *filename) {
|
||||
FILE *file;
|
||||
|
||||
printf("Saving configuration to '%s'\n", filename);
|
||||
|
||||
file = fopen(filename, "w");
|
||||
if (file == NULL) {
|
||||
// error
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LEN(options); i++) {
|
||||
const struct ConfigOption *option = &options[i];
|
||||
|
||||
switch (option->type) {
|
||||
case CONFIG_TYPE_BOOL:
|
||||
fprintf(file, "%s %s\n", option->name, *option->boolValue ? "true" : "false");
|
||||
break;
|
||||
case CONFIG_TYPE_UINT:
|
||||
fprintf(file, "%s %u\n", option->name, *option->uintValue);
|
||||
break;
|
||||
case CONFIG_TYPE_FLOAT:
|
||||
fprintf(file, "%s %f\n", option->name, *option->floatValue);
|
||||
break;
|
||||
default:
|
||||
assert(0); // unknown type
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
22
src/pc/configfile.h
Normal file
22
src/pc/configfile.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef CONFIGFILE_H
|
||||
#define CONFIGFILE_H
|
||||
|
||||
extern bool configFullscreen;
|
||||
extern unsigned int configKeyA;
|
||||
extern unsigned int configKeyB;
|
||||
extern unsigned int configKeyStart;
|
||||
extern unsigned int configKeyR;
|
||||
extern unsigned int configKeyZ;
|
||||
extern unsigned int configKeyCUp;
|
||||
extern unsigned int configKeyCDown;
|
||||
extern unsigned int configKeyCLeft;
|
||||
extern unsigned int configKeyCRight;
|
||||
extern unsigned int configKeyStickUp;
|
||||
extern unsigned int configKeyStickDown;
|
||||
extern unsigned int configKeyStickLeft;
|
||||
extern unsigned int configKeyStickRight;
|
||||
|
||||
void configfile_load(const char *filename);
|
||||
void configfile_save(const char *filename);
|
||||
|
||||
#endif
|
11
src/pc/controller/controller_api.h
Normal file
11
src/pc/controller/controller_api.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef CONTROLLER_API
|
||||
#define CONTROLLER_API
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
struct ControllerAPI {
|
||||
void (*init)(void);
|
||||
void (*read)(OSContPad *pad);
|
||||
};
|
||||
|
||||
#endif
|
151
src/pc/controller/controller_emscripten_keyboard.c
Normal file
151
src/pc/controller/controller_emscripten_keyboard.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
#ifdef TARGET_WEB
|
||||
|
||||
#include <string.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include "macros.h"
|
||||
#include "controller_keyboard.h"
|
||||
|
||||
static const struct {
|
||||
const char *code;
|
||||
int scancode;
|
||||
} keymap_browser[] = {
|
||||
{"Escape", 0x01},
|
||||
{"Digit1", 0x02 },
|
||||
{"Digit2", 0x03 },
|
||||
{"Digit3", 0x04 },
|
||||
{"Digit4", 0x05 },
|
||||
{"Digit5", 0x06 },
|
||||
{"Digit6", 0x07 },
|
||||
{"Digit7", 0x08 },
|
||||
{"Digit8", 0x09 },
|
||||
{"Digit9", 0x0a },
|
||||
{"Digit0", 0x0b },
|
||||
{"Minus", 0x0c },
|
||||
{"Equal", 0x0d },
|
||||
{"Backspace", 0x0e },
|
||||
{"Tab", 0x0f },
|
||||
{"KeyQ", 0x10 },
|
||||
{"KeyW", 0x11 },
|
||||
{"KeyE", 0x12 },
|
||||
{"KeyR", 0x13 },
|
||||
{"KeyT", 0x14 },
|
||||
{"KeyY", 0x15 },
|
||||
{"KeyU", 0x16 },
|
||||
{"KeyI", 0x17 },
|
||||
{"KeyO", 0x18 },
|
||||
{"KeyP", 0x19 },
|
||||
{"BracketLeft", 0x1a },
|
||||
{"BracketRight", 0x1b },
|
||||
{"Enter", 0x1c },
|
||||
{"ControlLeft", 0x1d },
|
||||
{"KeyA", 0x1e },
|
||||
{"KeyS", 0x1f },
|
||||
{"KeyD", 0x20 },
|
||||
{"KeyF", 0x21 },
|
||||
{"KeyG", 0x22 },
|
||||
{"KeyH", 0x23 },
|
||||
{"KeyJ", 0x24 },
|
||||
{"KeyK", 0x25 },
|
||||
{"KeyL", 0x26 },
|
||||
{"Semicolon", 0x27 },
|
||||
{"Quote", 0x28 },
|
||||
{"Backquote", 0x29 },
|
||||
{"ShiftLeft", 0x2a },
|
||||
{"Backslash", 0x2b },
|
||||
{"KeyZ", 0x2c },
|
||||
{"KeyX", 0x2d },
|
||||
{"KeyC", 0x2e },
|
||||
{"KeyV", 0x2f },
|
||||
{"KeyB", 0x30 },
|
||||
{"KeyN", 0x31 },
|
||||
{"KeyM", 0x32 },
|
||||
{"Comma", 0x33 },
|
||||
{"Period", 0x34 },
|
||||
{"Slash", 0x35 },
|
||||
{"ShiftRight", 0x36 },
|
||||
{"NumpadMultiply", 0x37 },
|
||||
{"AltLeft", 0x38 },
|
||||
{"Space", 0x39 },
|
||||
{"CapsLock", 0x3a },
|
||||
{"F1", 0x3b },
|
||||
{"F2", 0x3c },
|
||||
{"F3", 0x3d },
|
||||
{"F4", 0x3e },
|
||||
{"F5", 0x3f },
|
||||
{"F6", 0x40 },
|
||||
{"F7", 0x41 },
|
||||
{"F8", 0x42 },
|
||||
{"F9", 0x43 },
|
||||
{"F10", 0x44 },
|
||||
{"NumLock", 0x45 },
|
||||
{"ScrollLock", 0x46 },
|
||||
{"Numpad7", 0x47 },
|
||||
{"Numpad8", 0x48 },
|
||||
{"Numpad9", 0x49 },
|
||||
{"NumpadSubtract", 0x4a },
|
||||
{"Numpad4", 0x4b },
|
||||
{"Numpad5", 0x4c },
|
||||
{"Numpad6", 0x4d },
|
||||
{"NumpadAdd", 0x4e },
|
||||
{"Numpad1", 0x4f },
|
||||
{"Numpad2", 0x50 },
|
||||
{"Numpad3", 0x51 },
|
||||
{"Numpad0", 0x52 },
|
||||
{"NumpadDecimal", 0x53 },
|
||||
{"PrintScreen", 0x54 },
|
||||
// 0x55
|
||||
{"IntlBackslash", 0x56 },
|
||||
{"F11", 0x57 },
|
||||
{"F12", 0x58 },
|
||||
{"IntlRo", 0x59 },
|
||||
//{"Katakana", 0 },
|
||||
//{"Hiragana", 0 },
|
||||
{"NumpadEnter", 0x11c },
|
||||
{"ControlRight", 0x11d },
|
||||
{"NumpadDivide", 0x135 },
|
||||
{"AltRight", 0x138 },
|
||||
{"Home", 0x147 },
|
||||
{"ArrowUp", 0x148 },
|
||||
{"PageUp", 0x149 },
|
||||
{"ArrowLeft", 0x14b },
|
||||
{"ArrowRight", 0x14d },
|
||||
{"End", 0x14f },
|
||||
{"ArrowDown", 0x150 },
|
||||
{"PageDown", 0x151 },
|
||||
{"Insert", 0x152 },
|
||||
{"Delete", 0x153 },
|
||||
{"Pause", 0x21d },
|
||||
{"MetaLeft", 0x15b },
|
||||
{"MetaRight", 0x15c },
|
||||
{"ContextMenu", 0x15d },
|
||||
};
|
||||
|
||||
static EM_BOOL controller_emscripten_keyboard_handler(int event_type, const EmscriptenKeyboardEvent *key_event, UNUSED void *user_data) {
|
||||
for (size_t i = 0; i < sizeof(keymap_browser) / sizeof(keymap_browser[0]); i++) {
|
||||
if (strcmp(key_event->code, keymap_browser[i].code) == 0) {
|
||||
if (event_type == EMSCRIPTEN_EVENT_KEYDOWN) {
|
||||
return keyboard_on_key_down(keymap_browser[i].scancode);
|
||||
} else if (event_type == EMSCRIPTEN_EVENT_KEYUP) {
|
||||
return keyboard_on_key_up(keymap_browser[i].scancode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
static EM_BOOL controller_emscripten_keyboard_blur_handler(UNUSED int event_type, UNUSED const EmscriptenFocusEvent *focus_event, UNUSED void *user_data) {
|
||||
keyboard_on_all_keys_up();
|
||||
return EM_TRUE;
|
||||
}
|
||||
|
||||
void controller_emscripten_keyboard_init(void) {
|
||||
// Should be #window according to docs, but that crashes
|
||||
const char *target = EMSCRIPTEN_EVENT_TARGET_WINDOW;
|
||||
|
||||
emscripten_set_keydown_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_handler);
|
||||
emscripten_set_keyup_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_handler);
|
||||
emscripten_set_blur_callback(target, NULL, EM_FALSE, controller_emscripten_keyboard_blur_handler);
|
||||
}
|
||||
|
||||
#endif
|
8
src/pc/controller/controller_emscripten_keyboard.h
Normal file
8
src/pc/controller/controller_emscripten_keyboard.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef CONTROLLER_KEYBOARD_EMSCRIPTEN_H
|
||||
#define CONTROLLER_KEYBOARD_EMSCRIPTEN_H
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
void controller_emscripten_keyboard_init(void);
|
||||
#endif
|
||||
|
||||
#endif
|
36
src/pc/controller/controller_entry_point.c
Normal file
36
src/pc/controller/controller_entry_point.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "lib/src/libultra_internal.h"
|
||||
#include "lib/src/osContInternal.h"
|
||||
|
||||
#include "controller_recorded_tas.h"
|
||||
#include "controller_keyboard.h"
|
||||
|
||||
#include "controller_sdl.h"
|
||||
|
||||
static struct ControllerAPI *controller_implementations[] = {
|
||||
&controller_recorded_tas,
|
||||
&controller_sdl,
|
||||
&controller_keyboard,
|
||||
};
|
||||
|
||||
s32 osContInit(OSMesgQueue *mq, u8 *controllerBits, OSContStatus *status) {
|
||||
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||
controller_implementations[i]->init();
|
||||
}
|
||||
*controllerBits = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 osContStartReadData(OSMesgQueue *mesg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osContGetReadData(OSContPad *pad) {
|
||||
pad->button = 0;
|
||||
pad->stick_x = 0;
|
||||
pad->stick_y = 0;
|
||||
pad->errnum = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) {
|
||||
controller_implementations[i]->read(pad);
|
||||
}
|
||||
}
|
88
src/pc/controller/controller_keyboard.c
Normal file
88
src/pc/controller/controller_keyboard.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include <stdbool.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "controller_api.h"
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
#include "controller_emscripten_keyboard.h"
|
||||
#endif
|
||||
|
||||
#include "../configfile.h"
|
||||
|
||||
static int keyboard_buttons_down;
|
||||
|
||||
static int keyboard_mapping[13][2];
|
||||
|
||||
static int keyboard_map_scancode(int scancode) {
|
||||
int ret = 0;
|
||||
for (size_t i = 0; i < sizeof(keyboard_mapping) / sizeof(keyboard_mapping[0]); i++) {
|
||||
if (keyboard_mapping[i][0] == scancode) {
|
||||
ret |= keyboard_mapping[i][1];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool keyboard_on_key_down(int scancode) {
|
||||
int mapped = keyboard_map_scancode(scancode);
|
||||
keyboard_buttons_down |= mapped;
|
||||
return mapped != 0;
|
||||
}
|
||||
|
||||
bool keyboard_on_key_up(int scancode) {
|
||||
int mapped = keyboard_map_scancode(scancode);
|
||||
keyboard_buttons_down &= ~mapped;
|
||||
return mapped != 0;
|
||||
}
|
||||
|
||||
void keyboard_on_all_keys_up(void) {
|
||||
keyboard_buttons_down = 0;
|
||||
}
|
||||
|
||||
static void set_keyboard_mapping(int index, int mask, int scancode) {
|
||||
keyboard_mapping[index][0] = scancode;
|
||||
keyboard_mapping[index][1] = mask;
|
||||
}
|
||||
|
||||
static void keyboard_init(void) {
|
||||
int i = 0;
|
||||
|
||||
set_keyboard_mapping(i++, 0x80000, configKeyStickUp);
|
||||
set_keyboard_mapping(i++, 0x10000, configKeyStickLeft);
|
||||
set_keyboard_mapping(i++, 0x40000, configKeyStickDown);
|
||||
set_keyboard_mapping(i++, 0x20000, configKeyStickRight);
|
||||
set_keyboard_mapping(i++, A_BUTTON, configKeyA);
|
||||
set_keyboard_mapping(i++, B_BUTTON, configKeyB);
|
||||
set_keyboard_mapping(i++, Z_TRIG, configKeyZ);
|
||||
set_keyboard_mapping(i++, U_CBUTTONS, configKeyCUp);
|
||||
set_keyboard_mapping(i++, L_CBUTTONS, configKeyCLeft);
|
||||
set_keyboard_mapping(i++, D_CBUTTONS, configKeyCDown);
|
||||
set_keyboard_mapping(i++, R_CBUTTONS, configKeyCRight);
|
||||
set_keyboard_mapping(i++, R_TRIG, configKeyR);
|
||||
set_keyboard_mapping(i++, START_BUTTON, configKeyStart);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
controller_emscripten_keyboard_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void keyboard_read(OSContPad *pad) {
|
||||
pad->button |= keyboard_buttons_down;
|
||||
if ((keyboard_buttons_down & 0x30000) == 0x10000) {
|
||||
pad->stick_x = -128;
|
||||
}
|
||||
if ((keyboard_buttons_down & 0x30000) == 0x20000) {
|
||||
pad->stick_x = 127;
|
||||
}
|
||||
if ((keyboard_buttons_down & 0xc0000) == 0x40000) {
|
||||
pad->stick_y = -128;
|
||||
}
|
||||
if ((keyboard_buttons_down & 0xc0000) == 0x80000) {
|
||||
pad->stick_y = 127;
|
||||
}
|
||||
}
|
||||
|
||||
struct ControllerAPI controller_keyboard = {
|
||||
keyboard_init,
|
||||
keyboard_read
|
||||
};
|
19
src/pc/controller/controller_keyboard.h
Normal file
19
src/pc/controller/controller_keyboard.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef CONTROLLER_KEYBOARD_H
|
||||
#define CONTROLLER_KEYBOARD_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "controller_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
bool keyboard_on_key_down(int scancode);
|
||||
bool keyboard_on_key_up(int scancode);
|
||||
void keyboard_on_all_keys_up(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct ControllerAPI controller_keyboard;
|
||||
|
||||
#endif
|
29
src/pc/controller/controller_recorded_tas.c
Normal file
29
src/pc/controller/controller_recorded_tas.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <stdio.h>
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "controller_api.h"
|
||||
|
||||
static FILE *fp;
|
||||
|
||||
static void tas_init(void) {
|
||||
fp = fopen("cont.m64", "rb");
|
||||
if (fp != NULL) {
|
||||
uint8_t buf[0x400];
|
||||
fread(buf, 1, sizeof(buf), fp);
|
||||
}
|
||||
}
|
||||
|
||||
static void tas_read(OSContPad *pad) {
|
||||
if (fp != NULL) {
|
||||
uint8_t bytes[4] = {0};
|
||||
fread(bytes, 1, 4, fp);
|
||||
pad->button = (bytes[0] << 8) | bytes[1];
|
||||
pad->stick_x = bytes[2];
|
||||
pad->stick_y = bytes[3];
|
||||
}
|
||||
}
|
||||
|
||||
struct ControllerAPI controller_recorded_tas = {
|
||||
tas_init,
|
||||
tas_read
|
||||
};
|
8
src/pc/controller/controller_recorded_tas.h
Normal file
8
src/pc/controller/controller_recorded_tas.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef CONTROLLER_RECORDED_TAS_H
|
||||
#define CONTROLLER_RECORDED_TAS_H
|
||||
|
||||
#include "controller_api.h"
|
||||
|
||||
extern struct ControllerAPI controller_recorded_tas;
|
||||
|
||||
#endif
|
98
src/pc/controller/controller_sdl.c
Normal file
98
src/pc/controller/controller_sdl.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <ultra64.h>
|
||||
|
||||
#include "controller_api.h"
|
||||
|
||||
#define DEADZONE 4960
|
||||
|
||||
static bool init_ok;
|
||||
static SDL_GameController *sdl_cntrl;
|
||||
|
||||
static void controller_sdl_init(void) {
|
||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER) != 0) {
|
||||
fprintf(stderr, "SDL init error: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
static void controller_sdl_read(OSContPad *pad) {
|
||||
if (!init_ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
if (sdl_cntrl != NULL && !SDL_GameControllerGetAttached(sdl_cntrl)) {
|
||||
SDL_GameControllerClose(sdl_cntrl);
|
||||
sdl_cntrl = NULL;
|
||||
}
|
||||
if (sdl_cntrl == NULL) {
|
||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
sdl_cntrl = SDL_GameControllerOpen(i);
|
||||
if (sdl_cntrl != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sdl_cntrl == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_START)) pad->button |= START_BUTTON;
|
||||
if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) pad->button |= Z_TRIG;
|
||||
if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) pad->button |= R_TRIG;
|
||||
if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_A)) pad->button |= A_BUTTON;
|
||||
if (SDL_GameControllerGetButton(sdl_cntrl, SDL_CONTROLLER_BUTTON_X)) pad->button |= B_BUTTON;
|
||||
|
||||
int16_t leftx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTX);
|
||||
int16_t lefty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_LEFTY);
|
||||
int16_t rightx = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTX);
|
||||
int16_t righty = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_RIGHTY);
|
||||
|
||||
int16_t ltrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERLEFT);
|
||||
int16_t rtrig = SDL_GameControllerGetAxis(sdl_cntrl, SDL_CONTROLLER_AXIS_TRIGGERRIGHT);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
// Firefox has a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1606562
|
||||
// It sets down y to 32768.0f / 32767.0f, which is greater than the allowed 1.0f,
|
||||
// which SDL then converts to a int16_t by multiplying by 32767.0f, which overflows into -32768.
|
||||
// Maximum up will hence never become -32768 with the current version of SDL2,
|
||||
// so this workaround should be safe in compliant browsers.
|
||||
if (lefty == -32768) {
|
||||
lefty = 32767;
|
||||
}
|
||||
if (righty == -32768) {
|
||||
righty = 32767;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rightx < -0x4000) pad->button |= L_CBUTTONS;
|
||||
if (rightx > 0x4000) pad->button |= R_CBUTTONS;
|
||||
if (righty < -0x4000) pad->button |= U_CBUTTONS;
|
||||
if (righty > 0x4000) pad->button |= D_CBUTTONS;
|
||||
|
||||
if (ltrig > 30 * 256) pad->button |= Z_TRIG;
|
||||
if (rtrig > 30 * 256) pad->button |= R_TRIG;
|
||||
|
||||
uint32_t magnitude_sq = (uint32_t)(leftx * leftx) + (uint32_t)(lefty * lefty);
|
||||
if (magnitude_sq > (uint32_t)(DEADZONE * DEADZONE)) {
|
||||
pad->stick_x = leftx / 0x100;
|
||||
int stick_y = -lefty / 0x100;
|
||||
pad->stick_y = stick_y == 128 ? 127 : stick_y;
|
||||
}
|
||||
}
|
||||
|
||||
struct ControllerAPI controller_sdl = {
|
||||
controller_sdl_init,
|
||||
controller_sdl_read
|
||||
};
|
8
src/pc/controller/controller_sdl.h
Normal file
8
src/pc/controller/controller_sdl.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef CONTROLLER_SDL_H
|
||||
#define CONTROLLER_SDL_H
|
||||
|
||||
#include "controller_api.h"
|
||||
|
||||
extern struct ControllerAPI controller_sdl;
|
||||
|
||||
#endif
|
25
src/pc/gfx/gfx_cc.h
Normal file
25
src/pc/gfx/gfx_cc.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
enum {
|
||||
CC_0,
|
||||
CC_TEXEL0,
|
||||
CC_TEXEL1,
|
||||
CC_PRIM,
|
||||
CC_SHADE,
|
||||
CC_ENV,
|
||||
CC_TEXEL0A,
|
||||
CC_LOD
|
||||
};
|
||||
|
||||
enum {
|
||||
SHADER_0,
|
||||
SHADER_INPUT_1,
|
||||
SHADER_INPUT_2,
|
||||
SHADER_INPUT_3,
|
||||
SHADER_INPUT_4,
|
||||
SHADER_TEXEL0,
|
||||
SHADER_TEXEL0A,
|
||||
SHADER_TEXEL1
|
||||
};
|
||||
|
||||
#define SHADER_OPT_ALPHA (1 << 24)
|
||||
#define SHADER_OPT_FOG (1 << 25)
|
||||
#define SHADER_OPT_TEXTURE_EDGE (1 << 26)
|
503
src/pc/gfx/gfx_opengl.c
Normal file
503
src/pc/gfx/gfx_opengl.c
Normal file
|
@ -0,0 +1,503 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _LANGUAGE_C
|
||||
#define _LANGUAGE_C
|
||||
#endif
|
||||
#include <PR/gbi.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define FOR_WINDOWS 1
|
||||
#else
|
||||
#define FOR_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if FOR_WINDOWS
|
||||
#define GLEW_STATIC
|
||||
#include <GL/glew.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <SDL2/SDL_opengles2.h>
|
||||
#endif
|
||||
|
||||
#include "gfx_cc.h"
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
struct ShaderProgram {
|
||||
uint32_t shader_id;
|
||||
GLuint opengl_program_id;
|
||||
uint8_t num_inputs;
|
||||
bool used_textures[2];
|
||||
uint8_t num_floats;
|
||||
GLint attrib_locations[7];
|
||||
uint8_t attrib_sizes[7];
|
||||
uint8_t num_attribs;
|
||||
};
|
||||
|
||||
static struct ShaderProgram shader_program_pool[64];
|
||||
static uint8_t shader_program_pool_size;
|
||||
static GLuint opengl_vbo;
|
||||
|
||||
static bool gfx_opengl_z_is_from_0_to_1(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gfx_opengl_vertex_array_set_attribs(struct ShaderProgram *prg) {
|
||||
size_t num_floats = prg->num_floats;
|
||||
size_t pos = 0;
|
||||
|
||||
for (int i = 0; i < prg->num_attribs; i++) {
|
||||
glEnableVertexAttribArray(prg->attrib_locations[i]);
|
||||
glVertexAttribPointer(prg->attrib_locations[i], prg->attrib_sizes[i], GL_FLOAT, GL_FALSE, num_floats * sizeof(float), (void *)(pos * sizeof(float)));
|
||||
pos += prg->attrib_sizes[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_unload_shader(struct ShaderProgram *old_prg) {
|
||||
if (old_prg != NULL) {
|
||||
for (int i = 0; i < old_prg->num_attribs; i++) {
|
||||
glDisableVertexAttribArray(old_prg->attrib_locations[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) {
|
||||
glUseProgram(new_prg->opengl_program_id);
|
||||
gfx_opengl_vertex_array_set_attribs(new_prg);
|
||||
}
|
||||
|
||||
static void append_str(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
}
|
||||
|
||||
static void append_line(char *buf, size_t *len, const char *str) {
|
||||
while (*str != '\0') buf[(*len)++] = *str++;
|
||||
buf[(*len)++] = '\n';
|
||||
}
|
||||
|
||||
static const char *shader_item_to_str(uint32_t item, bool with_alpha, bool only_alpha, bool inputs_have_alpha, bool hint_single_element) {
|
||||
if (!only_alpha) {
|
||||
switch (item) {
|
||||
case SHADER_0:
|
||||
return with_alpha ? "vec4(0.0, 0.0, 0.0, 0.0)" : "vec3(0.0, 0.0, 0.0)";
|
||||
case SHADER_INPUT_1:
|
||||
return with_alpha || !inputs_have_alpha ? "vInput1" : "vInput1.rgb";
|
||||
case SHADER_INPUT_2:
|
||||
return with_alpha || !inputs_have_alpha ? "vInput2" : "vInput2.rgb";
|
||||
case SHADER_INPUT_3:
|
||||
return with_alpha || !inputs_have_alpha ? "vInput3" : "vInput3.rgb";
|
||||
case SHADER_INPUT_4:
|
||||
return with_alpha || !inputs_have_alpha ? "vInput4" : "vInput4.rgb";
|
||||
case SHADER_TEXEL0:
|
||||
return with_alpha ? "texVal0" : "texVal0.rgb";
|
||||
case SHADER_TEXEL0A:
|
||||
return hint_single_element ? "texVal0.a" :
|
||||
(with_alpha ? "vec4(texelVal0.a, texelVal0.a, texelVal0.a, texelVal0.a)" : "vec3(texelVal0.a, texelVal0.a, texelVal0.a)");
|
||||
case SHADER_TEXEL1:
|
||||
return with_alpha ? "texVal1" : "texVal1.rgb";
|
||||
}
|
||||
} else {
|
||||
switch (item) {
|
||||
case SHADER_0:
|
||||
return "0.0";
|
||||
case SHADER_INPUT_1:
|
||||
return "vInput1.a";
|
||||
case SHADER_INPUT_2:
|
||||
return "vInput2.a";
|
||||
case SHADER_INPUT_3:
|
||||
return "vInput3.a";
|
||||
case SHADER_INPUT_4:
|
||||
return "vInput4.a";
|
||||
case SHADER_TEXEL0:
|
||||
return "texVal0.a";
|
||||
case SHADER_TEXEL0A:
|
||||
return "texVal0.a";
|
||||
case SHADER_TEXEL1:
|
||||
return "texVal1.a";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void append_formula(char *buf, size_t *len, uint8_t c[2][4], bool do_single, bool do_multiply, bool do_mix, bool with_alpha, bool only_alpha, bool opt_alpha) {
|
||||
if (do_single) {
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false));
|
||||
} else if (do_multiply) {
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, " * ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
} else if (do_mix) {
|
||||
append_str(buf, len, "mix(");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ", ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ", ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
append_str(buf, len, ")");
|
||||
} else {
|
||||
append_str(buf, len, "(");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][0], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, " - ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][1], with_alpha, only_alpha, opt_alpha, false));
|
||||
append_str(buf, len, ") * ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][2], with_alpha, only_alpha, opt_alpha, true));
|
||||
append_str(buf, len, " + ");
|
||||
append_str(buf, len, shader_item_to_str(c[only_alpha][3], with_alpha, only_alpha, opt_alpha, false));
|
||||
}
|
||||
}
|
||||
|
||||
static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(uint32_t shader_id) {
|
||||
uint8_t c[2][4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
c[0][i] = (shader_id >> (i * 3)) & 7;
|
||||
c[1][i] = (shader_id >> (12 + i * 3)) & 7;
|
||||
}
|
||||
bool opt_alpha = (shader_id & SHADER_OPT_ALPHA) != 0;
|
||||
bool opt_fog = (shader_id & SHADER_OPT_FOG) != 0;
|
||||
bool opt_texture_edge = (shader_id & SHADER_OPT_TEXTURE_EDGE) != 0;
|
||||
bool used_textures[2] = {0, 0};
|
||||
int num_inputs = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (c[i][j] >= SHADER_INPUT_1 && c[i][j] <= SHADER_INPUT_4) {
|
||||
if (c[i][j] > num_inputs) {
|
||||
num_inputs = c[i][j];
|
||||
}
|
||||
}
|
||||
if (c[i][j] == SHADER_TEXEL0 || c[i][j] == SHADER_TEXEL0A) {
|
||||
used_textures[0] = true;
|
||||
}
|
||||
if (c[i][j] == SHADER_TEXEL1) {
|
||||
used_textures[1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool do_single[2] = {c[0][2] == 0, c[1][2] == 0};
|
||||
bool do_multiply[2] = {c[0][1] == 0 && c[0][3] == 0, c[1][1] == 0 && c[1][3] == 0};
|
||||
bool do_mix[2] = {c[0][1] == c[0][3], c[1][1] == c[1][3]};
|
||||
bool color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff);
|
||||
|
||||
char vs_buf[1024];
|
||||
char fs_buf[1024];
|
||||
size_t vs_len = 0;
|
||||
size_t fs_len = 0;
|
||||
size_t num_floats = 4;
|
||||
|
||||
// Vertex shader
|
||||
append_line(vs_buf, &vs_len, "#version 100");
|
||||
append_line(vs_buf, &vs_len, "attribute vec4 aVtxPos;");
|
||||
if (used_textures[0] || used_textures[1]) {
|
||||
append_line(vs_buf, &vs_len, "attribute vec2 aTexCoord;");
|
||||
append_line(vs_buf, &vs_len, "varying vec2 vTexCoord;");
|
||||
num_floats += 2;
|
||||
}
|
||||
if (opt_fog) {
|
||||
append_line(vs_buf, &vs_len, "attribute vec4 aFog;");
|
||||
append_line(vs_buf, &vs_len, "varying vec4 vFog;");
|
||||
num_floats += 4;
|
||||
}
|
||||
for (int i = 0; i < num_inputs; i++) {
|
||||
vs_len += sprintf(vs_buf + vs_len, "attribute vec%d aInput%d;\n", opt_alpha ? 4 : 3, i + 1);
|
||||
vs_len += sprintf(vs_buf + vs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1);
|
||||
num_floats += opt_alpha ? 4 : 3;
|
||||
}
|
||||
append_line(vs_buf, &vs_len, "void main() {");
|
||||
if (used_textures[0] || used_textures[1]) {
|
||||
append_line(vs_buf, &vs_len, "vTexCoord = aTexCoord;");
|
||||
}
|
||||
if (opt_fog) {
|
||||
append_line(vs_buf, &vs_len, "vFog = aFog;");
|
||||
}
|
||||
for (int i = 0; i < num_inputs; i++) {
|
||||
vs_len += sprintf(vs_buf + vs_len, "vInput%d = aInput%d;\n", i + 1, i + 1);
|
||||
}
|
||||
append_line(vs_buf, &vs_len, "gl_Position = aVtxPos;");
|
||||
append_line(vs_buf, &vs_len, "}");
|
||||
|
||||
// Fragment shader
|
||||
append_line(fs_buf, &fs_len, "#version 100");
|
||||
append_line(fs_buf, &fs_len, "precision mediump float;");
|
||||
if (used_textures[0] || used_textures[1]) {
|
||||
append_line(fs_buf, &fs_len, "varying vec2 vTexCoord;");
|
||||
}
|
||||
if (opt_fog) {
|
||||
append_line(fs_buf, &fs_len, "varying vec4 vFog;");
|
||||
}
|
||||
for (int i = 0; i < num_inputs; i++) {
|
||||
fs_len += sprintf(fs_buf + fs_len, "varying vec%d vInput%d;\n", opt_alpha ? 4 : 3, i + 1);
|
||||
}
|
||||
if (used_textures[0]) {
|
||||
append_line(fs_buf, &fs_len, "uniform sampler2D uTex0;");
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
append_line(fs_buf, &fs_len, "uniform sampler2D uTex1;");
|
||||
}
|
||||
append_line(fs_buf, &fs_len, "void main() {");
|
||||
|
||||
if (used_textures[0]) {
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal0 = texture2D(uTex0, vTexCoord);");
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
append_line(fs_buf, &fs_len, "vec4 texVal1 = texture2D(uTex1, vTexCoord);");
|
||||
}
|
||||
|
||||
append_str(fs_buf, &fs_len, opt_alpha ? "vec4 texel = " : "vec3 texel = ");
|
||||
if (!color_alpha_same && opt_alpha) {
|
||||
append_str(fs_buf, &fs_len, "vec4(");
|
||||
append_formula(fs_buf, &fs_len, c, do_single[0], do_multiply[0], do_mix[0], false, false, true);
|
||||
append_str(fs_buf, &fs_len, ", ");
|
||||
append_formula(fs_buf, &fs_len, c, do_single[1], do_multiply[1], do_mix[1], true, true, true);
|
||||
append_str(fs_buf, &fs_len, ")");
|
||||
} else {
|
||||
append_formula(fs_buf, &fs_len, c, do_single[0], do_multiply[0], do_mix[0], opt_alpha, false, opt_alpha);
|
||||
}
|
||||
append_line(fs_buf, &fs_len, ";");
|
||||
|
||||
if (opt_texture_edge && opt_alpha) {
|
||||
append_line(fs_buf, &fs_len, "if (texel.a > 0.3) texel.a = 1.0; else discard;");
|
||||
}
|
||||
// TODO discard if alpha is 0?
|
||||
if (opt_fog) {
|
||||
if (opt_alpha) {
|
||||
append_line(fs_buf, &fs_len, "texel = vec4(mix(texel.rgb, vFog.rgb, vFog.a), texel.a);");
|
||||
} else {
|
||||
append_line(fs_buf, &fs_len, "texel = mix(texel, vFog.rgb, vFog.a);");
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_alpha) {
|
||||
append_line(fs_buf, &fs_len, "gl_FragColor = texel;");
|
||||
} else {
|
||||
append_line(fs_buf, &fs_len, "gl_FragColor = vec4(texel, 1.0);");
|
||||
}
|
||||
append_line(fs_buf, &fs_len, "}");
|
||||
|
||||
vs_buf[vs_len] = '\0';
|
||||
fs_buf[fs_len] = '\0';
|
||||
|
||||
/*puts("Vertex shader:");
|
||||
puts(vs_buf);
|
||||
puts("Fragment shader:");
|
||||
puts(fs_buf);
|
||||
puts("End");*/
|
||||
|
||||
const GLchar *sources[2] = {vs_buf, fs_buf};
|
||||
const GLint lengths[2] = {vs_len, fs_len};
|
||||
GLint success;
|
||||
|
||||
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex_shader, 1, &sources[0], &lengths[0]);
|
||||
glCompileShader(vertex_shader);
|
||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
GLint max_length = 0;
|
||||
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &max_length);
|
||||
char error_log[1024];
|
||||
fprintf(stderr, "Vertex shader compilation failed\n");
|
||||
glGetShaderInfoLog(vertex_shader, max_length, &max_length, &error_log[0]);
|
||||
fprintf(stderr, "%s\n", &error_log[0]);
|
||||
abort();
|
||||
}
|
||||
|
||||
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader, 1, &sources[1], &lengths[1]);
|
||||
glCompileShader(fragment_shader);
|
||||
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
GLint max_length = 0;
|
||||
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &max_length);
|
||||
char error_log[1024];
|
||||
fprintf(stderr, "Fragment shader compilation failed\n");
|
||||
glGetShaderInfoLog(fragment_shader, max_length, &max_length, &error_log[0]);
|
||||
fprintf(stderr, "%s\n", &error_log[0]);
|
||||
abort();
|
||||
}
|
||||
|
||||
GLuint shader_program = glCreateProgram();
|
||||
glAttachShader(shader_program, vertex_shader);
|
||||
glAttachShader(shader_program, fragment_shader);
|
||||
glLinkProgram(shader_program);
|
||||
|
||||
size_t cnt = 0;
|
||||
|
||||
struct ShaderProgram *prg = &shader_program_pool[shader_program_pool_size++];
|
||||
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aVtxPos");
|
||||
prg->attrib_sizes[cnt] = 4;
|
||||
++cnt;
|
||||
|
||||
if (used_textures[0] || used_textures[1]) {
|
||||
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aTexCoord");
|
||||
prg->attrib_sizes[cnt] = 2;
|
||||
++cnt;
|
||||
}
|
||||
|
||||
if (opt_fog) {
|
||||
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, "aFog");
|
||||
prg->attrib_sizes[cnt] = 4;
|
||||
++cnt;
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_inputs; i++) {
|
||||
char name[16];
|
||||
sprintf(name, "aInput%d", i + 1);
|
||||
prg->attrib_locations[cnt] = glGetAttribLocation(shader_program, name);
|
||||
prg->attrib_sizes[cnt] = opt_alpha ? 4 : 3;
|
||||
++cnt;
|
||||
}
|
||||
|
||||
prg->shader_id = shader_id;
|
||||
prg->opengl_program_id = shader_program;
|
||||
prg->num_inputs = num_inputs;
|
||||
prg->used_textures[0] = used_textures[0];
|
||||
prg->used_textures[1] = used_textures[1];
|
||||
prg->num_floats = num_floats;
|
||||
prg->num_attribs = cnt;
|
||||
|
||||
gfx_opengl_load_shader(prg);
|
||||
|
||||
if (used_textures[0]) {
|
||||
GLint sampler_attrib = glGetUniformLocation(shader_program, "uTex0");
|
||||
glUniform1i(sampler_attrib, 0);
|
||||
}
|
||||
if (used_textures[1]) {
|
||||
GLint sampler_attrib = glGetUniformLocation(shader_program, "uTex1");
|
||||
glUniform1i(sampler_attrib, 1);
|
||||
}
|
||||
|
||||
return prg;
|
||||
}
|
||||
|
||||
static struct ShaderProgram *gfx_opengl_lookup_shader(uint32_t shader_id) {
|
||||
for (size_t i = 0; i < shader_program_pool_size; i++) {
|
||||
if (shader_program_pool[i].shader_id == shader_id) {
|
||||
return &shader_program_pool[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void gfx_opengl_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
|
||||
*num_inputs = prg->num_inputs;
|
||||
used_textures[0] = prg->used_textures[0];
|
||||
used_textures[1] = prg->used_textures[1];
|
||||
}
|
||||
|
||||
static GLuint gfx_opengl_new_texture(void) {
|
||||
GLuint ret;
|
||||
glGenTextures(1, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void gfx_opengl_select_texture(int tile, GLuint texture_id) {
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
}
|
||||
|
||||
static void gfx_opengl_upload_texture(uint8_t *rgba32_buf, int width, int height) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba32_buf);
|
||||
}
|
||||
|
||||
static uint32_t gfx_cm_to_opengl(uint32_t val) {
|
||||
if (val & G_TX_CLAMP) {
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
return (val & G_TX_MIRROR) ? GL_MIRRORED_REPEAT : GL_REPEAT;
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
||||
glActiveTexture(GL_TEXTURE0 + tile);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_depth_test(bool depth_test) {
|
||||
if (depth_test) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_depth_mask(bool z_upd) {
|
||||
glDepthMask(z_upd ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_zmode_decal(bool zmode_decal) {
|
||||
if (zmode_decal) {
|
||||
glPolygonOffset(-2, -2);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
} else {
|
||||
glPolygonOffset(0, 0);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_viewport(int x, int y, int width, int height) {
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_scissor(int x, int y, int width, int height) {
|
||||
glScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
static void gfx_opengl_set_use_alpha(bool use_alpha) {
|
||||
if (use_alpha) {
|
||||
glEnable(GL_BLEND);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_opengl_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
||||
//printf("flushing %d tris\n", buf_vbo_num_tris);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * buf_vbo_len, buf_vbo, GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3 * buf_vbo_num_tris);
|
||||
}
|
||||
|
||||
static void gfx_opengl_init(void) {
|
||||
#if FOR_WINDOWS
|
||||
glewInit();
|
||||
#endif
|
||||
|
||||
glGenBuffers(1, &opengl_vbo);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, opengl_vbo);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
static void gfx_opengl_start_frame(void) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDepthMask(GL_TRUE); // Must be set to clear Z-buffer
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
struct GfxRenderingAPI gfx_opengl_api = {
|
||||
gfx_opengl_z_is_from_0_to_1,
|
||||
gfx_opengl_unload_shader,
|
||||
gfx_opengl_load_shader,
|
||||
gfx_opengl_create_and_load_new_shader,
|
||||
gfx_opengl_lookup_shader,
|
||||
gfx_opengl_shader_get_info,
|
||||
gfx_opengl_new_texture,
|
||||
gfx_opengl_select_texture,
|
||||
gfx_opengl_upload_texture,
|
||||
gfx_opengl_set_sampler_parameters,
|
||||
gfx_opengl_set_depth_test,
|
||||
gfx_opengl_set_depth_mask,
|
||||
gfx_opengl_set_zmode_decal,
|
||||
gfx_opengl_set_viewport,
|
||||
gfx_opengl_set_scissor,
|
||||
gfx_opengl_set_use_alpha,
|
||||
gfx_opengl_draw_triangles,
|
||||
gfx_opengl_init,
|
||||
gfx_opengl_start_frame
|
||||
};
|
8
src/pc/gfx/gfx_opengl.h
Normal file
8
src/pc/gfx/gfx_opengl.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef GFX_OPENGL_H
|
||||
#define GFX_OPENGL_H
|
||||
|
||||
#include "gfx_rendering_api.h"
|
||||
|
||||
extern struct GfxRenderingAPI gfx_opengl_api;
|
||||
|
||||
#endif
|
1547
src/pc/gfx/gfx_pc.c
Normal file
1547
src/pc/gfx/gfx_pc.c
Normal file
File diff suppressed because it is too large
Load diff
19
src/pc/gfx/gfx_pc.h
Normal file
19
src/pc/gfx/gfx_pc.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef GFX_PC_H
|
||||
#define GFX_PC_H
|
||||
|
||||
struct GfxRenderingAPI;
|
||||
struct GfxWindowManagerAPI;
|
||||
|
||||
struct GfxDimensions {
|
||||
uint32_t width, height;
|
||||
float aspect_ratio;
|
||||
};
|
||||
|
||||
extern struct GfxDimensions gfx_current_dimensions;
|
||||
|
||||
void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi);
|
||||
void gfx_start_frame(void);
|
||||
void gfx_run(Gfx *commands);
|
||||
void gfx_end_frame(void);
|
||||
|
||||
#endif
|
32
src/pc/gfx/gfx_rendering_api.h
Normal file
32
src/pc/gfx/gfx_rendering_api.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef GFX_RENDERING_API_H
|
||||
#define GFX_RENDERING_API_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct ShaderProgram;
|
||||
|
||||
struct GfxRenderingAPI {
|
||||
bool (*z_is_from_0_to_1)(void);
|
||||
void (*unload_shader)(struct ShaderProgram *old_prg);
|
||||
void (*load_shader)(struct ShaderProgram *new_prg);
|
||||
struct ShaderProgram *(*create_and_load_new_shader)(uint32_t shader_id);
|
||||
struct ShaderProgram *(*lookup_shader)(uint32_t shader_id);
|
||||
void (*shader_get_info)(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]);
|
||||
uint32_t (*new_texture)(void);
|
||||
void (*select_texture)(int tile, uint32_t texture_id);
|
||||
void (*upload_texture)(uint8_t *rgba32_buf, int width, int height);
|
||||
void (*set_sampler_parameters)(int sampler, bool linear_filter, uint32_t cms, uint32_t cmt);
|
||||
void (*set_depth_test)(bool depth_test);
|
||||
void (*set_depth_mask)(bool z_upd);
|
||||
void (*set_zmode_decal)(bool zmode_decal);
|
||||
void (*set_viewport)(int x, int y, int width, int height);
|
||||
void (*set_scissor)(int x, int y, int width, int height);
|
||||
void (*set_use_alpha)(bool use_alpha);
|
||||
void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris);
|
||||
void (*init)(void);
|
||||
void (*start_frame)(void);
|
||||
};
|
||||
|
||||
#endif
|
7
src/pc/gfx/gfx_screen_config.h
Normal file
7
src/pc/gfx/gfx_screen_config.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef GFX_SCREEN_CONFIG_H
|
||||
#define GFX_SCREEN_CONFIG_H
|
||||
|
||||
#define DESIRED_SCREEN_WIDTH 640
|
||||
#define DESIRED_SCREEN_HEIGHT 480
|
||||
|
||||
#endif
|
8
src/pc/gfx/gfx_sdl.h
Normal file
8
src/pc/gfx/gfx_sdl.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef GFX_SDL_H
|
||||
#define GFX_SDL_H
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
|
||||
extern struct GfxWindowManagerAPI gfx_sdl;
|
||||
|
||||
#endif
|
183
src/pc/gfx/gfx_sdl2.c
Normal file
183
src/pc/gfx/gfx_sdl2.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
#ifdef __MINGW32__
|
||||
#define FOR_WINDOWS 1
|
||||
#else
|
||||
#define FOR_WINDOWS 0
|
||||
#endif
|
||||
|
||||
#if FOR_WINDOWS
|
||||
#define GLEW_STATIC
|
||||
#include <GL/glew.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#else
|
||||
#include <SDL2/SDL.h>
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#include <SDL2/SDL_opengles2.h>
|
||||
#endif
|
||||
|
||||
#include "gfx_window_manager_api.h"
|
||||
#include "gfx_screen_config.h"
|
||||
|
||||
#include "src/pc/controller/controller_keyboard.h"
|
||||
|
||||
static SDL_Window *wnd;
|
||||
static int inverted_scancode_table[512];
|
||||
|
||||
const SDL_Scancode windows_scancode_table[] =
|
||||
{
|
||||
/* 0 1 2 3 4 5 6 7 */
|
||||
/* 8 9 A B C D E F */
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */
|
||||
SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */
|
||||
|
||||
SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */
|
||||
SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */
|
||||
|
||||
SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */
|
||||
SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */
|
||||
|
||||
SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, SDL_SCANCODE_PRINTSCREEN,/* 3 */
|
||||
SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */
|
||||
|
||||
SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_HOME, /* 4 */
|
||||
SDL_SCANCODE_UP, SDL_SCANCODE_PAGEUP, SDL_SCANCODE_KP_MINUS, SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_5, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_END, /* 4 */
|
||||
|
||||
SDL_SCANCODE_DOWN, SDL_SCANCODE_PAGEDOWN, SDL_SCANCODE_INSERT, SDL_SCANCODE_DELETE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11, /* 5 */
|
||||
SDL_SCANCODE_F12, SDL_SCANCODE_PAUSE, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 5 */
|
||||
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_F13, SDL_SCANCODE_F14, SDL_SCANCODE_F15, SDL_SCANCODE_F16, /* 6 */
|
||||
SDL_SCANCODE_F17, SDL_SCANCODE_F18, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 6 */
|
||||
|
||||
SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */
|
||||
SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */
|
||||
};
|
||||
|
||||
const SDL_Scancode scancode_rmapping_extended[][2] = {
|
||||
{SDL_SCANCODE_KP_ENTER, SDL_SCANCODE_RETURN},
|
||||
{SDL_SCANCODE_RALT, SDL_SCANCODE_LALT},
|
||||
{SDL_SCANCODE_RCTRL, SDL_SCANCODE_LCTRL},
|
||||
{SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_SLASH},
|
||||
//{SDL_SCANCODE_KP_PLUS, SDL_SCANCODE_CAPSLOCK}
|
||||
};
|
||||
|
||||
const SDL_Scancode scancode_rmapping_nonextended[][2] = {
|
||||
{SDL_SCANCODE_KP_7, SDL_SCANCODE_HOME},
|
||||
{SDL_SCANCODE_KP_8, SDL_SCANCODE_UP},
|
||||
{SDL_SCANCODE_KP_9, SDL_SCANCODE_PAGEUP},
|
||||
{SDL_SCANCODE_KP_4, SDL_SCANCODE_LEFT},
|
||||
{SDL_SCANCODE_KP_6, SDL_SCANCODE_RIGHT},
|
||||
{SDL_SCANCODE_KP_1, SDL_SCANCODE_END},
|
||||
{SDL_SCANCODE_KP_2, SDL_SCANCODE_DOWN},
|
||||
{SDL_SCANCODE_KP_3, SDL_SCANCODE_PAGEDOWN},
|
||||
{SDL_SCANCODE_KP_0, SDL_SCANCODE_INSERT},
|
||||
{SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_DELETE},
|
||||
{SDL_SCANCODE_KP_MULTIPLY, SDL_SCANCODE_PRINTSCREEN}
|
||||
};
|
||||
|
||||
static void gfx_sdl_init(void) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
//SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||
|
||||
wnd = SDL_CreateWindow("Super Mario 64 PC-Port", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
DESIRED_SCREEN_WIDTH, DESIRED_SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
|
||||
SDL_GL_CreateContext(wnd);
|
||||
SDL_GL_SetSwapInterval(2); // TODO 0, 1 or 2 or remove this line
|
||||
|
||||
for (size_t i = 0; i < sizeof(windows_scancode_table) / sizeof(SDL_Scancode); i++) {
|
||||
inverted_scancode_table[windows_scancode_table[i]] = i;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(scancode_rmapping_extended) / sizeof(scancode_rmapping_extended[0]); i++) {
|
||||
inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]] + 0x100;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(scancode_rmapping_nonextended) / sizeof(scancode_rmapping_nonextended[0]); i++) {
|
||||
inverted_scancode_table[scancode_rmapping_extended[i][0]] = inverted_scancode_table[scancode_rmapping_extended[i][1]];
|
||||
inverted_scancode_table[scancode_rmapping_extended[i][1]] += 0x100;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
|
||||
int t;
|
||||
while (1) {
|
||||
t = SDL_GetTicks();
|
||||
run_one_game_iter();
|
||||
t = SDL_GetTicks() - t;
|
||||
|
||||
if (t < 1000 / 30) {
|
||||
SDL_Delay ((1000 / 30) - t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
|
||||
SDL_GetWindowSize(wnd, width, height);
|
||||
}
|
||||
|
||||
static int translate_scancode(int scancode) {
|
||||
if (scancode < 512) {
|
||||
return inverted_scancode_table[scancode];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_sdl_onkeydown(int scancode) {
|
||||
keyboard_on_key_down(translate_scancode(scancode));
|
||||
}
|
||||
|
||||
static void gfx_sdl_onkeyup(int scancode) {
|
||||
keyboard_on_key_up(translate_scancode(scancode));
|
||||
}
|
||||
|
||||
static void gfx_sdl_handle_events(void) {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
#ifndef TARGET_WEB
|
||||
// Scancodes are broken in Emscripten SDL2: https://bugzilla.libsdl.org/show_bug.cgi?id=3259
|
||||
case SDL_KEYDOWN:
|
||||
gfx_sdl_onkeydown(event.key.keysym.scancode);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
gfx_sdl_onkeyup(event.key.keysym.scancode);
|
||||
break;
|
||||
#endif
|
||||
case SDL_QUIT:
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_sdl_start_frame(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gfx_sdl_swap_buffers_begin(void) {
|
||||
SDL_GL_SwapWindow(wnd);
|
||||
}
|
||||
|
||||
static void gfx_sdl_swap_buffers_end(void) {
|
||||
}
|
||||
|
||||
static double gfx_sdl_get_time(void) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
struct GfxWindowManagerAPI gfx_sdl = {
|
||||
gfx_sdl_init,
|
||||
gfx_sdl_main_loop,
|
||||
gfx_sdl_get_dimensions,
|
||||
gfx_sdl_handle_events,
|
||||
gfx_sdl_start_frame,
|
||||
gfx_sdl_swap_buffers_begin,
|
||||
gfx_sdl_swap_buffers_end,
|
||||
gfx_sdl_get_time
|
||||
};
|
18
src/pc/gfx/gfx_window_manager_api.h
Normal file
18
src/pc/gfx/gfx_window_manager_api.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef GFX_WINDOW_MANAGER_API_H
|
||||
#define GFX_WINDOW_MANAGER_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct GfxWindowManagerAPI {
|
||||
void (*init)(void);
|
||||
void (*main_loop)(void (*run_one_game_iter)(void));
|
||||
void (*get_dimensions)(uint32_t *width, uint32_t *height);
|
||||
void (*handle_events)(void);
|
||||
bool (*start_frame)(void);
|
||||
void (*swap_buffers_begin)(void);
|
||||
void (*swap_buffers_end)(void);
|
||||
double (*get_time)(void); // For debug
|
||||
};
|
||||
|
||||
#endif
|
490
src/pc/mixer.c
Normal file
490
src/pc/mixer.c
Normal file
|
@ -0,0 +1,490 @@
|
|||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Note: Some of this is stolen from Mupen64Plus rsp audio plugin.
|
||||
// See abi.h for documentation.
|
||||
|
||||
#define DMEM_BASE 0x5c0
|
||||
|
||||
#define A_INIT 0x01
|
||||
#define A_CONTINUE 0x00
|
||||
#define A_LOOP 0x02
|
||||
#define A_OUT 0x02
|
||||
#define A_LEFT 0x02
|
||||
#define A_RIGHT 0x00
|
||||
#define A_VOL 0x04
|
||||
#define A_RATE 0x00
|
||||
#define A_AUX 0x08
|
||||
#define A_NOAUX 0x00
|
||||
#define A_MAIN 0x00
|
||||
#define A_MIX 0x10
|
||||
|
||||
struct alist_audio_t {
|
||||
/* main buffers */
|
||||
uint16_t in;
|
||||
uint16_t out;
|
||||
uint16_t count;
|
||||
|
||||
/* auxiliary buffers */
|
||||
uint16_t dry_right;
|
||||
uint16_t wet_left;
|
||||
uint16_t wet_right;
|
||||
|
||||
/* gains */
|
||||
int16_t dry;
|
||||
int16_t wet;
|
||||
|
||||
/* envelopes (0:left, 1:right) */
|
||||
int16_t vol[2];
|
||||
int16_t target[2];
|
||||
int32_t rate[2];
|
||||
|
||||
/* ADPCM loop point address */
|
||||
uint16_t *loop;
|
||||
|
||||
/* storage for ADPCM table and polef coefficients */
|
||||
int16_t table[16 * 8];
|
||||
};
|
||||
|
||||
struct ramp_t
|
||||
{
|
||||
int64_t value;
|
||||
int64_t step;
|
||||
int64_t target;
|
||||
};
|
||||
|
||||
struct env_mix_save_buffer_t {
|
||||
int16_t wet, pad0, dry, pad1;
|
||||
uint32_t ramp_targets[2];
|
||||
uint32_t exp_rates[2];
|
||||
uint32_t exp_seq[2];
|
||||
uint32_t ramp_values[2];
|
||||
};
|
||||
|
||||
static const int16_t RESAMPLE_LUT[64 * 4] = {
|
||||
(int16_t)0x0c39, (int16_t)0x66ad, (int16_t)0x0d46, (int16_t)0xffdf,
|
||||
(int16_t)0x0b39, (int16_t)0x6696, (int16_t)0x0e5f, (int16_t)0xffd8,
|
||||
(int16_t)0x0a44, (int16_t)0x6669, (int16_t)0x0f83, (int16_t)0xffd0,
|
||||
(int16_t)0x095a, (int16_t)0x6626, (int16_t)0x10b4, (int16_t)0xffc8,
|
||||
(int16_t)0x087d, (int16_t)0x65cd, (int16_t)0x11f0, (int16_t)0xffbf,
|
||||
(int16_t)0x07ab, (int16_t)0x655e, (int16_t)0x1338, (int16_t)0xffb6,
|
||||
(int16_t)0x06e4, (int16_t)0x64d9, (int16_t)0x148c, (int16_t)0xffac,
|
||||
(int16_t)0x0628, (int16_t)0x643f, (int16_t)0x15eb, (int16_t)0xffa1,
|
||||
(int16_t)0x0577, (int16_t)0x638f, (int16_t)0x1756, (int16_t)0xff96,
|
||||
(int16_t)0x04d1, (int16_t)0x62cb, (int16_t)0x18cb, (int16_t)0xff8a,
|
||||
(int16_t)0x0435, (int16_t)0x61f3, (int16_t)0x1a4c, (int16_t)0xff7e,
|
||||
(int16_t)0x03a4, (int16_t)0x6106, (int16_t)0x1bd7, (int16_t)0xff71,
|
||||
(int16_t)0x031c, (int16_t)0x6007, (int16_t)0x1d6c, (int16_t)0xff64,
|
||||
(int16_t)0x029f, (int16_t)0x5ef5, (int16_t)0x1f0b, (int16_t)0xff56,
|
||||
(int16_t)0x022a, (int16_t)0x5dd0, (int16_t)0x20b3, (int16_t)0xff48,
|
||||
(int16_t)0x01be, (int16_t)0x5c9a, (int16_t)0x2264, (int16_t)0xff3a,
|
||||
(int16_t)0x015b, (int16_t)0x5b53, (int16_t)0x241e, (int16_t)0xff2c,
|
||||
(int16_t)0x0101, (int16_t)0x59fc, (int16_t)0x25e0, (int16_t)0xff1e,
|
||||
(int16_t)0x00ae, (int16_t)0x5896, (int16_t)0x27a9, (int16_t)0xff10,
|
||||
(int16_t)0x0063, (int16_t)0x5720, (int16_t)0x297a, (int16_t)0xff02,
|
||||
(int16_t)0x001f, (int16_t)0x559d, (int16_t)0x2b50, (int16_t)0xfef4,
|
||||
(int16_t)0xffe2, (int16_t)0x540d, (int16_t)0x2d2c, (int16_t)0xfee8,
|
||||
(int16_t)0xffac, (int16_t)0x5270, (int16_t)0x2f0d, (int16_t)0xfedb,
|
||||
(int16_t)0xff7c, (int16_t)0x50c7, (int16_t)0x30f3, (int16_t)0xfed0,
|
||||
(int16_t)0xff53, (int16_t)0x4f14, (int16_t)0x32dc, (int16_t)0xfec6,
|
||||
(int16_t)0xff2e, (int16_t)0x4d57, (int16_t)0x34c8, (int16_t)0xfebd,
|
||||
(int16_t)0xff0f, (int16_t)0x4b91, (int16_t)0x36b6, (int16_t)0xfeb6,
|
||||
(int16_t)0xfef5, (int16_t)0x49c2, (int16_t)0x38a5, (int16_t)0xfeb0,
|
||||
(int16_t)0xfedf, (int16_t)0x47ed, (int16_t)0x3a95, (int16_t)0xfeac,
|
||||
(int16_t)0xfece, (int16_t)0x4611, (int16_t)0x3c85, (int16_t)0xfeab,
|
||||
(int16_t)0xfec0, (int16_t)0x4430, (int16_t)0x3e74, (int16_t)0xfeac,
|
||||
(int16_t)0xfeb6, (int16_t)0x424a, (int16_t)0x4060, (int16_t)0xfeaf,
|
||||
(int16_t)0xfeaf, (int16_t)0x4060, (int16_t)0x424a, (int16_t)0xfeb6,
|
||||
(int16_t)0xfeac, (int16_t)0x3e74, (int16_t)0x4430, (int16_t)0xfec0,
|
||||
(int16_t)0xfeab, (int16_t)0x3c85, (int16_t)0x4611, (int16_t)0xfece,
|
||||
(int16_t)0xfeac, (int16_t)0x3a95, (int16_t)0x47ed, (int16_t)0xfedf,
|
||||
(int16_t)0xfeb0, (int16_t)0x38a5, (int16_t)0x49c2, (int16_t)0xfef5,
|
||||
(int16_t)0xfeb6, (int16_t)0x36b6, (int16_t)0x4b91, (int16_t)0xff0f,
|
||||
(int16_t)0xfebd, (int16_t)0x34c8, (int16_t)0x4d57, (int16_t)0xff2e,
|
||||
(int16_t)0xfec6, (int16_t)0x32dc, (int16_t)0x4f14, (int16_t)0xff53,
|
||||
(int16_t)0xfed0, (int16_t)0x30f3, (int16_t)0x50c7, (int16_t)0xff7c,
|
||||
(int16_t)0xfedb, (int16_t)0x2f0d, (int16_t)0x5270, (int16_t)0xffac,
|
||||
(int16_t)0xfee8, (int16_t)0x2d2c, (int16_t)0x540d, (int16_t)0xffe2,
|
||||
(int16_t)0xfef4, (int16_t)0x2b50, (int16_t)0x559d, (int16_t)0x001f,
|
||||
(int16_t)0xff02, (int16_t)0x297a, (int16_t)0x5720, (int16_t)0x0063,
|
||||
(int16_t)0xff10, (int16_t)0x27a9, (int16_t)0x5896, (int16_t)0x00ae,
|
||||
(int16_t)0xff1e, (int16_t)0x25e0, (int16_t)0x59fc, (int16_t)0x0101,
|
||||
(int16_t)0xff2c, (int16_t)0x241e, (int16_t)0x5b53, (int16_t)0x015b,
|
||||
(int16_t)0xff3a, (int16_t)0x2264, (int16_t)0x5c9a, (int16_t)0x01be,
|
||||
(int16_t)0xff48, (int16_t)0x20b3, (int16_t)0x5dd0, (int16_t)0x022a,
|
||||
(int16_t)0xff56, (int16_t)0x1f0b, (int16_t)0x5ef5, (int16_t)0x029f,
|
||||
(int16_t)0xff64, (int16_t)0x1d6c, (int16_t)0x6007, (int16_t)0x031c,
|
||||
(int16_t)0xff71, (int16_t)0x1bd7, (int16_t)0x6106, (int16_t)0x03a4,
|
||||
(int16_t)0xff7e, (int16_t)0x1a4c, (int16_t)0x61f3, (int16_t)0x0435,
|
||||
(int16_t)0xff8a, (int16_t)0x18cb, (int16_t)0x62cb, (int16_t)0x04d1,
|
||||
(int16_t)0xff96, (int16_t)0x1756, (int16_t)0x638f, (int16_t)0x0577,
|
||||
(int16_t)0xffa1, (int16_t)0x15eb, (int16_t)0x643f, (int16_t)0x0628,
|
||||
(int16_t)0xffac, (int16_t)0x148c, (int16_t)0x64d9, (int16_t)0x06e4,
|
||||
(int16_t)0xffb6, (int16_t)0x1338, (int16_t)0x655e, (int16_t)0x07ab,
|
||||
(int16_t)0xffbf, (int16_t)0x11f0, (int16_t)0x65cd, (int16_t)0x087d,
|
||||
(int16_t)0xffc8, (int16_t)0x10b4, (int16_t)0x6626, (int16_t)0x095a,
|
||||
(int16_t)0xffd0, (int16_t)0x0f83, (int16_t)0x6669, (int16_t)0x0a44,
|
||||
(int16_t)0xffd8, (int16_t)0x0e5f, (int16_t)0x6696, (int16_t)0x0b39,
|
||||
(int16_t)0xffdf, (int16_t)0x0d46, (int16_t)0x66ad, (int16_t)0x0c39
|
||||
};
|
||||
|
||||
static uint8_t alist_buffer[0x1000];
|
||||
static struct alist_audio_t alist_audio;
|
||||
|
||||
static inline size_t align(size_t x, size_t amount) {
|
||||
--amount;
|
||||
return (x + amount) & ~amount;
|
||||
}
|
||||
|
||||
static inline int16_t clamp_s16(int32_t v) {
|
||||
return v < -32768 ? -32768 : v > 32767 ? 32767 : v;
|
||||
}
|
||||
|
||||
static inline int16_t sample_mix(int16_t dst, int16_t src, int16_t gain) {
|
||||
int32_t src_modified = (src * gain) >> 15;
|
||||
return clamp_s16(dst + src_modified);
|
||||
}
|
||||
|
||||
void aClearBuffer(uint64_t *cmd, uint16_t dmem, uint16_t count) {
|
||||
dmem += DMEM_BASE;
|
||||
//assert(align(count, 16) == count);
|
||||
count = align(count, 16);
|
||||
memset(alist_buffer + dmem, 0, count);
|
||||
}
|
||||
|
||||
void aSetBuffer(uint64_t *cmd, uint8_t flags, uint16_t dmemin, uint16_t dmemout, uint16_t count) {
|
||||
if (flags & A_AUX) {
|
||||
// Parameter names are not really correct for A_AUX
|
||||
alist_audio.dry_right = dmemin + DMEM_BASE;
|
||||
alist_audio.wet_left = dmemout + DMEM_BASE;
|
||||
alist_audio.wet_right = count + DMEM_BASE;
|
||||
} else {
|
||||
alist_audio.in = dmemin + DMEM_BASE;
|
||||
alist_audio.out = dmemout + DMEM_BASE;
|
||||
alist_audio.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
void aLoadBuffer(uint64_t *cmd, uint16_t *addr) {
|
||||
// addr &= ~7
|
||||
memcpy(alist_buffer + alist_audio.in, addr, alist_audio.count);
|
||||
}
|
||||
|
||||
void aSaveBuffer(uint64_t *cmd, uint16_t *addr) {
|
||||
memcpy(addr, alist_buffer + alist_audio.out, alist_audio.count);
|
||||
}
|
||||
|
||||
void aDMEMMove(uint64_t *cmd, uint16_t dmemin, uint16_t dmemout, uint16_t count) {
|
||||
dmemin += DMEM_BASE;
|
||||
dmemout += DMEM_BASE;
|
||||
//assert(align(count, 16) == count);
|
||||
count = align(count, 16); // Microcode does this
|
||||
memmove(alist_buffer + dmemout, alist_buffer + dmemin, count);
|
||||
}
|
||||
|
||||
void aMix(uint64_t *cmd, uint8_t flags, uint16_t gain, uint16_t dmemin, uint16_t dmemout) {
|
||||
dmemin += DMEM_BASE;
|
||||
dmemout += DMEM_BASE;
|
||||
|
||||
// originally count is rounded up to nearest 32 bytes
|
||||
|
||||
int16_t *dst = (int16_t*)(alist_buffer + dmemout);
|
||||
const int16_t *src = (const int16_t*)(alist_buffer + dmemin);
|
||||
size_t count = alist_audio.count >> 1;
|
||||
count = align(count, 16);
|
||||
|
||||
while (count != 0) {
|
||||
*dst = sample_mix(*dst, *src, gain);
|
||||
++dst;
|
||||
++src;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int16_t ramp_step(struct ramp_t* ramp) {
|
||||
int target_reached;
|
||||
|
||||
ramp->value += ramp->step;
|
||||
|
||||
target_reached = (ramp->step <= 0)
|
||||
? (ramp->value <= ramp->target)
|
||||
: (ramp->value >= ramp->target);
|
||||
|
||||
if (target_reached)
|
||||
{
|
||||
ramp->value = ramp->target;
|
||||
ramp->step = 0;
|
||||
}
|
||||
|
||||
return (int16_t)(ramp->value >> 16);
|
||||
}
|
||||
|
||||
void aEnvMixer(uint64_t *cmd, uint8_t flags, uint16_t *addr) {
|
||||
size_t n = (flags & A_AUX) ? 4 : 2;
|
||||
|
||||
const int16_t *const in = (int16_t*)(alist_buffer + alist_audio.in);
|
||||
int16_t *const dl = (int16_t*)(alist_buffer + alist_audio.out);
|
||||
int16_t *const dr = (int16_t*)(alist_buffer + alist_audio.dry_right);
|
||||
int16_t *const wl = (int16_t*)(alist_buffer + alist_audio.wet_left);
|
||||
int16_t *const wr = (int16_t*)(alist_buffer + alist_audio.wet_right);
|
||||
|
||||
struct ramp_t ramps[2];
|
||||
int32_t exp_seq[2];
|
||||
int32_t exp_rates[2];
|
||||
int16_t dry;
|
||||
int16_t wet;
|
||||
|
||||
uint32_t ptr = 0;
|
||||
uint32_t x, y;
|
||||
uint32_t count = alist_audio.count;
|
||||
struct env_mix_save_buffer_t *s = (struct env_mix_save_buffer_t*)addr;
|
||||
|
||||
if (flags & A_INIT) {
|
||||
ramps[0].value = (alist_audio.vol[0] << 16);
|
||||
ramps[1].value = (alist_audio.vol[1] << 16);
|
||||
ramps[0].target = (alist_audio.target[0] << 16);
|
||||
ramps[1].target = (alist_audio.target[1] << 16);
|
||||
exp_rates[0] = alist_audio.rate[0];
|
||||
exp_rates[1] = alist_audio.rate[1];
|
||||
exp_seq[0] = (alist_audio.vol[0] * alist_audio.rate[0]);
|
||||
exp_seq[1] = (alist_audio.vol[1] * alist_audio.rate[1]);
|
||||
dry = alist_audio.dry;
|
||||
wet = alist_audio.wet;
|
||||
} else {
|
||||
wet = s->wet;
|
||||
dry = s->dry;
|
||||
ramps[0].target = s->ramp_targets[0];
|
||||
ramps[1].target = s->ramp_targets[1];
|
||||
exp_rates[0] = s->exp_rates[0];
|
||||
exp_rates[1] = s->exp_rates[1];
|
||||
exp_seq[0] = s->exp_seq[0];
|
||||
exp_seq[1] = s->exp_seq[1];
|
||||
ramps[0].value = s->ramp_values[0];
|
||||
ramps[1].value = s->ramp_values[1];
|
||||
}
|
||||
|
||||
/* init which ensure ramp.step != 0 iff ramp.value == ramp.target */
|
||||
ramps[0].step = ramps[0].target - ramps[0].value;
|
||||
ramps[1].step = ramps[1].target - ramps[1].value;
|
||||
|
||||
for (y = 0; y < count; y += 16)
|
||||
{
|
||||
if (ramps[0].step != 0)
|
||||
{
|
||||
exp_seq[0] = ((int64_t)exp_seq[0]*(int64_t)exp_rates[0]) >> 16;
|
||||
ramps[0].step = (exp_seq[0] - ramps[0].value) >> 3;
|
||||
}
|
||||
|
||||
if (ramps[1].step != 0)
|
||||
{
|
||||
exp_seq[1] = ((int64_t)exp_seq[1]*(int64_t)exp_rates[1]) >> 16;
|
||||
ramps[1].step = (exp_seq[1] - ramps[1].value) >> 3;
|
||||
}
|
||||
|
||||
for (x = 0; x < 8; ++x) {
|
||||
int16_t l_vol = ramp_step(&ramps[0]);
|
||||
int16_t r_vol = ramp_step(&ramps[1]);
|
||||
int16_t in_sample = in[ptr];
|
||||
|
||||
dl[ptr] = sample_mix(dl[ptr], in_sample, clamp_s16((l_vol * dry + 0x4000) >> 15));
|
||||
dr[ptr] = sample_mix(dr[ptr], in_sample, clamp_s16((r_vol * dry + 0x4000) >> 15));
|
||||
if (n == 4) {
|
||||
wl[ptr] = sample_mix(wl[ptr], in_sample, clamp_s16((l_vol * wet + 0x4000) >> 15));
|
||||
wr[ptr] = sample_mix(wr[ptr], in_sample, clamp_s16((r_vol * wet + 0x4000) >> 15));
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
s->wet = wet;
|
||||
s->dry = dry;
|
||||
s->ramp_targets[0] = ramps[0].target;
|
||||
s->ramp_targets[1] = ramps[1].target;
|
||||
s->exp_rates[0] = exp_rates[0];
|
||||
s->exp_rates[1] = exp_rates[1];
|
||||
s->exp_seq[0] = exp_seq[0];
|
||||
s->exp_seq[1] = exp_seq[1];
|
||||
s->ramp_values[0] = ramps[0].value;
|
||||
s->ramp_values[1] = ramps[1].value;
|
||||
}
|
||||
|
||||
void aResample(uint64_t *cmd, uint8_t flags, uint16_t pitch, uint16_t *state_addr) {
|
||||
int16_t *dst = (int16_t*)(alist_buffer + alist_audio.out);
|
||||
int16_t *src = (int16_t*)(alist_buffer + alist_audio.in);
|
||||
size_t count = alist_audio.count >> 1;
|
||||
uint32_t pitch_accumulator = 0;
|
||||
|
||||
count = align(count, 8);
|
||||
|
||||
src -= 4;
|
||||
|
||||
if (flags & A_INIT) {
|
||||
memset(src, 0, 4 * sizeof(int16_t));
|
||||
} else {
|
||||
memcpy(src, state_addr, 4 * sizeof(int16_t));
|
||||
pitch_accumulator = state_addr[4];
|
||||
}
|
||||
|
||||
while (count != 0) {
|
||||
const int16_t *lut = RESAMPLE_LUT + ((pitch_accumulator & 0xfc00) >> 8);
|
||||
|
||||
*dst++ = clamp_s16((src[0] * lut[0] + src[1] * lut[1] + src[2] * lut[2] + src[3] * lut[3]) >> 15);
|
||||
pitch_accumulator += (pitch << 1);
|
||||
src += pitch_accumulator >> 16;
|
||||
pitch_accumulator &= 0xffff;
|
||||
--count;
|
||||
}
|
||||
|
||||
memcpy(state_addr, src, 4 * sizeof(int16_t));
|
||||
state_addr[4] = pitch_accumulator;
|
||||
}
|
||||
|
||||
void aInterleave(uint64_t *cmd, uint16_t inL, uint16_t inR) {
|
||||
inL += DMEM_BASE;
|
||||
inR += DMEM_BASE;
|
||||
|
||||
int16_t *dst = (int16_t*)(alist_buffer + alist_audio.out);
|
||||
int16_t *srcL = (int16_t*)(alist_buffer + inL);
|
||||
int16_t *srcR = (int16_t*)(alist_buffer + inR);
|
||||
|
||||
size_t count = alist_audio.count >> 2;
|
||||
|
||||
count = align(count, 4);
|
||||
|
||||
// Unroll a bit
|
||||
while (count != 0) {
|
||||
int16_t l1 = *srcL++;
|
||||
int16_t l2 = *srcL++;
|
||||
int16_t r1 = *srcR++;
|
||||
int16_t r2 = *srcR++;
|
||||
|
||||
*dst++ = l1;
|
||||
*dst++ = r1;
|
||||
*dst++ = l2;
|
||||
*dst++ = r2;
|
||||
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
// These two share the same opcode but parameters and what they do are different depending on flags
|
||||
void aSetVolume(uint64_t *cmd, uint8_t flags, uint16_t vol, uint16_t voltgt, uint16_t volrate) {
|
||||
if (flags & A_AUX) {
|
||||
// Parameter names are not really correct for A_AUX
|
||||
alist_audio.dry = vol;
|
||||
alist_audio.wet = volrate;
|
||||
} else {
|
||||
size_t lr = (flags & A_LEFT) ? 0 : 1;
|
||||
|
||||
assert(flags & A_VOL);
|
||||
alist_audio.vol[lr] = vol;
|
||||
}
|
||||
}
|
||||
void aSetVolume32(uint64_t *cmd, uint8_t flags, uint16_t voltgt, uint32_t volrate) {
|
||||
size_t lr = (flags & A_LEFT) ? 0 : 1;
|
||||
|
||||
assert(!(flags & A_VOL) && !(flags & A_AUX));
|
||||
alist_audio.target[lr] = voltgt;
|
||||
alist_audio.rate[lr] = volrate;
|
||||
}
|
||||
|
||||
void aSetLoop(uint64_t *cmd, uint16_t *addr) {
|
||||
alist_audio.loop = addr;
|
||||
}
|
||||
|
||||
void aLoadADPCM(uint64_t *cmd, uint16_t count, uint16_t *addr) {
|
||||
assert(align(count, 8) == count);
|
||||
memcpy(alist_audio.table, addr, count);
|
||||
}
|
||||
|
||||
static inline int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
|
||||
unsigned lshift, unsigned rshift) {
|
||||
int16_t sample = (uint16_t)(byte & mask) << lshift;
|
||||
sample >>= rshift; /* signed */
|
||||
return sample;
|
||||
}
|
||||
|
||||
static unsigned int adpcm_predict_frame_4bits(int16_t* dst, uint8_t* src, uint8_t scale) {
|
||||
unsigned int i;
|
||||
unsigned int rshift = (scale < 12) ? 12 - scale : 0;
|
||||
|
||||
for(i = 0; i < 8; ++i) {
|
||||
uint8_t byte = *src++;
|
||||
|
||||
*(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift);
|
||||
*(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift);
|
||||
}
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
static int32_t rdot(size_t n, const int16_t *x, const int16_t *y) {
|
||||
int32_t accu = 0;
|
||||
|
||||
y += n;
|
||||
|
||||
while (n != 0) {
|
||||
accu += *(x++) * *(--y);
|
||||
--n;
|
||||
}
|
||||
|
||||
return accu;
|
||||
}
|
||||
|
||||
static void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
|
||||
const int16_t* cb_entry, const int16_t* last_samples, size_t count) {
|
||||
const int16_t* const book1 = cb_entry;
|
||||
const int16_t* const book2 = cb_entry + 8;
|
||||
|
||||
const int16_t l1 = last_samples[0];
|
||||
const int16_t l2 = last_samples[1];
|
||||
|
||||
size_t i;
|
||||
|
||||
assert(count <= 8);
|
||||
|
||||
for(i = 0; i < count; ++i) {
|
||||
int32_t accu = (int32_t)src[i] << 11;
|
||||
accu += book1[i]*l1 + book2[i]*l2 + rdot(i, book2, src);
|
||||
dst[i] = clamp_s16(accu >> 11);
|
||||
}
|
||||
}
|
||||
|
||||
void aADPCMdec(uint64_t *cmd, uint8_t flags, uint16_t *last_frame_addr) {
|
||||
int16_t *dst = (int16_t*)(alist_buffer + alist_audio.out);
|
||||
uint8_t *src = alist_buffer + alist_audio.in;
|
||||
size_t count = alist_audio.count;
|
||||
int16_t last_frame[16];
|
||||
|
||||
count = align(count, 32);
|
||||
assert((count & 0x1f) == 0);
|
||||
|
||||
if (flags & A_INIT) {
|
||||
memset(last_frame, 0, sizeof(last_frame));
|
||||
} else {
|
||||
memcpy(last_frame, ((flags & A_LOOP) ? alist_audio.loop : last_frame_addr), sizeof(last_frame));
|
||||
}
|
||||
|
||||
memcpy(dst, last_frame, sizeof(last_frame));
|
||||
dst += 16;
|
||||
|
||||
while (count != 0) {
|
||||
int16_t frame[16];
|
||||
uint8_t code = *src++;
|
||||
uint8_t scale = code >> 4;
|
||||
const int16_t *const cb_entry = alist_audio.table + ((code & 0xf) * 16);
|
||||
|
||||
src += adpcm_predict_frame_4bits(frame, src, scale);
|
||||
|
||||
adpcm_compute_residuals(last_frame, frame, cb_entry, last_frame + 14, 8);
|
||||
adpcm_compute_residuals(last_frame + 8, frame + 8, cb_entry, last_frame + 6, 8);
|
||||
|
||||
memcpy(dst, last_frame, sizeof(last_frame));
|
||||
dst += 16;
|
||||
|
||||
count -= 32;
|
||||
}
|
||||
|
||||
memcpy(last_frame_addr, last_frame, sizeof(last_frame));
|
||||
}
|
39
src/pc/mixer.h
Normal file
39
src/pc/mixer.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef MIXER_H
|
||||
#define MIXER_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
|
||||
#undef aSegment
|
||||
#undef aClearBuffer
|
||||
#undef aSetBuffer
|
||||
#undef aLoadBuffer
|
||||
#undef aSaveBuffer
|
||||
#undef aDMEMMove
|
||||
#undef aMix
|
||||
#undef aEnvMixer
|
||||
#undef aResample
|
||||
#undef aInterleave
|
||||
#undef aSetVolume
|
||||
#undef aSetVolume32
|
||||
#undef aSetLoop
|
||||
#undef aLoadADPCM
|
||||
#undef aADPCMdec
|
||||
|
||||
#define aSegment(pkt, s, b)
|
||||
void aClearBuffer(uint64_t *cmd, uint16_t dmem, uint16_t count);
|
||||
void aSetBuffer(uint64_t *cmd, uint8_t flags, uint16_t dmemin, uint16_t dmemout, uint16_t count);
|
||||
void aLoadBuffer(uint64_t *cmd, uint16_t *addr);
|
||||
void aSaveBuffer(uint64_t *cmd, uint16_t *addr);
|
||||
void aDMEMMove(uint64_t *cmd, uint16_t dmemin, uint16_t dmemout, uint16_t count);
|
||||
void aMix(uint64_t *cmd, uint8_t flags, uint16_t gain, uint16_t dmemin, uint16_t dmemout);
|
||||
void aEnvMixer(uint64_t *cmd, uint8_t flags, uint16_t *addr);
|
||||
void aResample(uint64_t *cmd, uint8_t flags, uint16_t pitch, uint16_t *state_addr);
|
||||
void aInterleave(uint64_t *cmd, uint16_t inL, uint16_t inR);
|
||||
void aSetVolume(uint64_t *cmd, uint8_t flags, uint16_t vol, uint16_t voltgt, uint16_t volrate);
|
||||
void aSetVolume32(uint64_t *cmd, uint8_t flags, uint16_t voltgt, uint32_t volrate);
|
||||
void aSetLoop(uint64_t *cmd, uint16_t *addr);
|
||||
void aLoadADPCM(uint64_t *cmd, uint16_t count, uint16_t *addr);
|
||||
void aADPCMdec(uint64_t *cmd, uint8_t flags, uint16_t *last_frame_addr);
|
||||
|
||||
|
||||
#endif
|
162
src/pc/pc_main.c
Normal file
162
src/pc/pc_main.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#endif
|
||||
|
||||
#include "sm64.h"
|
||||
|
||||
#include "game/memory.h"
|
||||
#include "audio/external.h"
|
||||
|
||||
#include "gfx/gfx_pc.h"
|
||||
#include "gfx/gfx_opengl.h"
|
||||
#include "gfx/gfx_sdl.h"
|
||||
|
||||
#include "audio/audio_api.h"
|
||||
#include "audio/audio_sdl.h"
|
||||
#include "audio/audio_null.h"
|
||||
|
||||
#include "configfile.h"
|
||||
|
||||
#define CONFIG_FILE "sm64config.txt"
|
||||
|
||||
OSMesg D_80339BEC;
|
||||
OSMesgQueue gSIEventMesgQueue;
|
||||
|
||||
s8 gResetTimer;
|
||||
s8 D_8032C648;
|
||||
s8 gDebugLevelSelect;
|
||||
s8 gShowProfiler;
|
||||
s8 gShowDebugText;
|
||||
|
||||
static struct AudioAPI *audio_api;
|
||||
static struct GfxWindowManagerAPI *wm_api;
|
||||
static struct GfxRenderingAPI *rendering_api;
|
||||
|
||||
extern void gfx_run(Gfx *commands);
|
||||
extern void thread5_game_loop(void *arg);
|
||||
extern void create_next_audio_buffer(s16 *samples, u32 num_samples);
|
||||
void game_loop_one_iteration(void);
|
||||
|
||||
void dispatch_audio_sptask(struct SPTask *spTask) {
|
||||
}
|
||||
|
||||
void set_vblank_handler(s32 index, struct VblankHandler *handler, OSMesgQueue *queue, OSMesg *msg) {
|
||||
}
|
||||
|
||||
static uint8_t inited = 0;
|
||||
|
||||
#include "game/display.h" // for gGlobalTimer
|
||||
void send_display_list(struct SPTask *spTask) {
|
||||
if (!inited) {
|
||||
return;
|
||||
}
|
||||
gfx_run((Gfx *)spTask->task.t.data_ptr);
|
||||
}
|
||||
|
||||
#define printf
|
||||
|
||||
void produce_one_frame(void) {
|
||||
gfx_start_frame();
|
||||
game_loop_one_iteration();
|
||||
|
||||
int samples_left = audio_api->buffered();
|
||||
u32 num_audio_samples = samples_left < audio_api->get_desired_buffered() ? 544 : 528;
|
||||
//printf("Audio samples: %d %u\n", samples_left, num_audio_samples);
|
||||
s16 audio_buffer[544 * 2 * 2];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
/*if (audio_cnt-- == 0) {
|
||||
audio_cnt = 2;
|
||||
}
|
||||
u32 num_audio_samples = audio_cnt < 2 ? 528 : 544;*/
|
||||
create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
|
||||
}
|
||||
//printf("Audio samples before submitting: %d\n", audio_api->buffered());
|
||||
audio_api->play(audio_buffer, 2 * num_audio_samples * 4);
|
||||
|
||||
gfx_end_frame();
|
||||
}
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
static void em_main_loop(void) {
|
||||
}
|
||||
|
||||
static void request_anim_frame(void (*func)(double time)) {
|
||||
EM_ASM(requestAnimationFrame(function(time) {
|
||||
dynCall("vd", $0, [time]);
|
||||
}), func);
|
||||
}
|
||||
|
||||
static void on_anim_frame(double time) {
|
||||
static double target_time;
|
||||
|
||||
time *= 0.03; // milliseconds to frame count (33.333 ms -> 1)
|
||||
|
||||
if (time >= target_time + 10.0) {
|
||||
// We are lagging 10 frames behind, probably due to coming back after inactivity,
|
||||
// so reset, with a small margin to avoid potential jitter later.
|
||||
target_time = time - 0.010;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// If refresh rate is 15 Hz or something we might need to generate two frames
|
||||
if (time >= target_time) {
|
||||
produce_one_frame();
|
||||
target_time = target_time + 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
request_anim_frame(on_anim_frame);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void save_config(void) {
|
||||
configfile_save(CONFIG_FILE);
|
||||
}
|
||||
|
||||
void main_func(void) {
|
||||
static u64 pool[0x165000/8 / 4 * sizeof(void *)];
|
||||
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
|
||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||
|
||||
configfile_load(CONFIG_FILE);
|
||||
atexit(save_config);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
emscripten_set_main_loop(em_main_loop, 0, 0);
|
||||
request_anim_frame(on_anim_frame);
|
||||
#endif
|
||||
wm_api = &gfx_sdl;
|
||||
rendering_api = &gfx_opengl_api;
|
||||
gfx_init(wm_api, rendering_api);
|
||||
|
||||
if (audio_api == NULL && audio_sdl.init())
|
||||
audio_api = &audio_sdl;
|
||||
|
||||
if (audio_api == NULL) {
|
||||
audio_api = &audio_null;
|
||||
}
|
||||
|
||||
audio_init();
|
||||
sound_init();
|
||||
|
||||
thread5_game_loop(NULL);
|
||||
#ifdef TARGET_WEB
|
||||
/*for (int i = 0; i < atoi(argv[1]); i++) {
|
||||
game_loop_one_iteration();
|
||||
}*/
|
||||
inited = 1;
|
||||
#else
|
||||
inited = 1;
|
||||
while (1) {
|
||||
wm_api->main_loop(produce_one_frame);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
main_func();
|
||||
return 0;
|
||||
}
|
160
src/pc/ultra_reimplementation.c
Normal file
160
src/pc/ultra_reimplementation.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "lib/src/libultra_internal.h"
|
||||
#include "macros.h"
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
extern OSMgrArgs piMgrArgs;
|
||||
|
||||
u64 osClockRate = 62500000;
|
||||
|
||||
s32 osPiStartDma(UNUSED OSIoMesg *mb, UNUSED s32 priority, UNUSED s32 direction,
|
||||
uintptr_t devAddr, void *vAddr, size_t nbytes,
|
||||
UNUSED OSMesgQueue *mq) {
|
||||
memcpy(vAddr, (const void *) devAddr, nbytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osSetEventMesg(UNUSED OSEvent e, UNUSED OSMesgQueue *mq, UNUSED OSMesg msg) {
|
||||
}
|
||||
s32 osJamMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||
return 0;
|
||||
}
|
||||
s32 osSendMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED s32 flag) {
|
||||
return 0;
|
||||
}
|
||||
s32 osRecvMesg(UNUSED OSMesgQueue *mq, UNUSED OSMesg *msg, UNUSED s32 flag) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t osVirtualToPhysical(void *addr) {
|
||||
return (uintptr_t) addr;
|
||||
}
|
||||
|
||||
void osCreateViManager(UNUSED OSPri pri) {
|
||||
}
|
||||
void osViSetMode(UNUSED OSViMode *mode) {
|
||||
}
|
||||
void osViSetEvent(UNUSED OSMesgQueue *mq, UNUSED OSMesg msg, UNUSED u32 retraceCount) {
|
||||
}
|
||||
void osViBlack(UNUSED u8 active) {
|
||||
}
|
||||
void osViSetSpecialFeatures(UNUSED u32 func) {
|
||||
}
|
||||
void osViSwapBuffer(UNUSED void *vaddr) {
|
||||
}
|
||||
|
||||
OSTime osGetTime(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void osWritebackDCacheAll(void) {
|
||||
}
|
||||
|
||||
void osWritebackDCache(UNUSED void *a, UNUSED size_t b) {
|
||||
}
|
||||
|
||||
void osInvalDCache(UNUSED void *a, UNUSED size_t b) {
|
||||
}
|
||||
|
||||
u32 osGetCount(void) {
|
||||
static u32 counter;
|
||||
return counter++;
|
||||
}
|
||||
|
||||
s32 osAiSetFrequency(u32 freq) {
|
||||
u32 a1;
|
||||
s32 a2;
|
||||
u32 D_8033491C;
|
||||
|
||||
#ifdef VERSION_EU
|
||||
D_8033491C = 0x02E6025C;
|
||||
#else
|
||||
D_8033491C = 0x02E6D354;
|
||||
#endif
|
||||
|
||||
a1 = D_8033491C / (float) freq + .5f;
|
||||
|
||||
if (a1 < 0x84) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
a2 = (a1 / 66) & 0xff;
|
||||
if (a2 > 16) {
|
||||
a2 = 16;
|
||||
}
|
||||
|
||||
return D_8033491C / (s32) a1;
|
||||
}
|
||||
|
||||
s32 osEepromProbe(UNUSED OSMesgQueue *mq) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 osEepromLongRead(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) {
|
||||
u8 content[512];
|
||||
s32 ret = -1;
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
if (EM_ASM_INT({
|
||||
var s = localStorage.sm64_save_file;
|
||||
if (s && s.length === 684) {
|
||||
try {
|
||||
var binary = atob(s);
|
||||
if (binary.length === 512) {
|
||||
for (var i = 0; i < 512; i++) {
|
||||
HEAPU8[$0 + i] = binary.charCodeAt(i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}, content)) {
|
||||
memcpy(buffer, content + address * 8, nbytes);
|
||||
ret = 0;
|
||||
}
|
||||
#else
|
||||
FILE *fp = fopen("sm64_save_file.bin", "rb");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (fread(content, 1, 512, fp) == 512) {
|
||||
memcpy(buffer, content + address * 8, nbytes);
|
||||
ret = 0;
|
||||
}
|
||||
fclose(fp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 osEepromLongWrite(UNUSED OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) {
|
||||
u8 content[512] = {0};
|
||||
if (address != 0 || nbytes != 512) {
|
||||
osEepromLongRead(mq, 0, content, 512);
|
||||
}
|
||||
memcpy(content + address * 8, buffer, nbytes);
|
||||
|
||||
#ifdef TARGET_WEB
|
||||
EM_ASM({
|
||||
var str = "";
|
||||
for (var i = 0; i < 512; i++) {
|
||||
str += String.fromCharCode(HEAPU8[$0 + i]);
|
||||
}
|
||||
localStorage.sm64_save_file = btoa(str);
|
||||
}, content);
|
||||
s32 ret = 0;
|
||||
#else
|
||||
FILE* fp = fopen("sm64_save_file.bin", "wb");
|
||||
if (fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
s32 ret = fwrite(content, 1, 512, fp) == 512 ? 0 : -1;
|
||||
fclose(fp);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
CC := gcc
|
||||
CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 -O3 -s
|
||||
CFLAGS := -Llib -Iinclude -I . -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 -O3 -s
|
||||
PROGRAMS := n64graphics n64graphics_ci mio0 n64cksum textconv patch_libultra_math iplfontutil aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv
|
||||
|
||||
n64graphics_SOURCES := n64graphics.c utils.c
|
||||
|
|
25
tools/audiofile-0.3.6/ACKNOWLEDGEMENTS
Normal file
25
tools/audiofile-0.3.6/ACKNOWLEDGEMENTS
Normal file
|
@ -0,0 +1,25 @@
|
|||
Thanks to all who have contributed patches for the Audio File Library:
|
||||
* Jason Allen
|
||||
* Julien Boulnois
|
||||
* Davy Durham
|
||||
* Bruce Forsberg
|
||||
* Fabrizio Gennari
|
||||
* Simon Kagedal
|
||||
* Thomas Klausner
|
||||
* Daniel Kobras
|
||||
* Michael Krause
|
||||
* Wim Lewis
|
||||
* Eric Mitchell
|
||||
* Cristian Morales Vega
|
||||
* Mark Murnane
|
||||
* Michael Palimaka
|
||||
* Jean-Francois Panisset
|
||||
* Axel Roebel
|
||||
* Matthias Rumpke
|
||||
* Chris Wolf
|
||||
|
||||
Thanks to Douglas Scott of SGI for helping me understand the tricky parts
|
||||
of the Audio File Library API. Thanks to Chris Pirazzi and Scott Porter
|
||||
of SGI for creating the Audio File Library in the first place.
|
||||
|
||||
Thanks also to all who have reported bugs.
|
5
tools/audiofile-0.3.6/AUTHORS
Normal file
5
tools/audiofile-0.3.6/AUTHORS
Normal file
|
@ -0,0 +1,5 @@
|
|||
Audio File Library Authors
|
||||
|
||||
Michael Pruett <michael@68k.org>
|
||||
|
||||
Chris Pirazzi, Scott Porter, and Doug Scott
|
502
tools/audiofile-0.3.6/COPYING
Normal file
502
tools/audiofile-0.3.6/COPYING
Normal file
|
@ -0,0 +1,502 @@
|
|||
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!
|
339
tools/audiofile-0.3.6/COPYING.GPL
Normal file
339
tools/audiofile-0.3.6/COPYING.GPL
Normal 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.
|
1953
tools/audiofile-0.3.6/ChangeLog
Normal file
1953
tools/audiofile-0.3.6/ChangeLog
Normal file
File diff suppressed because it is too large
Load diff
182
tools/audiofile-0.3.6/INSTALL
Normal file
182
tools/audiofile-0.3.6/INSTALL
Normal file
|
@ -0,0 +1,182 @@
|
|||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
897
tools/audiofile-0.3.6/Makefile
Normal file
897
tools/audiofile-0.3.6/Makefile
Normal file
|
@ -0,0 +1,897 @@
|
|||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# Makefile. Generated from Makefile.in by configure.
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/audiofile
|
||||
pkgincludedir = $(includedir)/audiofile
|
||||
pkglibdir = $(libdir)/audiofile
|
||||
pkglibexecdir = $(libexecdir)/audiofile
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = i686-w64-mingw32
|
||||
host_triplet = i686-w64-mingw32
|
||||
subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||
$(srcdir)/Makefile.in $(srcdir)/audiofile-uninstalled.pc.in \
|
||||
$(srcdir)/audiofile.pc.in $(srcdir)/audiofile.spec.in \
|
||||
$(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \
|
||||
ChangeLog INSTALL NEWS TODO config.guess config.sub depcomp \
|
||||
install-sh ltmain.sh missing
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES = audiofile.spec audiofile.pc \
|
||||
audiofile-uninstalled.pc
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
SOURCES =
|
||||
DIST_SOURCES =
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
|
||||
html-recursive info-recursive install-data-recursive \
|
||||
install-dvi-recursive install-exec-recursive \
|
||||
install-html-recursive install-info-recursive \
|
||||
install-pdf-recursive install-ps-recursive install-recursive \
|
||||
installcheck-recursive installdirs-recursive pdf-recursive \
|
||||
ps-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
|
||||
DATA = $(pkgconfig_DATA)
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
|
||||
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
|
||||
distdir dist dist-all distcheck
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
am__remove_distdir = \
|
||||
if test -d "$(distdir)"; then \
|
||||
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||
&& rm -rf "$(distdir)" \
|
||||
|| { sleep 5 && rm -rf "$(distdir)"; }; \
|
||||
else :; fi
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
DIST_ARCHIVES = $(distdir).tar.gz
|
||||
GZIP_ENV = --best
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
|
||||
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
|
||||
distcleancheck_listfiles = find . -type f -print
|
||||
A2X = /usr/bin/a2x
|
||||
ACLOCAL = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/missing --run aclocal-1.11
|
||||
AMTAR = $${TAR-tar}
|
||||
AR = ar
|
||||
ASCIIDOC = /usr/bin/asciidoc
|
||||
AUDIOFILE_VERSION = 0.3.6
|
||||
AUDIOFILE_VERSION_INFO = 1:0:0
|
||||
AUTOCONF = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/missing --run autoconf
|
||||
AUTOHEADER = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/missing --run autoheader
|
||||
AUTOMAKE = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/missing --run automake-1.11
|
||||
AWK = gawk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=gcc3
|
||||
CFLAGS = -g -O2
|
||||
COVERAGE_CFLAGS =
|
||||
COVERAGE_LIBS =
|
||||
CPP = gcc -E
|
||||
CPPFLAGS =
|
||||
CXX = g++
|
||||
CXXCPP = g++ -E
|
||||
CXXDEPMODE = depmode=gcc3
|
||||
CXXFLAGS = -g -O2
|
||||
CYGPATH_W = cygpath -w
|
||||
DEFS = -DHAVE_CONFIG_H
|
||||
DEPDIR = .deps
|
||||
DLLTOOL = dlltool
|
||||
DSYMUTIL =
|
||||
DUMPBIN =
|
||||
ECHO_C =
|
||||
ECHO_N = -n
|
||||
ECHO_T =
|
||||
EGREP = /usr/bin/grep -E
|
||||
EXEEXT = .exe
|
||||
FGREP = /usr/bin/grep -F
|
||||
FLAC_CFLAGS =
|
||||
FLAC_LIBS =
|
||||
GENHTML =
|
||||
GREP = /usr/bin/grep
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_SCRIPT = ${INSTALL}
|
||||
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
|
||||
LCOV =
|
||||
LD = C:/git-sdk-64/mingw32/i686-w64-mingw32/bin/ld.exe
|
||||
LDFLAGS =
|
||||
LIBOBJS =
|
||||
LIBS =
|
||||
LIBTOOL = $(SHELL) $(top_builddir)/libtool
|
||||
LIPO =
|
||||
LN_S = cp -pR
|
||||
LTLIBOBJS =
|
||||
MAKEINFO = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/missing --run makeinfo
|
||||
MANIFEST_TOOL = :
|
||||
MKDIR_P = /usr/bin/mkdir -p
|
||||
NM = /mingw32/bin/nm -B
|
||||
NMEDIT =
|
||||
OBJDUMP = objdump
|
||||
OBJEXT = o
|
||||
OTOOL =
|
||||
OTOOL64 =
|
||||
PACKAGE = audiofile
|
||||
PACKAGE_BUGREPORT =
|
||||
PACKAGE_NAME = audiofile
|
||||
PACKAGE_STRING = audiofile 0.3.6
|
||||
PACKAGE_TARNAME = audiofile
|
||||
PACKAGE_URL =
|
||||
PACKAGE_VERSION = 0.3.6
|
||||
PATH_SEPARATOR = :
|
||||
PKG_CONFIG = /mingw32/bin/pkg-config
|
||||
PKG_CONFIG_LIBDIR =
|
||||
PKG_CONFIG_PATH = /mingw32/lib/pkgconfig:/mingw32/share/pkgconfig
|
||||
RANLIB = ranlib
|
||||
SED = /usr/bin/sed
|
||||
SET_MAKE =
|
||||
SHELL = /bin/sh
|
||||
STRIP = strip
|
||||
TEST_BIN =
|
||||
VALGRIND =
|
||||
VERSION = 0.3.6
|
||||
WERROR_CFLAGS =
|
||||
abs_builddir = /c/Users/marti/Desktop/audiofile-0.3.6
|
||||
abs_srcdir = /c/Users/marti/Desktop/audiofile-0.3.6
|
||||
abs_top_builddir = /c/Users/marti/Desktop/audiofile-0.3.6
|
||||
abs_top_srcdir = /c/Users/marti/Desktop/audiofile-0.3.6
|
||||
ac_ct_AR = ar
|
||||
ac_ct_CC = gcc
|
||||
ac_ct_CXX = g++
|
||||
ac_ct_DUMPBIN =
|
||||
am__include = include
|
||||
am__leading_dot = .
|
||||
am__quote =
|
||||
am__tar = $${TAR-tar} chof - "$$tardir"
|
||||
am__untar = $${TAR-tar} xf -
|
||||
bindir = ${exec_prefix}/bin
|
||||
build = i686-w64-mingw32
|
||||
build_alias = i686-w64-mingw32
|
||||
build_cpu = i686
|
||||
build_os = mingw32
|
||||
build_vendor = w64
|
||||
builddir = .
|
||||
datadir = ${datarootdir}
|
||||
datarootdir = ${prefix}/share
|
||||
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
|
||||
dvidir = ${docdir}
|
||||
exec_prefix = ${prefix}
|
||||
host = i686-w64-mingw32
|
||||
host_alias =
|
||||
host_cpu = i686
|
||||
host_os = mingw32
|
||||
host_vendor = w64
|
||||
htmldir = ${docdir}
|
||||
includedir = ${prefix}/include
|
||||
infodir = ${datarootdir}/info
|
||||
install_sh = ${SHELL} /c/Users/marti/Desktop/audiofile-0.3.6/install-sh
|
||||
libdir = ${exec_prefix}/lib
|
||||
libexecdir = ${exec_prefix}/libexec
|
||||
localedir = ${datarootdir}/locale
|
||||
localstatedir = ${prefix}/var
|
||||
mandir = ${datarootdir}/man
|
||||
mkdir_p = /usr/bin/mkdir -p
|
||||
oldincludedir = /usr/include
|
||||
pdfdir = ${docdir}
|
||||
prefix = /mingw32
|
||||
program_transform_name = s,x,x,
|
||||
psdir = ${docdir}
|
||||
sbindir = ${exec_prefix}/sbin
|
||||
sharedstatedir = ${prefix}/com
|
||||
srcdir = .
|
||||
sysconfdir = ${prefix}/etc
|
||||
target_alias =
|
||||
top_build_prefix =
|
||||
top_builddir = .
|
||||
top_srcdir = .
|
||||
SUBDIRS = gtest libaudiofile sfcommands test examples docs
|
||||
EXTRA_DIST = \
|
||||
ACKNOWLEDGEMENTS \
|
||||
NOTES \
|
||||
README \
|
||||
TODO \
|
||||
COPYING.GPL \
|
||||
configure configure.ac \
|
||||
audiofile.spec.in \
|
||||
audiofile.pc.in \
|
||||
audiofile-uninstalled.pc.in
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = audiofile.pc
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
am--refresh: Makefile
|
||||
@:
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
|
||||
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
echo ' $(SHELL) ./config.status'; \
|
||||
$(SHELL) ./config.status;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
config.h: stamp-h1
|
||||
@if test ! -f $@; then rm -f stamp-h1; else :; fi
|
||||
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||
$(srcdir)/config.h.in: $(am__configure_deps)
|
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h stamp-h1
|
||||
audiofile.spec: $(top_builddir)/config.status $(srcdir)/audiofile.spec.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
audiofile.pc: $(top_builddir)/config.status $(srcdir)/audiofile.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
audiofile-uninstalled.pc: $(top_builddir)/config.status $(srcdir)/audiofile-uninstalled.pc.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
install-pkgconfigDATA: $(pkgconfig_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-pkgconfigDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
$(RECURSIVE_TARGETS):
|
||||
@fail= failcom='exit 1'; \
|
||||
for f in x $$MAKEFLAGS; do \
|
||||
case $$f in \
|
||||
*=* | --[!k]*);; \
|
||||
*k*) failcom='fail=yes';; \
|
||||
esac; \
|
||||
done; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
$(RECURSIVE_CLEAN_TARGETS):
|
||||
@fail= failcom='exit 1'; \
|
||||
for f in x $$MAKEFLAGS; do \
|
||||
case $$f in \
|
||||
*=* | --[!k]*);; \
|
||||
*k*) failcom='fail=yes';; \
|
||||
esac; \
|
||||
done; \
|
||||
dot_seen=no; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
rev=''; for subdir in $$list; do \
|
||||
if test "$$subdir" = "."; then :; else \
|
||||
rev="$$subdir $$rev"; \
|
||||
fi; \
|
||||
done; \
|
||||
rev="$$rev ."; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
ctags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
|
||||
done
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
$(am__remove_distdir)
|
||||
test -d "$(distdir)" || mkdir "$(distdir)"
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-hook
|
||||
-test -n "$(am__skip_mode_fix)" \
|
||||
|| find "$(distdir)" -type d ! -perm -755 \
|
||||
-exec chmod u+rwx,go+rx {} \; -o \
|
||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|
||||
|| chmod -R a+r "$(distdir)"
|
||||
dist-gzip: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-bzip2: distdir
|
||||
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-lzip: distdir
|
||||
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-lzma: distdir
|
||||
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-xz: distdir
|
||||
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-tarZ: distdir
|
||||
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-shar: distdir
|
||||
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-zip: distdir
|
||||
-rm -f $(distdir).zip
|
||||
zip -rq $(distdir).zip $(distdir)
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist dist-all: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
case '$(DIST_ARCHIVES)' in \
|
||||
*.tar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
|
||||
*.tar.bz2*) \
|
||||
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||
*.tar.lzma*) \
|
||||
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
|
||||
*.tar.lz*) \
|
||||
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
|
||||
*.tar.xz*) \
|
||||
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
|
||||
*.tar.Z*) \
|
||||
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||
*.shar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir); chmod u+w $(distdir)
|
||||
mkdir $(distdir)/_build
|
||||
mkdir $(distdir)/_inst
|
||||
chmod a-w $(distdir)
|
||||
test -d $(distdir)/_build || exit 0; \
|
||||
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||
&& am__cwd=`pwd` \
|
||||
&& $(am__cd) $(distdir)/_build \
|
||||
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||
distuninstallcheck \
|
||||
&& chmod -R a-w "$$dc_install_base" \
|
||||
&& ({ \
|
||||
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||
&& rm -rf "$$dc_destdir" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||
&& rm -rf $(DIST_ARCHIVES) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
|
||||
&& cd "$$am__cwd" \
|
||||
|| exit 1
|
||||
$(am__remove_distdir)
|
||||
@(echo "$(distdir) archives ready for distribution: "; \
|
||||
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
|
||||
distuninstallcheck:
|
||||
@test -n '$(distuninstallcheck_dir)' || { \
|
||||
echo 'ERROR: trying to run $@ with an empty' \
|
||||
'$$(distuninstallcheck_dir)' >&2; \
|
||||
exit 1; \
|
||||
}; \
|
||||
$(am__cd) '$(distuninstallcheck_dir)' || { \
|
||||
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
|
||||
exit 1; \
|
||||
}; \
|
||||
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|
||||
|| { echo "ERROR: files left after uninstall:" ; \
|
||||
if test -n "$(DESTDIR)"; then \
|
||||
echo " (check DESTDIR support)"; \
|
||||
fi ; \
|
||||
$(distuninstallcheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
distcleancheck: distclean
|
||||
@if test '$(srcdir)' = . ; then \
|
||||
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||
$(distcleancheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile $(DATA) config.h
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean-local:
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-local mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-generic distclean-hdr \
|
||||
distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-recursive
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-pkgconfigDATA
|
||||
|
||||
install-dvi: install-dvi-recursive
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-recursive
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-recursive
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-recursive
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-pkgconfigDATA
|
||||
|
||||
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
|
||||
ctags-recursive install-am install-strip tags-recursive
|
||||
|
||||
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
|
||||
all all-am am--refresh check check-am clean clean-generic \
|
||||
clean-libtool clean-local ctags ctags-recursive dist dist-all \
|
||||
dist-bzip2 dist-gzip dist-hook dist-lzip dist-lzma dist-shar \
|
||||
dist-tarZ dist-xz dist-zip distcheck distclean \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
installdirs-am maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
|
||||
ps ps-am tags tags-recursive uninstall uninstall-am \
|
||||
uninstall-pkgconfigDATA
|
||||
|
||||
|
||||
dist-hook: audiofile.spec
|
||||
cp audiofile.spec $(distdir)
|
||||
|
||||
#coverage:
|
||||
# $(MAKE) coverage-reset
|
||||
# $(MAKE) check
|
||||
# $(MAKE) coverage-report
|
||||
|
||||
#coverage-reset:
|
||||
# $(LCOV) --base-directory=. --directory ./libaudiofile --zerocounters
|
||||
|
||||
#coverage-report:
|
||||
# $(LCOV) --directory ./libaudiofile \
|
||||
# --capture \
|
||||
# --output-file ./lcov.info
|
||||
|
||||
# $(LCOV) --directory ./libaudiofile \
|
||||
# --output-file ./lcov.info \
|
||||
# --remove ./lcov.info \
|
||||
# "/usr/include/*" "gtest/*" "*/UT_*"
|
||||
|
||||
# $(mkdir_p) ./coverage
|
||||
# git_commit=`GIT_DIR=./.git git log -1 --pretty=format:%h 2>/dev/null`; \
|
||||
# $(GENHTML) --title "audiofile 0.3.6 $$git_commit" \
|
||||
# --output-directory ./coverage ./lcov.info
|
||||
# @echo
|
||||
# @echo 'lcov report can be found here:'
|
||||
# @echo 'file:///c/Users/marti/Desktop/audiofile-0.3.6/coverage/index.html'
|
||||
# @echo
|
||||
|
||||
#clean-local:
|
||||
# -rm -rf coverage
|
||||
|
||||
#.PHONY: coverage-reset coverage coverage-report
|
||||
coverage:
|
||||
@echo "Code coverage is not enabled."
|
||||
@exit 1
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
58
tools/audiofile-0.3.6/Makefile.am
Normal file
58
tools/audiofile-0.3.6/Makefile.am
Normal file
|
@ -0,0 +1,58 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = gtest libaudiofile sfcommands test examples docs
|
||||
|
||||
EXTRA_DIST = \
|
||||
ACKNOWLEDGEMENTS \
|
||||
NOTES \
|
||||
README \
|
||||
TODO \
|
||||
COPYING.GPL \
|
||||
configure configure.ac \
|
||||
audiofile.spec.in \
|
||||
audiofile.pc.in \
|
||||
audiofile-uninstalled.pc.in
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = audiofile.pc
|
||||
|
||||
dist-hook: audiofile.spec
|
||||
cp audiofile.spec $(distdir)
|
||||
|
||||
if ENABLE_COVERAGE
|
||||
coverage:
|
||||
$(MAKE) coverage-reset
|
||||
$(MAKE) check
|
||||
$(MAKE) coverage-report
|
||||
|
||||
coverage-reset:
|
||||
$(LCOV) --base-directory=@top_srcdir@ --directory @top_srcdir@/libaudiofile --zerocounters
|
||||
|
||||
coverage-report:
|
||||
$(LCOV) --directory @top_srcdir@/libaudiofile \
|
||||
--capture \
|
||||
--output-file @top_builddir@/lcov.info
|
||||
|
||||
$(LCOV) --directory @top_srcdir@/libaudiofile \
|
||||
--output-file @top_builddir@/lcov.info \
|
||||
--remove @top_builddir@/lcov.info \
|
||||
"/usr/include/*" "gtest/*" "*/UT_*"
|
||||
|
||||
$(mkdir_p) @top_builddir@/coverage
|
||||
git_commit=`GIT_DIR=@top_srcdir@/.git git log -1 --pretty=format:%h 2>/dev/null`; \
|
||||
$(GENHTML) --title "@PACKAGE@ @VERSION@ $$git_commit" \
|
||||
--output-directory @top_builddir@/coverage @top_builddir@/lcov.info
|
||||
@echo
|
||||
@echo 'lcov report can be found here:'
|
||||
@echo 'file://@abs_top_builddir@/coverage/index.html'
|
||||
@echo
|
||||
|
||||
clean-local:
|
||||
-rm -rf coverage
|
||||
|
||||
.PHONY: coverage-reset coverage coverage-report
|
||||
else
|
||||
coverage:
|
||||
@echo "Code coverage is not enabled."
|
||||
@exit 1
|
||||
endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue