Compare commits
85 Commits
skmp/palet
...
Pgta/Duck-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ea5f41be | ||
|
|
f7d23f3bb3 | ||
|
|
24114d9a07 | ||
|
|
df7e4439d1 | ||
|
|
d83ae53746 | ||
|
|
4178d6f8f0 | ||
|
|
5914842483 | ||
|
|
a6facaec30 | ||
|
|
eea56cb195 | ||
|
|
968922b0d7 | ||
|
|
b1b225b345 | ||
|
|
d240a6d33f | ||
|
|
a584cee0cc | ||
|
|
9da3c4b076 | ||
|
|
59a75bf12b | ||
|
|
62dbf132c1 | ||
|
|
82bc55c3d4 | ||
|
|
2cb15f3728 | ||
|
|
9eace08c7e | ||
|
|
0657700e11 | ||
|
|
6c71054cb4 | ||
|
|
99431370a2 | ||
|
|
d240d3ba68 | ||
|
|
a3a610d8ee | ||
|
|
446182f159 | ||
|
|
5ef077fa14 | ||
|
|
6b41a458c5 | ||
|
|
fbfb684425 | ||
|
|
e97d96c6ad | ||
|
|
375b507cd8 | ||
|
|
c7c4e42f40 | ||
|
|
aa115cdbf6 | ||
|
|
f495bffd00 | ||
|
|
dec63c5bff | ||
|
|
3cfdb3c931 | ||
|
|
374141eda1 | ||
|
|
41e544c0f1 | ||
|
|
0ba1c595cd | ||
|
|
02799207ed | ||
|
|
687a9ab137 | ||
|
|
3a342b2a9c | ||
|
|
cc07dc3c52 | ||
|
|
325f903186 | ||
|
|
95384c1d0d | ||
|
|
5e690010fd | ||
|
|
6dcf028717 | ||
|
|
3d176a239a | ||
|
|
6eba303fb0 | ||
|
|
cfaab31a71 | ||
|
|
0f3929a3b0 | ||
|
|
f2e2ff8a29 | ||
|
|
4a336c7a1a | ||
|
|
fbce6234fe | ||
|
|
5984c4f432 | ||
|
|
1c12637506 | ||
|
|
3b7f5cffc3 | ||
|
|
aba5bdac62 | ||
|
|
19debfced6 | ||
|
|
020fe7b5b5 | ||
|
|
7e7d7de546 | ||
|
|
0f34808e8c | ||
|
|
ad0e0ac6fb | ||
|
|
c1f9cea93c | ||
|
|
44cd7935b8 | ||
|
|
c82f4f0998 | ||
|
|
2fb88c56ef | ||
|
|
bcba2f1eae | ||
|
|
13ff64119c | ||
|
|
1e069ec895 | ||
|
|
1a4b84869a | ||
|
|
fd7f44e7c2 | ||
|
|
6bd5a124cd | ||
|
|
b739b89fd6 | ||
|
|
6d67dc2ffd | ||
|
|
a7d85c2f7d | ||
|
|
2365fe663b | ||
|
|
38c78d0151 | ||
|
|
e07a46a372 | ||
|
|
9c0fd4fd67 | ||
|
|
23031096c2 | ||
|
|
dde656e932 | ||
|
|
95a090df77 | ||
|
|
30e7db4b85 | ||
|
|
3b3cad4443 | ||
|
|
6d73e6e79d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -379,7 +379,6 @@ liberty/texconv*
|
||||
liberty/imgtool*
|
||||
liberty/coltool*
|
||||
liberty/streamheaderpack*
|
||||
liberty/merge-palettes*
|
||||
liberty/extract-sfx*
|
||||
liberty/pack-sfx*
|
||||
liberty/analyze-profile*
|
||||
|
||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -146,9 +146,6 @@
|
||||
"coroutine": "cpp",
|
||||
"future": "cpp",
|
||||
"latch": "cpp",
|
||||
"syncstream": "cpp",
|
||||
"mycommon.h": "c",
|
||||
"file_tex.h": "c",
|
||||
"optparse.h": "c"
|
||||
"syncstream": "cpp"
|
||||
}
|
||||
}
|
||||
|
||||
150
liberty/Makefile
150
liberty/Makefile
@@ -15,16 +15,16 @@ IS_MAC := $(shell uname -s | grep -i "darwin" > /dev/null && echo "yes" || echo
|
||||
|
||||
MOD_NAME?=
|
||||
|
||||
GTA_DIR?=../../gta3
|
||||
GTA_DIR?=../../liberty
|
||||
GTA_GAMEFILES_LOOSE_DIR?=../gamefiles/liberty
|
||||
GTA_MOD_DIR?=../../gta3_mod$(MOD_NAME)
|
||||
GTA_MOD_DIR?=../../liberty_mod$(MOD_NAME)
|
||||
GTA_MOD_IMG_DIR?=$(GTA_MOD_DIR)/img
|
||||
GTA_MOD_CUTS_DIR=$(GTA_MOD_DIR)/cuts
|
||||
GTA_MOD_SFX_DIR?=$(GTA_MOD_DIR)/sfx
|
||||
GTA_MOD_LOOSE_DIR?=$(GTA_MOD_DIR)/loose
|
||||
|
||||
REPACK_DIR?=repack-data
|
||||
REPACK_GTA_DIR?=$(REPACK_DIR)/gta3
|
||||
REPACK_GTA_DIR?=$(REPACK_DIR)/liberty
|
||||
REPACK_IMG_ORIG_DIR?=$(REPACK_DIR)/img-orig
|
||||
REPACK_IMG_DC_DIR?=$(REPACK_DIR)/img-dc
|
||||
REPACK_SFX_ORIG_DIR?=$(REPACK_DIR)/sfx-orig
|
||||
@@ -33,9 +33,6 @@ REPACK_STREAM_DECODED_DIR?=$(REPACK_DIR)/stream-decoded
|
||||
REPACK_STREAM_DEST_DIR=$(REPACK_GTA_DIR)/stream
|
||||
REPACK_CUTS_ORIG_DIR?=$(REPACK_DIR)/cuts-orig
|
||||
REPACK_CUTS_DC_DIR?=$(REPACK_DIR)/cuts-dc
|
||||
REPACK_MISC_TXD_EXTRACT_DIR?=$(REPACK_DIR)/misc-extract
|
||||
REPACK_TEXTURES_DIR?=$(REPACK_DIR)/textures
|
||||
REPACK_TEXTURE_CLUSTERS_DIR?=$(REPACK_DIR)/texture-clusters
|
||||
|
||||
LIBS :=
|
||||
TEXCONV_FLAGS :=
|
||||
@@ -186,6 +183,14 @@ $(REPACK_GTA_DIR)/GTA3SF8.b: assets/GTA3SF8.b
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
$(REPACK_GTA_DIR)/0GDTEX.PVR: assets/0GDTEX.PVR
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
$(REPACK_GTA_DIR)/%.ico: assets/%.ico
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
1ST_READ.BIN: $(TARGET)
|
||||
rm -f $(TARGET).bin
|
||||
rm -f 1ST_READ.BIN
|
||||
@@ -201,20 +206,20 @@ IP.BIN:
|
||||
rm -f IP.BIN
|
||||
$(KOS_BASE)/utils/makeip/makeip ip.txt IP.BIN
|
||||
|
||||
$(PROJECT_NAME).iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME).iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME).iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ.BIN $(REPACK_GTA_DIR)
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME).iso $(REPACK_GTA_DIR)
|
||||
|
||||
$(PROJECT_NAME)-no-repack.iso: IP.BIN 1ST_READ.BIN $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME)-no-repack.iso: IP.BIN 1ST_READ.BIN $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME)-no-repack.iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ.BIN $(REPACK_GTA_DIR)
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME)-no-repack.iso $(REPACK_GTA_DIR)
|
||||
|
||||
|
||||
$(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME).ds.iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp $(TARGET).bin $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
@@ -225,7 +230,7 @@ $(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_
|
||||
$(KOS_BASE)/utils/scramble/scramble $(TARGET)-prebuilt.bin 1ST_READ_PREBUILT.BIN
|
||||
mkdir -p $(REPACK_GTA_DIR)
|
||||
|
||||
$(PROJECT_NAME)-prebuilt.iso: IP.BIN 1ST_READ_PREBUILT.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME)-prebuilt.iso: IP.BIN 1ST_READ_PREBUILT.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ_PREBUILT.BIN $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME).iso $(REPACK_GTA_DIR)
|
||||
@@ -244,15 +249,15 @@ $(PROJECT_NAME)-prebuilt.cdi: $(PROJECT_NAME)-prebuilt.iso
|
||||
rm 1ST_READ_PREBUILT.BIN
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
else
|
||||
$(PROJECT_NAME).cdi: $(TARGET) $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME).cdi: $(TARGET) $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME).cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
|
||||
$(PROJECT_NAME)-no-repack.cdi: $(TARGET) $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME)-no-repack.cdi: $(TARGET) $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME)-no-repack.cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
|
||||
$(PROJECT_NAME)-prebuilt.cdi: $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b
|
||||
$(PROJECT_NAME)-prebuilt.cdi: $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTA3SF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME).cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
endif
|
||||
@@ -307,16 +312,16 @@ coltool: ../src/tools/coltool.cpp
|
||||
streamheaderpack: ../src/tools/streamheaderpack.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
merge-palettes: ../src/tools/merge-palettes.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
#### Repacking ####
|
||||
|
||||
TXD_OPTS_fonts = 512 512
|
||||
TXD_OPTS_hud = 512 512
|
||||
TXD_OPTS_menu = 512 512
|
||||
TXD_OPTS_fonts = 256 256
|
||||
TXD_OPTS_hud = 128 128
|
||||
TXD_OPTS_menu = 512 512 \
|
||||
--delete-tex mapTop03 --delete-tex mapTop02 --delete-tex mapTop01 \
|
||||
--delete-tex mapMid03 --delete-tex mapMid02 --delete-tex mapMid01 \
|
||||
--delete-tex mapBot03 --delete-tex mapBot02 --delete-tex mapBot01
|
||||
TXD_OPTS_LOADSC0 = 512 512
|
||||
TXD_OPTS_LOADSC1 = 512 512
|
||||
TXD_OPTS_LOADSC10 = 512 512
|
||||
@@ -364,15 +369,12 @@ TXD_OPTS_frontend = 512 512 \
|
||||
--include-tex assets/ps4_f.png ps4_f \
|
||||
--include-tex assets/xbox_d.png xbox_d \
|
||||
--include-tex assets/xbox_f.png xbox_f
|
||||
TXD_OPTS_generic = 512 512
|
||||
TXD_OPTS_MISC = 512 512
|
||||
TXD_OPTS_particle = 512 512
|
||||
|
||||
DEFAULT_RES = 512
|
||||
|
||||
PVR_ENCODER ?= PVRTEX
|
||||
TEXTURE_DOWNSAMPLE_TXD ?= NONE
|
||||
TEXTURE_DOWNSAMPLE_IMG ?= NONE
|
||||
TEXTURE_DOWNSAMPLE_IMG ?= HALF
|
||||
|
||||
-include texlist.mk
|
||||
-include modlist.mk
|
||||
@@ -400,11 +402,6 @@ STREAM_ADPCM_DC = $(addprefix $(REPACK_STREAM_DEST_DIR)/, $(STREAM_WAV:.wav=.APM
|
||||
IMG_TEXTURES_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_TEXTURES))
|
||||
IMG_MODELS_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_MODELS))
|
||||
|
||||
ALL_TEXTURES_ORIG = $(addprefix $(GTA_DIR)/,$(MISC_TXD)) $(IMG_TEXTURES_ORIG)
|
||||
ALL_TEXTURES_EXTRACT_PATH = $(addprefix $(REPACK_MISC_TXD_EXTRACT_DIR)/,$(MISC_TXD)) $(IMG_TEXTURES_ORIG)
|
||||
ALL_TEXTURES_ORIG_EXTRACT_txd = $(ALL_TEXTURES_EXTRACT_PATH:.txd=.extract)
|
||||
ALL_TEXTURES_ORIG_EXTRACT = $(ALL_TEXTURES_ORIG_EXTRACT_txd:.TXD=.extract)
|
||||
|
||||
CUTS_IFP_ORIG = $(addprefix $(REPACK_CUTS_ORIG_DIR)/, $(CUTS_IFP))
|
||||
CUTS_MISC_ORIG = $(addprefix $(REPACK_CUTS_ORIG_DIR)/, $(CUTS_MISC))
|
||||
|
||||
@@ -415,85 +412,12 @@ SFX_REPACK_DC = $(SFX_REPACK_DC_WAV:.wav=.pcm)
|
||||
STREAM_MP3_DECODED = $(addprefix $(REPACK_STREAM_DECODED_DIR)/, $(STREAM_MP3:.mp3=.wav))
|
||||
STREAM_WAV_DECODED = $(addprefix $(REPACK_STREAM_DECODED_DIR)/, $(STREAM_WAV))
|
||||
|
||||
.PRECIOUS: $(SFX_ORIG) $(SFX_REPACK_DC) $(STREAM_MP3_DECODED) $(STREAM_WAV_DECODED) $(ALL_TEXTURES_ORIG_EXTRACT)
|
||||
.PRECIOUS: $(SFX_ORIG) $(SFX_REPACK_DC) $(STREAM_MP3_DECODED) $(STREAM_WAV_DECODED)
|
||||
|
||||
# extracting textures from .txd
|
||||
|
||||
# loose, gamefiles
|
||||
$(REPACK_MISC_TXD_EXTRACT_DIR)/%.extract: $(GTA_GAMEFILES_LOOSE_DIR)/%.TXD texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) $(TXD_OPTS_$(notdir $*)) -e extract
|
||||
@touch $@
|
||||
$(REPACK_MISC_TXD_EXTRACT_DIR)/%.extract: $(GTA_GAMEFILES_LOOSE_DIR)/%.txd texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) $(TXD_OPTS_$(notdir $*)) -e extract
|
||||
@touch $@
|
||||
|
||||
# loose, originals
|
||||
$(REPACK_MISC_TXD_EXTRACT_DIR)/%.extract: $(GTA_DIR)/%.TXD texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) $(TXD_OPTS_$(notdir $*)) -e extract
|
||||
@touch $@
|
||||
$(REPACK_MISC_TXD_EXTRACT_DIR)/%.extract: $(GTA_DIR)/%.txd texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) $(TXD_OPTS_$(notdir $*)) -e extract
|
||||
@touch $@
|
||||
|
||||
# img files
|
||||
$(REPACK_IMG_ORIG_DIR)/%.extract: $(REPACK_IMG_ORIG_DIR)/%.TXD texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) 1024 1024 -e extract
|
||||
@touch $@
|
||||
|
||||
$(REPACK_IMG_ORIG_DIR)/%.extract: $(REPACK_IMG_ORIG_DIR)/%.txd texconv
|
||||
@rm -rf $(basename $@).contents
|
||||
@mkdir -p $(basename $@).contents
|
||||
@mkdir -p $(REPACK_TEXTURES_DIR)
|
||||
./texconv $< $(basename $@) 1024 1024 -e extract
|
||||
@touch $@
|
||||
|
||||
|
||||
$(REPACK_DIR)/extracted: $(ALL_TEXTURES_ORIG_EXTRACT)
|
||||
echo && echo && echo "Extracted TXDs" && echo && echo
|
||||
@touch $@
|
||||
|
||||
# Clustering them
|
||||
|
||||
$(REPACK_DIR)/clustered: $(REPACK_DIR)/extracted ../src/tools/pal-clusters.py
|
||||
echo "Creating clusters..."
|
||||
python3 ../src/tools/pal-clusters.py $(REPACK_TEXTURES_DIR) $(REPACK_TEXTURE_CLUSTERS_DIR)
|
||||
echo && echo && echo "Created texture clusters" && echo && echo
|
||||
@touch $@
|
||||
|
||||
# Palette creation
|
||||
|
||||
CLUSTERS := $(shell seq 0 63)
|
||||
PAL_FILES := $(foreach cluster,$(CLUSTERS),$(REPACK_TEXTURE_CLUSTERS_DIR)/$(cluster).pal)
|
||||
|
||||
$(REPACK_TEXTURE_CLUSTERS_DIR)/%.pal: $(REPACK_DIR)/clustered | pvrtex
|
||||
../vendor/pvrtex/pvrtex $$(ls $(REPACK_TEXTURE_CLUSTERS_DIR)/cluster_$*/*.tga | sed 's/^/-i /') -f PAL4BPP -o $@
|
||||
|
||||
$(REPACK_GTA_DIR)/dc-palette: $(REPACK_DIR)/clustered $(PAL_FILES) merge-palettes
|
||||
./merge-palettes $(REPACK_TEXTURE_CLUSTERS_DIR) $(REPACK_GTA_DIR)/dc-palette
|
||||
echo && echo && echo "Created cluster palettes" && echo && echo
|
||||
|
||||
|
||||
|
||||
$(REPACK_DIR)/repacked: $(REPACK_GTA_DIR)/models/gta3.img $(REPACK_GTA_DIR)/models/gta3.dir $(LOOSE_FILES_DC) $(STREAM_ADPCM_DC) $(SFX_DC_RAW) $(SFX_DC_DSC) streamheaderpack $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_DIR)/repacked: $(REPACK_GTA_DIR)/models/gta3.img $(REPACK_GTA_DIR)/models/gta3.dir $(LOOSE_FILES_DC) $(STREAM_ADPCM_DC) $(SFX_DC_RAW) $(SFX_DC_DSC) streamheaderpack
|
||||
mkdir -p $(@D)
|
||||
# $(REPACK_GTA_DIR) needed as first argument as paths in the game prefix with stream/
|
||||
./streamheaderpack liberty $(REPACK_GTA_DIR) $(REPACK_STREAM_DEST_DIR)/hdr.bin
|
||||
cp $(REPACK_GTA_DIR)/dc-palette $(REPACK_GTA_DIR)/dc-palette.pal
|
||||
@git archive --format zip --output "$(REPACK_GTA_DIR)/DCA3-$(GIT_VERSION).zip" HEAD
|
||||
@touch $@
|
||||
@echo && echo && echo "*** Repack Completed Successfully ($(PROJECT_NAME)) ***" && echo && echo
|
||||
@@ -532,18 +456,18 @@ $(REPACK_IMG_DC_DIR)/%.DFF: $(REPACK_IMG_ORIG_DIR)/%.DFF texconv
|
||||
./texconv $< $@
|
||||
|
||||
# first try the mods img directory. NB, the textures are not resized here, unlike normal .img textures
|
||||
$(REPACK_IMG_DC_DIR)/%.txd: $(GTA_MOD_IMG_DIR)/%.txd texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_IMG_DC_DIR)/%.txd: $(GTA_MOD_IMG_DIR)/%.txd texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ 1024 1024 -e $(PVR_ENCODER) -d NONE
|
||||
$(REPACK_IMG_DC_DIR)/%.TXD: $(GTA_MOD_IMG_DIR)/%.TXD texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_IMG_DC_DIR)/%.TXD: $(GTA_MOD_IMG_DIR)/%.TXD texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ 1024 1024 -e $(PVR_ENCODER) -d NONE
|
||||
|
||||
# if not, the extracted img directory
|
||||
$(REPACK_IMG_DC_DIR)/%.txd: $(REPACK_IMG_ORIG_DIR)/%.txd texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_IMG_DC_DIR)/%.txd: $(REPACK_IMG_ORIG_DIR)/%.txd texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(DEFAULT_RES) $(DEFAULT_RES) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_IMG)
|
||||
$(REPACK_IMG_DC_DIR)/%.TXD: $(REPACK_IMG_ORIG_DIR)/%.TXD texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_IMG_DC_DIR)/%.TXD: $(REPACK_IMG_ORIG_DIR)/%.TXD texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(DEFAULT_RES) $(DEFAULT_RES) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_IMG)
|
||||
|
||||
@@ -589,26 +513,26 @@ $(REPACK_GTA_DIR)/%.DFF: $(GTA_DIR)/%.DFF texconv
|
||||
|
||||
# first try the mods loose directory
|
||||
# Note the mods loose directory is not resized, unlike the normal .txd textures
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_MOD_LOOSE_DIR)/%.txd texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_MOD_LOOSE_DIR)/%.txd texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ 1024 1024 -e $(PVR_ENCODER) -d NONE
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_MOD_LOOSE_DIR)/%.TXD texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_MOD_LOOSE_DIR)/%.TXD texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ 1024 1024 -e $(PVR_ENCODER) -d NONE
|
||||
|
||||
# then the gamefiles directory
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_GAMEFILES_LOOSE_DIR)/%.txd texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_GAMEFILES_LOOSE_DIR)/%.txd texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(TXD_OPTS_$(notdir $*)) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_TXD)
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_GAMEFILES_LOOSE_DIR)/%.TXD texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_GAMEFILES_LOOSE_DIR)/%.TXD texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(TXD_OPTS_$(notdir $*)) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_TXD)
|
||||
|
||||
# if not, the original files
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_DIR)/%.txd texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.txd: $(GTA_DIR)/%.txd texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(TXD_OPTS_$(notdir $*)) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_TXD)
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_DIR)/%.TXD texconv $(REPACK_GTA_DIR)/dc-palette
|
||||
$(REPACK_GTA_DIR)/%.TXD: $(GTA_DIR)/%.TXD texconv
|
||||
@mkdir -p $(@D)
|
||||
./texconv $< $@ $(TXD_OPTS_$(notdir $*)) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_TXD)
|
||||
|
||||
|
||||
BIN
liberty/assets/0GDTEX.PVR
Normal file
BIN
liberty/assets/0GDTEX.PVR
Normal file
Binary file not shown.
BIN
liberty/assets/0GDTEX.png
Normal file
BIN
liberty/assets/0GDTEX.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
liberty/assets/settings.ico
Normal file
BIN
liberty/assets/settings.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
@@ -1,46 +1,6 @@
|
||||
# models/coll/peds.col # not actually used
|
||||
MISC_TXD = \
|
||||
models/fonts.txd \
|
||||
models/frontend.txd \
|
||||
models/generic.txd \
|
||||
models/hud.txd \
|
||||
models/menu.txd \
|
||||
models/MISC.TXD \
|
||||
models/particle.txd \
|
||||
txd/LOADSC0.TXD \
|
||||
txd/LOADSC1.TXD \
|
||||
txd/LOADSC10.TXD \
|
||||
txd/LOADSC11.TXD \
|
||||
txd/LOADSC12.TXD \
|
||||
txd/LOADSC13.TXD \
|
||||
txd/LOADSC14.TXD \
|
||||
txd/LOADSC15.TXD \
|
||||
txd/LOADSC16.TXD \
|
||||
txd/LOADSC17.TXD \
|
||||
txd/LOADSC18.TXD \
|
||||
txd/LOADSC19.TXD \
|
||||
txd/LOADSC2.TXD \
|
||||
txd/LOADSC20.TXD \
|
||||
txd/LOADSC21.TXD \
|
||||
txd/LOADSC22.TXD \
|
||||
txd/LOADSC23.TXD \
|
||||
txd/LOADSC24.TXD \
|
||||
txd/LOADSC25.TXD \
|
||||
txd/LOADSC3.TXD \
|
||||
txd/LOADSC4.TXD \
|
||||
txd/LOADSC5.TXD \
|
||||
txd/LOADSC6.TXD \
|
||||
txd/LOADSC7.TXD \
|
||||
txd/LOADSC8.TXD \
|
||||
txd/LOADSC9.TXD \
|
||||
txd/mainsc1.txd \
|
||||
txd/mainsc2.txd \
|
||||
txd/NEWS.TXD \
|
||||
txd/SPLASH1.TXD \
|
||||
txd/SPLASH2.TXD \
|
||||
txd/SPLASH3.TXD
|
||||
|
||||
MISC_FILES = $(MISC_TXD) \
|
||||
MISC_FILES = \
|
||||
anim/cuts.dir \
|
||||
anim/cuts.img \
|
||||
anim/gta3.ini \
|
||||
@@ -176,4 +136,44 @@ MISC_FILES = $(MISC_TXD) \
|
||||
TEXT/italian.gxt \
|
||||
TEXT/spanish.gxt \
|
||||
\
|
||||
models/fonts.txd \
|
||||
models/frontend.txd \
|
||||
models/generic.txd \
|
||||
models/hud.txd \
|
||||
models/menu.txd \
|
||||
models/MISC.TXD \
|
||||
models/particle.txd \
|
||||
txd/LOADSC0.TXD \
|
||||
txd/LOADSC1.TXD \
|
||||
txd/LOADSC10.TXD \
|
||||
txd/LOADSC11.TXD \
|
||||
txd/LOADSC12.TXD \
|
||||
txd/LOADSC13.TXD \
|
||||
txd/LOADSC14.TXD \
|
||||
txd/LOADSC15.TXD \
|
||||
txd/LOADSC16.TXD \
|
||||
txd/LOADSC17.TXD \
|
||||
txd/LOADSC18.TXD \
|
||||
txd/LOADSC19.TXD \
|
||||
txd/LOADSC2.TXD \
|
||||
txd/LOADSC20.TXD \
|
||||
txd/LOADSC21.TXD \
|
||||
txd/LOADSC22.TXD \
|
||||
txd/LOADSC23.TXD \
|
||||
txd/LOADSC24.TXD \
|
||||
txd/LOADSC25.TXD \
|
||||
txd/LOADSC3.TXD \
|
||||
txd/LOADSC4.TXD \
|
||||
txd/LOADSC5.TXD \
|
||||
txd/LOADSC6.TXD \
|
||||
txd/LOADSC7.TXD \
|
||||
txd/LOADSC8.TXD \
|
||||
txd/LOADSC9.TXD \
|
||||
txd/mainsc1.txd \
|
||||
txd/mainsc2.txd \
|
||||
txd/NEWS.TXD \
|
||||
txd/SPLASH1.TXD \
|
||||
txd/SPLASH2.TXD \
|
||||
txd/SPLASH3.TXD \
|
||||
\
|
||||
audio/sfx.SDT
|
||||
|
||||
@@ -118,6 +118,7 @@ OBJS_NO_FAST_MATH = \
|
||||
../src/miami/core/Cam.o \
|
||||
../src/miami/core/Camera.o \
|
||||
../src/miami/vehicles/Bike.o \
|
||||
../src/miami/vehicles/Boat.o \
|
||||
../src/miami/renderer/Particle.o
|
||||
|
||||
KOS_CPPFLAGS += -fbuiltin -ffast-math -ffp-contract=fast \
|
||||
@@ -182,7 +183,15 @@ $(TARGET): $(OBJS)
|
||||
run: $(TARGET)
|
||||
$(KOS_LOADER) $(TARGET)
|
||||
|
||||
$(REPACK_GTA_DIR)/GTAVCSF8.b: GTAVCSF8.b
|
||||
$(REPACK_GTA_DIR)/GTAVCSF8.b: assets/GTAVCSF8.b
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
$(REPACK_GTA_DIR)/0GDTEX.PVR: assets/0GDTEX.PVR
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
$(REPACK_GTA_DIR)/%.ico: assets/%.ico
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
@@ -201,20 +210,20 @@ IP.BIN:
|
||||
rm -f IP.BIN
|
||||
$(KOS_BASE)/utils/makeip/makeip ip.txt IP.BIN
|
||||
|
||||
$(PROJECT_NAME).iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME).iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME).iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ.BIN $(REPACK_GTA_DIR)
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME).iso $(REPACK_GTA_DIR)
|
||||
|
||||
$(PROJECT_NAME)-no-repack.iso: IP.BIN 1ST_READ.BIN $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME)-no-repack.iso: IP.BIN 1ST_READ.BIN $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME)-no-repack.iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ.BIN $(REPACK_GTA_DIR)
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME)-no-repack.iso $(REPACK_GTA_DIR)
|
||||
|
||||
|
||||
$(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(PROJECT_NAME).ds.iso
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp $(TARGET).bin $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
@@ -225,7 +234,7 @@ $(PROJECT_NAME).ds.iso: IP.BIN 1ST_READ.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_
|
||||
$(KOS_BASE)/utils/scramble/scramble $(TARGET)-prebuilt.bin 1ST_READ_PREBUILT.BIN
|
||||
mkdir -p $(REPACK_GTA_DIR)
|
||||
|
||||
$(PROJECT_NAME)-prebuilt.iso: IP.BIN 1ST_READ_PREBUILT.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME)-prebuilt.iso: IP.BIN 1ST_READ_PREBUILT.BIN $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
rm -f $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
cp 1ST_READ_PREBUILT.BIN $(REPACK_GTA_DIR)/1ST_READ.BIN
|
||||
mkisofs -C 0,11702 -V $(PROJECT_NAME) -G IP.BIN -r -J -l -o $(PROJECT_NAME).iso $(REPACK_GTA_DIR)
|
||||
@@ -244,15 +253,15 @@ $(PROJECT_NAME)-prebuilt.cdi: $(PROJECT_NAME)-prebuilt.iso
|
||||
rm 1ST_READ_PREBUILT.BIN
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
else
|
||||
$(PROJECT_NAME).cdi: $(TARGET) $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME).cdi: $(TARGET) $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME).cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
|
||||
$(PROJECT_NAME)-no-repack.cdi: $(TARGET) $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME)-no-repack.cdi: $(TARGET) $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME)-no-repack.cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
|
||||
$(PROJECT_NAME)-prebuilt.cdi: $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b
|
||||
$(PROJECT_NAME)-prebuilt.cdi: $(REPACK_DIR)/repacked $(REPACK_GTA_DIR)/GTAVCSF8.b $(REPACK_GTA_DIR)/0GDTEX.PVR $(REPACK_GTA_DIR)/settings.ico
|
||||
mkdcdisc -e $(TARGET) -o $(PROJECT_NAME).cdi -d $(REPACK_GTA_DIR)/ $(MKDCDISC_PAD_OPTION) -n $(PROJECT_NAME) -a $(TEAM_NAME) -s $(DISC_SERIAL) -r $(RELEASE_DATE)
|
||||
@echo && echo && echo "*** CDI Baked Successfully ($@) ***" && echo && echo
|
||||
endif
|
||||
|
||||
BIN
miami/assets/0GDTEX.PVR
Normal file
BIN
miami/assets/0GDTEX.PVR
Normal file
Binary file not shown.
BIN
miami/assets/0GDTEX.png
Normal file
BIN
miami/assets/0GDTEX.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
miami/assets/settings.ico
Normal file
BIN
miami/assets/settings.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 766 B |
@@ -173,6 +173,7 @@ public:
|
||||
char GetCDAudioDriveLetter (void);
|
||||
|
||||
void UpdateEffectsVolume(void);
|
||||
void UpdateStreamsVolume(void);
|
||||
|
||||
#ifdef DC_SH4
|
||||
void UpdateChannelVolume(uint32 nChannel);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "crossplatform.h"
|
||||
|
||||
#if !defined(AUDIO_OAL) && !defined(AUDIO_MSS)
|
||||
#define syncf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define streamf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define verbosef(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define debugf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
|
||||
@@ -47,6 +49,8 @@
|
||||
/* Quick access to the AICA channels */
|
||||
#define AICA_CHANNEL(x) (AICA_MEM_CHANNELS + (x) * sizeof(aica_channel_t))
|
||||
|
||||
static uint32_t chn_version[64];
|
||||
|
||||
int aica_play_chn(int chn, int size, uint32_t aica_buffer, int fmt, int vol, int pan, int loop, int freq) {
|
||||
// assert(size <= 65534);
|
||||
// We gotta fix this at some point
|
||||
@@ -70,6 +74,7 @@ int aica_play_chn(int chn, int size, uint32_t aica_buffer, int fmt, int vol, int
|
||||
chan->freq = freq;
|
||||
chan->vol = vol;
|
||||
chan->pan = pan;
|
||||
chan->version = ++chn_version[chn];
|
||||
snd_sh4_to_aica(tmp, cmd->size);
|
||||
return chn;
|
||||
}
|
||||
@@ -363,6 +368,13 @@ cSampleManager::Initialise(void)
|
||||
if (channels[i].ch != -1) {
|
||||
assert(channels[i].nSfx != -1);
|
||||
|
||||
uint32_t channel_version = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(channels[i].ch) + offsetof(aica_channel_t, version));
|
||||
|
||||
if (chn_version[channels[i].ch] != channel_version) {
|
||||
syncf("Stream version missmatch, skipping update. expected %d got %d\n", chn_version[channels[i].ch], channel_version);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t channel_pos = (g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(channels[i].ch) + offsetof(aica_channel_t, pos)) & 0xffff);
|
||||
// verbosef("Channel %d pos: %d\n", i, channel_pos);
|
||||
if (!channels[i].loop) {
|
||||
@@ -389,21 +401,28 @@ cSampleManager::Initialise(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(streams[i].mtx);
|
||||
if (streams[i].playing) {
|
||||
uint32_t channel_version = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(streams[i].mapped_ch[0]) + offsetof(aica_channel_t, version));
|
||||
|
||||
if (chn_version[streams[i].mapped_ch[0]] != channel_version) {
|
||||
syncf("Stream version missmatch, skipping update. expected %d got %d\n", chn_version[streams[i].mapped_ch[0]], channel_version);
|
||||
continue;
|
||||
}
|
||||
|
||||
// get channel pos
|
||||
uint32_t channel_pos = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(streams[i].mapped_ch[0]) + offsetof(aica_channel_t, pos)) & 0xffff;
|
||||
uint32_t logical_pos = channel_pos;
|
||||
if (logical_pos > STREAM_CHANNEL_SAMPLE_COUNT/2) {
|
||||
logical_pos -= STREAM_CHANNEL_SAMPLE_COUNT/2;
|
||||
}
|
||||
verbosef("Stream %d pos: %d, log: %d, rem: %d\n", i, channel_pos, logical_pos, streams[i].played_samples);
|
||||
streamf("Stream %d pos: %d, log: %d, played: %d\n", i, channel_pos, logical_pos, streams[i].played_samples);
|
||||
|
||||
bool can_refill = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_fetch = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_refill = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + (!streams[i].first_refill)*STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_fetch = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2 + (!streams[i].first_refill)*STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
// copy over data if needed from staging
|
||||
if (channel_pos >= STREAM_CHANNEL_SAMPLE_COUNT/2 && !streams[i].next_is_upper_half) {
|
||||
streams[i].next_is_upper_half = true;
|
||||
if (can_refill) { // could we need a refill?
|
||||
verbosef("Filling channel %d with lower half\n", i);
|
||||
streamf("Filling channel %d with lower half\n", i);
|
||||
// fill lower half
|
||||
spu_memload(streams[i].aica_buffers[0], streams[i].buffer, STREAM_CHANNEL_BUFFER_SIZE/2);
|
||||
if (streams[i].stereo) {
|
||||
@@ -419,7 +438,7 @@ cSampleManager::Initialise(void)
|
||||
} else if (channel_pos < STREAM_CHANNEL_SAMPLE_COUNT/2 && streams[i].next_is_upper_half) {
|
||||
streams[i].next_is_upper_half = false;
|
||||
if (can_refill) { // could we need a refill?
|
||||
verbosef("Filling channel %d with upper half\n", i);
|
||||
streamf("Filling channel %d with upper half\n", i);
|
||||
// fill upper half
|
||||
spu_memload(streams[i].aica_buffers[0] + STREAM_CHANNEL_BUFFER_SIZE/2, streams[i].buffer, STREAM_CHANNEL_BUFFER_SIZE/2);
|
||||
if (streams[i].stereo) {
|
||||
@@ -439,7 +458,7 @@ cSampleManager::Initialise(void)
|
||||
// if end of file, stop
|
||||
if ((streams[i].played_samples + logical_pos) > streams[i].total_samples) {
|
||||
// stop channel
|
||||
debugf("Auto stopping stream: %d -> {%d, %d}, %d total\n", i, streams[i].mapped_ch[0], streams[i].mapped_ch[1], streams[i].total_samples);
|
||||
streamf("Auto stopping stream: %d -> {%d, %d}, %d total\n", i, streams[i].mapped_ch[0], streams[i].mapped_ch[1], streams[i].total_samples);
|
||||
aica_stop_chn(streams[i].mapped_ch[0]);
|
||||
aica_stop_chn(streams[i].mapped_ch[1]);
|
||||
streams[i].playing = false;
|
||||
@@ -447,7 +466,7 @@ cSampleManager::Initialise(void)
|
||||
}
|
||||
|
||||
if (do_read) {
|
||||
debugf("Queueing stream read: %d, file: %d, buffer: %p, size: %d, tell: %d\n", i, streams[i].fd, streams[i].buffer, do_read, fs_tell(streams[i].fd));
|
||||
streamf("Queueing stream read: %d, file: %d, buffer: %p, size: %d, file_offset: %d\n", i, streams[i].fd, streams[i].buffer, do_read, streams[i].file_offset);
|
||||
CdStreamQueueAudioRead(streams[i].fd, streams[i].buffer, do_read, streams[i].file_offset);
|
||||
streams[i].file_offset += do_read;
|
||||
}
|
||||
@@ -487,6 +506,7 @@ cSampleManager::Initialise(void)
|
||||
void
|
||||
cSampleManager::Terminate(void)
|
||||
{
|
||||
CdStreamDiscardAudioRead(fdPedSfx);
|
||||
fs_close(fdPedSfx);
|
||||
}
|
||||
|
||||
@@ -525,6 +545,7 @@ void
|
||||
cSampleManager::SetMusicMasterVolume(uint8 nVolume)
|
||||
{
|
||||
m_nMusicVolume = nVolume;
|
||||
UpdateStreamsVolume();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -538,6 +559,7 @@ void
|
||||
cSampleManager::SetMusicFadeVolume(uint8 nVolume)
|
||||
{
|
||||
m_nMusicFadeVolume = nVolume;
|
||||
UpdateStreamsVolume();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -737,9 +759,9 @@ cSampleManager::LoadPedComment(uint32 nComment)
|
||||
|
||||
assert(m_aSamples[nComment].nByteSize <= PED_BLOCKSIZE_ADPCM);
|
||||
|
||||
CdStreamQueueAudioRead(nComment, (void*)nPedSlotSfxAddr[nCurrentPedSlot], m_aSamples[nComment].nByteSize, m_aSamples[nComment].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
CdStreamQueueAudioRead(fdPedSfx, (void*)nPedSlotSfxAddr[nCurrentPedSlot], m_aSamples[nComment].nByteSize, m_aSamples[nComment].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
debugf("Loading ped comment %d, offset: %d, size: %d\n", nComment, m_aSamples[nComment].nFileOffset, m_aSamples[nComment].nByteSize);
|
||||
fs_seek(fdPedSfx, cmd->seek, SEEK_SET);
|
||||
assert(fs_seek(fdPedSfx, cmd->seek, SEEK_SET) == cmd->seek);
|
||||
|
||||
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
@@ -1027,7 +1049,7 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream, uint32_t seek_by
|
||||
{
|
||||
ASSERT( nStream < MAX_STREAMS );
|
||||
file_t f = fs_open(DCStreamedNameTable[nFile], O_RDONLY);
|
||||
debugf("PreloadStreamedFile(%p, %d, %d) is %s\n", f, nFile, nStream, DCStreamedNameTable[nFile]);
|
||||
streamf("PreloadStreamedFile(%p, %d, %d) is %s\n", f, nFile, nStream, DCStreamedNameTable[nFile]);
|
||||
assert(f >= 0 );
|
||||
WavHeader hdr;
|
||||
assert(fs_read(f, &hdr, sizeof(hdr)) == sizeof(hdr));
|
||||
@@ -1050,13 +1072,13 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream, uint32_t seek_by
|
||||
streams[nStream].next_is_upper_half = true;
|
||||
streams[nStream].first_refill = true;
|
||||
|
||||
debugf("PreloadStreamedFile: %s: stream: %d, freq: %d, chans: %d, byte size: %d, played samples: %d\n", DCStreamedNameTable[nFile], nStream, hdr.samplesPerSec, hdr.numOfChan, hdr.dataSize, streams[nStream].played_samples);
|
||||
streamf("PreloadStreamedFile: %s: stream: %d, freq: %d, chans: %d, byte size: %d, played samples: %d\n", DCStreamedNameTable[nFile], nStream, hdr.samplesPerSec, hdr.numOfChan, hdr.dataSize, streams[nStream].played_samples);
|
||||
|
||||
|
||||
// How to avoid the lock?
|
||||
if (seek_bytes_aligned) {
|
||||
streams[nStream].played_samples = seek_bytes_aligned * (streams[nStream].stereo ? 1 : 2);
|
||||
debugf("Seeking aligned to: %d, played_samples: %d\n", seek_bytes_aligned, streams[nStream].played_samples);
|
||||
streamf("Seeking aligned to: %d, played_samples: %d\n", seek_bytes_aligned, streams[nStream].played_samples);
|
||||
fs_seek(streams[nStream].fd, 2048 + seek_bytes_aligned, SEEK_SET);
|
||||
} else {
|
||||
fs_seek(f, 2048, SEEK_SET);
|
||||
@@ -1085,7 +1107,7 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream, uint32_t seek_by
|
||||
streams[nStream].file_offset = fs_tell(f);
|
||||
}
|
||||
|
||||
verbosef("PreloadStreamedFile: %p %d - %s, %d, %d, \n", f, nFile, DCStreamedNameTable[nFile], streams[nStream].rate, streams[nStream].stereo);
|
||||
streamf("PreloadStreamedFile: %p %d - %s, %d, %d, \n", f, nFile, DCStreamedNameTable[nFile], streams[nStream].rate, streams[nStream].stereo);
|
||||
}
|
||||
|
||||
// we can't really pause a stream, so we just make it go very slow with zero volume
|
||||
@@ -1208,12 +1230,29 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static uint8 nStreamVolumes[MAX_STREAMS];
|
||||
static uint8 nStreamPans[MAX_STREAMS];
|
||||
static uint8 nStreamEffect[MAX_STREAMS];
|
||||
void
|
||||
cSampleManager::UpdateStreamsVolume(void)
|
||||
{
|
||||
if(_bSampmanInitialised) {
|
||||
for (int nStream = 0; nStream < MAX_STREAMS; nStream++) {
|
||||
SetStreamedVolumeAndPan(nStreamVolumes[nStream], nStreamPans[nStream], nStreamEffect[nStream], nStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
|
||||
{
|
||||
ASSERT( nStream < MAX_STREAMS );
|
||||
if (nVolume > MAX_VOLUME)
|
||||
nVolume = MAX_VOLUME;
|
||||
nStreamVolumes[nStream] = nVolume;
|
||||
nStreamPans[nStream] = nPan;
|
||||
nStreamEffect[nStream] = nEffectFlag;
|
||||
nVolume = linearlize_volume(nVolume); //nVolume * 255 / MAX_VOLUME;
|
||||
nVolume = m_nMusicFadeVolume * nVolume * m_nMusicVolume >> 14;
|
||||
if (streams[nStream].vol != nVolume || streams[nStream].nPan != nPan) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct CColLine
|
||||
struct alignas(8) CColLine
|
||||
{
|
||||
// NB: this has to be compatible with two CVuVectors
|
||||
CVector p0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct CColPoint
|
||||
struct alignas(8) CColPoint
|
||||
{
|
||||
CVector point;
|
||||
int pad1;
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
|
||||
#include "SurfaceTable.h"
|
||||
|
||||
struct CColSphere
|
||||
struct alignas(8) CColSphere
|
||||
{
|
||||
// NB: this has to be compatible with a CVuVector
|
||||
CVector center;
|
||||
float radius;
|
||||
uint8 surface;
|
||||
uint8 piece;
|
||||
void Set(float radius, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0) {
|
||||
this->radius = radius;
|
||||
this->surface = surf;
|
||||
this->piece = piece;
|
||||
}
|
||||
void Set(float radius, const CVector ¢er, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0);
|
||||
};
|
||||
@@ -23,6 +23,10 @@
|
||||
#include "Collision.h"
|
||||
#include "Frontend.h"
|
||||
|
||||
#ifdef DC_SH4
|
||||
#include "VuCollision.h"
|
||||
#endif
|
||||
|
||||
#ifdef VU_COLLISION
|
||||
#include "VuCollision.h"
|
||||
|
||||
@@ -737,7 +741,12 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
|
||||
|
||||
// transform line to model space
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline(matTransform * line.p0, matTransform * line.p1);
|
||||
CColLine newline;
|
||||
#ifndef DC_SH4
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#else
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#endif
|
||||
|
||||
// If we don't intersect with the bounding box, no chance on the rest
|
||||
if(!TestLineBox(newline, model.boundingBox))
|
||||
@@ -1577,7 +1586,12 @@ CCollision::ProcessLineOfSight(const CColLine &line,
|
||||
|
||||
// transform line to model space
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline(matTransform * line.p0, matTransform * line.p1);
|
||||
CColLine newline;
|
||||
#ifdef DC_SH4
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#else
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#endif
|
||||
|
||||
// If we don't intersect with the bounding box, no chance on the rest
|
||||
if(!TestLineBox(newline, model.boundingBox))
|
||||
@@ -1601,8 +1615,18 @@ CCollision::ProcessLineOfSight(const CColLine &line,
|
||||
}
|
||||
|
||||
if(coldist < mindist){
|
||||
#ifndef DC_SH4
|
||||
point.point = matrix * point.point;
|
||||
point.normal = Multiply3x3(matrix, point.normal);
|
||||
#else
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrix)));
|
||||
mat_trans_single3_nodiv(point.point.x,
|
||||
point.point.y,
|
||||
point.point.z);
|
||||
mat_trans_normal3(point.normal.x,
|
||||
point.normal.y,
|
||||
point.normal.z);
|
||||
#endif
|
||||
mindist = coldist;
|
||||
return true;
|
||||
}
|
||||
@@ -1739,9 +1763,14 @@ CCollision::ProcessVerticalLine(const CColLine &line,
|
||||
|
||||
// transform line to model space
|
||||
// Why does the game seem to do this differently than above?
|
||||
CColLine newline(MultiplyInverse(matrix, line.p0), MultiplyInverse(matrix, line.p1));
|
||||
newline.p1.x = newline.p0.x;
|
||||
newline.p1.y = newline.p0.y;
|
||||
CMatrix matTransform;
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline;
|
||||
#ifndef DC_SH4
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#else
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#endif
|
||||
|
||||
if(!TestVerticalLineBox(newline, model.boundingBox))
|
||||
return false;
|
||||
@@ -1765,14 +1794,31 @@ CCollision::ProcessVerticalLine(const CColLine &line,
|
||||
}
|
||||
|
||||
if(coldist < mindist){
|
||||
#ifndef DC_SH4
|
||||
point.point = matrix * point.point;
|
||||
point.normal = Multiply3x3(matrix, point.normal);
|
||||
#else
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrix)));
|
||||
mat_trans_single3_nodiv(point.point.x,
|
||||
point.point.y,
|
||||
point.point.z);
|
||||
mat_trans_normal3(point.normal.x,
|
||||
point.normal.y,
|
||||
point.normal.z);
|
||||
#endif
|
||||
if(TempStoredPoly.valid && poly){
|
||||
*poly = TempStoredPoly;
|
||||
#ifndef DC_SH4
|
||||
poly->verts[0] = matrix * poly->verts[0];
|
||||
poly->verts[1] = matrix * poly->verts[1];
|
||||
poly->verts[2] = matrix * poly->verts[2];
|
||||
#else
|
||||
mat_trans_single3_nodiv(poly->verts[0].x, poly->verts[0].y, poly->verts[0].z);
|
||||
mat_trans_single3_nodiv(poly->verts[1].x, poly->verts[1].y, poly->verts[1].z);
|
||||
mat_trans_single3_nodiv(poly->verts[2].x, poly->verts[2].y, poly->verts[2].z);
|
||||
#endif
|
||||
}
|
||||
|
||||
mindist = coldist;
|
||||
return true;
|
||||
}
|
||||
@@ -2123,25 +2169,60 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
assert(modelA.numLines <= MAXNUMLINES);
|
||||
|
||||
// From model A space to model B space
|
||||
matAB = Invert(matrixB, matAB);
|
||||
Invert(matrixB, matAB);
|
||||
#ifndef DC_SH4
|
||||
matAB *= matrixA;
|
||||
#else
|
||||
mat_load(reinterpret_cast<const matrix_t*>(&matAB));
|
||||
mat_apply(reinterpret_cast<const matrix_t*>(&matrixA));
|
||||
#endif
|
||||
|
||||
CColSphere bsphereAB; // bounding sphere of A in B space
|
||||
bsphereAB.radius = modelA.boundingSphere.radius;
|
||||
#ifndef DC_SH4
|
||||
bsphereAB.center = matAB * modelA.boundingSphere.center;
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelA.boundingSphere.center.x,
|
||||
modelA.boundingSphere.center.y,
|
||||
modelA.boundingSphere.center.z,
|
||||
bsphereAB.center.x,
|
||||
bsphereAB.center.y,
|
||||
bsphereAB.center.z);
|
||||
#endif
|
||||
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
|
||||
return 0;
|
||||
// B to A space
|
||||
matBA = Invert(matrixA, matBA);
|
||||
matBA *= matrixB;
|
||||
|
||||
// transform modelA's spheres and lines to B space
|
||||
for(i = 0; i < modelA.numSpheres; i++){
|
||||
CColSphere &s = modelA.spheres[i];
|
||||
#ifndef DC_SH4
|
||||
aSpheresA[i].Set(s.radius, matAB * s.center, s.surface, s.piece);
|
||||
#else
|
||||
auto &d = aSpheresA[i];
|
||||
mat_trans_single3_nodiv_nomod(s.center.x, s.center.y, s.center.z,
|
||||
d.center.x, d.center.y, d.center.z);
|
||||
d.Set(s.radius, s.surface, s.piece);
|
||||
#endif
|
||||
}
|
||||
for(i = 0; i < modelA.numLines; i++)
|
||||
|
||||
for(i = 0; i < modelA.numLines; i++) {
|
||||
#ifndef DC_SH4
|
||||
aLinesA[i].Set(matAB * modelA.lines[i].p0, matAB * modelA.lines[i].p1);
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelA.lines[i].p0.x,
|
||||
modelA.lines[i].p0.y,
|
||||
modelA.lines[i].p0.z,
|
||||
aLinesA[i].p0.x,
|
||||
aLinesA[i].p0.y,
|
||||
aLinesA[i].p0.z);
|
||||
mat_trans_single3_nodiv_nomod(modelA.lines[i].p1.x,
|
||||
modelA.lines[i].p1.y,
|
||||
modelA.lines[i].p1.z,
|
||||
aLinesA[i].p1.x,
|
||||
aLinesA[i].p1.y,
|
||||
aLinesA[i].p1.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test them against model B's bounding volumes
|
||||
int numSpheresA = 0;
|
||||
@@ -2160,9 +2241,26 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
int numSpheresB = 0;
|
||||
int numBoxesB = 0;
|
||||
int numTrianglesB = 0;
|
||||
// B to A space
|
||||
Invert(matrixA, matBA);
|
||||
#ifndef DC_SH4
|
||||
matBA *= matrixB;
|
||||
#else
|
||||
mat_load(reinterpret_cast<const matrix_t*>(&matBA));
|
||||
mat_apply(reinterpret_cast<const matrix_t*>(&matrixB));
|
||||
#endif
|
||||
for(i = 0; i < modelB.numSpheres; i++){
|
||||
s.radius = modelB.spheres[i].radius;
|
||||
#ifndef DC_SH4
|
||||
s.center = matBA * modelB.spheres[i].center;
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelB.spheres[i].center.x,
|
||||
modelB.spheres[i].center.y,
|
||||
modelB.spheres[i].center.z,
|
||||
s.center.x,
|
||||
s.center.y,
|
||||
s.center.z);
|
||||
#endif
|
||||
if(TestSphereBox(s, modelA.boundingBox))
|
||||
aSphereIndicesB[numSpheresB++] = i;
|
||||
}
|
||||
@@ -2209,9 +2307,22 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
if(hasCollided)
|
||||
numCollisions++;
|
||||
}
|
||||
|
||||
#ifdef DC_SH4
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrixB)));
|
||||
#endif
|
||||
for(i = 0; i < numCollisions; i++){
|
||||
#ifndef DC_SH4
|
||||
spherepoints[i].point = matrixB * spherepoints[i].point;
|
||||
spherepoints[i].normal = Multiply3x3(matrixB, spherepoints[i].normal);
|
||||
#else
|
||||
mat_trans_single3_nodiv(spherepoints[i].point.x,
|
||||
spherepoints[i].point.y,
|
||||
spherepoints[i].point.z);
|
||||
mat_trans_normal3(spherepoints[i].normal.x,
|
||||
spherepoints[i].normal.y,
|
||||
spherepoints[i].normal.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
// And the same thing for the lines in A
|
||||
@@ -2242,8 +2353,17 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
for(i = 0; i < numLinesA; i++)
|
||||
if(aCollided[i]){
|
||||
j = aLineIndicesA[i];
|
||||
#ifndef DC_SH4
|
||||
linepoints[j].point = matrixB * linepoints[j].point;
|
||||
linepoints[j].normal = Multiply3x3(matrixB, linepoints[j].normal);
|
||||
#else
|
||||
mat_trans_single3_nodiv(linepoints[j].point.x,
|
||||
linepoints[j].point.y,
|
||||
linepoints[j].point.z);
|
||||
mat_trans_normal3(linepoints[j].normal.x,
|
||||
linepoints[j].normal.y,
|
||||
linepoints[j].normal.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
return numCollisions; // sphere collisions
|
||||
|
||||
@@ -479,6 +479,7 @@ RemoveFirstInQueue(Queue *queue)
|
||||
}
|
||||
|
||||
std::vector<AudioReadCmd> pendingAudioReads;
|
||||
volatile int pendingAudioRead_fd = -1;
|
||||
#if !defined(DC_SH4)
|
||||
std::mutex pendingAudioReadsMutex;
|
||||
#endif
|
||||
@@ -487,8 +488,9 @@ void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, st
|
||||
AudioReadCmd cmd = { pBuffer, fd, bytes, seek};
|
||||
if (!callback) {
|
||||
cmd.callback = [](AudioReadCmd* cmd){
|
||||
lseek(cmd->fd, cmd->seek, SEEK_SET);
|
||||
read(cmd->fd, cmd->dest, cmd->size);
|
||||
assert(pendingAudioRead_fd == cmd->fd);
|
||||
assert(lseek(cmd->fd, cmd->seek, SEEK_SET) == cmd->seek);
|
||||
assert(read(cmd->fd, cmd->dest, cmd->size) == cmd->size);
|
||||
};
|
||||
} else {
|
||||
cmd.callback = callback;
|
||||
@@ -500,7 +502,7 @@ void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, st
|
||||
auto mask = irq_disable();
|
||||
#endif
|
||||
for (auto it = pendingAudioReads.rbegin(); it != pendingAudioReads.rend(); ++it) {
|
||||
if (it->fd == -1 || it->fd == fd) {
|
||||
if (it->fd == -1) {
|
||||
*it = cmd;
|
||||
goto out;
|
||||
}
|
||||
@@ -532,6 +534,12 @@ void CdStreamDiscardAudioRead(int fd) {
|
||||
#if defined(DC_SH4)
|
||||
irq_restore(mask);
|
||||
#endif
|
||||
|
||||
while (pendingAudioRead_fd == fd) {
|
||||
#if defined(DC_SH4)
|
||||
thd_pass();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
AudioReadCmd CdStreamNextAudioRead() {
|
||||
@@ -548,6 +556,8 @@ AudioReadCmd CdStreamNextAudioRead() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(pendingAudioRead_fd == -1);
|
||||
pendingAudioRead_fd = cmd.fd;
|
||||
#if defined(DC_SH4)
|
||||
irq_restore(mask);
|
||||
#endif
|
||||
@@ -568,6 +578,7 @@ int read_loop(int fd, void* pBuffer, size_t bytes) {
|
||||
auto cmd = CdStreamNextAudioRead();
|
||||
while (cmd.fd != -1) {
|
||||
cmd.callback(&cmd);
|
||||
pendingAudioRead_fd = -1;
|
||||
cmd = CdStreamNextAudioRead();
|
||||
}
|
||||
}
|
||||
@@ -584,6 +595,7 @@ void *CdStreamThread(void *param)
|
||||
auto cmd = CdStreamNextAudioRead();
|
||||
while (cmd.fd != -1) {
|
||||
cmd.callback(&cmd);
|
||||
pendingAudioRead_fd = -1;
|
||||
cmd = CdStreamNextAudioRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -692,118 +692,383 @@ char *DoubleSidedNames[] = {
|
||||
"sbwy_tunl_cstm2",
|
||||
"sbwy_tunl_cstm1",
|
||||
"tenmnt6ad",
|
||||
"LUIGICLUBout",
|
||||
"redlightbuild03",
|
||||
"dinerind",
|
||||
"dinerind02",
|
||||
"franksclb02",
|
||||
"glassfx1",
|
||||
"lswank_inside",
|
||||
"luigiineerclub",
|
||||
"swank_inside",
|
||||
"train_rust",
|
||||
"glassfx2",
|
||||
"glassfx3",
|
||||
"glassfx4",
|
||||
"glassfx55",
|
||||
"glassfx_composh",
|
||||
"glassfxsub1",
|
||||
"glassfxsub2",
|
||||
""
|
||||
|
||||
};
|
||||
char *TreeNames[] = {
|
||||
"coast_treepatch",
|
||||
"comparknewtrees",
|
||||
"comtreepatchprk",
|
||||
"condotree01",
|
||||
"condotree1",
|
||||
"indatree03",
|
||||
"indtreepatch5",
|
||||
"indtreepatch06f",
|
||||
"new_carprktrees",
|
||||
"new_carprktrees4",
|
||||
"newcoasttrees1",
|
||||
"newcoasttrees2",
|
||||
"newcoasttrees3",
|
||||
"newtreepatch_sub",
|
||||
"newtrees1_sub",
|
||||
"newunitrepatch",
|
||||
"pinetree_narrow",
|
||||
"pinetree_wide",
|
||||
"treencom2",
|
||||
"treepatch",
|
||||
"treepatch01_sub",
|
||||
"treepatch02_sub",
|
||||
"treepatch2",
|
||||
"treepatch2b",
|
||||
"treepatch03",
|
||||
"treepatch03_sub",
|
||||
"treepatch04_sub",
|
||||
"treepatch05_sub",
|
||||
"treepatch06_sub",
|
||||
"treepatch07_sub",
|
||||
"treepatch08_sub",
|
||||
"treepatch09_sub",
|
||||
"treepatch10_sub",
|
||||
"treepatch11_sub",
|
||||
"treepatch12_sub",
|
||||
"treepatch13_sub",
|
||||
"treepatch14_sub",
|
||||
"treepatch15_sub",
|
||||
"treepatch16_sub",
|
||||
"treepatch17_sub",
|
||||
"treepatch18_sub",
|
||||
"treepatch19_sub",
|
||||
"treepatch20_sub",
|
||||
"treepatch21_sub",
|
||||
"treepatch22_sub",
|
||||
"treepatch23_sub",
|
||||
"treepatch24_sub",
|
||||
"treepatch25_sub",
|
||||
"treepatch26_sub",
|
||||
"treepatch27_sub",
|
||||
"treepatch28_sub",
|
||||
"treepatch29_sub",
|
||||
"treepatch30_sub",
|
||||
"treepatch31_sub",
|
||||
"treepatch32_sub",
|
||||
"treepatch33_sub",
|
||||
"treepatch34_sub",
|
||||
"treepatch35_sub",
|
||||
"treepatch69",
|
||||
"treepatch152_sub",
|
||||
"treepatch153_sub",
|
||||
"treepatch171_sub",
|
||||
"treepatch172_sub",
|
||||
"treepatch173_sub",
|
||||
"treepatch212_sub",
|
||||
"treepatch213_sub",
|
||||
"treepatch214_sub",
|
||||
"treepatcha",
|
||||
"treepatchb",
|
||||
"treepatchcomtop1",
|
||||
"treepatchd",
|
||||
"treepatche",
|
||||
"treepatchh",
|
||||
"treepatchindaa2",
|
||||
"treepatchindnew",
|
||||
"treepatchindnew2",
|
||||
"treepatchk",
|
||||
"treepatchkb4",
|
||||
"treepatchkb5",
|
||||
"treepatchkb6",
|
||||
"treepatchkb7",
|
||||
"treepatchkb9",
|
||||
"treepatchl",
|
||||
"treepatchm",
|
||||
"treepatchnew_sub",
|
||||
"treepatchttwrs",
|
||||
"treesuni1",
|
||||
"trepatchindaa1",
|
||||
"veg_bush2",
|
||||
"veg_bush14",
|
||||
"veg_tree1",
|
||||
"veg_tree3",
|
||||
"veg_treea1",
|
||||
"veg_treea3",
|
||||
"veg_treeb1",
|
||||
"veg_treenew01",
|
||||
"veg_treenew03",
|
||||
"veg_treenew05",
|
||||
"veg_treenew06",
|
||||
"veg_treenew08",
|
||||
"veg_treenew09",
|
||||
"veg_treenew10",
|
||||
"veg_treenew16",
|
||||
"veg_treenew17",
|
||||
"vegclubtree01",
|
||||
"vegclubtree02",
|
||||
"vegclubtree03",
|
||||
"vegpathtree",
|
||||
"Dam_pod1",
|
||||
"building_fucked",
|
||||
"ch_roof_kb",
|
||||
"chtwn_fmrkt",
|
||||
"hghwysgn01",
|
||||
"hghwysgn02",
|
||||
"hghwysgn_sub",
|
||||
"ind_land037",
|
||||
"ind_land125ind",
|
||||
"indbilbridge1",
|
||||
"industpatch05",
|
||||
"iten_club01",
|
||||
"iten_details7",
|
||||
"iten_washline02",
|
||||
"iten_washline03",
|
||||
"mak_Watertank",
|
||||
"mak_Watertank2",
|
||||
"mak_Watertank3",
|
||||
"pharmas",
|
||||
"rd_Road1A5",
|
||||
"rdsign02bk",
|
||||
"rdsign06",
|
||||
"rdsign14",
|
||||
"rdsign15",
|
||||
"rdsign17",
|
||||
"rdsign18bk",
|
||||
"rdsign19",
|
||||
"rdsign19",
|
||||
"wire_shed",
|
||||
"Dam_pod2",
|
||||
"Dineradam",
|
||||
"Gdyn_barrier17",
|
||||
"LODky_skyscrp6",
|
||||
"LODt_skyscrp1",
|
||||
"LODy_skyscrp23",
|
||||
"LODy_skyscrp26b",
|
||||
"Pumpfirescape",
|
||||
"Pumphouse",
|
||||
"airtower1",
|
||||
"airtower2",
|
||||
"bar_barrier10",
|
||||
"bar_barrier10b",
|
||||
"bar_barrier12",
|
||||
"bar_barrier16",
|
||||
"bar_barriergate1",
|
||||
"barrierturn",
|
||||
"billboard01",
|
||||
"billboard02",
|
||||
"billboard03",
|
||||
"carlift01",
|
||||
"carlift02",
|
||||
"carparkfence",
|
||||
"casino_garden",
|
||||
"chinabanner1",
|
||||
"chinabanner2",
|
||||
"chinabanner3",
|
||||
"chinabanner4",
|
||||
"coast_treepatch",
|
||||
"comparknewtrees",
|
||||
"comtreepatchprk",
|
||||
"condo_ivy",
|
||||
"condotree01",
|
||||
"condotree1",
|
||||
"cons_buid02",
|
||||
"cranebasea",
|
||||
"cranebaseb",
|
||||
"cranesmalltop",
|
||||
"cranetopa",
|
||||
"cranetopb",
|
||||
"csky_skyscrp23",
|
||||
"csky_skyscrp26b",
|
||||
"damfence01",
|
||||
"damfence02",
|
||||
"damfence03",
|
||||
"damfence04",
|
||||
"damfence05",
|
||||
"damfence06",
|
||||
"damfence07",
|
||||
"damfence08",
|
||||
"damfencing",
|
||||
"dinerind",
|
||||
"dinerind02",
|
||||
"dinersign",
|
||||
"doc_crane_cab",
|
||||
"doc_crane_leggs",
|
||||
"doc_shedbig1",
|
||||
"doc_shedbig12",
|
||||
"doc_shedbig13",
|
||||
"doc_shedbig2",
|
||||
"doc_shedbig3",
|
||||
"doc_shedbig31",
|
||||
"doc_shedbig4",
|
||||
"fencesmallb",
|
||||
"firescapa1",
|
||||
"firescapb1",
|
||||
"foundation",
|
||||
"glassfx1",
|
||||
"glassfx2",
|
||||
"glassfx3",
|
||||
"glassfx4",
|
||||
"glassfx55",
|
||||
"glassfx_composh",
|
||||
"glassfxsub1",
|
||||
"glassfxsub2",
|
||||
"helix_barrier",
|
||||
"ind_customroad001",
|
||||
"ind_customroad002",
|
||||
"ind_customroad003",
|
||||
"ind_customroad004",
|
||||
"ind_customroad005",
|
||||
"ind_customroad006",
|
||||
"ind_customroad008",
|
||||
"ind_customroad009",
|
||||
"ind_customroad010",
|
||||
"ind_customroad011",
|
||||
"ind_customroad012",
|
||||
"ind_customroad013",
|
||||
"ind_customroad014",
|
||||
"ind_customroad015",
|
||||
"ind_customroad016",
|
||||
"ind_customroad017",
|
||||
"ind_customroad018",
|
||||
"ind_customroad019",
|
||||
"ind_customroad020",
|
||||
"ind_customroad021",
|
||||
"ind_customroad022",
|
||||
"ind_customroad023",
|
||||
"ind_customroad024",
|
||||
"ind_customroad025",
|
||||
"ind_customroad026",
|
||||
"ind_customroad028",
|
||||
"ind_customroad029",
|
||||
"ind_customroad033",
|
||||
"ind_customroad034",
|
||||
"ind_customroad035",
|
||||
"ind_customroad036",
|
||||
"ind_customroad037",
|
||||
"ind_customroad038",
|
||||
"ind_customroad039",
|
||||
"ind_customroad040",
|
||||
"ind_customroad041",
|
||||
"ind_customroad042",
|
||||
"ind_customroad043",
|
||||
"ind_customroad044",
|
||||
"ind_customroad045",
|
||||
"ind_customroad046",
|
||||
"ind_customroad047",
|
||||
"ind_customroad048",
|
||||
"ind_customroad049",
|
||||
"ind_customroad050",
|
||||
"ind_customroad051",
|
||||
"ind_customroad052",
|
||||
"ind_customroad053",
|
||||
"ind_customroad054",
|
||||
"ind_customroad055",
|
||||
"ind_customroad056",
|
||||
"ind_customroad057",
|
||||
"ind_customroad058",
|
||||
"ind_customroad059",
|
||||
"ind_customroad060",
|
||||
"ind_customroad061",
|
||||
"ind_customroad062",
|
||||
"ind_customroad063",
|
||||
"ind_customroad064",
|
||||
"ind_customroad065",
|
||||
"ind_customroad066",
|
||||
"ind_customroad067",
|
||||
"ind_customroad068",
|
||||
"ind_customroad069",
|
||||
"ind_customroad070",
|
||||
"ind_customroad071",
|
||||
"ind_customroad072",
|
||||
"ind_customroad073",
|
||||
"ind_customroad074",
|
||||
"ind_customroad075",
|
||||
"ind_customroad076",
|
||||
"ind_customroad077",
|
||||
"ind_customroad078",
|
||||
"ind_customroad079",
|
||||
"ind_customroad080",
|
||||
"ind_customroad081",
|
||||
"ind_customroad082",
|
||||
"ind_customroad083",
|
||||
"ind_customroad084",
|
||||
"ind_customroad085",
|
||||
"ind_customroad086",
|
||||
"ind_customroad087",
|
||||
"ind_customroad088",
|
||||
"ind_customroad089",
|
||||
"ind_customroad090",
|
||||
"ind_customroad091",
|
||||
"ind_customroad093",
|
||||
"ind_customroad094",
|
||||
"ind_customroad095",
|
||||
"ind_customroad096",
|
||||
"ind_customroad097",
|
||||
"ind_customroad098",
|
||||
"ind_customroad099",
|
||||
"ind_customroad0bb",
|
||||
"indatree03",
|
||||
"indhelix_barrier",
|
||||
"indjunk",
|
||||
"indtreepatch06f",
|
||||
"indtreepatch5",
|
||||
"iten_washline01",
|
||||
"kmricndo01",
|
||||
"kmricndo02",
|
||||
"lhouse_barrier1",
|
||||
"lhouse_barrier2",
|
||||
"lhouse_barrier3",
|
||||
"mak_billboard",
|
||||
"mak_billboardsrvc",
|
||||
"mscp_barrier",
|
||||
"mscp_barrier01",
|
||||
"mscp_barriersup",
|
||||
"nbbridgerda",
|
||||
"nbbridgerdb",
|
||||
"new_carprktrees",
|
||||
"new_carprktrees4",
|
||||
"newairportwall1",
|
||||
"newairportwall2",
|
||||
"newairportwall3",
|
||||
"newairportwall4",
|
||||
"newairportwall5",
|
||||
"newairportwall6",
|
||||
"newcoasttrees1",
|
||||
"newcoasttrees2",
|
||||
"newcoasttrees3",
|
||||
"newtreepatch_sub",
|
||||
"newtrees1_sub",
|
||||
"newunitrepatch",
|
||||
"nrailsteps",
|
||||
"nrailstepswest",
|
||||
"overpassind",
|
||||
"pinetree_narrow",
|
||||
"pinetree_wide",
|
||||
"plnt_chimgrad",
|
||||
"plnt_pipepart01",
|
||||
"plnt_pipjoin4way04",
|
||||
"plnt_pylon01",
|
||||
"rd_Road1A10",
|
||||
"salvsdetail",
|
||||
"salvstrans",
|
||||
"skyscrapenew",
|
||||
"skyscrpunbuilt2",
|
||||
"sub_billboard1",
|
||||
"sub_tripbboard",
|
||||
"subfraightback02",
|
||||
"subfraightback03",
|
||||
"subfraightback04",
|
||||
"subsign1",
|
||||
"tall_fence",
|
||||
"tcsky_skyscrp6",
|
||||
"telepole",
|
||||
"telepole01",
|
||||
"telepole02",
|
||||
"telepole03",
|
||||
"telepole04",
|
||||
"tenkb_builds01",
|
||||
"tenkb_builds03",
|
||||
"tenkb_builds04",
|
||||
"tenkb_builds05",
|
||||
"tenkb_builds06",
|
||||
"tenkb_builds11",
|
||||
"trainstairst",
|
||||
"treencom2",
|
||||
"treepatch",
|
||||
"treepatch01_sub",
|
||||
"treepatch02_sub",
|
||||
"treepatch03",
|
||||
"treepatch03_sub",
|
||||
"treepatch04_sub",
|
||||
"treepatch05_sub",
|
||||
"treepatch06_sub",
|
||||
"treepatch07_sub",
|
||||
"treepatch08_sub",
|
||||
"treepatch09_sub",
|
||||
"treepatch10_sub",
|
||||
"treepatch11_sub",
|
||||
"treepatch12_sub",
|
||||
"treepatch13_sub",
|
||||
"treepatch14_sub",
|
||||
"treepatch152_sub",
|
||||
"treepatch153_sub",
|
||||
"treepatch15_sub",
|
||||
"treepatch16_sub",
|
||||
"treepatch171_sub",
|
||||
"treepatch172_sub",
|
||||
"treepatch173_sub",
|
||||
"treepatch17_sub",
|
||||
"treepatch18_sub",
|
||||
"treepatch19_sub",
|
||||
"treepatch2",
|
||||
"treepatch20_sub",
|
||||
"treepatch212_sub",
|
||||
"treepatch213_sub",
|
||||
"treepatch214_sub",
|
||||
"treepatch21_sub",
|
||||
"treepatch22_sub",
|
||||
"treepatch23_sub",
|
||||
"treepatch24_sub",
|
||||
"treepatch25_sub",
|
||||
"treepatch26_sub",
|
||||
"treepatch27_sub",
|
||||
"treepatch28_sub",
|
||||
"treepatch29_sub",
|
||||
"treepatch2b",
|
||||
"treepatch30_sub",
|
||||
"treepatch31_sub",
|
||||
"treepatch32_sub",
|
||||
"treepatch33_sub",
|
||||
"treepatch34_sub",
|
||||
"treepatch35_sub",
|
||||
"treepatch69",
|
||||
"treepatcha",
|
||||
"treepatchb",
|
||||
"treepatchcomtop1",
|
||||
"treepatchd",
|
||||
"treepatche",
|
||||
"treepatchh",
|
||||
"treepatchindaa2",
|
||||
"treepatchindnew",
|
||||
"treepatchindnew2",
|
||||
"treepatchk",
|
||||
"treepatchkb4",
|
||||
"treepatchkb5",
|
||||
"treepatchkb6",
|
||||
"treepatchkb7",
|
||||
"treepatchkb9",
|
||||
"treepatchl",
|
||||
"treepatchm",
|
||||
"treepatchnew_sub",
|
||||
"treepatchttwrs",
|
||||
"treesuni1",
|
||||
"trepatchindaa1",
|
||||
"veg_bush14",
|
||||
"veg_bush2",
|
||||
"veg_tree1",
|
||||
"veg_tree3",
|
||||
"veg_treea1",
|
||||
"veg_treea3",
|
||||
"veg_treeb1",
|
||||
"veg_treenew01",
|
||||
"veg_treenew03",
|
||||
"veg_treenew05",
|
||||
"veg_treenew06",
|
||||
"veg_treenew08",
|
||||
"veg_treenew09",
|
||||
"veg_treenew10",
|
||||
"veg_treenew16",
|
||||
"veg_treenew17",
|
||||
"vegclubtree01",
|
||||
"vegclubtree02",
|
||||
"vegclubtree03",
|
||||
"vegpathtree",
|
||||
"wlst_skyscrp1",
|
||||
""
|
||||
};
|
||||
char *OptimizedNames[] = {
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <cctype>
|
||||
|
||||
#ifdef DC_SH4
|
||||
#include <dc/vmu_pkg.h>
|
||||
#endif
|
||||
|
||||
namespace mINI
|
||||
{
|
||||
namespace INIStringUtil
|
||||
@@ -335,6 +339,7 @@ namespace mINI
|
||||
private:
|
||||
std::ifstream fileReadStream;
|
||||
T_LineDataPtr lineData;
|
||||
std::size_t start_offt;
|
||||
|
||||
T_LineData readFile()
|
||||
{
|
||||
@@ -343,7 +348,7 @@ namespace mINI
|
||||
fileContents.resize(fileReadStream.tellg());
|
||||
fileReadStream.seekg(0, std::ios::beg);
|
||||
std::size_t fileSize = fileContents.size();
|
||||
fileReadStream.read(&fileContents[0], fileSize);
|
||||
fileReadStream.read(const_cast<char *>(fileContents.c_str()), fileSize);
|
||||
fileReadStream.close();
|
||||
T_LineData output;
|
||||
if (fileSize == 0)
|
||||
@@ -352,7 +357,19 @@ namespace mINI
|
||||
}
|
||||
std::string buffer;
|
||||
buffer.reserve(50);
|
||||
for (std::size_t i = 0; i < fileSize; ++i)
|
||||
#ifdef DC_SH4
|
||||
{
|
||||
vmu_pkg_t vmu_pkg;
|
||||
if(vmu_pkg_parse(reinterpret_cast<uint8*>(const_cast<int8*>(fileContents.c_str())), &vmu_pkg) != 0) {
|
||||
// If we failed to parse, we assume it's raw with no VMS header.
|
||||
start_offt = 0;
|
||||
} else {
|
||||
start_offt = reinterpret_cast<unsigned int>(vmu_pkg.data)
|
||||
- reinterpret_cast<unsigned int>(fileContents.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (std::size_t i = start_offt; i < fileSize; ++i)
|
||||
{
|
||||
char& c = fileContents[i];
|
||||
if (c == '\n')
|
||||
@@ -378,6 +395,8 @@ namespace mINI
|
||||
{
|
||||
lineData = std::make_shared<T_LineData>();
|
||||
}
|
||||
|
||||
start_offt = 0;
|
||||
}
|
||||
~INIReader() { }
|
||||
|
||||
@@ -426,22 +445,71 @@ namespace mINI
|
||||
{
|
||||
private:
|
||||
std::ofstream fileWriteStream;
|
||||
|
||||
std::stringstream memStream;
|
||||
inline static std::ios_base::iostate lastError_;
|
||||
public:
|
||||
bool prettyPrint = false;
|
||||
|
||||
INIGenerator(std::string const& filename)
|
||||
INIGenerator(std::string const& filename, bool prettyPrint_=false)
|
||||
: fileWriteStream(filename, std::ios::out | std::ios::binary),
|
||||
prettyPrint(prettyPrint_)
|
||||
{
|
||||
fileWriteStream.open(filename, std::ios::out | std::ios::binary);
|
||||
lastError_ = fileWriteStream.rdstate();
|
||||
}
|
||||
|
||||
~INIGenerator()
|
||||
{
|
||||
if(!fileWriteStream.good()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = memStream.str();
|
||||
const char *buf = str.c_str();
|
||||
int buf_size = memStream.tellp();
|
||||
|
||||
#ifdef DC_SH4
|
||||
uint8_t *data;
|
||||
uint8_t icon_buf[512 * 1];
|
||||
vmu_pkg_t vmu_pkg = {
|
||||
.desc_short = "DCA-L Config",
|
||||
.desc_long = "DCA-L Settings File",
|
||||
.app_id = "The Gang",
|
||||
.icon_cnt = 1,
|
||||
.icon_anim_speed = 0,
|
||||
.data_len = buf_size,
|
||||
.icon_data = icon_buf,
|
||||
.data = reinterpret_cast<const uint8_t*>(buf),
|
||||
};
|
||||
|
||||
if (vmu_pkg_load_icon(&vmu_pkg, "settings.ico") < 0) {
|
||||
vmu_pkg.icon_cnt = 0;
|
||||
}
|
||||
|
||||
if(vmu_pkg_build(&vmu_pkg, &data, &buf_size) < 0) {
|
||||
lastError_ = std::ios_base::badbit;
|
||||
return;
|
||||
}
|
||||
|
||||
buf = reinterpret_cast<char*>(data);
|
||||
#endif
|
||||
|
||||
fileWriteStream.write(buf, buf_size);
|
||||
lastError_ = fileWriteStream.rdstate();
|
||||
|
||||
#ifdef DC_SH4
|
||||
// Must free the internal buffer allocated by vmu_pkg_build().
|
||||
free(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator<<(const std::string& str)
|
||||
{
|
||||
memStream << str;
|
||||
return true;
|
||||
}
|
||||
~INIGenerator() { }
|
||||
|
||||
bool operator<<(INIStructure const& data)
|
||||
{
|
||||
if (!fileWriteStream.is_open())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!data.size())
|
||||
{
|
||||
return true;
|
||||
@@ -451,13 +519,13 @@ namespace mINI
|
||||
{
|
||||
auto const& section = it->first;
|
||||
auto const& collection = it->second;
|
||||
fileWriteStream
|
||||
memStream
|
||||
<< "["
|
||||
<< section
|
||||
<< "]";
|
||||
if (collection.size())
|
||||
{
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
auto it2 = collection.begin();
|
||||
for (;;)
|
||||
{
|
||||
@@ -465,7 +533,7 @@ namespace mINI
|
||||
INIStringUtil::replace(key, "=", "\\=");
|
||||
auto value = it2->second;
|
||||
INIStringUtil::trim(value);
|
||||
fileWriteStream
|
||||
memStream
|
||||
<< key
|
||||
<< ((prettyPrint) ? " = " : "=")
|
||||
<< value;
|
||||
@@ -473,21 +541,29 @@ namespace mINI
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
if (++it == data.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
if (prettyPrint)
|
||||
{
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return fileWriteStream.rdstate() == fileWriteStream.goodbit;
|
||||
}
|
||||
|
||||
static std::ios_base::iostate lastError() { return lastError_; }
|
||||
static bool wasGood() { return lastError_ == std::ios_base::goodbit; }
|
||||
};
|
||||
|
||||
class INIWriter
|
||||
@@ -667,12 +743,15 @@ namespace mINI
|
||||
{
|
||||
struct stat buf;
|
||||
bool fileExists = (stat(filename.c_str(), &buf) == 0);
|
||||
|
||||
if (!fileExists)
|
||||
{
|
||||
INIGenerator generator(filename);
|
||||
generator.prettyPrint = prettyPrint;
|
||||
return generator << data;
|
||||
if(INIGenerator generator(filename, prettyPrint); generator) {
|
||||
generator << data;
|
||||
}
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
|
||||
INIStructure originalData;
|
||||
T_LineDataPtr lineData;
|
||||
bool readSuccess = false;
|
||||
@@ -688,23 +767,21 @@ namespace mINI
|
||||
return false;
|
||||
}
|
||||
T_LineData output = getLazyOutput(lineData, data, originalData);
|
||||
std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary);
|
||||
if (fileWriteStream.is_open())
|
||||
{
|
||||
if (output.size())
|
||||
if (INIGenerator generator(filename, prettyPrint); generator && output.size())
|
||||
{
|
||||
auto line = output.begin();
|
||||
for (;;)
|
||||
{
|
||||
fileWriteStream << *line;
|
||||
generator << *line;
|
||||
if (++line == output.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
generator << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -741,9 +818,10 @@ namespace mINI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
INIGenerator generator(filename);
|
||||
generator.prettyPrint = pretty;
|
||||
return generator << data;
|
||||
if(INIGenerator generator(filename, pretty); generator) {
|
||||
generator << data;
|
||||
}
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
bool write(INIStructure& data, bool pretty = false) const
|
||||
{
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
#include "common.h"
|
||||
|
||||
CMatrix::CMatrix(void)
|
||||
{
|
||||
m_attachment = nil;
|
||||
m_hasRwMatrix = false;
|
||||
}
|
||||
|
||||
CMatrix::CMatrix(CMatrix const &m)
|
||||
{
|
||||
m_attachment = nil;
|
||||
@@ -510,14 +504,9 @@ operator*(const CMatrix &m1, const CMatrix &m2)
|
||||
{
|
||||
// TODO: VU0 code
|
||||
CMatrix out;
|
||||
#if defined(RW_DC) && 0 // THIS IS BROKEN, 4th element shouldn't be processed
|
||||
# ifdef DC_SH4
|
||||
MATH_Load_Matrix_Product(reinterpret_cast<const matrix_t *>(&m1), reinterpret_cast<const matrix_t *>(&m2));
|
||||
|
||||
# elif defined(RW_DC)
|
||||
mat_load(reinterpret_cast<const matrix_t *>(&m2));
|
||||
mat_apply(reinterpret_cast<const matrix_t *>(&m1));
|
||||
# endif
|
||||
#if defined(RW_DC)
|
||||
mat_load(reinterpret_cast<const matrix_t *>(&m1));
|
||||
mat_apply(reinterpret_cast<const matrix_t *>(&m2));
|
||||
mat_store(reinterpret_cast<matrix_t *>(&out));
|
||||
#else
|
||||
out.rx = m1.rx * m2.rx + m1.fx * m2.ry + m1.ux * m2.rz;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
class CMatrix
|
||||
class alignas(8) CMatrix
|
||||
{
|
||||
public:
|
||||
union
|
||||
@@ -8,17 +8,17 @@ public:
|
||||
alignas(8) float f[4][4];
|
||||
struct alignas(8)
|
||||
{
|
||||
float rx, ry, rz, rw;
|
||||
float fx, fy, fz, fw;
|
||||
float ux, uy, uz, uw;
|
||||
float px, py, pz, pw;
|
||||
float rx, ry, rz, rw=0.0f;
|
||||
float fx, fy, fz, fw=0.0f;
|
||||
float ux, uy, uz, uw=0.0f;
|
||||
float px, py, pz, pw=1.0f;
|
||||
};
|
||||
};
|
||||
|
||||
RwMatrix *m_attachment;
|
||||
bool m_hasRwMatrix; // are we the owner?
|
||||
RwMatrix *m_attachment = nil;
|
||||
bool m_hasRwMatrix = false; // are we the owner?
|
||||
|
||||
CMatrix(void);
|
||||
CMatrix(void) {}
|
||||
CMatrix(CMatrix const &m);
|
||||
CMatrix(RwMatrix *matrix, bool owner = false);
|
||||
CMatrix(float scale){
|
||||
|
||||
@@ -45,7 +45,7 @@ __always_inline void TransformPoint(CVuVector &out, const CMatrix &mat, const CV
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
mat_trans_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z, out.y);
|
||||
mat_trans_single3_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z);
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
@@ -72,7 +72,7 @@ __always_inline void TransformPoint(CVuVector &out, const CMatrix &mat, const Rw
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
mat_trans_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z, out.y);
|
||||
mat_trans_single3_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z);
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
@@ -80,7 +80,6 @@ __always_inline void TransformPoint(CVuVector &out, const CMatrix &mat, const Rw
|
||||
|
||||
__always_inline void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride)
|
||||
{
|
||||
assert(false);
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
paddub $3,%4,$0\n\
|
||||
@@ -110,9 +109,11 @@ __always_inline void TransformPoints(CVuVector *out, int n, const CMatrix &mat,
|
||||
": : "r" (out) , "r" (n), "r" (&mat), "r" (in), "r" (stride): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
mat_transform(reinterpret_cast<vector_t *>(const_cast<RwV3d *>(in)),
|
||||
reinterpret_cast<vector_t *>(out),
|
||||
n, stride - sizeof(vector_t));
|
||||
while(n--) {
|
||||
mat_trans_single3_nodiv_nomod(in->x, in->y, in->z, out->x, out->y, out->z);
|
||||
in = reinterpret_cast<const RwV3d *>(reinterpret_cast<const uint8_t *>(in) + stride);
|
||||
++out;
|
||||
}
|
||||
#else
|
||||
while(n--){
|
||||
*out = mat * *in;
|
||||
|
||||
@@ -39,7 +39,11 @@
|
||||
#define AMMO_X 66.0f
|
||||
#define HEALTH_X 110.0f
|
||||
#define STARS_X 60.0f
|
||||
#ifdef RW_DC
|
||||
#define ZONE_Y 64.0f
|
||||
#else
|
||||
#define ZONE_Y 30.0f
|
||||
#endif
|
||||
#define VEHICLE_Y 55.0f
|
||||
#define CLOCK_X 111.0f
|
||||
#define SUBS_Y 68.0f
|
||||
|
||||
@@ -58,7 +58,11 @@ public:
|
||||
};
|
||||
|
||||
enum {
|
||||
#ifdef RW_DC
|
||||
NUM_RAIN_STREAKS = 10
|
||||
#elif
|
||||
NUM_RAIN_STREAKS = 35
|
||||
#endif
|
||||
};
|
||||
|
||||
struct tRainStreak
|
||||
|
||||
@@ -5220,6 +5220,10 @@ cAudioManager::ProcessPedOneShots(cPedParams ¶ms)
|
||||
if (iSound > 60)
|
||||
iSound = 21;
|
||||
}
|
||||
// In some cases the left and right channels have different loop points
|
||||
// This looks like a data file issue where the left and right channels have different loop points
|
||||
// This is a hot fix to always have the correct loop point for each channel individually
|
||||
SET_LOOP_OFFSETS(m_sQueueSample.m_nSampleIndex)
|
||||
AddSampleToRequestedQueue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +198,7 @@ public:
|
||||
char GetCDAudioDriveLetter (void);
|
||||
|
||||
void UpdateEffectsVolume(void);
|
||||
void UpdateStreamsVolume(void);
|
||||
|
||||
#ifdef DC_SH4
|
||||
void UpdateChannelVolume(uint32 nChannel);
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "thread/thread.h"
|
||||
|
||||
#if !defined(AUDIO_OAL) && !defined(AUDIO_MSS)
|
||||
#define syncf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define streamf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define verbosef(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
#define debugf(...) // dbglog(DBG_CRITICAL, __VA_ARGS__)
|
||||
|
||||
@@ -46,6 +48,8 @@
|
||||
/* Quick access to the AICA channels */
|
||||
#define AICA_CHANNEL(x) (AICA_MEM_CHANNELS + (x) * sizeof(aica_channel_t))
|
||||
|
||||
static uint32_t chn_version[64];
|
||||
|
||||
int aica_play_chn(int chn, int size, uint32_t aica_buffer, int fmt, int vol, int pan, int loop, int freq) {
|
||||
// assert(size <= 65534);
|
||||
// We gotta fix this at some point
|
||||
@@ -69,6 +73,7 @@ int aica_play_chn(int chn, int size, uint32_t aica_buffer, int fmt, int vol, int
|
||||
chan->freq = freq;
|
||||
chan->vol = vol;
|
||||
chan->pan = pan;
|
||||
chan->version = ++chn_version[chn];
|
||||
snd_sh4_to_aica(tmp, cmd->size);
|
||||
return chn;
|
||||
}
|
||||
@@ -370,6 +375,12 @@ cSampleManager::Initialise(void)
|
||||
if (channels[i].ch != -1) {
|
||||
assert(channels[i].nSfx != -1);
|
||||
|
||||
uint32_t channel_version = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(channels[i].ch) + offsetof(aica_channel_t, version));
|
||||
|
||||
if (chn_version[channels[i].ch] != channel_version) {
|
||||
syncf("SFX version missmatch, skipping update. expected %d got %d\n", chn_version[channels[i].ch], channel_version);
|
||||
continue;
|
||||
}
|
||||
uint16_t channel_pos = (g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(channels[i].ch) + offsetof(aica_channel_t, pos)) & 0xffff);
|
||||
// verbosef("Channel %d pos: %d\n", i, channel_pos);
|
||||
if (!channels[i].loop) {
|
||||
@@ -396,21 +407,27 @@ cSampleManager::Initialise(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(streams[i].mtx);
|
||||
if (streams[i].playing) {
|
||||
uint32_t channel_version = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(streams[i].mapped_ch[0]) + offsetof(aica_channel_t, version));
|
||||
|
||||
if (chn_version[streams[i].mapped_ch[0]] != channel_version) {
|
||||
syncf("Stream version missmatch, skipping update. expected %d got %d\n", chn_version[streams[i].mapped_ch[0]], channel_version);
|
||||
continue;
|
||||
}
|
||||
// get channel pos
|
||||
uint32_t channel_pos = g2_read_32(SPU_RAM_UNCACHED_BASE + AICA_CHANNEL(streams[i].mapped_ch[0]) + offsetof(aica_channel_t, pos)) & 0xffff;
|
||||
uint32_t logical_pos = channel_pos;
|
||||
if (logical_pos > STREAM_CHANNEL_SAMPLE_COUNT/2) {
|
||||
logical_pos -= STREAM_CHANNEL_SAMPLE_COUNT/2;
|
||||
}
|
||||
verbosef("Stream %d pos: %d, log: %d, rem: %d\n", i, channel_pos, logical_pos, streams[i].played_samples);
|
||||
streamf("Stream %d pos: %d, log: %d, played: %d\n", i, channel_pos, logical_pos, streams[i].played_samples);
|
||||
|
||||
bool can_refill = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_fetch = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_refill = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + (!streams[i].first_refill)*STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
bool can_fetch = (streams[i].played_samples + STREAM_CHANNEL_SAMPLE_COUNT/2 + STREAM_CHANNEL_SAMPLE_COUNT/2 + (!streams[i].first_refill)*STREAM_CHANNEL_SAMPLE_COUNT/2) < streams[i].total_samples;
|
||||
// copy over data if needed from staging
|
||||
if (channel_pos >= STREAM_CHANNEL_SAMPLE_COUNT/2 && !streams[i].next_is_upper_half) {
|
||||
streams[i].next_is_upper_half = true;
|
||||
if (can_refill) { // could we need a refill?
|
||||
verbosef("Filling channel %d with lower half\n", i);
|
||||
streamf("Filling channel %d with lower half\n", i);
|
||||
// fill lower half
|
||||
spu_memload(streams[i].aica_buffers[0], streams[i].buffer, STREAM_CHANNEL_BUFFER_SIZE/2);
|
||||
if (streams[i].stereo) {
|
||||
@@ -426,7 +443,7 @@ cSampleManager::Initialise(void)
|
||||
} else if (channel_pos < STREAM_CHANNEL_SAMPLE_COUNT/2 && streams[i].next_is_upper_half) {
|
||||
streams[i].next_is_upper_half = false;
|
||||
if (can_refill) { // could we need a refill?
|
||||
verbosef("Filling channel %d with upper half\n", i);
|
||||
streamf("Filling channel %d with upper half\n", i);
|
||||
// fill upper half
|
||||
spu_memload(streams[i].aica_buffers[0] + STREAM_CHANNEL_BUFFER_SIZE/2, streams[i].buffer, STREAM_CHANNEL_BUFFER_SIZE/2);
|
||||
if (streams[i].stereo) {
|
||||
@@ -446,7 +463,7 @@ cSampleManager::Initialise(void)
|
||||
// if end of file, stop
|
||||
if ((streams[i].played_samples + logical_pos) > streams[i].total_samples) {
|
||||
// stop channel
|
||||
debugf("Auto stopping stream: %d -> {%d, %d}, %d total\n", i, streams[i].mapped_ch[0], streams[i].mapped_ch[1], streams[i].total_samples);
|
||||
streamf("Auto stopping stream: %d -> {%d, %d}, %d total\n", i, streams[i].mapped_ch[0], streams[i].mapped_ch[1], streams[i].total_samples);
|
||||
aica_stop_chn(streams[i].mapped_ch[0]);
|
||||
aica_stop_chn(streams[i].mapped_ch[1]);
|
||||
streams[i].playing = false;
|
||||
@@ -454,7 +471,7 @@ cSampleManager::Initialise(void)
|
||||
}
|
||||
|
||||
if (do_read) {
|
||||
debugf("Queueing stream read: %d, file: %d, buffer: %p, size: %d, tell: %d\n", i, streams[i].fd, streams[i].buffer, do_read, fs_tell(streams[i].fd));
|
||||
streamf("Queueing stream read: %d, file: %d, buffer: %p, size: %d, file_offset: %d\n", i, streams[i].fd, streams[i].buffer, do_read, streams[i].file_offset);
|
||||
CdStreamQueueAudioRead(streams[i].fd, streams[i].buffer, do_read, streams[i].file_offset);
|
||||
streams[i].file_offset += do_read;
|
||||
}
|
||||
@@ -494,6 +511,7 @@ cSampleManager::Initialise(void)
|
||||
void
|
||||
cSampleManager::Terminate(void)
|
||||
{
|
||||
CdStreamDiscardAudioRead(fdPedSfx);
|
||||
fs_close(fdPedSfx);
|
||||
}
|
||||
|
||||
@@ -520,7 +538,6 @@ cSampleManager::UpdateEffectsVolume(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
|
||||
{
|
||||
@@ -532,6 +549,7 @@ void
|
||||
cSampleManager::SetMusicMasterVolume(uint8 nVolume)
|
||||
{
|
||||
m_nMusicVolume = nVolume;
|
||||
UpdateStreamsVolume();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -551,6 +569,7 @@ void
|
||||
cSampleManager::SetMusicFadeVolume(uint8 nVolume)
|
||||
{
|
||||
m_nMusicFadeVolume = nVolume;
|
||||
UpdateStreamsVolume();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -696,8 +715,8 @@ cSampleManager::LoadMissionAudio(uint8 nSlot, uint32 nSample)
|
||||
ASSERT(nSample < TOTAL_AUDIO_SAMPLES);
|
||||
|
||||
debugf("Loading mission audio comment %d, offset: %d, size: %d\n", nSample, m_aSamples[nSample].nFileOffset, m_aSamples[nSample].nByteSize);
|
||||
CdStreamQueueAudioRead(nSample, (void*)gPlayerTalkData, m_aSamples[nSample].nByteSize, m_aSamples[nSample].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
fs_seek(fdPedSfx, cmd->seek, SEEK_SET);
|
||||
CdStreamQueueAudioRead(fdPedSfx, (void*)gPlayerTalkData, m_aSamples[nSample].nByteSize, m_aSamples[nSample].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
assert(fs_seek(fdPedSfx, cmd->seek, SEEK_SET) == cmd->seek);
|
||||
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
// fs_read(fdPedSfx, SPU_BASE_U8 + (uintptr_t)cmd->dest, cmd->size);
|
||||
@@ -793,8 +812,8 @@ cSampleManager::LoadPedComment(uint32 nComment)
|
||||
assert(m_aSamples[nComment].nByteSize <= pedBlocksizeMax);
|
||||
|
||||
debugf("Loading ped comment %d, offset: %d, size: %d\n", nComment, m_aSamples[nComment].nFileOffset, m_aSamples[nComment].nByteSize);
|
||||
CdStreamQueueAudioRead(nComment, (void*)nPedSlotSfxAddr[nCurrentPedSlot], m_aSamples[nComment].nByteSize, m_aSamples[nComment].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
fs_seek(fdPedSfx, cmd->seek, SEEK_SET);
|
||||
CdStreamQueueAudioRead(fdPedSfx, (void*)nPedSlotSfxAddr[nCurrentPedSlot], m_aSamples[nComment].nByteSize, m_aSamples[nComment].nFileOffset, [](AudioReadCmd* cmd) {
|
||||
assert(fs_seek(fdPedSfx, cmd->seek, SEEK_SET) == cmd->seek);
|
||||
|
||||
|
||||
// TODO: When we can dma directly to AICA, we can use this instead
|
||||
@@ -1098,7 +1117,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream, uint32_t seek_b
|
||||
ASSERT( nFile < TOTAL_STREAMED_SOUNDS );
|
||||
|
||||
file_t f = fs_open(DCStreamedNameTable[nFile], O_RDONLY);
|
||||
debugf("PreloadStreamedFile(%p, %d, %d) is %s\n", f, nFile, nStream, DCStreamedNameTable[nFile]);
|
||||
streamf("PreloadStreamedFile(%p, %d, %d) is %s\n", f, nFile, nStream, DCStreamedNameTable[nFile]);
|
||||
assert(f >= 0 );
|
||||
WavHeader hdr;
|
||||
assert(fs_read(f, &hdr, sizeof(hdr)) == sizeof(hdr));
|
||||
@@ -1130,13 +1149,13 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream, uint32_t seek_b
|
||||
streams[nStream].next_is_upper_half = true;
|
||||
streams[nStream].first_refill = true;
|
||||
|
||||
debugf("PreloadStreamedFile: %s: stream: %d, freq: %d, chans: %d, byte size: %d, played samples: %d\n", DCStreamedNameTable[nFile], nStream, hdr.samplesPerSec, hdr.numOfChan, hdr.dataSize, streams[nStream].played_samples);
|
||||
streamf("PreloadStreamedFile: %s: stream: %d, freq: %d, chans: %d, byte size: %d, played samples: %d\n", DCStreamedNameTable[nFile], nStream, hdr.samplesPerSec, hdr.numOfChan, hdr.dataSize, streams[nStream].played_samples);
|
||||
|
||||
|
||||
// How to avoid the lock?
|
||||
if (seek_bytes_aligned) {
|
||||
streams[nStream].played_samples = seek_bytes_aligned * (streams[nStream].stereo ? 1 : 2);
|
||||
debugf("Seeking aligned to: %d, played_samples: %d\n", seek_bytes_aligned, streams[nStream].played_samples);
|
||||
streamf("Seeking aligned to: %d, played_samples: %d\n", seek_bytes_aligned, streams[nStream].played_samples);
|
||||
fs_seek(streams[nStream].fd, 2048 + seek_bytes_aligned, SEEK_SET);
|
||||
} else {
|
||||
fs_seek(f, 2048, SEEK_SET);
|
||||
@@ -1165,7 +1184,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream, uint32_t seek_b
|
||||
streams[nStream].file_offset = fs_tell(f);
|
||||
}
|
||||
|
||||
verbosef("PreloadStreamedFile: %p %d - %s, %d, %d, \n", f, nFile, DCStreamedNameTable[nFile], streams[nStream].rate, streams[nStream].stereo);
|
||||
streamf("PreloadStreamedFile: %p %d - %s, %d, %d, \n", f, nFile, DCStreamedNameTable[nFile], streams[nStream].rate, streams[nStream].stereo);
|
||||
}
|
||||
|
||||
// we can't really pause a stream, so we just make it go very slow with zero volume
|
||||
@@ -1292,12 +1311,28 @@ cSampleManager::GetStreamedFilePosition(uint8 nStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static uint8 nStreamVolumes[MAX_STREAMS];
|
||||
static uint8 nStreamPans[MAX_STREAMS];
|
||||
static uint8 nStreamEffect[MAX_STREAMS];
|
||||
void
|
||||
cSampleManager::UpdateStreamsVolume(void)
|
||||
{
|
||||
if(_bSampmanInitialised) {
|
||||
for (int nStream = 0; nStream < MAX_STREAMS; nStream++) {
|
||||
SetStreamedVolumeAndPan(nStreamVolumes[nStream], nStreamPans[nStream], nStreamEffect[nStream], nStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
|
||||
{
|
||||
ASSERT( nStream < MAX_STREAMS );
|
||||
if (nVolume > MAX_VOLUME)
|
||||
nVolume = MAX_VOLUME;
|
||||
nStreamVolumes[nStream] = nVolume;
|
||||
nStreamPans[nStream] = nPan;
|
||||
nStreamEffect[nStream] = nEffectFlag;
|
||||
nVolume = linearlize_volume(nVolume); //nVolume * 255 / MAX_VOLUME;
|
||||
nVolume = m_nMusicFadeVolume * nVolume * m_nMusicVolume >> 14;
|
||||
if (streams[nStream].vol != nVolume || streams[nStream].nPan != nPan) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct CColLine
|
||||
struct alignas(8) CColLine
|
||||
{
|
||||
// NB: this has to be compatible with two CVuVectors
|
||||
CVector p0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct CColPoint
|
||||
struct alignas(8) CColPoint
|
||||
{
|
||||
CVector point;
|
||||
int pad1;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "SurfaceTable.h"
|
||||
|
||||
struct CSphere
|
||||
struct alignas(8) CSphere
|
||||
{
|
||||
// NB: this has to be compatible with a CVuVector
|
||||
CVector center;
|
||||
@@ -15,6 +15,11 @@ struct CColSphere : public CSphere
|
||||
uint8 surface;
|
||||
uint8 piece;
|
||||
|
||||
void Set(float radius, uint8 surf = SURFACE_DEFAULT, uint8 piece = 0) {
|
||||
this->radius = radius;
|
||||
this->surface = surf;
|
||||
this->piece = piece;
|
||||
}
|
||||
void Set(float radius, const CVector ¢er, uint8 surf, uint8 piece);
|
||||
bool IntersectRay(CVector const &from, CVector const &dir, CVector &entry, CVector &exit);
|
||||
using CSphere::Set;
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
#include "Camera.h"
|
||||
#include "ColStore.h"
|
||||
|
||||
#ifdef DC_SH4
|
||||
#include "VuCollision.h"
|
||||
#endif
|
||||
|
||||
#ifdef VU_COLLISION
|
||||
#include "VuCollision.h"
|
||||
|
||||
@@ -572,7 +576,12 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
|
||||
|
||||
// transform line to model space
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline(matTransform * line.p0, matTransform * line.p1);
|
||||
CColLine newline;
|
||||
#ifndef DC_SH4
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#else
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#endif
|
||||
|
||||
// If we don't intersect with the bounding box, no chance on the rest
|
||||
if(!TestLineBox(newline, model.boundingBox))
|
||||
@@ -1428,7 +1437,12 @@ CCollision::ProcessLineOfSight(const CColLine &line,
|
||||
|
||||
// transform line to model space
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline(matTransform * line.p0, matTransform * line.p1);
|
||||
CColLine newline;
|
||||
#ifdef DC_SH4
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#else
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#endif
|
||||
|
||||
// If we don't intersect with the bounding box, no chance on the rest
|
||||
if(!TestLineBox(newline, model.boundingBox))
|
||||
@@ -1455,8 +1469,18 @@ CCollision::ProcessLineOfSight(const CColLine &line,
|
||||
}
|
||||
|
||||
if(coldist < mindist){
|
||||
#ifndef DC_SH4
|
||||
point.point = matrix * point.point;
|
||||
point.normal = Multiply3x3(matrix, point.normal);
|
||||
#else
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrix)));
|
||||
mat_trans_single3_nodiv(point.point.x,
|
||||
point.point.y,
|
||||
point.point.z);
|
||||
mat_trans_normal3(point.normal.x,
|
||||
point.normal.y,
|
||||
point.normal.z);
|
||||
#endif
|
||||
mindist = coldist;
|
||||
return true;
|
||||
}
|
||||
@@ -1593,7 +1617,14 @@ CCollision::ProcessVerticalLine(const CColLine &line,
|
||||
|
||||
// transform line to model space
|
||||
// Why does the game seem to do this differently than above?
|
||||
CColLine newline(MultiplyInverse(matrix, line.p0), MultiplyInverse(matrix, line.p1));
|
||||
CMatrix matTransform;
|
||||
Invert(matrix, matTransform);
|
||||
CColLine newline;
|
||||
#ifndef DC_SH4
|
||||
newline.Set(matTransform * line.p0, matTransform * line.p1);
|
||||
#else
|
||||
TransformPoints(reinterpret_cast<CVuVector*>(&newline), 2, matTransform, &line.p0, sizeof(CColLine)/2);
|
||||
#endif
|
||||
|
||||
if(!TestLineBox(newline, model.boundingBox))
|
||||
return false;
|
||||
@@ -1618,13 +1649,29 @@ CCollision::ProcessVerticalLine(const CColLine &line,
|
||||
}
|
||||
|
||||
if(coldist < mindist){
|
||||
#ifndef DC_SH4
|
||||
point.point = matrix * point.point;
|
||||
point.normal = Multiply3x3(matrix, point.normal);
|
||||
#else
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrix)));
|
||||
mat_trans_single3_nodiv(point.point.x,
|
||||
point.point.y,
|
||||
point.point.z);
|
||||
mat_trans_normal3(point.normal.x,
|
||||
point.normal.y,
|
||||
point.normal.z);
|
||||
#endif
|
||||
if(TempStoredPoly.valid && poly){
|
||||
*poly = TempStoredPoly;
|
||||
#ifndef DC_SH4
|
||||
poly->verts[0] = matrix * poly->verts[0];
|
||||
poly->verts[1] = matrix * poly->verts[1];
|
||||
poly->verts[2] = matrix * poly->verts[2];
|
||||
#else
|
||||
mat_trans_single3_nodiv(poly->verts[0].x, poly->verts[0].y, poly->verts[0].z);
|
||||
mat_trans_single3_nodiv(poly->verts[1].x, poly->verts[1].y, poly->verts[1].z);
|
||||
mat_trans_single3_nodiv(poly->verts[2].x, poly->verts[2].y, poly->verts[2].z);
|
||||
#endif
|
||||
}
|
||||
mindist = coldist;
|
||||
return true;
|
||||
@@ -1976,26 +2023,60 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
assert(modelA.numLines <= MAXNUMLINES);
|
||||
|
||||
// From model A space to model B space
|
||||
matAB = Invert(matrixB, matAB);
|
||||
Invert(matrixB, matAB);
|
||||
#ifndef DC_SH4
|
||||
matAB *= matrixA;
|
||||
#else
|
||||
mat_load(reinterpret_cast<const matrix_t*>(&matAB));
|
||||
mat_apply(reinterpret_cast<const matrix_t*>(&matrixA));
|
||||
#endif
|
||||
|
||||
CColSphere bsphereAB; // bounding sphere of A in B space
|
||||
bsphereAB.radius = modelA.boundingSphere.radius;
|
||||
#ifndef DC_SH4
|
||||
bsphereAB.center = matAB * modelA.boundingSphere.center;
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelA.boundingSphere.center.x,
|
||||
modelA.boundingSphere.center.y,
|
||||
modelA.boundingSphere.center.z,
|
||||
bsphereAB.center.x,
|
||||
bsphereAB.center.y,
|
||||
bsphereAB.center.z);
|
||||
#endif
|
||||
if(!TestSphereBox(bsphereAB, modelB.boundingBox))
|
||||
return 0;
|
||||
// B to A space
|
||||
matBA = Invert(matrixA, matBA);
|
||||
matBA *= matrixB;
|
||||
|
||||
// transform modelA's spheres and lines to B space
|
||||
for(i = 0; i < modelA.numSpheres; i++){
|
||||
CColSphere &s = modelA.spheres[i];
|
||||
#ifndef DC_SH4
|
||||
aSpheresA[i].Set(s.radius, matAB * s.center, s.surface, s.piece);
|
||||
#else
|
||||
auto &d = aSpheresA[i];
|
||||
mat_trans_single3_nodiv_nomod(s.center.x, s.center.y, s.center.z,
|
||||
d.center.x, d.center.y, d.center.z);
|
||||
d.Set(s.radius, s.surface, s.piece);
|
||||
#endif
|
||||
}
|
||||
for(i = 0; i < modelA.numLines; i++)
|
||||
aLinesA[i].Set(matAB * modelA.lines[i].p0, matAB * modelA.lines[i].p1);
|
||||
|
||||
for(i = 0; i < modelA.numLines; i++) {
|
||||
#ifndef DC_SH4
|
||||
aLinesA[i].Set(matAB * modelA.lines[i].p0, matAB * modelA.lines[i].p1);
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelA.lines[i].p0.x,
|
||||
modelA.lines[i].p0.y,
|
||||
modelA.lines[i].p0.z,
|
||||
aLinesA[i].p0.x,
|
||||
aLinesA[i].p0.y,
|
||||
aLinesA[i].p0.z);
|
||||
mat_trans_single3_nodiv_nomod(modelA.lines[i].p1.x,
|
||||
modelA.lines[i].p1.y,
|
||||
modelA.lines[i].p1.z,
|
||||
aLinesA[i].p1.x,
|
||||
aLinesA[i].p1.y,
|
||||
aLinesA[i].p1.z);
|
||||
#endif
|
||||
}
|
||||
// Test them against model B's bounding volumes
|
||||
int numSpheresA = 0;
|
||||
int numLinesA = 0;
|
||||
@@ -2013,9 +2094,26 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
int numSpheresB = 0;
|
||||
int numBoxesB = 0;
|
||||
int numTrianglesB = 0;
|
||||
// B to A space
|
||||
Invert(matrixA, matBA);
|
||||
#ifndef DC_SH4
|
||||
matBA *= matrixB;
|
||||
#else
|
||||
mat_load(reinterpret_cast<const matrix_t*>(&matBA));
|
||||
mat_apply(reinterpret_cast<const matrix_t*>(&matrixB));
|
||||
#endif
|
||||
for(i = 0; i < modelB.numSpheres; i++){
|
||||
s.radius = modelB.spheres[i].radius;
|
||||
#ifndef DC_SH4
|
||||
s.center = matBA * modelB.spheres[i].center;
|
||||
#else
|
||||
mat_trans_single3_nodiv_nomod(modelB.spheres[i].center.x,
|
||||
modelB.spheres[i].center.y,
|
||||
modelB.spheres[i].center.z,
|
||||
s.center.x,
|
||||
s.center.y,
|
||||
s.center.z);
|
||||
#endif
|
||||
if(TestSphereBox(s, modelA.boundingBox))
|
||||
aSphereIndicesB[numSpheresB++] = i;
|
||||
}
|
||||
@@ -2062,9 +2160,22 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
if(hasCollided)
|
||||
numCollisions++;
|
||||
}
|
||||
|
||||
#ifdef DC_SH4
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&matrixB)));
|
||||
#endif
|
||||
for(i = 0; i < numCollisions; i++){
|
||||
#ifndef DC_SH4
|
||||
spherepoints[i].point = matrixB * spherepoints[i].point;
|
||||
spherepoints[i].normal = Multiply3x3(matrixB, spherepoints[i].normal);
|
||||
#else
|
||||
mat_trans_single3_nodiv(spherepoints[i].point.x,
|
||||
spherepoints[i].point.y,
|
||||
spherepoints[i].point.z);
|
||||
mat_trans_normal3(spherepoints[i].normal.x,
|
||||
spherepoints[i].normal.y,
|
||||
spherepoints[i].normal.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
// And the same thing for the lines in A
|
||||
@@ -2095,8 +2206,17 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
|
||||
for(i = 0; i < numLinesA; i++)
|
||||
if(aCollided[i]){
|
||||
j = aLineIndicesA[i];
|
||||
#ifndef DC_SH4
|
||||
linepoints[j].point = matrixB * linepoints[j].point;
|
||||
linepoints[j].normal = Multiply3x3(matrixB, linepoints[j].normal);
|
||||
#else
|
||||
mat_trans_single3_nodiv(linepoints[j].point.x,
|
||||
linepoints[j].point.y,
|
||||
linepoints[j].point.z);
|
||||
mat_trans_normal3(linepoints[j].normal.x,
|
||||
linepoints[j].normal.y,
|
||||
linepoints[j].normal.z);
|
||||
#endif
|
||||
}
|
||||
|
||||
return numCollisions; // sphere collisions
|
||||
|
||||
@@ -479,6 +479,7 @@ RemoveFirstInQueue(Queue *queue)
|
||||
}
|
||||
|
||||
std::vector<AudioReadCmd> pendingAudioReads;
|
||||
volatile int pendingAudioRead_fd = -1;
|
||||
#if !defined(DC_SH4)
|
||||
std::mutex pendingAudioReadsMutex;
|
||||
#endif
|
||||
@@ -487,8 +488,9 @@ void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, st
|
||||
AudioReadCmd cmd = { pBuffer, fd, bytes, seek};
|
||||
if (!callback) {
|
||||
cmd.callback = [](AudioReadCmd* cmd){
|
||||
lseek(cmd->fd, cmd->seek, SEEK_SET);
|
||||
read(cmd->fd, cmd->dest, cmd->size);
|
||||
assert(pendingAudioRead_fd == cmd->fd);
|
||||
assert(lseek(cmd->fd, cmd->seek, SEEK_SET) == cmd->seek);
|
||||
assert(read(cmd->fd, cmd->dest, cmd->size) == cmd->size);
|
||||
};
|
||||
} else {
|
||||
cmd.callback = callback;
|
||||
@@ -500,7 +502,7 @@ void CdStreamQueueAudioRead(int fd, void* pBuffer, size_t bytes, size_t seek, st
|
||||
auto mask = irq_disable();
|
||||
#endif
|
||||
for (auto it = pendingAudioReads.rbegin(); it != pendingAudioReads.rend(); ++it) {
|
||||
if (it->fd == -1 || it->fd == fd) {
|
||||
if (it->fd == -1) {
|
||||
*it = cmd;
|
||||
goto out;
|
||||
}
|
||||
@@ -532,6 +534,12 @@ void CdStreamDiscardAudioRead(int fd) {
|
||||
#if defined(DC_SH4)
|
||||
irq_restore(mask);
|
||||
#endif
|
||||
|
||||
while (pendingAudioRead_fd == fd) {
|
||||
#if defined(DC_SH4)
|
||||
thd_pass();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
AudioReadCmd CdStreamNextAudioRead() {
|
||||
@@ -548,6 +556,8 @@ AudioReadCmd CdStreamNextAudioRead() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(pendingAudioRead_fd == -1);
|
||||
pendingAudioRead_fd = cmd.fd;
|
||||
#if defined(DC_SH4)
|
||||
irq_restore(mask);
|
||||
#endif
|
||||
@@ -568,6 +578,7 @@ int read_loop(int fd, void* pBuffer, size_t bytes) {
|
||||
auto cmd = CdStreamNextAudioRead();
|
||||
while (cmd.fd != -1) {
|
||||
cmd.callback(&cmd);
|
||||
pendingAudioRead_fd = -1;
|
||||
cmd = CdStreamNextAudioRead();
|
||||
}
|
||||
}
|
||||
@@ -584,6 +595,7 @@ void *CdStreamThread(void *param)
|
||||
auto cmd = CdStreamNextAudioRead();
|
||||
while (cmd.fd != -1) {
|
||||
cmd.callback(&cmd);
|
||||
pendingAudioRead_fd = -1;
|
||||
cmd = CdStreamNextAudioRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -718,269 +718,671 @@ CFileLoader::LoadObjectTypes(const char *filename)
|
||||
//find . -type f -name "*rail*.dff" ! -name "*shad*"
|
||||
//find . -type f -name "*veg*.dff" ! -name "*shad*"
|
||||
char *AlphaTestNames[] = {
|
||||
"xpolytrees2_dt",
|
||||
"gf_treesfw3_01",
|
||||
"ci_trees05",
|
||||
"xpolytrees3_dt",
|
||||
"LODrtrees5",
|
||||
"LODrtrees2",
|
||||
"nbt_mansiontrees04",
|
||||
"malltreereflect2",
|
||||
"veg_treeb1",
|
||||
"LODrtrees4",
|
||||
"Streetlamp2",
|
||||
"nbt_mansiontrees02",
|
||||
"LODmrgtrees4",
|
||||
"gf_tree2_02",
|
||||
"malltreereflect",
|
||||
"nbt_hoteltrees02",
|
||||
"veg_treea1",
|
||||
"Streetlamp1",
|
||||
"gf_treesfw5_01",
|
||||
"nbt_mansiontrees05",
|
||||
"malltrees01",
|
||||
"xpolytrees4_dt",
|
||||
"nbt_mansiontrees03",
|
||||
"xpolytrees1_dt",
|
||||
"hoteltrees01",
|
||||
"hoteltrees03",
|
||||
"gf_treesfw1_01",
|
||||
"veg_tree3",
|
||||
"ap_treeshot1_02",
|
||||
"hoteltrees02",
|
||||
"ci_trees03",
|
||||
"veg_treea3",
|
||||
"mc_treesfw3_01",
|
||||
"ap_treesfw1_01",
|
||||
"nbt_hoteltrees01",
|
||||
"ci_trees04",
|
||||
"gf_treesfw2_01",
|
||||
"LODrtrees3",
|
||||
"ci_trees1",
|
||||
"mc_treesfw1_01",
|
||||
"LODrtrees1",
|
||||
"gf_treesfw4_01",
|
||||
"nbt_mansiontrees01",
|
||||
"hoteltrees06",
|
||||
"mn_treesis_int",
|
||||
"hoteltrees05",
|
||||
"mc_treesfw2_01",
|
||||
"gf_tree1_01",
|
||||
"mn_treesisl05",
|
||||
"doublestreetlght1",
|
||||
"ci_trees02",
|
||||
"bank_palms09",
|
||||
"veg_palmkb3",
|
||||
"lw_palm1",
|
||||
"veg_palmkb5",
|
||||
"bank_palms21",
|
||||
"veg_palmkb1",
|
||||
"veg_palmbig14",
|
||||
"veg_palmkb14",
|
||||
"veg_palm02",
|
||||
"veg_palmkb2",
|
||||
"veg_palmkb9",
|
||||
"bank_palms28",
|
||||
"veg_palmkb7",
|
||||
"bank_palms23",
|
||||
"bank_palms32",
|
||||
"veg_palmkb8",
|
||||
"bank_palms02",
|
||||
"bank_palms33",
|
||||
"veg_palmkbb11",
|
||||
"veg_palmkb4",
|
||||
"veg_palm01",
|
||||
"veg_palm03",
|
||||
"veg_palmkb13",
|
||||
"veg_palmkb10",
|
||||
"veg_palm04",
|
||||
"gf_tennisfence",
|
||||
"marinafence04",
|
||||
"marinafence01",
|
||||
"b_hse_pierfence",
|
||||
"ap_wallfence5",
|
||||
"dockfence",
|
||||
"dtn_hospital_fence",
|
||||
"mc_fence1",
|
||||
"od_clubfence_dy",
|
||||
"ap_wallfence1",
|
||||
"const_woodfence30",
|
||||
"bb_fence1",
|
||||
"ap_seafences",
|
||||
"marinafence03",
|
||||
"nbthotel08fence02",
|
||||
"dt_sheraton_fence",
|
||||
"dt_scabby_fence04",
|
||||
"nbt_barfence01",
|
||||
"ap_wallfence2",
|
||||
"od_clevelfence",
|
||||
"mc_fence2",
|
||||
"ci_fence2",
|
||||
"dt_scabby_fence03",
|
||||
"mansionfence",
|
||||
"nbt_hotel07fence",
|
||||
"marinafence02",
|
||||
"fence01",
|
||||
"compound_fence",
|
||||
"ap_wallfence7",
|
||||
"fencehaitism",
|
||||
"od_clubfence_nt",
|
||||
"marinafence05",
|
||||
"ap_wallfence6",
|
||||
"Mansion2_C_fence",
|
||||
"dt_scabby_fence07",
|
||||
"kickfence",
|
||||
"pw_backfence1",
|
||||
"mc_fence3",
|
||||
"washfence1",
|
||||
"LODst_woodfence30",
|
||||
"washfence2",
|
||||
"carparkfence0",
|
||||
"ap_wallfence3",
|
||||
"fencesmallb",
|
||||
"ap_wallfence4",
|
||||
"fencehaiti",
|
||||
"stationfence",
|
||||
"dt_scabby_fence01",
|
||||
"pw_bayfence2_01",
|
||||
"lha_carfence",
|
||||
"tall_fence",
|
||||
"ap_seaplanfence1",
|
||||
"LODse_pierfence",
|
||||
"marinaveg3",
|
||||
"ml_vegbits05",
|
||||
"svegrgedoor",
|
||||
"ml_vegbits04",
|
||||
"nrth3veg35",
|
||||
"nrth3veg05",
|
||||
"ht_veg01_nt",
|
||||
"nbeachvegy1",
|
||||
"odnvegbush1",
|
||||
"washvegy4",
|
||||
"ht_veg02_nt",
|
||||
"wshotelveg1",
|
||||
"dtn_veg3",
|
||||
"nrth7veg09",
|
||||
"washvegy238",
|
||||
"veg_palwee02",
|
||||
"nrth3veg50",
|
||||
"washpshoutveg",
|
||||
"nrth4veg08",
|
||||
"washvegy3",
|
||||
"washvegy241",
|
||||
"washvegy2",
|
||||
"washvegy239",
|
||||
"odnvegbush2b",
|
||||
"veg_gaz",
|
||||
"nrth1veg21",
|
||||
"ht_veg04_dy",
|
||||
"ml_vegbits03",
|
||||
"nbeachvegy2",
|
||||
"nrth3veg16",
|
||||
"ht_veg02_dy",
|
||||
"nrth4veg05",
|
||||
"ht_veg04_nt",
|
||||
"veg_palwee01",
|
||||
"ht_veg01_dy",
|
||||
"vegeha1",
|
||||
"veged",
|
||||
"veg_ivy_balcny_kb3",
|
||||
"nrth1veg42",
|
||||
"marinaveg1",
|
||||
"nrth3veg25",
|
||||
"veg_fern_balcny_kb1",
|
||||
"spad_veg1",
|
||||
"washvegy2413",
|
||||
"marinaveg2",
|
||||
"washvegy240",
|
||||
"vegetationb",
|
||||
"nrth1veg37",
|
||||
"ml_vegbits01",
|
||||
"veged01",
|
||||
"dtn_veg4",
|
||||
"washvegy242",
|
||||
"veg_palwee03",
|
||||
"nrth3veg59",
|
||||
"nrth4veg212",
|
||||
"nrth4veg21",
|
||||
"nrth7veg",
|
||||
"washvegy237",
|
||||
"nrth3veg08",
|
||||
"nrth4veg09",
|
||||
"veg_fern_balcny_kb2",
|
||||
"ml_vegbits02",
|
||||
"odnvegbush2",
|
||||
"vegetationb03",
|
||||
"veged02",
|
||||
"kb_planterbox",
|
||||
"plants05b",
|
||||
"nbdecoshplants",
|
||||
"ap_planters2_01",
|
||||
"ml_planterbed",
|
||||
"marinaplanter1",
|
||||
"washskyplant1",
|
||||
"dzplant",
|
||||
"ci_planter2",
|
||||
"ap_planters1_01",
|
||||
"gf_planters4",
|
||||
"washskyplant2",
|
||||
"kb_planter+bush",
|
||||
"marinaplanter2",
|
||||
"ci_planter1",
|
||||
"plants04",
|
||||
"gf_planters2",
|
||||
"kb_planterbush2",
|
||||
"plants01",
|
||||
"kb_planter+bush2",
|
||||
"plants05",
|
||||
"ci_busht_04",
|
||||
"starsbush2",
|
||||
"mansbushes2",
|
||||
"odnvegbush1",
|
||||
"odrv_bushes",
|
||||
"ci_busht_02",
|
||||
"mlmallbush",
|
||||
"mansbushes",
|
||||
"nbw_bush02",
|
||||
"ci_busht_08",
|
||||
"nbw_bush01",
|
||||
"odnvegbush2b",
|
||||
"ap_carbush2_01",
|
||||
"new_bushtest42",
|
||||
"new_bushsm",
|
||||
"mallbushs",
|
||||
"odrv_bushes01",
|
||||
"kb_planter+bush",
|
||||
"ci_busht_06",
|
||||
"beach_bush08s",
|
||||
"beach_bush06s",
|
||||
"new_bushtest",
|
||||
"doontoon66_bushes01",
|
||||
"beach_bush04",
|
||||
"starbitbush",
|
||||
"beach_bush02",
|
||||
"lhavnew_bush",
|
||||
"kb_planterbush2",
|
||||
"ci_busht_11",
|
||||
"odnvegbush2",
|
||||
"kb_planter+bush2",
|
||||
"mallbushdense",
|
||||
"dk_rail06",
|
||||
"cl_railing",
|
||||
"docks10rail",
|
||||
"cl_railingb",
|
||||
"dk_rail05",
|
||||
"shpfrnts03rail01",
|
||||
"dk_rail02",
|
||||
"nbeachbit03rails",
|
||||
"ci_mans1rail",
|
||||
"dk_rail07",
|
||||
"dk_rail01",
|
||||
"ci_mans2rail1",
|
||||
"ci_mans1rail1",
|
||||
"dk_rail04",
|
||||
"shpfrnts03rail02",
|
||||
"dk_rail03",
|
||||
"BillBd04",
|
||||
"BillBd1",
|
||||
"BillBd2",
|
||||
"BillBd3",
|
||||
"LODk_grassarea",
|
||||
"LODmrgtrees4",
|
||||
"LODo_polgrnda10",
|
||||
"LODo_polgrnda12",
|
||||
"LODo_polgrnda13",
|
||||
"LODo_polgrnda14",
|
||||
"LODo_polgrnda16",
|
||||
"LODo_polgrnda17",
|
||||
"LODo_polgrnda7",
|
||||
"LODo_polgrnda8",
|
||||
"LODo_polgrnda9",
|
||||
"LODrtrees1",
|
||||
"LODrtrees2",
|
||||
"LODrtrees3",
|
||||
"LODrtrees4",
|
||||
"LODrtrees5",
|
||||
"LODse_pierfence",
|
||||
"LODst_woodfence30",
|
||||
"Man3_base_hedge",
|
||||
"Mansion2_C_fence",
|
||||
"Rose_Bush01",
|
||||
"Rose_Bush03",
|
||||
"Starhouse",
|
||||
"Streetlamp1",
|
||||
"Streetlamp2",
|
||||
"ap_blastdef_01",
|
||||
"ap_blastdef_03",
|
||||
"ap_boardshad1",
|
||||
"ap_carbush2_01",
|
||||
"ap_planters1_01",
|
||||
"ap_planters2_01",
|
||||
"ap_radar1_01",
|
||||
"ap_seafences",
|
||||
"ap_seaplanfence1",
|
||||
"ap_stairsout02",
|
||||
"ap_stairsout03",
|
||||
"ap_stairsout04",
|
||||
"ap_stairsout1",
|
||||
"ap_subfraightback01",
|
||||
"ap_subfraightback02",
|
||||
"ap_subfraightback04",
|
||||
"ap_treesfw1_01",
|
||||
"ap_treeshot1_02",
|
||||
"ap_wallfence1",
|
||||
"ap_wallfence2",
|
||||
"ap_wallfence3",
|
||||
"ap_wallfence4",
|
||||
"ap_wallfence5",
|
||||
"ap_wallfence6",
|
||||
"ap_wallfence7",
|
||||
"b_hse_pierfence",
|
||||
"bank_palms02",
|
||||
"bank_palms09",
|
||||
"bank_palms21",
|
||||
"bank_palms23",
|
||||
"bank_palms28",
|
||||
"bank_palms32",
|
||||
"bank_palms33",
|
||||
"basketballcourt04",
|
||||
"basketballcourt05",
|
||||
"bb_fence1",
|
||||
"beach_bush02",
|
||||
"beach_bush04",
|
||||
"beach_bush06s",
|
||||
"beach_bush08s",
|
||||
"biggrass2",
|
||||
"bldigste1mesh",
|
||||
"boatcranelg0",
|
||||
"build1",
|
||||
"buldingsite1",
|
||||
"carparkfence0",
|
||||
"chandelier",
|
||||
"ci_astagelights",
|
||||
"ci_astudganwal",
|
||||
"ci_boards1",
|
||||
"ci_boards2",
|
||||
"ci_busht_02",
|
||||
"ci_busht_04",
|
||||
"ci_busht_06",
|
||||
"ci_busht_08",
|
||||
"ci_busht_11",
|
||||
"ci_dstudiogantry",
|
||||
"ci_fence2",
|
||||
"ci_mans1rail",
|
||||
"ci_mans1rail1",
|
||||
"ci_mans2rail1",
|
||||
"ci_planter1",
|
||||
"ci_planter2",
|
||||
"ci_pornsetxtra",
|
||||
"ci_shipset",
|
||||
"ci_stairsout01",
|
||||
"ci_trees02",
|
||||
"ci_trees03",
|
||||
"ci_trees04",
|
||||
"ci_trees05",
|
||||
"ci_trees1",
|
||||
"cl_curtains",
|
||||
"cl_lightsuprts",
|
||||
"cl_railing",
|
||||
"cl_railingb",
|
||||
"cl_recessedlights1",
|
||||
"club_exterior01",
|
||||
"club_exterior02",
|
||||
"club_exterior06",
|
||||
"club_exterior07",
|
||||
"club_exterior08",
|
||||
"club_exterior09",
|
||||
"compound_fence",
|
||||
"concerth.col",
|
||||
"concerth02",
|
||||
"concerth03",
|
||||
"concerth04",
|
||||
"concerth05",
|
||||
"concerth06",
|
||||
"concerth07",
|
||||
"concerth08",
|
||||
"concerth09",
|
||||
"concerth10",
|
||||
"concerth11",
|
||||
"concerth12",
|
||||
"concerth27",
|
||||
"concerth29",
|
||||
"concerth48",
|
||||
"concerth49",
|
||||
"concerth50",
|
||||
"concerth51",
|
||||
"concerth52",
|
||||
"concerth54",
|
||||
"concerth56",
|
||||
"const_woodfence30",
|
||||
"cranebasea0",
|
||||
"crgoshp010",
|
||||
"crocneon",
|
||||
"deco_polgrnda10",
|
||||
"deco_polgrnda12",
|
||||
"deco_polgrnda13",
|
||||
"deco_polgrnda14",
|
||||
"deco_polgrnda16",
|
||||
"deco_polgrnda17",
|
||||
"deco_polgrnda7",
|
||||
"deco_polgrnda8",
|
||||
"deco_polgrnda9",
|
||||
"dk_cargoshp01",
|
||||
"dk_cargoshp03",
|
||||
"dk_cargoshp04",
|
||||
"dk_cargoshp05",
|
||||
"dk_cargoshp10",
|
||||
"dk_cargoshp100",
|
||||
"dk_cargoshp12",
|
||||
"dk_cargoshp24",
|
||||
"dk_cargoshp25",
|
||||
"dk_cargoshp28",
|
||||
"dk_cargoshp31",
|
||||
"dk_cargoshp32",
|
||||
"dk_cargoshp35",
|
||||
"dk_cargoshp40",
|
||||
"dk_cargoshp41",
|
||||
"dk_cargoshp47",
|
||||
"dk_cargoshp50",
|
||||
"dk_cargoshp51",
|
||||
"dk_cargoshp53",
|
||||
"dk_cargoshp54",
|
||||
"dk_cargoshp64",
|
||||
"dk_cargoshp65",
|
||||
"dk_cargoshp66",
|
||||
"dk_cargoshp68",
|
||||
"dk_cargoshp70",
|
||||
"dk_cargoshp71",
|
||||
"dk_cargoshp72",
|
||||
"dk_cargoshp73",
|
||||
"dk_cargoshp76",
|
||||
"dk_cargoshp95",
|
||||
"dk_rail01",
|
||||
"dk_rail02",
|
||||
"dk_rail03",
|
||||
"dk_rail03",
|
||||
"dk_rail04",
|
||||
"dk_rail05",
|
||||
"dk_rail06",
|
||||
"dk_rail07",
|
||||
"doc_crane_cab0",
|
||||
"doc_crane_cab01",
|
||||
"doc_crane_cab02",
|
||||
"doc_crane_cab03",
|
||||
"doc_crane_cab04",
|
||||
"doc_craneeggs04",
|
||||
"dock_grassarea",
|
||||
"dock_props01",
|
||||
"dock_props02",
|
||||
"dockcranescale0",
|
||||
"dockcranescale01",
|
||||
"dockfence",
|
||||
"dockgate01",
|
||||
"dockgate02",
|
||||
"dockgrass",
|
||||
"docks10",
|
||||
"docks10rail",
|
||||
"docksware01",
|
||||
"doontoon18",
|
||||
"doontoon25_alfas",
|
||||
"doontoon32_alfa",
|
||||
"doontoon66_bushes01",
|
||||
"doontoon76",
|
||||
"doublestreetlght1",
|
||||
"drive_flowers06",
|
||||
"dt_compound_alfas",
|
||||
"dt_scabby_fence01",
|
||||
"dt_scabby_fence03",
|
||||
"dt_scabby_fence04",
|
||||
"dt_scabby_fence07",
|
||||
"dt_sheraton_fence",
|
||||
"dt_stadium__alfa1",
|
||||
"dtn_cablesa",
|
||||
"dtn_cablesb",
|
||||
"dtn_cablesc",
|
||||
"dtn_cablesd",
|
||||
"dtn_cablese",
|
||||
"dtn_cablesf",
|
||||
"dtn_hospital_fence",
|
||||
"dtn_veg3",
|
||||
"dtn_veg4",
|
||||
"dts_telwire1",
|
||||
"dts_telwire2",
|
||||
"dts_telwire4",
|
||||
"dts_telwire9",
|
||||
"dzplant",
|
||||
"fence01",
|
||||
"fencehaiti",
|
||||
"fencehaitism",
|
||||
"fencesmallb",
|
||||
"gf_drdivide1_01",
|
||||
"gf_drivingrange1",
|
||||
"gf_golfwall",
|
||||
"gf_picket1_01",
|
||||
"gf_planters2",
|
||||
"gf_planters4",
|
||||
"gf_stadlight1_02",
|
||||
"gf_tennisfence",
|
||||
"gf_tree1_01",
|
||||
"gf_tree2_02",
|
||||
"gf_treesfw1_01",
|
||||
"gf_treesfw2_01",
|
||||
"gf_treesfw3_01",
|
||||
"gf_treesfw4_01",
|
||||
"gf_treesfw5_01",
|
||||
"grassbitsjm",
|
||||
"grasspatch",
|
||||
"haitinwire11",
|
||||
"haitinwire22",
|
||||
"haitinwire23",
|
||||
"havanahouse12b",
|
||||
"hoteltrees01",
|
||||
"hoteltrees02",
|
||||
"hoteltrees03",
|
||||
"hoteltrees05",
|
||||
"hoteltrees06",
|
||||
"ht_veg01_dy",
|
||||
"ht_veg01_nt",
|
||||
"ht_veg02_dy",
|
||||
"ht_veg02_nt",
|
||||
"ht_veg04_dy",
|
||||
"ht_veg04_nt",
|
||||
"kb_planter",
|
||||
"kb_planter+bush",
|
||||
"kb_planter+bush2",
|
||||
"kb_planterbox",
|
||||
"kb_planterbush2",
|
||||
"kickfence",
|
||||
"labiggrass",
|
||||
"labiggrass01",
|
||||
"labiggrass02",
|
||||
"lh_haiblockc3",
|
||||
"lha_carfence",
|
||||
"lhavnew_bush",
|
||||
"lhbasket",
|
||||
"lhbillboard05xx",
|
||||
"lhroofst01",
|
||||
"lhroofst02",
|
||||
"lhroofst03",
|
||||
"lhroofst04",
|
||||
"lhroofst07",
|
||||
"lhroofst08",
|
||||
"lhroofst09",
|
||||
"lhroofst10",
|
||||
"lhroofst11",
|
||||
"lhroofst12",
|
||||
"lhroofst14",
|
||||
"lhroofst16",
|
||||
"lhroofst17",
|
||||
"lhroofst18",
|
||||
"lhroofst19",
|
||||
"lhroofstuffg",
|
||||
"lhsteps3",
|
||||
"lithavabit01",
|
||||
"lithavabit03",
|
||||
"lithavabit04",
|
||||
"lithavabit05",
|
||||
"lithavabit06",
|
||||
"lithavabit07",
|
||||
"lithavabit08",
|
||||
"lithavabit09",
|
||||
"lithavabit10",
|
||||
"lithavabit11",
|
||||
"lithavabit12",
|
||||
"littlehacoast02",
|
||||
"littlehacoast05",
|
||||
"lw_palm1",
|
||||
"mallbushdense",
|
||||
"mallbushs",
|
||||
"malltreereflect",
|
||||
"malltreereflect2",
|
||||
"malltrees01",
|
||||
"man_build01",
|
||||
"man_build01_al",
|
||||
"man_build02",
|
||||
"man_build02_al",
|
||||
"man_build03",
|
||||
"man_build03_al",
|
||||
"man_build04",
|
||||
"man_build04_fnce",
|
||||
"man_build05",
|
||||
"man_build05_al",
|
||||
"man_build_int",
|
||||
"man_chandeliers",
|
||||
"man_f_chandelier",
|
||||
"man_lights_pool",
|
||||
"man_pool",
|
||||
"man_safenewmny",
|
||||
"man_scar_curtains",
|
||||
"man_scar_props206",
|
||||
"man_sdr_folge",
|
||||
"man_sdr_rug",
|
||||
"man_twr_stairs",
|
||||
"man_twr_stairsB",
|
||||
"man_xchandeliers",
|
||||
"mansbushes",
|
||||
"mansbushes2",
|
||||
"mansion1b",
|
||||
"mansionfence",
|
||||
"marinafence01",
|
||||
"marinafence02",
|
||||
"marinafence03",
|
||||
"marinafence04",
|
||||
"marinafence05",
|
||||
"marinaplanter1",
|
||||
"marinaplanter2",
|
||||
"marinaveg1",
|
||||
"marinaveg2",
|
||||
"marinaveg3",
|
||||
"mc_fence1",
|
||||
"mc_fence2",
|
||||
"mc_fence3",
|
||||
"mc_largebuild",
|
||||
"mc_tower_01",
|
||||
"mc_tower_02",
|
||||
"mc_tower_03",
|
||||
"mc_treesfw1_01",
|
||||
"mc_treesfw2_01",
|
||||
"mc_treesfw3_01",
|
||||
"mc_wall",
|
||||
"mc_wall2",
|
||||
"mc_wall3",
|
||||
"ml_planterbed",
|
||||
"ml_vegbits01",
|
||||
"ml_vegbits02",
|
||||
"ml_vegbits03",
|
||||
"ml_vegbits04",
|
||||
"ml_vegbits05",
|
||||
"mlmallbush",
|
||||
"mn_treesis_int",
|
||||
"mn_treesisl05",
|
||||
"nbchflw01",
|
||||
"nbchflw02",
|
||||
"nbdcprmndfnc1",
|
||||
"nbdcprmndfnc2",
|
||||
"nbdecoshplants",
|
||||
"nbeachbed01",
|
||||
"nbeachbed02",
|
||||
"nbeachbit03rails",
|
||||
"nbeachvegy1",
|
||||
"nbeachvegy2",
|
||||
"nbecland12",
|
||||
"nbecland12bball",
|
||||
"nbecland12gates",
|
||||
"nbt_balcony02",
|
||||
"nbt_balcony03",
|
||||
"nbt_balcony05",
|
||||
"nbt_barfence01",
|
||||
"nbt_hotel06balcony",
|
||||
"nbt_hotel07fence",
|
||||
"nbt_hoteltrees01",
|
||||
"nbt_hoteltrees02",
|
||||
"nbt_mansion01",
|
||||
"nbt_mansion02",
|
||||
"nbt_mansion03",
|
||||
"nbt_mansion04",
|
||||
"nbt_mansion0402",
|
||||
"nbt_mansiontrees01",
|
||||
"nbt_mansiontrees02",
|
||||
"nbt_mansiontrees03",
|
||||
"nbt_mansiontrees04",
|
||||
"nbt_mansiontrees05",
|
||||
"nbt_rooftopstart",
|
||||
"nbthotel08fence02",
|
||||
"nbw_bush01",
|
||||
"nbw_bush02",
|
||||
"nbwbusshy2",
|
||||
"new_bushsm",
|
||||
"new_bushtest",
|
||||
"new_bushtest42",
|
||||
"newbuild01",
|
||||
"newbuild02",
|
||||
"nhaitiplnt14",
|
||||
"nhaitiplnt15",
|
||||
"nrth1veg21",
|
||||
"nrth1veg37",
|
||||
"nrth1veg42",
|
||||
"nrth3veg05",
|
||||
"nrth3veg08",
|
||||
"nrth3veg16",
|
||||
"nrth3veg25",
|
||||
"nrth3veg35",
|
||||
"nrth3veg50",
|
||||
"nrth3veg59",
|
||||
"nrth4veg05",
|
||||
"nrth4veg08",
|
||||
"nrth4veg09",
|
||||
"nrth4veg21",
|
||||
"nrth4veg212",
|
||||
"nrth7veg",
|
||||
"nrth7veg09",
|
||||
"nt_cablebox1_01",
|
||||
"nt_cablebox2_01",
|
||||
"nt_cablebox3_01",
|
||||
"nt_cablebox4_01",
|
||||
"nt_cablebox5_01",
|
||||
"nt_cablebox6_01",
|
||||
"od_alleys1_01_dy",
|
||||
"od_alleys1_01_nt",
|
||||
"od_alleys1b_01_dy",
|
||||
"od_alleys1b_01_nt",
|
||||
"od_alleys2_01_dy",
|
||||
"od_alleys2_01_nt",
|
||||
"od_alleys3_01_dy",
|
||||
"od_alleys3_01_nt",
|
||||
"od_alleys3b_01_dy",
|
||||
"od_alleys3b_01_nt",
|
||||
"od_bighotsign01",
|
||||
"od_clevelfence",
|
||||
"od_clubfence_dy",
|
||||
"od_clubfence_nt",
|
||||
"oddoorway",
|
||||
"oddoorway2",
|
||||
"oddoorwayS02",
|
||||
"oddoorwayS1",
|
||||
"odnvegbush1",
|
||||
"odnvegbush2",
|
||||
"odnvegbush2b",
|
||||
"odnwiret",
|
||||
"odrampbit",
|
||||
"odrroofst02",
|
||||
"odrroofst06",
|
||||
"odrroofst07",
|
||||
"odrv_bushes",
|
||||
"odrv_bushes01",
|
||||
"pierentrance02",
|
||||
"plants01",
|
||||
"plants04",
|
||||
"plants05",
|
||||
"plants05b",
|
||||
"pw_backfence1",
|
||||
"pw_bayfence2_01",
|
||||
"rustship_structure0",
|
||||
"scrapgate",
|
||||
"sexgarden2",
|
||||
"shipstairs",
|
||||
"shpfrnts03rail01",
|
||||
"shpfrnts03rail02",
|
||||
"sjmgrass",
|
||||
"sjmgrass2",
|
||||
"spad_veg1",
|
||||
"starbbnet02",
|
||||
"starbitbush",
|
||||
"starbits05",
|
||||
"starbits06",
|
||||
"starbits13",
|
||||
"starbits13b",
|
||||
"starbits13c",
|
||||
"starbits17",
|
||||
"starbits20",
|
||||
"starbits22",
|
||||
"starbits24",
|
||||
"starbits45",
|
||||
"starbits46",
|
||||
"starbits49",
|
||||
"starbits50",
|
||||
"starbits51",
|
||||
"starbits52",
|
||||
"starbits54",
|
||||
"starbits55",
|
||||
"starbits56",
|
||||
"starbits57",
|
||||
"starbits58",
|
||||
"starbits59",
|
||||
"starblocks04",
|
||||
"stardepot_FENCE",
|
||||
"starfbed02",
|
||||
"starfbed03",
|
||||
"starfbed04",
|
||||
"starfbed05",
|
||||
"starfbed06",
|
||||
"starsbush2",
|
||||
"starwaterfrnt08",
|
||||
"stationfence",
|
||||
"stripinter",
|
||||
"stripinterupside",
|
||||
"striplights",
|
||||
"svegrgedoor",
|
||||
"tall_fence",
|
||||
"telewire02",
|
||||
"telewire03",
|
||||
"telewire04",
|
||||
"telgrphpole02",
|
||||
"tesad06",
|
||||
"tesad06sas",
|
||||
"tesad06ss",
|
||||
"veg_fern_balcny_kb1",
|
||||
"veg_fern_balcny_kb2",
|
||||
"veg_gaz",
|
||||
"veg_ivy_balcny_kb3",
|
||||
"veg_palm01",
|
||||
"veg_palm02",
|
||||
"veg_palm03",
|
||||
"veg_palm04",
|
||||
"veg_palmbig14",
|
||||
"veg_palmkb1",
|
||||
"veg_palmkb10",
|
||||
"veg_palmkb13",
|
||||
"veg_palmkb14",
|
||||
"veg_palmkb1pERC",
|
||||
"veg_palmkb2",
|
||||
"veg_palmkb3",
|
||||
"veg_palmkb4",
|
||||
"veg_palmkb5",
|
||||
"veg_palmkb7",
|
||||
"veg_palmkb8",
|
||||
"veg_palmkb9",
|
||||
"veg_palmkbb11",
|
||||
"veg_palwee01",
|
||||
"veg_palwee02",
|
||||
"veg_palwee03",
|
||||
"veg_tree3",
|
||||
"veg_treea1",
|
||||
"veg_treea3",
|
||||
"veg_treeb1",
|
||||
"veged",
|
||||
"veged01",
|
||||
"veged02",
|
||||
"vegeha1",
|
||||
"vegetationb",
|
||||
"vegetationb03",
|
||||
"washbuild003",
|
||||
"washbuild005",
|
||||
"washbuild013",
|
||||
"washbuild014",
|
||||
"washbuild015",
|
||||
"washbuild017",
|
||||
"washbuild018",
|
||||
"washbuild020",
|
||||
"washbuild021",
|
||||
"washbuild025",
|
||||
"washbuild025neon",
|
||||
"washbuild030",
|
||||
"washbuild033",
|
||||
"washbuild039",
|
||||
"washbuild040",
|
||||
"washbuild041",
|
||||
"washbuild043",
|
||||
"washbuild050",
|
||||
"washbuild05067",
|
||||
"washbuild058",
|
||||
"washbuild062",
|
||||
"washbuild063",
|
||||
"washbuild066",
|
||||
"washbuild068",
|
||||
"washbuild069",
|
||||
"washbuild071",
|
||||
"washbuild072",
|
||||
"washbuild073",
|
||||
"washbuild074",
|
||||
"washbuild075",
|
||||
"washbuild081",
|
||||
"washbuild0812",
|
||||
"washbuild111",
|
||||
"washbuild112",
|
||||
"washbuild114",
|
||||
"washbuild116",
|
||||
"washbuild119",
|
||||
"washbuild120",
|
||||
"washbuild121",
|
||||
"washbuild184",
|
||||
"washbuild187",
|
||||
"washbuild191",
|
||||
"washbuild192",
|
||||
"washbuild194",
|
||||
"washbuild195",
|
||||
"washbuild198",
|
||||
"washbuild199",
|
||||
"washbuild200",
|
||||
"washbuild201",
|
||||
"washbuild202",
|
||||
"washbuild203",
|
||||
"washbuild206",
|
||||
"washbuild210",
|
||||
"washbuild213",
|
||||
"washbuild214",
|
||||
"washbuild215",
|
||||
"washbuild216",
|
||||
"washbuild217",
|
||||
"washbuild231",
|
||||
"washelipad",
|
||||
"washfence1",
|
||||
"washfence2",
|
||||
"washpshoutdet",
|
||||
"washpshoutveg",
|
||||
"washskyplant1",
|
||||
"washskyplant2",
|
||||
"washundermall1",
|
||||
"washvegy2",
|
||||
"washvegy237",
|
||||
"washvegy238",
|
||||
"washvegy239",
|
||||
"washvegy240",
|
||||
"washvegy241",
|
||||
"washvegy2413",
|
||||
"washvegy242",
|
||||
"washvegy3",
|
||||
"washvegy4",
|
||||
"woshmallglas1",
|
||||
"woshmallglas2",
|
||||
"wsgbuildwl97",
|
||||
"wshbuildws42",
|
||||
"wshotelsign35",
|
||||
"wshotelveg1",
|
||||
"wshscarland226",
|
||||
"wshtelgrphcabl01",
|
||||
"wshtelgrphcabl02",
|
||||
"wshtelgrphcabl03",
|
||||
"wshtelgrphcabl04",
|
||||
"wshtelgrphcabl05",
|
||||
"wshtelgrphcabl06",
|
||||
"wshtelgrphcabl07",
|
||||
"wshtelgrphcabl08",
|
||||
"wshtelgrphcabl09",
|
||||
"wshtelgrphcabl10",
|
||||
"wshtelgrphcabl11",
|
||||
"xpolytrees1_dt",
|
||||
"xpolytrees2_dt",
|
||||
"xpolytrees3_dt",
|
||||
"xpolytrees4_dt",
|
||||
|
||||
"",
|
||||
};
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ const CRGBA SCROLLBAR_COLOR = LABEL_COLOR;
|
||||
#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION)
|
||||
#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen))
|
||||
|
||||
#define MIN_DRAWDIST 0.5f // default was 0.925f
|
||||
#define MAX_DRAWDIST 1.8f
|
||||
|
||||
int GetOptionCount(int screen)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -729,10 +732,10 @@ CMenuManager::CheckSliderMovement(int value)
|
||||
break;
|
||||
case MENUACTION_DRAWDIST:
|
||||
if(value > 0)
|
||||
m_PrefsLOD += ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
|
||||
m_PrefsLOD += ((MAX_DRAWDIST - MIN_DRAWDIST) / MENUSLIDER_LOGICAL_BARS);
|
||||
else
|
||||
m_PrefsLOD -= ((1.8f - 0.925f) / MENUSLIDER_LOGICAL_BARS);
|
||||
m_PrefsLOD = Clamp(m_PrefsLOD, 0.925f, 1.8f);
|
||||
m_PrefsLOD -= ((MAX_DRAWDIST - MIN_DRAWDIST) / MENUSLIDER_LOGICAL_BARS);
|
||||
m_PrefsLOD = Clamp(m_PrefsLOD, MIN_DRAWDIST, MAX_DRAWDIST);
|
||||
CRenderer::ms_lodDistScale = m_PrefsLOD;
|
||||
break;
|
||||
|
||||
@@ -1562,7 +1565,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
|
||||
ProcessSlider(m_PrefsBrightness / 384.0f, SLIDER_Y(70.0f), HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true);
|
||||
break;
|
||||
case MENUACTION_DRAWDIST:
|
||||
ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, SLIDER_Y(99.0f), HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true);
|
||||
ProcessSlider((m_PrefsLOD - MIN_DRAWDIST) / (MAX_DRAWDIST - MIN_DRAWDIST), SLIDER_Y(99.0f), HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, SCREEN_WIDTH, true);
|
||||
break;
|
||||
case MENUACTION_MUSICVOLUME:
|
||||
if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
|
||||
|
||||
@@ -2026,6 +2026,10 @@ void CPad::Update(int16 pad)
|
||||
NewState.RightStickY = 0;
|
||||
NewState.RightShock = 0;
|
||||
NewState.LeftShoulder1 = 0;
|
||||
NewState.Cross = 0; // Added for safety
|
||||
NewState.Triangle = 0; // Added for safety
|
||||
NewState.Circle = 0; // Added for safety
|
||||
NewState.Square = 0; // Added for safety
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2048,8 +2052,13 @@ void CPad::Update(int16 pad)
|
||||
NewState.RightStickX = state->joy2x;
|
||||
NewState.RightStickY = state->joy2y;
|
||||
NewState.RightShock = state->dpad_left;
|
||||
|
||||
NewState.LeftShoulder1 = (state->rtrig > 128 && state->ltrig > 128) ? 255 : 0;
|
||||
// Add PS2-style A and B mappings, This may be the only solution for purchase items issue ?...
|
||||
//Further more we can add other PS2 specific mapping here as certain `bool CPad::` functions are not available for mapping down below.
|
||||
NewState.Cross = NewState.A; // A -> Cross (accept/purchase)
|
||||
NewState.Triangle = NewState.B; // B -> Triangle (exit)
|
||||
NewState.Circle = NewState.X; // Optional: X -> Circle
|
||||
NewState.Square = NewState.Y; // Optional: Y -> Square
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2076,6 +2085,10 @@ void CPad::Update(int16 pad)
|
||||
NewState.RightStickY = 0;
|
||||
NewState.RightShock = 0;
|
||||
NewState.LeftShoulder1 = 0;
|
||||
NewState.Cross = 0; // Added for safety
|
||||
NewState.Triangle = 0; // Added for safety
|
||||
NewState.Circle = 0; // Added for safety
|
||||
NewState.Square = 0; // Added for safety
|
||||
}
|
||||
|
||||
// if (old_contMaple == nullptr && contMaple != nullptr)
|
||||
@@ -2132,12 +2145,12 @@ void CPad::Update(int16 pad)
|
||||
if ( JustOutOfFrontend != 0 )
|
||||
--JustOutOfFrontend;
|
||||
|
||||
#ifdef RW_DC
|
||||
|
||||
//auto old_contMaple = contMaple;
|
||||
//auto n_dev = maple_enum_count();
|
||||
contMaple = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||
state = (cont_state_t *)maple_dev_status(contMaple);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void CPad::DoCheats(void)
|
||||
@@ -3515,16 +3528,15 @@ bool CPad::CycleCameraModeJustDown(void)
|
||||
bool result;
|
||||
switch (CURMODE)
|
||||
{
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
case 0: //audible feedback when changing camera ?
|
||||
|
||||
{
|
||||
result = !!(NewState.Select && !OldState.Select);
|
||||
result = !!(NewState.DPadUp && !OldState.DPadUp);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
case 1: //audible feedback when changing camera ?
|
||||
{
|
||||
result = !!(NewState.DPadUp && !OldState.DPadUp);
|
||||
|
||||
@@ -3541,9 +3553,9 @@ bool CPad::CycleCameraModeJustDown(void)
|
||||
{
|
||||
switch (CURMODE)
|
||||
{
|
||||
case 1:
|
||||
case 1: //audible feedback when changing camera ?
|
||||
{
|
||||
result = !!(NewState.DPadDown && !OldState.DPadDown);
|
||||
result = !!(NewState.DPadUp && !OldState.DPadUp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -3869,36 +3881,49 @@ bool CPad::CollectPickupJustDown(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CPad::DuckJustDown(void)
|
||||
bool CPad::DuckJustDown(void)
|
||||
{
|
||||
if (ArePlayerControlsDisabled())
|
||||
if (ArePlayerControlsDisabled()) {
|
||||
duckFrameCounter = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef RW_DC
|
||||
switch (CPad::GetPad(0)->Mode)
|
||||
{
|
||||
case 0: //Xbox Mode
|
||||
if (CPad::GetPad(0)->IsDualAnalog)
|
||||
{
|
||||
return !!(NewState.X&& !OldState.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !!(NewState.X&& !OldState.X);
|
||||
}
|
||||
case 1: //PS2 Mode
|
||||
if (CPad::GetPad(0)->IsDualAnalog)
|
||||
{
|
||||
return !!(NewState.X&& !OldState.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
return !!(NewState.X&& !OldState.X);
|
||||
}
|
||||
bool buttonPressed = false;
|
||||
switch (CPad::GetPad(0)->Mode) {
|
||||
case 0: // Xbox Mode
|
||||
buttonPressed = NewState.X;
|
||||
break;
|
||||
case 1: // PS2 Mode
|
||||
buttonPressed = NewState.X;
|
||||
break;
|
||||
}
|
||||
|
||||
if (buttonPressed) {
|
||||
duckFrameCounter++;
|
||||
if (duckFrameCounter >= DUCK_DELAY_FRAMES && !isDucking) {
|
||||
isDucking = true;
|
||||
return true; // Trigger ducking after delay
|
||||
}
|
||||
} else {
|
||||
duckFrameCounter = 0;
|
||||
isDucking = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
#else
|
||||
return !!(NewState.LeftShock && !OldState.LeftShock);
|
||||
bool buttonPressed = NewState.Square;
|
||||
if (buttonPressed) {
|
||||
duckFrameCounter++;
|
||||
if (duckFrameCounter >= DUCK_DELAY_FRAMES && !isDucking) {
|
||||
isDucking = true;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
duckFrameCounter = 0;
|
||||
isDucking = false;
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -173,11 +173,26 @@ public:
|
||||
uint32 CameraJustUpTime;
|
||||
uint32 CameraLastPressed;
|
||||
bool CameraIsDoublePressed;
|
||||
static const int DUCK_DELAY_FRAMES = 30; // 1 second at 30 FPS
|
||||
int duckFrameCounter; // Frames the duck button has been held
|
||||
bool isDucking; // Tracks if duck action is active
|
||||
|
||||
#ifdef DETECT_PAD_INPUT_SWITCH
|
||||
static bool IsAffectedByController;
|
||||
static bool IsAffectedByController;
|
||||
#endif
|
||||
CPad() { }
|
||||
|
||||
CPad() : duckFrameCounter(0), isDucking(false), // New variables initialized
|
||||
SteeringLeftRightBuffer{0}, DrunkDrivingBufferUsed(0), Phase(0), Mode(0),
|
||||
ShakeDur(0), DisablePlayerControls(0), ShakeFreq(0), iCurrHornHistory(0),
|
||||
JustOutOfFrontend(0), bApplyBrakes(0), LastTimeTouched(0), AverageWeapon(0),
|
||||
AverageEntries(0), IsKeyboardMouse(false), IsDualAnalog(false),
|
||||
CameraJustDown(false), CameraJustUp(false), CameraJustUpTime(0),
|
||||
CameraLastPressed(0), CameraIsDoublePressed(false) {
|
||||
Clear(false);
|
||||
memset(bHornHistory, 0, sizeof(bHornHistory));
|
||||
memset(CheatString, 0, sizeof(CheatString));
|
||||
}
|
||||
|
||||
~CPad() { }
|
||||
|
||||
static bool bDisplayNoControllerMessage;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#pragma warning(disable: 4838) // narrowing conversion
|
||||
#pragma warning(disable: 4996) // POSIX names
|
||||
|
||||
#include "src/common_defines.h"
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#define __STDC_LIMIT_MACROS // so we get UINT32_MAX etc
|
||||
#endif
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "vmu/vmu.h"
|
||||
|
||||
#ifdef RWLIBS
|
||||
extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList);
|
||||
#endif
|
||||
@@ -195,7 +197,13 @@ CustomFrontendOptionsPopulate(void)
|
||||
#define MINI_CASE_SENSITIVE
|
||||
#include "ini.h"
|
||||
|
||||
mINI::INIFile ini("reVC.ini");
|
||||
mINI::INIFile ini(
|
||||
#ifdef DC_SIM
|
||||
"reVC.ini"
|
||||
#else
|
||||
"/vmu/" VMU_DEFAULT_PATH "/reVCini"
|
||||
#endif
|
||||
);
|
||||
mINI::INIStructure cfg;
|
||||
|
||||
bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
|
||||
@@ -483,13 +491,19 @@ void SaveINIControllerSettings()
|
||||
#endif
|
||||
StoreIni("Controller", "PadButtonsInited", ControlsManager.ms_padButtonsInited);
|
||||
|
||||
ini.write(cfg);
|
||||
{
|
||||
RAIIVmuBeep(VMU_DEFAULT_PATH, 1.0f);
|
||||
ini.write(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadINISettings()
|
||||
{
|
||||
if (!ini.read(cfg))
|
||||
return false;
|
||||
{
|
||||
RAIIVmuBeep(VMU_DEFAULT_PATH, 1.0f);
|
||||
if (!ini.read(cfg))
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef IMPROVED_VIDEOMODE
|
||||
ReadIniIfExists("VideoMode", "Width", &FrontEndMenuManager.m_nPrefsWidth);
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
#include <sys/stat.h>
|
||||
#include <cctype>
|
||||
|
||||
#ifdef DC_SH4
|
||||
#include <dc/vmu_pkg.h>
|
||||
#endif
|
||||
|
||||
namespace mINI
|
||||
{
|
||||
namespace INIStringUtil
|
||||
@@ -335,6 +339,7 @@ namespace mINI
|
||||
private:
|
||||
std::ifstream fileReadStream;
|
||||
T_LineDataPtr lineData;
|
||||
std::size_t start_offt;
|
||||
|
||||
T_LineData readFile()
|
||||
{
|
||||
@@ -343,7 +348,7 @@ namespace mINI
|
||||
fileContents.resize(fileReadStream.tellg());
|
||||
fileReadStream.seekg(0, std::ios::beg);
|
||||
std::size_t fileSize = fileContents.size();
|
||||
fileReadStream.read(&fileContents[0], fileSize);
|
||||
fileReadStream.read(const_cast<char *>(fileContents.c_str()), fileSize);
|
||||
fileReadStream.close();
|
||||
T_LineData output;
|
||||
if (fileSize == 0)
|
||||
@@ -352,7 +357,19 @@ namespace mINI
|
||||
}
|
||||
std::string buffer;
|
||||
buffer.reserve(50);
|
||||
for (std::size_t i = 0; i < fileSize; ++i)
|
||||
#ifdef DC_SH4
|
||||
{
|
||||
vmu_pkg_t vmu_pkg;
|
||||
if(vmu_pkg_parse(reinterpret_cast<uint8*>(const_cast<int8*>(fileContents.c_str())), &vmu_pkg) != 0) {
|
||||
// If we failed to parse, we assume it's raw with no VMS header.
|
||||
start_offt = 0;
|
||||
} else {
|
||||
start_offt = reinterpret_cast<unsigned int>(vmu_pkg.data)
|
||||
- reinterpret_cast<unsigned int>(fileContents.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (std::size_t i = start_offt; i < fileSize; ++i)
|
||||
{
|
||||
char& c = fileContents[i];
|
||||
if (c == '\n')
|
||||
@@ -378,6 +395,8 @@ namespace mINI
|
||||
{
|
||||
lineData = std::make_shared<T_LineData>();
|
||||
}
|
||||
|
||||
start_offt = 0;
|
||||
}
|
||||
~INIReader() { }
|
||||
|
||||
@@ -426,22 +445,71 @@ namespace mINI
|
||||
{
|
||||
private:
|
||||
std::ofstream fileWriteStream;
|
||||
|
||||
std::stringstream memStream;
|
||||
inline static std::ios_base::iostate lastError_;
|
||||
public:
|
||||
bool prettyPrint = false;
|
||||
|
||||
INIGenerator(std::string const& filename)
|
||||
INIGenerator(std::string const& filename, bool prettyPrint_=false)
|
||||
: fileWriteStream(filename, std::ios::out | std::ios::binary),
|
||||
prettyPrint(prettyPrint_)
|
||||
{
|
||||
fileWriteStream.open(filename, std::ios::out | std::ios::binary);
|
||||
lastError_ = fileWriteStream.rdstate();
|
||||
}
|
||||
|
||||
~INIGenerator()
|
||||
{
|
||||
if(!fileWriteStream.good()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = memStream.str();
|
||||
const char *buf = str.c_str();
|
||||
int buf_size = memStream.tellp();
|
||||
|
||||
#ifdef DC_SH4
|
||||
uint8_t *data;
|
||||
uint8_t icon_buf[512 * 1];
|
||||
vmu_pkg_t vmu_pkg = {
|
||||
.desc_short = "DCA-M Config",
|
||||
.desc_long = "DCA-M Settings File",
|
||||
.app_id = "The Gang",
|
||||
.icon_cnt = 1,
|
||||
.icon_anim_speed = 0,
|
||||
.data_len = buf_size,
|
||||
.icon_data = icon_buf,
|
||||
.data = reinterpret_cast<const uint8_t*>(buf),
|
||||
};
|
||||
|
||||
if (vmu_pkg_load_icon(&vmu_pkg, "settings.ico") < 0) {
|
||||
vmu_pkg.icon_cnt = 0;
|
||||
}
|
||||
|
||||
if(vmu_pkg_build(&vmu_pkg, &data, &buf_size) < 0) {
|
||||
lastError_ = std::ios_base::badbit;
|
||||
return;
|
||||
}
|
||||
|
||||
buf = reinterpret_cast<char*>(data);
|
||||
#endif
|
||||
|
||||
fileWriteStream.write(buf, buf_size);
|
||||
lastError_ = fileWriteStream.rdstate();
|
||||
|
||||
#ifdef DC_SH4
|
||||
// Must free the internal buffer allocated by vmu_pkg_build().
|
||||
free(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator<<(const std::string& str)
|
||||
{
|
||||
memStream << str;
|
||||
return true;
|
||||
}
|
||||
~INIGenerator() { }
|
||||
|
||||
bool operator<<(INIStructure const& data)
|
||||
{
|
||||
if (!fileWriteStream.is_open())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!data.size())
|
||||
{
|
||||
return true;
|
||||
@@ -451,13 +519,13 @@ namespace mINI
|
||||
{
|
||||
auto const& section = it->first;
|
||||
auto const& collection = it->second;
|
||||
fileWriteStream
|
||||
memStream
|
||||
<< "["
|
||||
<< section
|
||||
<< "]";
|
||||
if (collection.size())
|
||||
{
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
auto it2 = collection.begin();
|
||||
for (;;)
|
||||
{
|
||||
@@ -465,7 +533,7 @@ namespace mINI
|
||||
INIStringUtil::replace(key, "=", "\\=");
|
||||
auto value = it2->second;
|
||||
INIStringUtil::trim(value);
|
||||
fileWriteStream
|
||||
memStream
|
||||
<< key
|
||||
<< ((prettyPrint) ? " = " : "=")
|
||||
<< value;
|
||||
@@ -473,21 +541,29 @@ namespace mINI
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
if (++it == data.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
if (prettyPrint)
|
||||
{
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
memStream << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return fileWriteStream.rdstate() == fileWriteStream.goodbit;
|
||||
}
|
||||
|
||||
static std::ios_base::iostate lastError() { return lastError_; }
|
||||
static bool wasGood() { return lastError_ == std::ios_base::goodbit; }
|
||||
};
|
||||
|
||||
class INIWriter
|
||||
@@ -667,12 +743,15 @@ namespace mINI
|
||||
{
|
||||
struct stat buf;
|
||||
bool fileExists = (stat(filename.c_str(), &buf) == 0);
|
||||
|
||||
if (!fileExists)
|
||||
{
|
||||
INIGenerator generator(filename);
|
||||
generator.prettyPrint = prettyPrint;
|
||||
return generator << data;
|
||||
if(INIGenerator generator(filename, prettyPrint); generator) {
|
||||
generator << data;
|
||||
}
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
|
||||
INIStructure originalData;
|
||||
T_LineDataPtr lineData;
|
||||
bool readSuccess = false;
|
||||
@@ -688,23 +767,21 @@ namespace mINI
|
||||
return false;
|
||||
}
|
||||
T_LineData output = getLazyOutput(lineData, data, originalData);
|
||||
std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary);
|
||||
if (fileWriteStream.is_open())
|
||||
{
|
||||
if (output.size())
|
||||
if (INIGenerator generator(filename, prettyPrint); generator && output.size())
|
||||
{
|
||||
auto line = output.begin();
|
||||
for (;;)
|
||||
{
|
||||
fileWriteStream << *line;
|
||||
generator << *line;
|
||||
if (++line == output.end())
|
||||
{
|
||||
break;
|
||||
}
|
||||
fileWriteStream << INIStringUtil::endl;
|
||||
generator << INIStringUtil::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -741,9 +818,10 @@ namespace mINI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
INIGenerator generator(filename);
|
||||
generator.prettyPrint = pretty;
|
||||
return generator << data;
|
||||
if(INIGenerator generator(filename, pretty); generator) {
|
||||
generator << data;
|
||||
}
|
||||
return INIGenerator::wasGood();
|
||||
}
|
||||
bool write(INIStructure& data, bool pretty = false) const
|
||||
{
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
#include "common.h"
|
||||
|
||||
CMatrix::CMatrix(void)
|
||||
{
|
||||
m_attachment = nil;
|
||||
m_hasRwMatrix = false;
|
||||
}
|
||||
|
||||
CMatrix::CMatrix(CMatrix const &m)
|
||||
{
|
||||
m_attachment = nil;
|
||||
@@ -434,6 +428,11 @@ operator*(const CMatrix &m1, const CMatrix &m2)
|
||||
{
|
||||
// TODO: VU0 code
|
||||
CMatrix out;
|
||||
#if defined(RW_DC)
|
||||
mat_load(reinterpret_cast<const matrix_t *>(&m1));
|
||||
mat_apply(reinterpret_cast<const matrix_t *>(&m2));
|
||||
mat_store(reinterpret_cast<matrix_t *>(&out));
|
||||
#else
|
||||
out.rx = m1.rx * m2.rx + m1.fx * m2.ry + m1.ux * m2.rz;
|
||||
out.ry = m1.ry * m2.rx + m1.fy * m2.ry + m1.uy * m2.rz;
|
||||
out.rz = m1.rz * m2.rx + m1.fz * m2.ry + m1.uz * m2.rz;
|
||||
@@ -446,6 +445,7 @@ operator*(const CMatrix &m1, const CMatrix &m2)
|
||||
out.px = m1.rx * m2.px + m1.fx * m2.py + m1.ux * m2.pz + m1.px;
|
||||
out.py = m1.ry * m2.px + m1.fy * m2.py + m1.uy * m2.pz + m1.py;
|
||||
out.pz = m1.rz * m2.px + m1.fz * m2.py + m1.uz * m2.pz + m1.pz;
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
class CMatrix
|
||||
class alignas(8) CMatrix
|
||||
{
|
||||
public:
|
||||
#ifdef GTA_PS2
|
||||
@@ -23,18 +23,18 @@ public:
|
||||
float f[4][4];
|
||||
struct
|
||||
{
|
||||
float rx, ry, rz, rw;
|
||||
float fx, fy, fz, fw;
|
||||
float ux, uy, uz, uw;
|
||||
float px, py, pz, pw;
|
||||
float rx, ry, rz, rw=0.0f;
|
||||
float fx, fy, fz, fw=0.0f;
|
||||
float ux, uy, uz, uw=0.0f;
|
||||
float px, py, pz, pw=1.0f;
|
||||
};
|
||||
};
|
||||
|
||||
RwMatrix *m_attachment;
|
||||
bool m_hasRwMatrix; // are we the owner?
|
||||
RwMatrix *m_attachment=nil;
|
||||
bool m_hasRwMatrix=false; // are we the owner?
|
||||
#endif
|
||||
|
||||
CMatrix(void);
|
||||
CMatrix(void) {}
|
||||
CMatrix(CMatrix const &m);
|
||||
CMatrix(RwMatrix *matrix, bool owner = false);
|
||||
CMatrix(float scale){
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
class TYPEALIGN(16) CVuVector : public CVector
|
||||
#include "maths.h"
|
||||
|
||||
#ifdef RW_DC
|
||||
#define VECTOR_ALIGN 8
|
||||
#else
|
||||
#define VECTOR_ALIGN 16
|
||||
#endif
|
||||
|
||||
class TYPEALIGN(VECTOR_ALIGN) CVuVector : public CVector
|
||||
{
|
||||
public:
|
||||
float w;
|
||||
@@ -26,7 +34,123 @@ public:
|
||||
// TODO: operator-
|
||||
};
|
||||
|
||||
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in);
|
||||
void TransformPoint(CVuVector &out, const CMatrix &mat, const RwV3d &in);
|
||||
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride);
|
||||
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const CVuVector *in);
|
||||
__always_inline void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
lqc2 vf01,0x0(%2)\n\
|
||||
lqc2 vf02,0x0(%1)\n\
|
||||
lqc2 vf03,0x10(%1)\n\
|
||||
lqc2 vf04,0x20(%1)\n\
|
||||
lqc2 vf05,0x30(%1)\n\
|
||||
vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
sqc2 vf06,0x0(%0)\n\
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
mat_trans_single3_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z);
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
}
|
||||
|
||||
__always_inline void TransformPoint(CVuVector &out, const CMatrix &mat, const RwV3d &in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
ldr $8,0x0(%2)\n\
|
||||
ldl $8,0x7(%2)\n\
|
||||
lw $9,0x8(%2)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
lqc2 vf02,0x0(%1)\n\
|
||||
lqc2 vf03,0x10(%1)\n\
|
||||
lqc2 vf04,0x20(%1)\n\
|
||||
lqc2 vf05,0x30(%1)\n\
|
||||
vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
sqc2 vf06,0x0(%0)\n\
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
mat_trans_single3_nodiv_nomod(in.x, in.y, in.z, out.x, out.y, out.z);
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
}
|
||||
|
||||
__always_inline void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride)
|
||||
{
|
||||
#ifdef GTA_PS3
|
||||
__asm__ __volatile__("\n\
|
||||
paddub $3,%4,$0\n\
|
||||
lqc2 vf02,0x0(%2)\n\
|
||||
lqc2 vf03,0x10(%2)\n\
|
||||
lqc2 vf04,0x20(%2)\n\
|
||||
lqc2 vf05,0x30(%2)\n\
|
||||
ldr $8,0x0(%3)\n\
|
||||
ldl $8,0x7(%3)\n\
|
||||
lw $9,0x8(%3)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
1: vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
add %3,%3,$3\n\
|
||||
ldr $8,0x0(%3)\n\
|
||||
ldl $8,0x7(%3)\n\
|
||||
lw $9,0x8(%3)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
addi %1,%1,-1\n\
|
||||
addiu %0,%0,0x10\n\
|
||||
sqc2 vf06,-0x10(%0)\n\
|
||||
bnez %1,1b\n\
|
||||
": : "r" (out) , "r" (n), "r" (&mat), "r" (in), "r" (stride): "memory");
|
||||
#elif defined(DC_SH4)
|
||||
mat_load(reinterpret_cast<matrix_t *>(const_cast<CMatrix *>(&mat)));
|
||||
while(n--) {
|
||||
mat_trans_single3_nodiv_nomod(in->x, in->y, in->z, out->x, out->y, out->z);
|
||||
in = reinterpret_cast<const RwV3d *>(reinterpret_cast<const uint8_t *>(in) + stride);
|
||||
++out;
|
||||
}
|
||||
#else
|
||||
while(n--){
|
||||
*out = mat * *in;
|
||||
in = (RwV3d*)((uint8*)in + stride);
|
||||
out++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__always_inline void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const CVuVector *in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
lqc2 vf02,0x0(%2)\n\
|
||||
lqc2 vf03,0x10(%2)\n\
|
||||
lqc2 vf04,0x20(%2)\n\
|
||||
lqc2 vf05,0x30(%2)\n\
|
||||
lqc2 vf01,0x0(%3)\n\
|
||||
nop\n\
|
||||
1: vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
lqc2 vf01,0x10(%3)\n\
|
||||
addiu %3,%3,0x10\n\
|
||||
addi %1,%1,-1\n\
|
||||
addiu %0,%0,0x10\n\
|
||||
sqc2 vf06,-0x10(%0)\n\
|
||||
bnez %1,1b\n\
|
||||
": : "r" (out) , "r" (n), "r" (&mat) ,"r" (in): "memory");
|
||||
#else
|
||||
TransformPoints(out, n, mat, in, sizeof(CVuVector));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3,116 +3,3 @@
|
||||
#include "VuVector.h"
|
||||
|
||||
// TODO: move more stuff into here
|
||||
|
||||
|
||||
void TransformPoint(CVuVector &out, const CMatrix &mat, const CVuVector &in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
lqc2 vf01,0x0(%2)\n\
|
||||
lqc2 vf02,0x0(%1)\n\
|
||||
lqc2 vf03,0x10(%1)\n\
|
||||
lqc2 vf04,0x20(%1)\n\
|
||||
lqc2 vf05,0x30(%1)\n\
|
||||
vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
sqc2 vf06,0x0(%0)\n\
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
}
|
||||
|
||||
void TransformPoint(CVuVector &out, const CMatrix &mat, const RwV3d &in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
ldr $8,0x0(%2)\n\
|
||||
ldl $8,0x7(%2)\n\
|
||||
lw $9,0x8(%2)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
lqc2 vf02,0x0(%1)\n\
|
||||
lqc2 vf03,0x10(%1)\n\
|
||||
lqc2 vf04,0x20(%1)\n\
|
||||
lqc2 vf05,0x30(%1)\n\
|
||||
vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
sqc2 vf06,0x0(%0)\n\
|
||||
": : "r" (&out) , "r" (&mat) ,"r" (&in): "memory");
|
||||
#else
|
||||
out = mat * in;
|
||||
#endif
|
||||
}
|
||||
|
||||
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const RwV3d *in, int stride)
|
||||
{
|
||||
#ifdef GTA_PS3
|
||||
__asm__ __volatile__("\n\
|
||||
paddub $3,%4,$0\n\
|
||||
lqc2 vf02,0x0(%2)\n\
|
||||
lqc2 vf03,0x10(%2)\n\
|
||||
lqc2 vf04,0x20(%2)\n\
|
||||
lqc2 vf05,0x30(%2)\n\
|
||||
ldr $8,0x0(%3)\n\
|
||||
ldl $8,0x7(%3)\n\
|
||||
lw $9,0x8(%3)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
1: vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
add %3,%3,$3\n\
|
||||
ldr $8,0x0(%3)\n\
|
||||
ldl $8,0x7(%3)\n\
|
||||
lw $9,0x8(%3)\n\
|
||||
pcpyld $10,$9,$8\n\
|
||||
qmtc2 $10,vf01\n\
|
||||
addi %1,%1,-1\n\
|
||||
addiu %0,%0,0x10\n\
|
||||
sqc2 vf06,-0x10(%0)\n\
|
||||
bnez %1,1b\n\
|
||||
": : "r" (out) , "r" (n), "r" (&mat), "r" (in), "r" (stride): "memory");
|
||||
#else
|
||||
while(n--){
|
||||
*out = mat * *in;
|
||||
in = (RwV3d*)((uint8*)in + stride);
|
||||
out++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TransformPoints(CVuVector *out, int n, const CMatrix &mat, const CVuVector *in)
|
||||
{
|
||||
#ifdef GTA_PS2
|
||||
__asm__ __volatile__("\n\
|
||||
lqc2 vf02,0x0(%2)\n\
|
||||
lqc2 vf03,0x10(%2)\n\
|
||||
lqc2 vf04,0x20(%2)\n\
|
||||
lqc2 vf05,0x30(%2)\n\
|
||||
lqc2 vf01,0x0(%3)\n\
|
||||
nop\n\
|
||||
1: vmulax.xyz ACC, vf02,vf01\n\
|
||||
vmadday.xyz ACC, vf03,vf01\n\
|
||||
vmaddaz.xyz ACC, vf04,vf01\n\
|
||||
vmaddw.xyz vf06,vf05,vf00\n\
|
||||
lqc2 vf01,0x10(%3)\n\
|
||||
addiu %3,%3,0x10\n\
|
||||
addi %1,%1,-1\n\
|
||||
addiu %0,%0,0x10\n\
|
||||
sqc2 vf06,-0x10(%0)\n\
|
||||
bnez %1,1b\n\
|
||||
": : "r" (out) , "r" (n), "r" (&mat) ,"r" (in): "memory");
|
||||
#else
|
||||
while(n--){
|
||||
*out = mat * *in;
|
||||
in++;
|
||||
out++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/common_defines.h"
|
||||
|
||||
#include <dc/matrix.h>
|
||||
|
||||
#ifdef DC_SH4
|
||||
|
||||
#define mat_trans_nodiv_nomod(x, y, z, x2, y2, z2, w2) do { \
|
||||
register float __x __asm__("fr12") = (x); \
|
||||
register float __y __asm__("fr13") = (y); \
|
||||
register float __z __asm__("fr14") = (z); \
|
||||
register float __w __asm__("fr15") = 1.0f; \
|
||||
__asm__ __volatile__( "ftrv xmtrx, fv12\n" \
|
||||
: "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) \
|
||||
: "0" (__x), "1" (__y), "2" (__z), "3" (__w) ); \
|
||||
x2 = __x; y2 = __y; z2 = __z; w2 = __w; \
|
||||
} while(false)
|
||||
|
||||
#else
|
||||
|
||||
#define mat_trans_nodiv_nomod(x_, y_, z_, x2, y2, z2, w2) do { \
|
||||
vector_t tmp = { x_, y_, z_, 1.0f }; \
|
||||
mat_transform(&tmp, &tmp, 1, 0); \
|
||||
x2 = tmp.x; y2 = tmp.y; z2 = tmp.z; w2 = tmp.w; \
|
||||
} while(false)
|
||||
#endif
|
||||
|
||||
|
||||
// wrapper around float versions of functions
|
||||
// in gta they are in CMaths but that makes the code rather noisy
|
||||
|
||||
|
||||
@@ -60,7 +60,11 @@ public:
|
||||
};
|
||||
|
||||
enum {
|
||||
#ifdef RW_DC
|
||||
NUM_RAIN_STREAKS = 10
|
||||
#elif
|
||||
NUM_RAIN_STREAKS = 35
|
||||
#endif
|
||||
};
|
||||
|
||||
struct tRainStreak
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " <input_root_folder> <output_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string inputFolder = argv[1];
|
||||
std::string outputFileName = argv[2];
|
||||
|
||||
// Open the output file for writing in binary mode.
|
||||
std::ofstream outFile(outputFileName, std::ios::binary);
|
||||
if (!outFile) {
|
||||
std::cerr << "Error: Cannot open output file " << outputFileName << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Process each file from 0.pal to 63.pal.
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
std::string filePath = inputFolder + "/" + std::to_string(i) + ".pal";
|
||||
std::ifstream inFile(filePath, std::ios::binary);
|
||||
if (!inFile) {
|
||||
std::cerr << "Error: Cannot open input file " << filePath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read header (first 4 bytes). They should equal "DPAL".
|
||||
char header[4];
|
||||
inFile.read(header, 4);
|
||||
if (inFile.gcount() != 4 || std::string(header, 4) != "DPAL") {
|
||||
std::cerr << "Error: File " << filePath << " has an invalid header." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the next 4 bytes (number of palette entries).
|
||||
uint32_t numEntries = 0;
|
||||
inFile.read(reinterpret_cast<char*>(&numEntries), sizeof(numEntries));
|
||||
if (inFile.gcount() != sizeof(numEntries)) {
|
||||
std::cerr << "Error: Could not read palette entry count from " << filePath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (numEntries != 16) {
|
||||
std::cerr << "Error: File " << filePath << " has " << numEntries
|
||||
<< " entries, expected 16." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the remaining bytes (the palette values).
|
||||
std::vector<char> paletteData((std::istreambuf_iterator<char>(inFile)),
|
||||
std::istreambuf_iterator<char>());
|
||||
inFile.close();
|
||||
|
||||
// Write palette data to the output file.
|
||||
outFile.write(paletteData.data(), paletteData.size());
|
||||
if (!outFile) {
|
||||
std::cerr << "Error: Writing to output file failed." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
outFile.close();
|
||||
std::cout << "Successfully combined 64 .pal files into " << outputFileName << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
import os
|
||||
import shutil
|
||||
import argparse
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from sklearn.cluster import KMeans
|
||||
|
||||
def compute_mse(original, quantized):
|
||||
"""
|
||||
Compute Mean Squared Error between two images (numpy arrays).
|
||||
"""
|
||||
if original.shape != quantized.shape:
|
||||
raise ValueError("Images must have the same dimensions")
|
||||
mse = np.mean((original - quantized) ** 2)
|
||||
return mse
|
||||
|
||||
def extract_palette_feature(quantized_image, num_colors=16):
|
||||
"""
|
||||
Extract a flattened feature vector from the quantized image palette.
|
||||
Uses the getcolors() method to get (count, color) tuples.
|
||||
If the color is an integer (palette index), it converts it to an RGB tuple.
|
||||
Sorts the colors by brightness (sum of RGB).
|
||||
Pads with zeros if fewer than num_colors colors are present.
|
||||
"""
|
||||
colors = quantized_image.getcolors(maxcolors=256)
|
||||
if colors is None:
|
||||
raise ValueError("Too many colors in quantized image")
|
||||
|
||||
raw_palette = quantized_image.getpalette()
|
||||
color_list = []
|
||||
for count, col in colors:
|
||||
# Convert palette index to RGB if needed.
|
||||
if isinstance(col, int):
|
||||
rgb = tuple(raw_palette[col*3: col*3+3])
|
||||
else:
|
||||
rgb = col
|
||||
color_list.append(rgb)
|
||||
|
||||
color_list.sort(key=lambda c: sum(c))
|
||||
|
||||
if len(color_list) < num_colors:
|
||||
pad_length = num_colors - len(color_list)
|
||||
color_list.extend([(0, 0, 0)] * pad_length)
|
||||
elif len(color_list) > num_colors:
|
||||
color_list = color_list[:num_colors]
|
||||
|
||||
feature = np.array(color_list).flatten()
|
||||
return feature
|
||||
|
||||
def process_textures(input_dir, output_dir, error_threshold, num_palette_groups=64, palette_colors=16):
|
||||
accepted_features = []
|
||||
accepted_files = []
|
||||
non_paletteable_files = []
|
||||
|
||||
for filename in os.listdir(input_dir):
|
||||
if filename.lower().endswith('.tga'):
|
||||
filepath = os.path.join(input_dir, filename)
|
||||
try:
|
||||
original = Image.open(filepath).convert("RGB")
|
||||
# Quantize image to a palette of palette_colors colors.
|
||||
quantized = original.quantize(colors=palette_colors, method=Image.FASTOCTREE, dither=Image.NONE)
|
||||
quantized_rgb = quantized.convert("RGB")
|
||||
|
||||
original_arr = np.array(original, dtype=np.float32)
|
||||
quantized_arr = np.array(quantized_rgb, dtype=np.float32)
|
||||
|
||||
mse = compute_mse(original_arr, quantized_arr)
|
||||
|
||||
if mse <= error_threshold:
|
||||
feature = extract_palette_feature(quantized, num_colors=palette_colors)
|
||||
accepted_features.append(feature)
|
||||
accepted_files.append(filepath)
|
||||
# print(f"File {filename} MSE={mse:.2f} -> paletteable")
|
||||
else:
|
||||
non_paletteable_files.append(filepath)
|
||||
# print(f"File {filename} MSE={mse:.2f} -> non-paletteable")
|
||||
except Exception as e:
|
||||
print(f"Error processing {filename}: {e}")
|
||||
|
||||
print(f"Total textures processed: {len(accepted_files) + len(non_paletteable_files)}")
|
||||
print(f"Paletteable textures: {len(accepted_files)}")
|
||||
print(f"Non-paletteable textures: {len(non_paletteable_files)}")
|
||||
|
||||
if accepted_features:
|
||||
features_array = np.array(accepted_features)
|
||||
kmeans = KMeans(n_clusters=num_palette_groups, random_state=42)
|
||||
cluster_labels = kmeans.fit_predict(features_array)
|
||||
|
||||
for i in range(num_palette_groups):
|
||||
cluster_dir = os.path.join(output_dir, f"cluster_{i}")
|
||||
os.makedirs(cluster_dir, exist_ok=True)
|
||||
|
||||
for filepath, label in zip(accepted_files, cluster_labels):
|
||||
dest_dir = os.path.join(output_dir, f"cluster_{label}")
|
||||
shutil.copy(filepath, dest_dir)
|
||||
|
||||
cluster_filepath = filepath + ".cluster"
|
||||
with open(cluster_filepath, "w") as cluster_file:
|
||||
cluster_file.write(str(label))
|
||||
|
||||
nonpal_dir = os.path.join(output_dir, "cluster_64")
|
||||
os.makedirs(nonpal_dir, exist_ok=True)
|
||||
for filepath in non_paletteable_files:
|
||||
shutil.copy(filepath, nonpal_dir)
|
||||
|
||||
cluster_filepath = filepath + ".cluster"
|
||||
with open(cluster_filepath, "w") as cluster_file:
|
||||
cluster_file.write("64")
|
||||
|
||||
print("Grouping complete.")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Group .tga textures into palette clusters and a non-paletteable group.")
|
||||
parser.add_argument("input_dir", type=str, help="Path to folder containing .tga textures")
|
||||
parser.add_argument("output_dir", type=str, help="Path to output folder for grouped textures")
|
||||
parser.add_argument("--threshold", type=float, default=500.0,
|
||||
help="Error threshold for palette quality (default: 500.0)")
|
||||
parser.add_argument("--palette_colors", type=int, default=16,
|
||||
help="Number of colors for palette quantization (default: 16)")
|
||||
parser.add_argument("--num_palette_groups", type=int, default=64,
|
||||
help="Number of palette groups to form (default: 64)")
|
||||
args = parser.parse_args()
|
||||
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
process_textures(args.input_dir, args.output_dir, args.threshold, args.num_palette_groups, args.palette_colors)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -67,7 +67,6 @@ namespace rw::dc {
|
||||
extern int32 maxRasterHeight;
|
||||
extern int32 downsampleMode;
|
||||
extern int32 pvrEncoder;
|
||||
extern const char* dstFile;
|
||||
}
|
||||
|
||||
RwTexDictionary *LoadTxd(RwStream *stream);
|
||||
@@ -308,8 +307,6 @@ int main(int argc, const char** argv) {
|
||||
rw::dc::pvrEncoder = PVRTOOL;
|
||||
} else if (strcmp(param, "pvrtex") == 0 || strcmp(param, "PVRTEX") == 0) {
|
||||
rw::dc::pvrEncoder = PVRTEX;
|
||||
} else if (strcmp(param, "extract") == 0 || strcmp(param, "EXTRACT") == 0) {
|
||||
rw::dc::pvrEncoder = EXTRACT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,8 +344,6 @@ int main(int argc, const char** argv) {
|
||||
assert(RwEngineStart());
|
||||
currentFile = argv[1];
|
||||
|
||||
rw::dc::dstFile = argv[2];
|
||||
|
||||
if (strstr(argv[1], ".txd") || strstr(argv[1], ".TXD")) {
|
||||
auto stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, argv[1]);
|
||||
assert(stream && "failed to open input");
|
||||
@@ -383,14 +378,12 @@ int main(int argc, const char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
if (rw::dc::pvrEncoder != EXTRACT) {
|
||||
auto streamOut = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, argv[2]);
|
||||
assert(streamOut && "failed to open output");
|
||||
|
||||
StoreTxd(texDict, streamOut);
|
||||
|
||||
RwStreamClose(streamOut, nil);
|
||||
}
|
||||
auto streamOut = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMWRITE, argv[2]);
|
||||
assert(streamOut && "failed to open output");
|
||||
|
||||
StoreTxd(texDict, streamOut);
|
||||
|
||||
RwStreamClose(streamOut, nil);
|
||||
} else if (strstr(argv[1], ".dff") || strstr(argv[1], ".DFF")) {
|
||||
rw::Texture::setLoadTextures(false);
|
||||
rw::Texture::setCreateDummies(true);
|
||||
|
||||
2
vendor/dca3-kos
vendored
2
vendor/dca3-kos
vendored
Submodule vendor/dca3-kos updated: 5d475f6ecf...5f69d048aa
220
vendor/librw/src/dc/rwdc.cpp
vendored
220
vendor/librw/src/dc/rwdc.cpp
vendored
@@ -10,7 +10,6 @@
|
||||
#endif
|
||||
|
||||
#if defined(DC_TEXCONV)
|
||||
#include <fcntl.h>
|
||||
#include "tri_stripper.h"
|
||||
#include <sha256.h>
|
||||
extern const char* currentFile;
|
||||
@@ -576,7 +575,7 @@ size_t vertexBufferFree() {
|
||||
|
||||
bool vertexOverflown() {
|
||||
return PVR_GET(PVR_TA_VERTBUF_POS) >= PVR_GET(PVR_TA_VERTBUF_END) ||
|
||||
PVR_GET(PVR_TA_OPB_POS)*4 >= PVR_GET(PVR_TA_OPB_END);
|
||||
(PVR_GET(PVR_TA_OPB_POS)*4 >= PVR_GET(PVR_TA_OPB_END) && PVR_GET(PVR_TA_OPB_POS) != PVR_GET(PVR_TA_OPB_INIT));
|
||||
}
|
||||
|
||||
constexpr size_t freeVertexTarget_Step_Up = 32 * 1024;
|
||||
@@ -1037,7 +1036,7 @@ public:
|
||||
|
||||
// Templated constructor to accept any callable object.
|
||||
template <typename F>
|
||||
move_only_function(F f)
|
||||
move_only_function(F&& f)
|
||||
: callable_(new model<F>(std::move(f))) {}
|
||||
|
||||
// Move constructor.
|
||||
@@ -1081,7 +1080,7 @@ private:
|
||||
template <typename F>
|
||||
struct model : concept_t {
|
||||
F f;
|
||||
explicit model(F f) : f(std::move(f)) {}
|
||||
explicit model(F&& f) : f(std::move(f)) {}
|
||||
R invoke(Args&&... args) override {
|
||||
return f(std::forward<Args>(args)...);
|
||||
}
|
||||
@@ -1094,8 +1093,27 @@ chunked_vector<move_only_function<void()>> opCallbacks;
|
||||
chunked_vector<move_only_function<void()>> blendCallbacks;
|
||||
chunked_vector<move_only_function<void()>> ptCallbacks;
|
||||
|
||||
static const unsigned short VIDEO_MODES = 2;
|
||||
static unsigned short VIDEO_MODE = 0;
|
||||
static rw::VideoMode videoModes[VIDEO_MODES] = {
|
||||
{ 640, 480, 16, VIDEOMODEEXCLUSIVE },
|
||||
{ 640, 480, 24, VIDEOMODEEXCLUSIVE },
|
||||
};
|
||||
|
||||
static pvr_init_params_t pvr_params = {
|
||||
.opb_sizes = {
|
||||
PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_8, PVR_BINSIZE_0,
|
||||
PVR_BINSIZE_8
|
||||
},
|
||||
.autosort_disabled = true
|
||||
};
|
||||
|
||||
void dcMotionBlur_v1(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
|
||||
|
||||
// not supported on 24 bpp
|
||||
if (videoModes[VIDEO_MODE].depth == 24) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t col = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
blendCallbacks.emplace_back([=]() {
|
||||
@@ -1205,6 +1223,11 @@ void dcMotionBlur_v1(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
|
||||
}
|
||||
|
||||
void dcMotionBlur_v3(uint8_t a, uint8_t r, uint8_t g, uint8_t b) {
|
||||
// not supported on 24 bpp
|
||||
if (videoModes[VIDEO_MODE].depth == 24) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t alpha = a;
|
||||
uint32_t col = (alpha * r / 255 << 16) | (alpha * g / 255 << 8) | alpha * b / 255;
|
||||
uint32_t mask_col = ((255 - a) << 16) | ((255 - a) << 8) | (255 - a);
|
||||
@@ -4601,7 +4624,6 @@ int32 maxRasterWidth = 64;
|
||||
int32 maxRasterHeight = 64;
|
||||
int32 downsampleMode = NONE;
|
||||
int32 pvrEncoder = PVRTEX;
|
||||
const char* dstFile;
|
||||
#endif
|
||||
|
||||
bool32
|
||||
@@ -4774,11 +4796,6 @@ rasterFromImage(Raster* raster, Image* image)
|
||||
assert(false && "Unhandled texture format");
|
||||
}
|
||||
|
||||
hash_sha256 img_hash;
|
||||
img_hash.sha256_init();
|
||||
img_hash.sha256_update((const uint8_t*)imageData.data(), imageData.size() * sizeof(imageData[0]));
|
||||
sha256_type img_hash_result = img_hash.sha256_final();
|
||||
|
||||
if (raster->width != image->width || raster->height != image->height) {
|
||||
printf("Downsample: %ix%i -> %ix%i\n", image->width, image->height, raster->width, raster->height);
|
||||
imageData = downscaleImage(imageData, image->width, image->height, raster->width, raster->height);
|
||||
@@ -4803,99 +4820,50 @@ rasterFromImage(Raster* raster, Image* image)
|
||||
fprintf(stderr, "Failed to write TGA file: %s\n", filename_tga);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pvrEncoder != EXTRACT) {
|
||||
char encodeCommand[512];
|
||||
|
||||
std::stringstream clusterfile;
|
||||
clusterfile << "repack-data/textures/" << std::hex;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
clusterfile << std::setfill('0') << std::setw(2) << (int)img_hash_result[i];
|
||||
}
|
||||
clusterfile << ".tga.cluster";
|
||||
char encodeCommand[512];
|
||||
|
||||
int cluster = -1;
|
||||
FILE* fclust = fopen(clusterfile.str().c_str(), "r");
|
||||
if (!fclust) {
|
||||
fprintf(stderr, "cluster: %s\n", clusterfile.str().c_str());
|
||||
}
|
||||
assert(fclust);
|
||||
// Now call PVR Compression
|
||||
switch(pvrEncoder) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
case PVRTEX:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"..\\vendor\\pvrtex\\pvrtex.exe -i %s -o %s -c small -d", filename_tga, filename_pvr);
|
||||
break;
|
||||
case PVRTOOL:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"pvrtool.exe %s -OF pvr -TW -CF SMART -VQ -VQDITHER 1 -o %s",
|
||||
filename_tga, filename_pvr);
|
||||
break;
|
||||
#else
|
||||
case PVRTEX:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"../vendor/pvrtex/pvrtex -i %s -o %s -c small -d", filename_tga, filename_pvr);
|
||||
break;
|
||||
case PVRTOOL:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"./pvrtool %s -OF pvr -TW -CF SMART -VQ -VQDITHER 1 -o %s",
|
||||
filename_tga, filename_pvr);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
fscanf(fclust, "%d", &cluster);
|
||||
fclose(fclust);
|
||||
int retCode = system(encodeCommand);
|
||||
|
||||
assert(cluster >= 0 && cluster <= 64);
|
||||
// Read PVR File
|
||||
assert(raster->width && raster->height && !natras->raster->texaddr);
|
||||
loadPVR(filename_pvr, raster, natras->raster, PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE);
|
||||
|
||||
|
||||
// Now call PVR Compression
|
||||
switch(pvrEncoder) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
case PVRTEX:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"..\\vendor\\pvrtex\\pvrtex.exe -i %s -o %s -c small -d", filename_tga, filename_pvr);
|
||||
break;
|
||||
case PVRTOOL:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"pvrtool.exe %s -OF pvr -TW -CF SMART -VQ -VQDITHER 1 -o %s",
|
||||
filename_tga, filename_pvr);
|
||||
break;
|
||||
#else
|
||||
case PVRTEX:
|
||||
if (cluster == 64)
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),"../vendor/pvrtex/pvrtex -i %s -o %s -c small -d", filename_tga, filename_pvr);
|
||||
else
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),"../vendor/pvrtex/pvrtex -i %s -o %s -c small -d -f PAL4BPP -q repack-data/texture-clusters/%d.pal", filename_tga, filename_pvr, cluster);
|
||||
break;
|
||||
case PVRTOOL:
|
||||
snprintf(encodeCommand, sizeof(encodeCommand),
|
||||
"./pvrtool %s -OF pvr -TW -CF SMART -VQ -VQDITHER 1 -o %s",
|
||||
filename_tga, filename_pvr);
|
||||
break;
|
||||
#endif
|
||||
case EXTRACT:
|
||||
break;
|
||||
}
|
||||
remove(filename_tga);
|
||||
remove(filename_pvr);
|
||||
|
||||
hash_sha256 hash;
|
||||
hash.sha256_init();
|
||||
hash.sha256_update((const uint8_t*)natras->raster->texaddr, natras->raster->texsize);
|
||||
sha256_type hash_result = hash.sha256_final();
|
||||
|
||||
int retCode = system(encodeCommand);
|
||||
|
||||
// Read PVR File
|
||||
assert(raster->width && raster->height && !natras->raster->texaddr);
|
||||
loadPVR(filename_pvr, raster, natras->raster, PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE);
|
||||
|
||||
|
||||
remove(filename_tga);
|
||||
remove(filename_pvr);
|
||||
|
||||
if (cluster != 64) {
|
||||
natras->raster->pvr_flags |= PVR_TXRFMT_4BPP_PAL(cluster);
|
||||
}
|
||||
|
||||
hash_sha256 hash;
|
||||
hash.sha256_init();
|
||||
hash.sha256_update((const uint8_t*)natras->raster->texaddr, natras->raster->texsize);
|
||||
sha256_type hash_result = hash.sha256_final();
|
||||
|
||||
natras->raster->pvr_id = hash_result[0] | (hash_result[1] << 8) | (hash_result[2] << 16) | (hash_result[3] << 24);
|
||||
} else {
|
||||
std::stringstream touchfile;
|
||||
touchfile << dstFile << ".contents/" << std::hex;
|
||||
|
||||
std::stringstream texture;
|
||||
texture << "repack-data/textures/" << std::hex;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
touchfile << std::setfill('0') << std::setw(2) << (int)img_hash_result[i];
|
||||
texture << std::setfill('0') << std::setw(2) << (int)img_hash_result[i];
|
||||
}
|
||||
texture << ".tga";
|
||||
|
||||
int fd = open(touchfile.str().c_str(), O_CREAT | O_TRUNC, 0666);
|
||||
assert(fd != -1);
|
||||
close(fd);
|
||||
assert(rename(filename_tga, texture.str().c_str()) == 0);
|
||||
}
|
||||
natras->raster->pvr_id = hash_result[0] | (hash_result[1] << 8) | (hash_result[2] << 16) | (hash_result[3] << 24);
|
||||
|
||||
|
||||
if(truecolimg)
|
||||
@@ -5033,14 +5001,6 @@ rasterToImage(Raster*)
|
||||
return nil;
|
||||
}
|
||||
|
||||
static pvr_init_params_t pvr_params = {
|
||||
.opb_sizes = {
|
||||
PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_8, PVR_BINSIZE_0,
|
||||
PVR_BINSIZE_8
|
||||
},
|
||||
.autosort_disabled = true
|
||||
};
|
||||
|
||||
int
|
||||
deviceSystem(DeviceReq req, void *arg0, int32 n)
|
||||
{
|
||||
@@ -5070,10 +5030,10 @@ deviceSystem(DeviceReq req, void *arg0, int32 n)
|
||||
|
||||
case DEVICEGETVIDEOMODEINFO:{
|
||||
auto rwmode = (VideoMode*)arg0;
|
||||
rwmode->width = 640;
|
||||
rwmode->height = 480;
|
||||
rwmode->depth = 16;
|
||||
rwmode->flags = VIDEOMODEEXCLUSIVE;
|
||||
rwmode->width = videoModes[n].width;
|
||||
rwmode->height = videoModes[n].height;
|
||||
rwmode->depth = videoModes[n].depth;
|
||||
rwmode->flags = videoModes[n].flags;
|
||||
return 1;
|
||||
}
|
||||
case DEVICEGETMAXMULTISAMPLINGLEVELS:
|
||||
@@ -5084,22 +5044,19 @@ deviceSystem(DeviceReq req, void *arg0, int32 n)
|
||||
if (n == 1) {
|
||||
VIDEO_MODE_SCALE_X = 1;
|
||||
pvr_params.fsaa_enabled = 0;
|
||||
pvr_params.vertex_buf_size = (1024 + 1024) * 1024;
|
||||
pvr_params.opb_overflow_count = 7; // 268800 bytes
|
||||
} else {
|
||||
VIDEO_MODE_SCALE_X = 2;
|
||||
pvr_params.fsaa_enabled = 1;
|
||||
pvr_params.vertex_buf_size = (1024 + 768) * 1024;
|
||||
pvr_params.opb_overflow_count = 4; // 307200 bytes
|
||||
}
|
||||
return 1;
|
||||
case DEVICESETSUBSYSTEM:
|
||||
return 1;
|
||||
case DEVICEGETNUMVIDEOMODES:
|
||||
return 1;
|
||||
return VIDEO_MODES;
|
||||
case DEVICEGETCURRENTVIDEOMODE:
|
||||
return 0;
|
||||
return VIDEO_MODE;
|
||||
case DEVICESETVIDEOMODE:
|
||||
VIDEO_MODE = n;
|
||||
return 1;
|
||||
default:
|
||||
assert(0 && "not implemented");
|
||||
@@ -5180,32 +5137,31 @@ driverOpen(void *o, int32, int32)
|
||||
#endif
|
||||
|
||||
#if !defined(DC_TEXCONV)
|
||||
|
||||
dbglog(DBG_CRITICAL, "atomicContexts: %d per %d allocation\n", decltype(atomicContexts)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
dbglog(DBG_CRITICAL, "skinContexts: %d per %d allocation\n", decltype(skinContexts)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
dbglog(DBG_CRITICAL, "matfxContexts: %d per %d allocation\n", decltype(matfxContexts)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
dbglog(DBG_CRITICAL, "opCallbacks: %d per %d allocation\n", decltype(opCallbacks)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
dbglog(DBG_CRITICAL, "blendCallbacks: %d per %d allocation\n", decltype(blendCallbacks)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
dbglog(DBG_CRITICAL, "ptCallbacks: %d per %d allocation\n", decltype(ptCallbacks)::chunk::item_count, decltype(atomicContexts)::chunk_size);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
pvr_init(&pvr_params);
|
||||
|
||||
#if !defined(DC_TEXCONV)
|
||||
uint32_t palette[1024];
|
||||
FILE* fpal = fopen("dc-palette.pal", "rb");
|
||||
assert(fpal);
|
||||
fread(palette, 1, 1024 * 4, fpal);
|
||||
fclose(fpal);
|
||||
|
||||
// write to pal regs
|
||||
PVR_SET(0x108, 0x3); // ARGB8888 pals
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
PVR_SET(0x1000 + i*4, palette[i]);
|
||||
if (pvr_params.fsaa_enabled) {
|
||||
pvr_params.vertex_buf_size = (1024 + 768) * 1024;
|
||||
pvr_params.opb_overflow_count = 4; // 307200 bytes
|
||||
} else {
|
||||
pvr_params.vertex_buf_size = (1024 + 1024) * 1024;
|
||||
pvr_params.opb_overflow_count = 7; // 268800 bytes
|
||||
}
|
||||
|
||||
if (videoModes[VIDEO_MODE].depth == 24) {
|
||||
pvr_params.vertex_buf_size -= 128 * 1024;
|
||||
pvr_params.opb_overflow_count -= pvr_params.fsaa_enabled ? 1 : 2;
|
||||
}
|
||||
|
||||
#if !defined(DC_SIM)
|
||||
vid_set_mode(DM_640x480, videoModes[VIDEO_MODE].depth == 24 ? PM_RGB888P : PM_RGB565);
|
||||
#endif
|
||||
pvr_init(&pvr_params);
|
||||
|
||||
fake_tex = pvr_mem_malloc(sizeof(fake_tex_data));
|
||||
|
||||
@@ -5330,9 +5286,9 @@ readNativeTexture(Stream *stream)
|
||||
|
||||
#ifdef DC_SH4
|
||||
uint8 *src = stream->mmap(pvr_size);
|
||||
// assert((pvr_size & 31) == 0);
|
||||
assert((pvr_size & 31) == 0);
|
||||
if (src) {
|
||||
if (((uintptr_t)src & 31) || pvr_size & 31) {
|
||||
if (((uintptr_t)src & 31)) {
|
||||
dcache_pref_block(src);
|
||||
|
||||
if ((uintptr_t)src & 3) {
|
||||
|
||||
17
vendor/librw/src/dc/tex-util.h
vendored
17
vendor/librw/src/dc/tex-util.h
vendored
@@ -21,8 +21,7 @@ enum downsampleModes {
|
||||
|
||||
enum pvrEncoders {
|
||||
PVRTOOL,
|
||||
PVRTEX,
|
||||
EXTRACT
|
||||
PVRTEX
|
||||
};
|
||||
|
||||
// TGA Header Struct
|
||||
@@ -142,10 +141,6 @@ void loadPVR(char *fname, rw::Raster* raster, auto* natras, auto flags) {
|
||||
natras->pvr_flags |= PVR_TXRFMT_YUV422;
|
||||
rasterFmt = rw::Raster::C565; // this is a bit of a hack
|
||||
break;
|
||||
case 0x5: // PAL4
|
||||
natras->pvr_flags |= PVR_TXRFMT_PAL4BPP;
|
||||
rasterFmt = raster->format & 0x0F00; // perserve for blending reasons
|
||||
break;
|
||||
default:
|
||||
assert(false && "Invalid texture format");
|
||||
break;
|
||||
@@ -158,11 +153,11 @@ void loadPVR(char *fname, rw::Raster* raster, auto* natras, auto flags) {
|
||||
natras->texaddr = alloc_malloc(natras, natras->texsize);
|
||||
fread(natras->texaddr, 1, natras->texsize, tex); /* Read in the PVR texture data */
|
||||
texconvf("PVR TEXTURE READ: %ix%i, %i, %i\n", HDR.nWidth, HDR.nHeight, natras->texoffs, natras->texsize);
|
||||
// if (natras->texsize >= 256) {
|
||||
// assert((natras->texsize & 31) == 0);
|
||||
// } else {
|
||||
// assert((natras->texsize & 31) == 0);
|
||||
// }
|
||||
if (natras->texsize >= 256) {
|
||||
assert((natras->texsize & 255) == 0);
|
||||
} else {
|
||||
assert((natras->texsize & 31) == 0);
|
||||
}
|
||||
|
||||
fclose(tex);
|
||||
}
|
||||
3
vendor/pvrtex/file_pvr.c
vendored
3
vendor/pvrtex/file_pvr.c
vendored
@@ -53,8 +53,7 @@ void fPvrWrite(const PvrTexEncoder *pte, const char *outfname) {
|
||||
}
|
||||
|
||||
if (pteIsPalettized(pte))
|
||||
idxcnt/= 4;
|
||||
// ErrorExit(".PVR format does not support compressed palettized textures\n");
|
||||
ErrorExit(".PVR format does not support compressed palettized textures\n");
|
||||
// JP - Rectangle VQ certainly does work on real hardware
|
||||
//if (pte->w != pte->h)
|
||||
// ErrorExit(".PVR format does not support non-square compressed textures\n");
|
||||
|
||||
50
vendor/pvrtex/main.c
vendored
50
vendor/pvrtex/main.c
vendored
@@ -12,7 +12,7 @@
|
||||
#include "file_pvr.h"
|
||||
#include "file_tex.h"
|
||||
|
||||
int log_level = LOG_DEBUG;
|
||||
int log_level = LOG_PROGRESS;
|
||||
void pteLogLocV(unsigned level, const char *file, unsigned line, const char *fmt, va_list args) {
|
||||
static const char * logtypes[] = {
|
||||
[LOG_ALL] = "ALL",
|
||||
@@ -163,11 +163,10 @@ int main(int argc, char **argv) {
|
||||
{"mip-resize", 'R', OPTPARSE_OPTIONAL},
|
||||
{"stride", 's', OPTPARSE_NONE},
|
||||
{"edge", 'e', OPTPARSE_REQUIRED},
|
||||
{"pallette", 'q', OPTPARSE_REQUIRED},
|
||||
{0}
|
||||
};
|
||||
|
||||
#define MAX_FNAMES 1024
|
||||
#define MAX_FNAMES 11
|
||||
const char *fnames[MAX_FNAMES];
|
||||
unsigned fname_cnt = 0;
|
||||
const char *outname = "";
|
||||
@@ -299,23 +298,6 @@ int main(int argc, char **argv) {
|
||||
ErrorExit("invalid max palette size parameter (should be [1, 16] for 4bpp, or [1, 256] for 8bpp)\n");
|
||||
}
|
||||
break;
|
||||
case 'q': {
|
||||
pxlARGB8888 pal[16];
|
||||
FILE* f = fopen(options.optarg, "rb");
|
||||
assert(f);
|
||||
assert(fseek(f, 8, SEEK_SET) == 0);
|
||||
assert(fread(pal, 1, 4 * 16, f) == 4 * 16);
|
||||
fclose(f);
|
||||
|
||||
pte.palette = malloc(16 * 4);
|
||||
pte.palette_size = 16;
|
||||
assert(pte.palette);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pte.palette[i] = pxlConvertARGB8888toABGR8888(pal[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ErrorExit("%s\n", options.errmsg);
|
||||
}
|
||||
@@ -408,34 +390,6 @@ int main(int argc, char **argv) {
|
||||
pte.edge_method = STBIR_EDGE_CLAMP;
|
||||
}
|
||||
|
||||
if (strcasecmp(extension, ".pal") == 0) {
|
||||
//Generate palette
|
||||
if (pte.pixel_format == PTE_PALETTE_4B || pte.pixel_format == PTE_PALETTE_8B) {
|
||||
if (pte.pixel_format == PTE_PALETTE_8B) {
|
||||
if (pte.palette_size == 0) {
|
||||
pte.palette_size = 256;
|
||||
} else if (pte.palette_size > 256) {
|
||||
ErrorExit("palette size must be 256 or less for 8bpp textures\n");
|
||||
}
|
||||
} else if (pte.pixel_format == PTE_PALETTE_4B) {
|
||||
if (pte.palette_size == 0) {
|
||||
pte.palette_size = 16;
|
||||
} else if (pte.palette_size > 16) {
|
||||
ErrorExit("palette size must be 16 or less for 4bpp textures\n");
|
||||
}
|
||||
}
|
||||
pteLog(LOG_PROGRESS, "Generating palette...\n");
|
||||
} else {
|
||||
assert(0 && ".pal file but no pal format");
|
||||
}
|
||||
|
||||
pteGenerateGlobalPalette(&pte);
|
||||
|
||||
fTexWritePalette(&pte, outname);
|
||||
// pteFree(&pte); // its okay, this will leak a bit
|
||||
return 0;
|
||||
}
|
||||
|
||||
pteEncodeTexture(&pte);
|
||||
|
||||
//Make preview
|
||||
|
||||
9
vendor/pvrtex/pixel.h
vendored
9
vendor/pvrtex/pixel.h
vendored
@@ -446,15 +446,6 @@ static inline pxlRGBA32 pxlConvertABGR8888toRGBA32(pxlABGR8888 color) {
|
||||
ret.a = color.a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline pxlABGR8888 pxlConvertARGB8888toABGR8888(pxlARGB8888 color) {
|
||||
pxlABGR8888 ret;
|
||||
ret.r = color.r;
|
||||
ret.g = color.g;
|
||||
ret.b = color.b;
|
||||
ret.a = color.a;
|
||||
return ret;
|
||||
}
|
||||
static inline pxlARGB8888 pxlConvertABGR8888toARGB8888(pxlABGR8888 color) {
|
||||
pxlARGB8888 ret;
|
||||
ret.r = color.r;
|
||||
|
||||
2
vendor/pvrtex/pvr_texture.h
vendored
2
vendor/pvrtex/pvr_texture.h
vendored
@@ -11,7 +11,7 @@ extern "C" {
|
||||
|
||||
#define PVR_MAX_TEXTURE_WIDTH 1024
|
||||
#define PVR_MAX_TEXTURE_HEIGHT 1024
|
||||
#define PVR_MAX_MIPMAPS (1024)
|
||||
#define PVR_MAX_MIPMAPS (11)
|
||||
|
||||
#define CHANNEL_CNT_ARGB 4
|
||||
#define VECTOR_W 2
|
||||
|
||||
39
vendor/pvrtex/pvr_texture_encoder.c
vendored
39
vendor/pvrtex/pvr_texture_encoder.c
vendored
@@ -85,10 +85,10 @@ void pteLoadFromFiles(PvrTexEncoder *pte, const char **fnames, unsigned filecnt)
|
||||
"When using custom mipmaps, the size of all levels must be a power of two"
|
||||
" (resize is not supported). %s has a size of %ux%u\n", fnames[i],
|
||||
img->w, img->h);
|
||||
// ErrorExitOn(img->w != img->h,
|
||||
// "When using custom mipmaps, all levels must be square"
|
||||
// " (resize is not supported). %s has a size of %ux%u\n", fnames[i],
|
||||
// img->w, img->h);
|
||||
ErrorExitOn(img->w != img->h,
|
||||
"When using custom mipmaps, all levels must be square"
|
||||
" (resize is not supported). %s has a size of %ux%u\n", fnames[i],
|
||||
img->w, img->h);
|
||||
}
|
||||
|
||||
maxw = MAX(maxw, img->w);
|
||||
@@ -288,38 +288,7 @@ void pteDitherRaws(PvrTexEncoder *pte, float dither_amt) {
|
||||
}
|
||||
|
||||
|
||||
void pteGenerateGlobalPalette(PvrTexEncoder *pte) {
|
||||
assert(pte);
|
||||
assert(pte->palette == NULL);
|
||||
assert(pte->palette_size > 0);
|
||||
assert(pte->palette_size <= 256);
|
||||
|
||||
VQCompressor vqc;
|
||||
vqcInit(&vqc, VQC_UINT8, 4, 1, pte->palette_size, pte->auto_small_vq);
|
||||
vqcSetRGBAGamma(&vqc, pte->rgb_gamma, pte->alpha_gamma);
|
||||
|
||||
//Add mipmaps to compressor input
|
||||
for (int i = 0; i < pte->src_img_cnt; i++) {
|
||||
uint32_t pixelcnt = pte->src_imgs[i].w * pte->src_imgs[i].h;
|
||||
vqcAddPoints(&vqc, pte->src_imgs[i].pixels, pixelcnt);
|
||||
}
|
||||
|
||||
//Do compression and save resulting palette
|
||||
vqcResults result = vqcCompress(&vqc, 8);
|
||||
assert(result.codebook);
|
||||
pte->palette = result.codebook;
|
||||
free(result.indices);
|
||||
|
||||
//~ for(unsigned i = 0; i < 256; i++) {
|
||||
//~ printf("(%i, %i, %i) ", pte->palette[i].r, pte->palette[i].g, pte->palette[i].b, pte->palette[i].a);
|
||||
//~ }
|
||||
}
|
||||
|
||||
void pteGeneratePalette(PvrTexEncoder *pte) {
|
||||
if (pte->palette) {
|
||||
// already has palette preloaded
|
||||
return;
|
||||
}
|
||||
assert(pte);
|
||||
assert(pte->mip_cnt > 0);
|
||||
assert(pte->mip_cnt <= PVR_MAX_MIPMAPS);
|
||||
|
||||
1
vendor/pvrtex/pvr_texture_encoder.h
vendored
1
vendor/pvrtex/pvr_texture_encoder.h
vendored
@@ -202,7 +202,6 @@ int pteSetSize(PvrTexEncoder *pte);
|
||||
void pteSetCompressed(PvrTexEncoder *pte, int codebook_size);
|
||||
void pteGeneratePreviews(PvrTexEncoder *pte);
|
||||
void pteAutoSelectPixelFormat(PvrTexEncoder *pte);
|
||||
void pteGenerateGlobalPalette(PvrTexEncoder *pte);
|
||||
|
||||
///////////
|
||||
void ErrorExitOn(int cond, const char *fmt, ...);
|
||||
|
||||
Reference in New Issue
Block a user