mirror of
https://github.com/libretro/prosystem-libretro.git
synced 2024-11-26 17:50:24 +00:00
Add libretro port of ProSystem 1.3e
This commit is contained in:
parent
7f61d2e660
commit
396e78f7d1
179
Makefile
Normal file
179
Makefile
Normal file
@ -0,0 +1,179 @@
|
||||
DEBUG = 0
|
||||
|
||||
ifeq ($(platform),)
|
||||
platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
platform = osx
|
||||
arch = intel
|
||||
ifeq ($(shell uname -p),powerpc)
|
||||
arch = ppc
|
||||
endif
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
platform = win
|
||||
endif
|
||||
endif
|
||||
|
||||
# system platform
|
||||
system_platform = unix
|
||||
ifeq ($(shell uname -a),)
|
||||
EXE_EXT = .exe
|
||||
system_platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
system_platform = osx
|
||||
arch = intel
|
||||
ifeq ($(shell uname -p),powerpc)
|
||||
arch = ppc
|
||||
endif
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
system_platform = win
|
||||
endif
|
||||
|
||||
TARGET_NAME := prosystem
|
||||
|
||||
ifeq ($(platform), unix)
|
||||
TARGET := $(TARGET_NAME)_libretro.so
|
||||
fpic := -fPIC
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
|
||||
else ifeq ($(platform), osx)
|
||||
TARGET := $(TARGET_NAME)_libretro.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
|
||||
ifeq ($(arch),ppc)
|
||||
FLAGS += -DMSB_FIRST
|
||||
OLD_GCC = 1
|
||||
endif
|
||||
OSXVER = `sw_vers -productVersion | cut -c 4`
|
||||
ifneq ($(OSXVER),9)
|
||||
fpic += -mmacosx-version-min=10.5
|
||||
endif
|
||||
else ifeq ($(platform), ios)
|
||||
TARGET := $(TARGET_NAME)_libretro_ios.dylib
|
||||
fpic := -fPIC
|
||||
SHARED := -dynamiclib
|
||||
|
||||
CC = clang -arch armv7 -isysroot $(IOSSDK)
|
||||
CXX = clang++ -arch armv7 -isysroot $(IOSSDK)
|
||||
OSXVER = `sw_vers -productVersion | cut -c 4`
|
||||
ifneq ($(OSXVER),9)
|
||||
SHARED += -miphoneos-version-min=5.0
|
||||
CC += -miphoneos-version-min=5.0
|
||||
CXX += -miphoneos-version-min=5.0
|
||||
endif
|
||||
else ifeq ($(platform), qnx)
|
||||
TARGET := $(TARGET_NAME)_libretro_qnx.so
|
||||
fpic := -fPIC
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
|
||||
CC = qcc -Vgcc_ntoarmv7le
|
||||
CXX = QCC -Vgcc_ntoarmv7le_cpp
|
||||
else ifeq ($(platform), ps3)
|
||||
TARGET := $(TARGET_NAME)_libretro_ps3.a
|
||||
CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe
|
||||
CXX = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-g++.exe
|
||||
AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe
|
||||
STATIC_LINKING = 1
|
||||
FLAGS += -DMSB_FIRST
|
||||
OLD_GCC = 1
|
||||
else ifeq ($(platform), sncps3)
|
||||
TARGET := $(TARGET_NAME)_libretro_ps3.a
|
||||
CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
CXX = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe
|
||||
AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe
|
||||
STATIC_LINKING = 1
|
||||
FLAGS += -DMSB_FIRST
|
||||
NO_GCC = 1
|
||||
else ifeq ($(platform), psp1)
|
||||
TARGET := $(TARGET_NAME)_libretro_psp1.a
|
||||
CC = psp-gcc$(EXE_EXT)
|
||||
CXX = psp-g++$(EXE_EXT)
|
||||
AR = psp-ar$(EXE_EXT)
|
||||
STATIC_LINKING = 1
|
||||
FLAGS += -G0 -DLSB_FIRST
|
||||
else
|
||||
TARGET := $(TARGET_NAME)_libretro.dll
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
SHARED := -shared -Wl,--no-undefined -Wl,--version-script=link.T
|
||||
LDFLAGS += -static-libgcc -static-libstdc++ -lwinmm
|
||||
endif
|
||||
PROSYSTEM_DIR := core
|
||||
|
||||
PROSYSTEM_SOURCES := $(PROSYSTEM_DIR)/Archive.cpp \
|
||||
$(PROSYSTEM_DIR)/Bios.cpp \
|
||||
$(PROSYSTEM_DIR)/Cartridge.cpp \
|
||||
$(PROSYSTEM_DIR)/Common.cpp \
|
||||
$(PROSYSTEM_DIR)/Database.cpp \
|
||||
$(PROSYSTEM_DIR)/Hash.cpp \
|
||||
$(PROSYSTEM_DIR)/Logger.cpp \
|
||||
$(PROSYSTEM_DIR)/Maria.cpp \
|
||||
$(PROSYSTEM_DIR)/Memory.cpp \
|
||||
$(PROSYSTEM_DIR)/Palette.cpp \
|
||||
$(PROSYSTEM_DIR)/Pokey.cpp \
|
||||
$(PROSYSTEM_DIR)/ProSystem.cpp \
|
||||
$(PROSYSTEM_DIR)/Region.cpp \
|
||||
$(PROSYSTEM_DIR)/Riot.cpp \
|
||||
$(PROSYSTEM_DIR)/Sally.cpp \
|
||||
$(PROSYSTEM_DIR)/Tia.cpp \
|
||||
$(PROSYSTEM_DIR)/Timer.cpp
|
||||
|
||||
LIBRETRO_SOURCES := libretro.cpp
|
||||
|
||||
SOURCES_C := $(PROSYSTEM_DIR)/lib/Zip.c \
|
||||
$(PROSYSTEM_DIR)/lib/Unzip.c
|
||||
|
||||
SOURCES := $(LIBRETRO_SOURCES) $(PROSYSTEM_SOURCES)
|
||||
OBJECTS := $(SOURCES:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
FLAGS += -O0 -g
|
||||
else
|
||||
FLAGS += -O0
|
||||
endif
|
||||
|
||||
LDFLAGS += $(fpic) -lz $(SHARED)
|
||||
FLAGS += $(fpic)
|
||||
FLAGS += -I. -Icore -Icore/lib
|
||||
|
||||
ifeq ($(OLD_GCC), 1)
|
||||
WARNINGS := -Wall
|
||||
else ifeq ($(NO_GCC), 1)
|
||||
WARNINGS :=
|
||||
else
|
||||
WARNINGS := -Wall \
|
||||
-Wno-narrowing \
|
||||
-Wno-sign-compare \
|
||||
-Wno-unused-variable \
|
||||
-Wno-unused-function \
|
||||
-Wno-uninitialized \
|
||||
-Wno-unused-result \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-overflow \
|
||||
-fno-strict-overflow
|
||||
endif
|
||||
|
||||
FLAGS += -D__LIBRETRO__ $(WARNINGS)
|
||||
|
||||
CXXFLAGS += $(FLAGS)
|
||||
CFLAGS += $(FLAGS) -std=gnu99
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
ifeq ($(STATIC_LINKING), 1)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
else
|
||||
$(CXX) -o $@ $^ $(LDFLAGS)
|
||||
endif
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) -c -o $@ $< $(CXXFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
.PHONY: clean
|
976
ProSystem.dat
Executable file
976
ProSystem.dat
Executable file
@ -0,0 +1,976 @@
|
||||
[4332c24e4f3bc72e7fe1b77adf66c2b7]
|
||||
title=3D Asteroids
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[0be996d25144966d5541c9eb4919b289]
|
||||
title=Ace Of Aces
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[aadde920b3aaba03bc10b40bd0619c94]
|
||||
title=Ace Of Aces
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[877dcc97a775ed55081864b2dbf5f1e2]
|
||||
title=Alien Brigade
|
||||
type=2
|
||||
pokey=false
|
||||
controller1=3
|
||||
controller2=3
|
||||
region=0
|
||||
flags=0
|
||||
[de3e9496cb7341f865f27e5a72c7f2f5]
|
||||
title=Alien Brigade
|
||||
type=2
|
||||
pokey=false
|
||||
controller1=3
|
||||
controller2=3
|
||||
region=1
|
||||
flags=0
|
||||
[07342c78619ba6ffcc61c10e907e3b50]
|
||||
title=Asteroids
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8fc3a695eaea3984912d98ed4a543376]
|
||||
title=Ballblazer
|
||||
type=0
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[b558814d54904ce0582e2f6a801d03af]
|
||||
title=Ballblazer
|
||||
type=0
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[42682415906c21c6af80e4198403ffda]
|
||||
title=Barnyard Blaster
|
||||
type=1
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[babe2bc2976688bafb8b23c192658126]
|
||||
title=Barnyard Blaster
|
||||
type=1
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[f5f6b69c5eb4b55fc163158d1a6b423e]
|
||||
title=Basketbrawl
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1
|
||||
[fba002089fcfa176454ab507e0eb76cb]
|
||||
title=Basketbrawl
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[5a09946e57dbe30408a8f253a28d07db]
|
||||
title=Centipede
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[38c056a48472d9a9e16ebda5ed91dae7]
|
||||
title=Centipede
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[93e4387864b014c155d7c17877990d1e]
|
||||
title=Choplifter
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1
|
||||
[59d4edb0230b5acc918b94f6bc94779f]
|
||||
title=Choplifter
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=1
|
||||
[2e8e28f6ad8b9b9267d518d880c73ebb]
|
||||
title=Commando
|
||||
type=1
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[55da6c6c3974d013f517e725aa60f48e]
|
||||
title=Commando
|
||||
type=1
|
||||
pokey=true
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[db691469128d9a4217ec7e315930b646]
|
||||
title=Crack'ed
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[7cbe78fa06f47ba6516a67a4b003c9ee]
|
||||
title=Crack'ed
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[a94e4560b6ad053a1c24e096f1262ebf]
|
||||
title=Crossbow
|
||||
type=2
|
||||
pokey=false
|
||||
controller1=3
|
||||
controller2=3
|
||||
region=0
|
||||
flags=0
|
||||
[63db371d67a98daec547b2abd5e7aa95]
|
||||
title=Crossbow
|
||||
type=2
|
||||
pokey=false
|
||||
controller1=3
|
||||
controller2=3
|
||||
region=1
|
||||
flags=0
|
||||
[179b76ff729d4849b8f66a502398acae]
|
||||
title=Dark Chambers
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[a2b8e2f159642c4b91de82e9a2928494]
|
||||
title=Dark Chambers
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[95ac811c7d27af0032ba090f28c107bd]
|
||||
title=Desert Falcon
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[2d5d99b993a885b063f9f22ce5e6523d]
|
||||
title=Desert Falcon
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[731879ea82fc0ca245e39e036fe293e6]
|
||||
title=Dig Dug
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1;
|
||||
[408dca9fc40e2b5d805f403fa0509436]
|
||||
title=Dig Dug
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[5e332fbfc1e0fc74223d2e73271ce650]
|
||||
title=Donkey Kong Jr
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[4dc5f88243250461bd61053b13777060]
|
||||
title=Donkey Kong Jr
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[19f1ee292a23636bd57d408b62de79c7]
|
||||
title=Donkey Kong
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8e96ef14ce9b5d84bcbc996b66d6d4c7]
|
||||
title=Donkey Kong
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[543484c00ba233736bcaba2da20eeea9]
|
||||
title=Double Dragon
|
||||
type=6
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[de2ebafcf0e37aaa9d0e9525a7f4dd62]
|
||||
title=Double Dragon
|
||||
type=6
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[2251a6a0f3aec84cc0aff66fc9fa91e8]
|
||||
title=F-18 Hornet
|
||||
type=5
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[e7709da8e49d3767301947a0a0b9d2e6]
|
||||
title=F-18 Hornet
|
||||
type=5
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[d25d5d19188e9f149977c49eb0367cd1]
|
||||
title=Fatal Run
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[23505651ac2e47f3637152066c3aa62f]
|
||||
title=Fatal Run
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[07dbbfe612a0a28e283c01545e59f25e]
|
||||
title=Fight Night
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[e80f24e953563e6b61556737d67d3836]
|
||||
title=Fight Night
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[cf76b00244105b8e03cdc37677ec1073]
|
||||
title=Food Fight
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[de0d4f5a9bf1c1bddee3ed2f7ec51209]
|
||||
title=Food Fight
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[fb8d803b328b2e442548f7799cfa9a4a]
|
||||
title=Galaga
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[f5dc7dc8e38072d3d65bd90a660148ce]
|
||||
title=Galaga
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[06204dadc975be5e5e37e7cc66f984cf]
|
||||
title=Gato
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[fd9e78e201b6baafddfd3e1fbfe6ba31]
|
||||
title=Hat Trick
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[0baec96787ce17f390e204de1a136e59]
|
||||
title=Hat Trick
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[c3672482ca93f70eafd9134b936c3feb]
|
||||
title=Ikari Warriors
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8c2c2a1ea6e9a928a44c3151ba5c1ce3]
|
||||
title=Ikari Warriors
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[baebc9246c087e893dfa489632157180]
|
||||
title=Impossible Mission
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[80dead01ea2db5045f6f4443faa6fce8]
|
||||
title=Impossible Mission
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[045fd12050b7f2b842d5970f2414e912]
|
||||
title=Jinks
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[dfb86f4d06f05ad00cf418f0a59a24f7]
|
||||
title=Jinks
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[f18b3b897a25ab3885b43b4bd141b396]
|
||||
title=Joust
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[f2dae0264a4b4a73762b9d7177e989f6]
|
||||
title=Joust
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[c3a5a8692a423d43d9d28dd5b7d109d9]
|
||||
title=Karateka
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[5e0a1e832bbcea6facb832fde23a440a]
|
||||
title=Karateka
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[17b3b764d33eae9b5260f01df7bb9d2f]
|
||||
title=Klax
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[f57d0af323d4e173fb49ed447f0563d7]
|
||||
title=Kung Fu Master
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=2;
|
||||
[2931b75811ad03f3ac9330838f3d231b]
|
||||
title=Kung Fu Master
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[431ca060201ee1f9eb49d44962874049]
|
||||
title=Mario Bros.
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[d2e861306be78e44248bb71d7475d8a3]
|
||||
title=Mario Bros.
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[37b5692e33a98115e574185fa8398c22]
|
||||
title=Mat Mania Challenge
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[6819c37b96063b024898a19dbae2df54]
|
||||
title=Mat Mania Challenge
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[f2f5e5841e4dda89a2faf8933dc33ea6]
|
||||
title=Mean 18 Ultimate Golf
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[2e9dbad6c0fa381a6cd1bb9abf98a104]
|
||||
title=Mean 18 Ultimate Golf
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[bedc30ec43587e0c98fc38c39c1ef9d0]
|
||||
title=Meltdown
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[c80155d7eec9e3dcb79aa6b83c9ccd1e]
|
||||
title=Meltdown
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[bc1e905db1008493a9632aa83ab4682b]
|
||||
title=Midnight Mutants
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1
|
||||
[6794ea31570eba0b88a0bf1ead3f3f1b]
|
||||
title=Midnight Mutants
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=1
|
||||
[017066f522908081ec3ee624f5e4a8aa]
|
||||
title=Missing in Action
|
||||
type=2
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=2
|
||||
[3bc8f554cf86f8132a623cc2201a564b]
|
||||
title=Motor Psycho
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[5330bfe428a6b601b7e76c2cfc4cd049]
|
||||
title=Motor Psycho
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[fc0ea52a9fac557251b65ee680d951e5]
|
||||
title=Ms. Pac-Man
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[56469e8c5ff8983c6cb8dadc64eb0363]
|
||||
title=Ms. Pac-Man
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[220121f771fc4b98cef97dc040e8d378]
|
||||
title=Ninja Golf
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[ea0c859aa54fe5eaf4c1f327fab06221]
|
||||
title=Ninja Golf
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[74569571a208f8b0b1ccfb22d7c914e1]
|
||||
title=One On One
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8dba0425f0262e5704581d8757a1a6e3]
|
||||
title=One On One
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[1a5207870dec6fae9111cb747e20d8e3]
|
||||
title=Pete Rose Baseball
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[386bded4a944bae455fedf56206dd1dd]
|
||||
title=Pete Rose Baseball
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[ec206c8db4316eb1ebce9fc960da7d8f]
|
||||
title=Pit Fighter (Overdump)
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[05f43244465943ce819780a71a5b572a]
|
||||
title=Pit Fighter
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[33aea1e2b6634a1dec8c7006d9afda22]
|
||||
title=Planet Smashers
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1
|
||||
[2837a8fd49b7fc7ccd70fd45b69c5099]
|
||||
title=Planet Smashers
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[86546808dc60961cdb1b20e761c50ab1]
|
||||
title=Plutos
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[584582bb09ee8122e7fc09dc7d1ed813]
|
||||
title=Pole Position II
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[865457e0e0f48253b08f77b9e18f93b2]
|
||||
title=Pole Position II
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[1745feadabb24e7cefc375904c73fa4c]
|
||||
title=Possible Mission
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[ac03806cef2558fc795a7d5d8dba7bc0]
|
||||
title=Rampage
|
||||
type=6
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[442761655bb25ddfe5f7ab16bf591c6f]
|
||||
title=Rampart
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[bfad016d6e77eaccec74c0340aded8b9]
|
||||
title=Realsports Baseball (Overdump)
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[383ed9bd1efb9b6cb3388a777678c928]
|
||||
title=Realsports Baseball
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8f7eb10ad0bd75474abf0c6c36c08486]
|
||||
title=Rescue On Fractalus
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[66ecaafe1b82ae68ffc96267aaf7a4d7]
|
||||
title=Robotron
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[980c35ae9625773a450aa7ef51751c04]
|
||||
title=Scrapyard Dog
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[53db322c201323fe2ca8f074c0a2bf86]
|
||||
title=Scrapyard Dog
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[b697d9c2d1b9f6cb21041286d1bbfa7f]
|
||||
title=Sentinel
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=2
|
||||
controller2=2
|
||||
region=0
|
||||
flags=0
|
||||
[5469b4de0608f23a5c4f98f331c9e75f]
|
||||
title=Sentinel
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=2
|
||||
controller2=2
|
||||
region=1
|
||||
flags=0
|
||||
[2d643ac548c40e58c99d0fe433ba4ba0]
|
||||
title=Sirius
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=2
|
||||
controller2=2
|
||||
region=0
|
||||
flags=0
|
||||
[cbb0746192540a13b4c7775c7ce2021f]
|
||||
title=Summer Games
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[cc18e3b37a507c4217eb6cb1de8c8538]
|
||||
title=Super Huey UH-IX
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[162f9c953f0657689cc74ab20b40280f]
|
||||
title=Super Huey UH-IX
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[59b5793bece1c80f77b55d60fb39cb94]
|
||||
title=Super Skatebordin'
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[95d7c321dce8f57623a9c5b4947bb375]
|
||||
title=Super Skatebordin'
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[44f862bca77d68b56b32534eda5c198d]
|
||||
title=Tank Command (Overdump)
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[5c4f752371a523f15e9980fea73b874d]
|
||||
title=Tank Command
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[1af475ff6429a160752b592f0f92b287]
|
||||
title=Title Match Pro Wrestling
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[3bb9c8d9adc912dd7f8471c97445cd8d]
|
||||
title=Title Match Pro Wrestling
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[c3903ab01a51222a52197dbfe6538ecf]
|
||||
title=Tomcat F-14 Simulator
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[682338364243b023ecc9d24f0abfc9a7]
|
||||
title=Tomcat F-14 Simulator
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[208ef955fa90a29815eb097bce89bace]
|
||||
title=Touchdown Football
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[d12e665347f354048b9d13092f7868c9]
|
||||
title=Tower Toppler (Overdump)
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[8d64763db3100aadc552db5e6868506a]
|
||||
title=Tower Toppler
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[32a37244a9c6cc928dcdf02b45365aa8]
|
||||
title=Tower Toppler
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[acf63758ecf3f3dd03e9d654ae6b69b7]
|
||||
title=Water Ski (Overdump)
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[427cb05d0a1abb068998e2760d77f4fb]
|
||||
title=Water Ski
|
||||
type=1
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[3799d72f78dda2ee87b0ef8bf7b91186]
|
||||
title=Winter Games
|
||||
type=3
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[05fb699db9eef564e2fe45c568746dbc]
|
||||
title=Xenophobe
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=0
|
||||
[70937c3184f0be33d06f7f4382ca54de]
|
||||
title=Xenophobe
|
||||
type=4
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
||||
[d7dc17379aa25e5ae3c14b9e780c6f6d]
|
||||
title=Xevious
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=0
|
||||
flags=1
|
||||
[b1a9f196ce5f47ca8caf8fa7bc4ca46c]
|
||||
title=Xevious
|
||||
type=0
|
||||
pokey=false
|
||||
controller1=1
|
||||
controller2=1
|
||||
region=1
|
||||
flags=0
|
162
core/Archive.cpp
Executable file
162
core/Archive.cpp
Executable file
@ -0,0 +1,162 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Archive.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Archive.h"
|
||||
#define ARCHIVE_SOURCE "Archive.cpp"
|
||||
|
||||
#define _MAX_PATH 128
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetUncompressedFileSize
|
||||
// ----------------------------------------------------------------------------
|
||||
uint archive_GetUncompressedFileSize(std::string filename) {
|
||||
if(filename.empty( ) || filename.size( ) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unzFile file = unzOpen(filename.c_str( ));
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Filename " + filename + " is not a valid zip file.", ARCHIVE_SOURCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int result = unzGoToFirstFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to find the first file within the zip file.", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unz_file_info_s zipInfo = {0};
|
||||
char buffer[_MAX_PATH] = {0};
|
||||
result = unzGetCurrentFileInfo(file, &zipInfo, buffer, _MAX_PATH, NULL, 0, NULL, 0);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to retrieve the current zipped file info.", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint size = zipInfo.uncompressed_size;
|
||||
unzClose(file);
|
||||
return size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Uncompress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Uncompress(std::string filename, byte* data, uint size) {
|
||||
if(filename.empty( ) || filename.size( ) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(data == NULL) {
|
||||
logger_LogError("Data parameter is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
unzFile file = unzOpen(filename.c_str( ));
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Filename " + filename + " is not a valid zip file.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = unzGoToFirstFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to find the first file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = unzOpenCurrentFile(file);
|
||||
if(result != UNZ_OK) {
|
||||
logger_LogInfo("Failed to open the first file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = unzReadCurrentFile(file, data, size);
|
||||
if(result != size) {
|
||||
logger_LogInfo("Failed to read first file data within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
unzCloseCurrentFile(file);
|
||||
unzClose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Compress
|
||||
// ----------------------------------------------------------------------------
|
||||
bool archive_Compress(std::string zipFilename, std::string filename, const byte* data, uint size) {
|
||||
if(zipFilename.empty( ) || zipFilename.size( ) == 0) {
|
||||
logger_LogError("Zip filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(filename.empty( ) || filename.size( ) == 0) {
|
||||
logger_LogError("Filename is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
if(data == NULL) {
|
||||
logger_LogError("Data parameter is invalid.", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
zipFile file = zipOpen(zipFilename.c_str( ), APPEND_STATUS_CREATE);
|
||||
if(file == NULL) {
|
||||
logger_LogInfo("Failed to create the zip file " + zipFilename + ".", ARCHIVE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
zip_fileinfo fileInfo = {0};
|
||||
fileInfo.dosDate = 1;
|
||||
|
||||
int result = zipOpenNewFileInZip(file, filename.c_str( ), &fileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION);
|
||||
if(result != ZIP_OK) {
|
||||
logger_LogInfo("Failed to open a new file within the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
logger_LogInfo("Result: " + result, ARCHIVE_SOURCE);
|
||||
zipClose(file, "Failed to compress.");
|
||||
return false;
|
||||
}
|
||||
|
||||
result = zipWriteInFileInZip(file, data, size);
|
||||
if(result != ZIP_OK) {
|
||||
logger_LogInfo("Failed to write data to the zip file " + filename + ".", ARCHIVE_SOURCE);
|
||||
zipCloseFileInZip(file);
|
||||
zipClose(file, "Failed to compress.");
|
||||
return false;
|
||||
}
|
||||
|
||||
zipCloseFileInZip(file);
|
||||
zipClose(file, "Comment");
|
||||
return true;
|
||||
}
|
42
core/Archive.h
Executable file
42
core/Archive.h
Executable file
@ -0,0 +1,42 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Archive.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef ARCHIVE_H
|
||||
#define ARCHIVE_H
|
||||
|
||||
#include <string>
|
||||
#include "Logger.h"
|
||||
#include "Cartridge.h"
|
||||
#include "zip.h"
|
||||
#include "unzip.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern uint archive_GetUncompressedFileSize(std::string filename);
|
||||
extern bool archive_Uncompress(std::string filename, byte* data, uint size);
|
||||
extern bool archive_Compress(std::string zipFilename, std::string filename, const byte* data, uint size);
|
||||
|
||||
#endif
|
113
core/Bios.cpp
Executable file
113
core/Bios.cpp
Executable file
@ -0,0 +1,113 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Bios.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Bios.h"
|
||||
#define BIOS_SOURCE "Bios.cpp"
|
||||
|
||||
bool bios_enabled = false;
|
||||
std::string bios_filename;
|
||||
|
||||
static byte* bios_data = NULL;
|
||||
static word bios_size = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool bios_Load(std::string filename) {
|
||||
if(filename.empty( ) || filename.length( ) == 0) {
|
||||
logger_LogError("Bios filename is invalid.", BIOS_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bios_Release( );
|
||||
logger_LogInfo("Opening bios file " + filename + ".", BIOS_SOURCE);
|
||||
|
||||
bios_size = archive_GetUncompressedFileSize(filename);
|
||||
if(bios_size == 0) {
|
||||
FILE* file = fopen(filename.c_str( ), "rb");
|
||||
if(file == NULL) {
|
||||
#ifndef WII
|
||||
logger_LogError("Failed to open the bios file " + filename + " for reading.", BIOS_SOURCE);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fseek(file, 0, SEEK_END)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the end of the bios file.", BIOS_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bios_size = ftell(file);
|
||||
if(fseek(file, 0, SEEK_SET)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the size of the bios file.", BIOS_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
bios_data = new byte[bios_size];
|
||||
if(fread(bios_data, 1, bios_size, file) != bios_size && ferror(file)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the bios data.", BIOS_SOURCE);
|
||||
bios_Release( );
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else {
|
||||
bios_data = new byte[bios_size];
|
||||
archive_Uncompress(filename, bios_data, bios_size);
|
||||
}
|
||||
|
||||
bios_filename = filename;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsLoaded
|
||||
// ----------------------------------------------------------------------------
|
||||
bool bios_IsLoaded( ) {
|
||||
return (bios_data != NULL)? true: false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void bios_Release( ) {
|
||||
if(bios_data) {
|
||||
delete [ ] bios_data;
|
||||
bios_size = 0;
|
||||
bios_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Store
|
||||
// ----------------------------------------------------------------------------
|
||||
void bios_Store( ) {
|
||||
if(bios_data != NULL && bios_enabled) {
|
||||
memory_WriteROM(65536 - bios_size, bios_size, bios_data);
|
||||
}
|
||||
}
|
45
core/Bios.h
Executable file
45
core/Bios.h
Executable file
@ -0,0 +1,45 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Bios.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef BIOS_H
|
||||
#define BIOS_H
|
||||
//#define NULL 0
|
||||
|
||||
#include <string>
|
||||
#include "Memory.h"
|
||||
#include "Archive.h"
|
||||
#include "Logger.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern bool bios_Load(std::string filename);
|
||||
extern bool bios_IsLoaded( );
|
||||
extern void bios_Store( );
|
||||
extern void bios_Release( );
|
||||
extern std::string bios_filename;
|
||||
extern bool bios_enabled;
|
||||
|
||||
#endif
|
402
core/Cartridge.cpp
Executable file
402
core/Cartridge.cpp
Executable file
@ -0,0 +1,402 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Cartridge.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Cartridge.h"
|
||||
#define CARTRIDGE_SOURCE "Cartridge.cpp"
|
||||
|
||||
std::string cartridge_title;
|
||||
std::string cartridge_description;
|
||||
std::string cartridge_year;
|
||||
std::string cartridge_maker;
|
||||
std::string cartridge_digest;
|
||||
std::string cartridge_filename;
|
||||
byte cartridge_type;
|
||||
byte cartridge_region;
|
||||
bool cartridge_pokey;
|
||||
byte cartridge_controller[2];
|
||||
byte cartridge_bank;
|
||||
uint cartridge_flags;
|
||||
|
||||
static byte* cartridge_buffer = NULL;
|
||||
static uint cartridge_size = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// HasHeader
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool cartridge_HasHeader(const byte* header) {
|
||||
const char HEADER_ID[ ] = {"ATARI7800"};
|
||||
for(int index = 0; index < 9; index++) {
|
||||
if(HEADER_ID[index] != header[index + 1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Header for CC2 hack
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool cartridge_CC2(const byte* header) {
|
||||
const char HEADER_ID[ ] = {">>"};
|
||||
for(int index = 0; index < 2; index++) {
|
||||
if(HEADER_ID[index] != header[index+1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetBankOffset
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint cartridge_GetBankOffset(byte bank) {
|
||||
if ((cartridge_type == CARTRIDGE_TYPE_SUPERCART || cartridge_type == CARTRIDGE_TYPE_SUPERCART_ROM || cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) && cartridge_size <= 65536) {
|
||||
// for some of these carts, there are only 4 banks. in this case we ignore bit 3
|
||||
// previously, games of this type had to be doubled. The first 4 banks needed to be duplicated at the end of the ROM
|
||||
return (bank & 3) * 16384;
|
||||
}
|
||||
|
||||
return bank * 16384;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteBank
|
||||
// ----------------------------------------------------------------------------
|
||||
static void cartridge_WriteBank(word address, byte bank) {
|
||||
uint offset = cartridge_GetBankOffset(bank);
|
||||
if(offset < cartridge_size) {
|
||||
memory_WriteROM(address, 16384, cartridge_buffer + offset);
|
||||
cartridge_bank = bank;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ReadHeader
|
||||
// ----------------------------------------------------------------------------
|
||||
static void cartridge_ReadHeader(const byte* header) {
|
||||
char temp[33] = {0};
|
||||
for(int index = 0; index < 32; index++) {
|
||||
temp[index] = header[index + 17];
|
||||
}
|
||||
cartridge_title = temp;
|
||||
|
||||
cartridge_size = header[49] << 32;
|
||||
cartridge_size |= header[50] << 16;
|
||||
cartridge_size |= header[51] << 8;
|
||||
cartridge_size |= header[52];
|
||||
|
||||
if(header[53] == 0) {
|
||||
if(cartridge_size > 131072) {
|
||||
cartridge_type = CARTRIDGE_TYPE_SUPERCART_LARGE;
|
||||
}
|
||||
else if(header[54] == 2 || header[54] == 3) {
|
||||
cartridge_type = CARTRIDGE_TYPE_SUPERCART;
|
||||
}
|
||||
else if(header[54] == 4 || header[54] == 5 || header[54] == 6 || header[54] == 7) {
|
||||
cartridge_type = CARTRIDGE_TYPE_SUPERCART_RAM;
|
||||
}
|
||||
else if(header[54] == 8 || header[54] == 9 || header[54] == 10 || header[54] == 11) {
|
||||
cartridge_type = CARTRIDGE_TYPE_SUPERCART_ROM;
|
||||
}
|
||||
else {
|
||||
cartridge_type = CARTRIDGE_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(header[53] == 1) {
|
||||
cartridge_type = CARTRIDGE_TYPE_ABSOLUTE;
|
||||
}
|
||||
else if(header[53] == 2) {
|
||||
cartridge_type = CARTRIDGE_TYPE_ACTIVISION;
|
||||
}
|
||||
else {
|
||||
cartridge_type = CARTRIDGE_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
cartridge_pokey = (header[54] & 1)? true: false;
|
||||
cartridge_controller[0] = header[55];
|
||||
cartridge_controller[1] = header[56];
|
||||
cartridge_region = header[57];
|
||||
cartridge_flags = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool cartridge_Load(const byte* data, uint size) {
|
||||
if(size <= 128) {
|
||||
logger_LogError("Cartridge data is invalid.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
cartridge_Release( );
|
||||
|
||||
byte header[128] = {0};
|
||||
for(int index = 0; index < 128; index++) {
|
||||
header[index] = data[index];
|
||||
}
|
||||
|
||||
if (cartridge_CC2(header)) {
|
||||
logger_LogError("Prosystem doesn't support CC2 hacks.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint offset = 0;
|
||||
if(cartridge_HasHeader(header)) {
|
||||
cartridge_ReadHeader(header);
|
||||
size -= 128;
|
||||
offset = 128;
|
||||
cartridge_size = size;
|
||||
}
|
||||
else {
|
||||
cartridge_size = size;
|
||||
}
|
||||
|
||||
cartridge_buffer = new byte[cartridge_size];
|
||||
for(int index = 0; index < cartridge_size; index++) {
|
||||
cartridge_buffer[index] = data[index + offset];
|
||||
}
|
||||
|
||||
cartridge_digest = hash_Compute(cartridge_buffer, cartridge_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool cartridge_Load(std::string filename) {
|
||||
if(filename.empty( ) || filename.length( ) == 0) {
|
||||
logger_LogError("Cartridge filename is invalid.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
cartridge_Release( );
|
||||
logger_LogInfo("Opening cartridge file " + filename + ".", CARTRIDGE_SOURCE);
|
||||
|
||||
byte* data = NULL;
|
||||
//uint size = archive_GetUncompressedFileSize(filename);
|
||||
uint size = 0;
|
||||
|
||||
if(size == 0) {
|
||||
FILE *file = fopen(filename.c_str( ), "rb");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the cartridge file " + filename + " for reading.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fseek(file, 0, SEEK_END)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the end of the cartridge file.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
size = ftell(file);
|
||||
if(fseek(file, 0, SEEK_SET)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the size of the cartridge file.", CARTRIDGE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
data = new byte[size];
|
||||
if(fread(data, 1, size, file) != size && ferror(file)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the cartridge data.", CARTRIDGE_SOURCE);
|
||||
cartridge_Release( );
|
||||
delete [ ] data;
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else {
|
||||
data = new byte[size];
|
||||
//archive_Uncompress(filename, data, size);
|
||||
}
|
||||
|
||||
if(!cartridge_Load(data, size)) {
|
||||
logger_LogError("Failed to load the cartridge data into memory.", CARTRIDGE_SOURCE);
|
||||
delete [ ] data;
|
||||
return false;
|
||||
}
|
||||
if(data != NULL) {
|
||||
delete [ ] data;
|
||||
}
|
||||
|
||||
cartridge_filename = filename;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Store
|
||||
// ----------------------------------------------------------------------------
|
||||
void cartridge_Store( ) {
|
||||
switch(cartridge_type) {
|
||||
case CARTRIDGE_TYPE_NORMAL:
|
||||
memory_WriteROM(65536 - cartridge_size, cartridge_size, cartridge_buffer);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART:
|
||||
if(cartridge_GetBankOffset(7) < cartridge_size) {
|
||||
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_LARGE:
|
||||
if(cartridge_GetBankOffset(8) < cartridge_size) {
|
||||
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(8));
|
||||
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(0));
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_RAM:
|
||||
if(cartridge_GetBankOffset(7) < cartridge_size) {
|
||||
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
|
||||
memory_ClearROM(16384, 16384);
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_ROM:
|
||||
if(cartridge_GetBankOffset(7) < cartridge_size && cartridge_GetBankOffset(6) < cartridge_size) {
|
||||
memory_WriteROM(49152, 16384, cartridge_buffer + cartridge_GetBankOffset(7));
|
||||
memory_WriteROM(16384, 16384, cartridge_buffer + cartridge_GetBankOffset(6));
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ABSOLUTE:
|
||||
memory_WriteROM(16384, 16384, cartridge_buffer);
|
||||
memory_WriteROM(32768, 32768, cartridge_buffer + cartridge_GetBankOffset(2));
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ACTIVISION:
|
||||
if(122880 < cartridge_size) {
|
||||
memory_WriteROM(40960, 16384, cartridge_buffer);
|
||||
memory_WriteROM(16384, 8192, cartridge_buffer + 106496);
|
||||
memory_WriteROM(24576, 8192, cartridge_buffer + 98304);
|
||||
memory_WriteROM(32768, 8192, cartridge_buffer + 122880);
|
||||
memory_WriteROM(57344, 8192, cartridge_buffer + 114688);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Write
|
||||
// ----------------------------------------------------------------------------
|
||||
void cartridge_Write(word address, byte data) {
|
||||
switch(cartridge_type) {
|
||||
case CARTRIDGE_TYPE_SUPERCART:
|
||||
case CARTRIDGE_TYPE_SUPERCART_RAM:
|
||||
case CARTRIDGE_TYPE_SUPERCART_ROM:
|
||||
if(address >= 32768 && address < 49152 && data < 9) {
|
||||
cartridge_StoreBank(data);
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_LARGE:
|
||||
if(address >= 32768 && address < 49152 && data < 9) {
|
||||
cartridge_StoreBank(data + 1);
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ABSOLUTE:
|
||||
if(address == 32768 && (data == 1 || data == 2)) {
|
||||
cartridge_StoreBank(data - 1);
|
||||
}
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ACTIVISION:
|
||||
if(address >= 65408) {
|
||||
cartridge_StoreBank(address & 7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(cartridge_pokey && address >= 0x4000 && address < 0x4009) {
|
||||
switch(address) {
|
||||
case POKEY_AUDF1:
|
||||
pokey_SetRegister(POKEY_AUDF1, data);
|
||||
break;
|
||||
case POKEY_AUDC1:
|
||||
pokey_SetRegister(POKEY_AUDC1, data);
|
||||
break;
|
||||
case POKEY_AUDF2:
|
||||
pokey_SetRegister(POKEY_AUDF2, data);
|
||||
break;
|
||||
case POKEY_AUDC2:
|
||||
pokey_SetRegister(POKEY_AUDC2, data);
|
||||
break;
|
||||
case POKEY_AUDF3:
|
||||
pokey_SetRegister(POKEY_AUDF3, data);
|
||||
break;
|
||||
case POKEY_AUDC3:
|
||||
pokey_SetRegister(POKEY_AUDC3, data);
|
||||
break;
|
||||
case POKEY_AUDF4:
|
||||
pokey_SetRegister(POKEY_AUDF4, data);
|
||||
break;
|
||||
case POKEY_AUDC4:
|
||||
pokey_SetRegister(POKEY_AUDC4, data);
|
||||
break;
|
||||
case POKEY_AUDCTL:
|
||||
pokey_SetRegister(POKEY_AUDCTL, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreBank
|
||||
// ----------------------------------------------------------------------------
|
||||
void cartridge_StoreBank(byte bank) {
|
||||
switch(cartridge_type) {
|
||||
case CARTRIDGE_TYPE_SUPERCART:
|
||||
cartridge_WriteBank(32768, bank);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_RAM:
|
||||
cartridge_WriteBank(32768, bank);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_ROM:
|
||||
cartridge_WriteBank(32768, bank);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_SUPERCART_LARGE:
|
||||
cartridge_WriteBank(32768, bank);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ABSOLUTE:
|
||||
cartridge_WriteBank(16384, bank);
|
||||
break;
|
||||
case CARTRIDGE_TYPE_ACTIVISION:
|
||||
cartridge_WriteBank(40960, bank);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsLoaded
|
||||
// ----------------------------------------------------------------------------
|
||||
bool cartridge_IsLoaded( ) {
|
||||
return (cartridge_buffer != NULL)? true: false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void cartridge_Release( ) {
|
||||
if(cartridge_buffer != NULL) {
|
||||
delete [ ] cartridge_buffer;
|
||||
cartridge_size = 0;
|
||||
cartridge_buffer = NULL;
|
||||
}
|
||||
}
|
73
core/Cartridge.h
Executable file
73
core/Cartridge.h
Executable file
@ -0,0 +1,73 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Cartridge.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CARTRIDGE_H
|
||||
#define CARTRIDGE_H
|
||||
#define CARTRIDGE_TYPE_NORMAL 0
|
||||
#define CARTRIDGE_TYPE_SUPERCART 1
|
||||
#define CARTRIDGE_TYPE_SUPERCART_LARGE 2
|
||||
#define CARTRIDGE_TYPE_SUPERCART_RAM 3
|
||||
#define CARTRIDGE_TYPE_SUPERCART_ROM 4
|
||||
#define CARTRIDGE_TYPE_ABSOLUTE 5
|
||||
#define CARTRIDGE_TYPE_ACTIVISION 6
|
||||
#define CARTRIDGE_CONTROLLER_NONE 0
|
||||
#define CARTRIDGE_CONTROLLER_JOYSTICK 1
|
||||
#define CARTRIDGE_CONTROLLER_LIGHTGUN 2
|
||||
#define CARTRIDGE_WSYNC_MASK 2
|
||||
#define CARTRIDGE_CYCLE_STEALING_MASK 1
|
||||
//#define NULL 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include "Equates.h"
|
||||
#include "Memory.h"
|
||||
#include "Hash.h"
|
||||
#include "Logger.h"
|
||||
#include "Pokey.h"
|
||||
#include "Archive.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern bool cartridge_Load(std::string filename);
|
||||
extern void cartridge_Store( );
|
||||
extern void cartridge_StoreBank(byte bank);
|
||||
extern void cartridge_Write(word address, byte data);
|
||||
extern bool cartridge_IsLoaded( );
|
||||
extern void cartridge_Release( );
|
||||
extern std::string cartridge_digest;
|
||||
extern std::string cartridge_title;
|
||||
extern std::string cartridge_description;
|
||||
extern std::string cartridge_year;
|
||||
extern std::string cartridge_maker;
|
||||
extern std::string cartridge_filename;
|
||||
extern byte cartridge_type;
|
||||
extern byte cartridge_region;
|
||||
extern bool cartridge_pokey;
|
||||
extern byte cartridge_controller[2];
|
||||
extern byte cartridge_bank;
|
||||
extern uint cartridge_flags;
|
||||
|
||||
#endif
|
197
core/Common.cpp
Executable file
197
core/Common.cpp
Executable file
@ -0,0 +1,197 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Common.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Common.h"
|
||||
|
||||
std::string common_defaultPath;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(double value) {
|
||||
return common_Format(value, "%f");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(double value, std::string specification) {
|
||||
char buffer[17] = {0};
|
||||
sprintf(buffer, specification.c_str( ), value);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(uint value) {
|
||||
char buffer[11] = {0};
|
||||
sprintf(buffer, "%d", value);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(word value) {
|
||||
char buffer[6] = {0};
|
||||
sprintf(buffer, "%d", value);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(byte value) {
|
||||
char buffer[4] = {0};
|
||||
sprintf(buffer, "%d", value);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(bool value) {
|
||||
return (value)? "true": "false";
|
||||
}
|
||||
# if 0
|
||||
// ----------------------------------------------------------------------------
|
||||
// Format
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Format(HRESULT result) {
|
||||
char buffer[10] = {0};
|
||||
sprintf(buffer, "%#8x", result);
|
||||
return std::string(buffer);
|
||||
}
|
||||
# endif
|
||||
// ----------------------------------------------------------------------------
|
||||
// ParseUint
|
||||
// ----------------------------------------------------------------------------
|
||||
uint common_ParseUint(std::string text) {
|
||||
return (uint)atoi(text.c_str( ));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ParseWord
|
||||
// ----------------------------------------------------------------------------
|
||||
word common_ParseWord(std::string text) {
|
||||
return (word)atoi(text.c_str( ));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ParseByte
|
||||
// ----------------------------------------------------------------------------
|
||||
byte common_ParseByte(std::string text) {
|
||||
return (byte)atoi(text.c_str( ));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ParseBool
|
||||
// ----------------------------------------------------------------------------
|
||||
bool common_ParseBool(std::string text) {
|
||||
if(text.compare("true") == 0 || text.compare("TRUE") == 0 || text.compare("True") == 0) {
|
||||
return true;
|
||||
}
|
||||
if(atoi(text.c_str( )) == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Trim
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Trim(std::string target) {
|
||||
int index;
|
||||
for(index = target.length( ) - 1; index >= 0; index--) {
|
||||
if(target[index] != 0x20 && target[index] != '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return target.substr(0, index + 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Remove
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Remove(std::string target, char value) {
|
||||
target.erase(std::remove(target.begin(), target.end(), value), target.end());
|
||||
return target;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Replace (string, from, to)
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_Replace(std::string target, char value1, char value2) {
|
||||
int length = 0;
|
||||
int index;
|
||||
for(index = 0; index < target.size( ); index++) {
|
||||
length++;
|
||||
}
|
||||
|
||||
char* buffer = new char[length + 1];
|
||||
for(index = 0; index < target.size( ); index++) {
|
||||
if(target[index] != value1) {
|
||||
buffer[index] = target[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[index] = value2;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[length] = 0;
|
||||
std::string source = buffer;
|
||||
delete[ ] buffer;
|
||||
return source;
|
||||
}
|
||||
# if 0
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetErrorMessage
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_GetErrorMessage( ) {
|
||||
return common_GetErrorMessage(GetLastError( ));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetErrorMessage
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_GetErrorMessage(DWORD error) {
|
||||
void* buffer;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer, 0, NULL);
|
||||
std::string message((char*)buffer);
|
||||
LocalFree(buffer);
|
||||
return message;
|
||||
}
|
||||
# endif
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetExtension
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string common_GetExtension(std::string filename) {
|
||||
int position = filename.rfind('.');
|
||||
if(position != -1) {
|
||||
return filename.substr(position);
|
||||
}
|
||||
return "";
|
||||
}
|
54
core/Common.h
Executable file
54
core/Common.h
Executable file
@ -0,0 +1,54 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Common.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern std::string common_Format(double value);
|
||||
extern std::string common_Format(double value, std::string specification);
|
||||
extern std::string common_Format(uint value);
|
||||
extern std::string common_Format(word value);
|
||||
extern std::string common_Format(byte value);
|
||||
extern std::string common_Format(bool value);
|
||||
//extern std::string common_Format(HRESULT result);
|
||||
extern std::string common_Trim(std::string target);
|
||||
extern std::string common_Remove(std::string target, char value);
|
||||
extern std::string common_Replace(std::string target, char value1, char value2);
|
||||
extern std::string common_GetErrorMessage( );
|
||||
//extern std::string common_GetErrorMessage(DWORD error);
|
||||
extern std::string common_GetExtension(std::string filename);
|
||||
extern uint common_ParseUint(std::string text);
|
||||
extern word common_ParseWord(std::string text);
|
||||
extern byte common_ParseByte(std::string text);
|
||||
extern bool common_ParseBool(std::string text);
|
||||
extern std::string common_defaultPath;
|
||||
|
||||
#endif
|
83
core/Database.cpp
Executable file
83
core/Database.cpp
Executable file
@ -0,0 +1,83 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Database.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Database.h"
|
||||
#define DATABASE_SOURCE "Database.cpp"
|
||||
|
||||
bool database_enabled = true;
|
||||
std::string database_filename;
|
||||
|
||||
static std::string database_GetValue(std::string entry) {
|
||||
int index = entry.rfind('=');
|
||||
return entry.substr(index + 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
void database_Initialize( ) {
|
||||
database_filename = common_defaultPath + "ProSystem.dat";
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool database_Load(std::string digest) {
|
||||
if(database_enabled) {
|
||||
logger_LogInfo("Accessing database " + database_filename + ".", DATABASE_SOURCE);
|
||||
|
||||
FILE* file = fopen(database_filename.c_str( ), "r");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the database for reading.", DATABASE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
while(fgets(buffer, 256, file) != NULL) {
|
||||
std::string line = buffer;
|
||||
if(line.compare(1, 32, digest.c_str( )) == 0) {
|
||||
std::string entry[7];
|
||||
for(int index = 0; index < 7; index++) {
|
||||
fgets(buffer, 256, file);
|
||||
entry[index] = common_Remove(buffer, '\n');
|
||||
entry[index] = common_Remove(entry[index], '\r');
|
||||
}
|
||||
|
||||
cartridge_title = database_GetValue(entry[0]);
|
||||
cartridge_type = common_ParseByte(database_GetValue(entry[1]));
|
||||
cartridge_pokey = common_ParseBool(database_GetValue(entry[2]));
|
||||
cartridge_controller[0] = common_ParseByte(database_GetValue(entry[3]));
|
||||
cartridge_controller[1] = common_ParseByte(database_GetValue(entry[4]));
|
||||
cartridge_region = common_ParseByte(database_GetValue(entry[5]));
|
||||
cartridge_flags = common_ParseUint(database_GetValue(entry[6]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
42
core/Database.h
Executable file
42
core/Database.h
Executable file
@ -0,0 +1,42 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Database.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef DATABASE_H
|
||||
#define DATABASE_H
|
||||
|
||||
#include <string>
|
||||
#include "Cartridge.h"
|
||||
#include "Logger.h"
|
||||
#include "Common.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void database_Initialize( );
|
||||
extern bool database_Load(std::string digest);
|
||||
extern bool database_enabled;
|
||||
extern std::string database_filename;
|
||||
|
||||
#endif
|
84
core/Equates.h
Executable file
84
core/Equates.h
Executable file
@ -0,0 +1,84 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Equates.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef EQUATES_H
|
||||
#define EQUATES_H
|
||||
|
||||
#define INPTCTRL 1
|
||||
#define INPT0 8
|
||||
#define INPT1 9
|
||||
#define INPT2 10
|
||||
#define INPT3 11
|
||||
#define INPT4 12
|
||||
#define INPT5 13
|
||||
#define AUDC0 21
|
||||
#define AUDC1 22
|
||||
#define AUDF0 23
|
||||
#define AUDF1 24
|
||||
#define AUDV0 25
|
||||
#define AUDV1 26
|
||||
#define BACKGRND 32
|
||||
#define P0C1 33
|
||||
#define P0C2 34
|
||||
#define P0C3 35
|
||||
#define WSYNC 36
|
||||
#define P1C1 37
|
||||
#define P1C2 38
|
||||
#define P1C3 39
|
||||
#define MSTAT 40
|
||||
#define P2C1 41
|
||||
#define P2C2 42
|
||||
#define P2C3 43
|
||||
#define DPPH 44
|
||||
#define P3C1 45
|
||||
#define P3C2 46
|
||||
#define P3C3 47
|
||||
#define DPPL 48
|
||||
#define P4C1 49
|
||||
#define P4C2 50
|
||||
#define P4C3 51
|
||||
#define CHARBASE 52
|
||||
#define P5C1 53
|
||||
#define P5C2 54
|
||||
#define P5C3 55
|
||||
#define OFFSET 56
|
||||
#define P6C1 57
|
||||
#define P6C2 58
|
||||
#define P6C3 59
|
||||
#define CTRL 60
|
||||
#define P7C1 61
|
||||
#define P7C2 62
|
||||
#define P7C3 63
|
||||
#define SWCHA 640
|
||||
#define CTLSWA 641
|
||||
#define SWCHB 642
|
||||
#define CTLSWB 643
|
||||
#define INTIM 644
|
||||
#define INTFLG 645
|
||||
#define TIM1T 660
|
||||
#define TIM8T 661
|
||||
#define TIM64T 662
|
||||
#define T1024T 663
|
||||
|
||||
#endif
|
235
core/Hash.cpp
Executable file
235
core/Hash.cpp
Executable file
@ -0,0 +1,235 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Hash.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Hash.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step1
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint hash_Step1(uint w, uint x, uint y, uint z, uint data, uint s) {
|
||||
w += (z ^ (x & (y ^ z))) + data;
|
||||
w = w << s | w >> (32 - s);
|
||||
w += x;
|
||||
return w;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step2
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint hash_Step2(uint w, uint x, uint y, uint z, uint data, uint s) {
|
||||
w += (y ^ (z & (x ^ y))) + data;
|
||||
w = w << s | w >> (32 - s);
|
||||
w += x;
|
||||
return w;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step3
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint hash_Step3(uint w, uint x, uint y, uint z, uint data, uint s) {
|
||||
w += (x ^ y ^ z) + data;
|
||||
w = w << s | w >> (32 - s);
|
||||
w += x;
|
||||
return w;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Step4
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint hash_Step4(uint w, uint x, uint y, uint z, uint data, uint s) {
|
||||
w += (y ^ (x | ~z)) + data;
|
||||
w = w << s | w >> (32 - s);
|
||||
w += x;
|
||||
return w;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Transform
|
||||
// ----------------------------------------------------------------------------
|
||||
static void hash_Transform(uint out[4], uint in[16]) {
|
||||
uint a, b, c, d;
|
||||
|
||||
a = out[0];
|
||||
b = out[1];
|
||||
c = out[2];
|
||||
d = out[3];
|
||||
|
||||
a = hash_Step1(a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
d = hash_Step1(d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
c = hash_Step1(c, d, a, b, in[2] + 0x242070db, 17);
|
||||
b = hash_Step1(b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
a = hash_Step1(a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
d = hash_Step1(d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
c = hash_Step1(c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
b = hash_Step1(b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
a = hash_Step1(a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
d = hash_Step1(d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
c = hash_Step1(c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
b = hash_Step1(b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
a = hash_Step1(a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
d = hash_Step1(d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
c = hash_Step1(c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
b = hash_Step1(b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
a = hash_Step2(a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
d = hash_Step2(d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
c = hash_Step2(c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
b = hash_Step2(b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
a = hash_Step2(a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
d = hash_Step2(d, a, b, c, in[10] + 0x02441453, 9);
|
||||
c = hash_Step2(c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
b = hash_Step2(b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
a = hash_Step2(a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
d = hash_Step2(d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
c = hash_Step2(c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
b = hash_Step2(b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
a = hash_Step2(a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
d = hash_Step2(d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
c = hash_Step2(c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
b = hash_Step2(b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
a = hash_Step3(a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
d = hash_Step3(d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
c = hash_Step3(c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
b = hash_Step3(b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
a = hash_Step3(a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
d = hash_Step3(d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
c = hash_Step3(c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
b = hash_Step3(b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
a = hash_Step3(a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
d = hash_Step3(d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
c = hash_Step3(c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
b = hash_Step3(b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
a = hash_Step3(a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
d = hash_Step3(d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
c = hash_Step3(c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
b = hash_Step3(b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
a = hash_Step4(a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
d = hash_Step4(d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
c = hash_Step4(c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
b = hash_Step4(b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
a = hash_Step4(a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
d = hash_Step4(d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
c = hash_Step4(c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
b = hash_Step4(b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
a = hash_Step4(a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
d = hash_Step4(d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
c = hash_Step4(c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
b = hash_Step4(b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
a = hash_Step4(a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
d = hash_Step4(d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
c = hash_Step4(c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
b = hash_Step4(b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
out[0] += a;
|
||||
out[1] += b;
|
||||
out[2] += c;
|
||||
out[3] += d;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Compute
|
||||
// ----------------------------------------------------------------------------
|
||||
std::string hash_Compute(const byte* source, uint length) {
|
||||
uint buffer1[4] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
|
||||
uint buffer2[2] = {0};
|
||||
byte buffer3[64] = {0};
|
||||
|
||||
uint temp = buffer2[0];
|
||||
if((buffer2[0] = temp + ((uint)length << 3)) < temp) {
|
||||
buffer2[1]++;
|
||||
}
|
||||
buffer2[1] += length >> 29;
|
||||
|
||||
temp = (temp >> 3) & 0x3f;
|
||||
if(temp) {
|
||||
byte* ptr = (byte*)buffer3 + temp;
|
||||
temp = 64 - temp;
|
||||
if(length < temp) {
|
||||
for(uint index = 0; index < length; index++) {
|
||||
ptr[index] = source[index];
|
||||
}
|
||||
}
|
||||
|
||||
for(uint index = 0; index < temp; index++) {
|
||||
ptr[index] = source[index];
|
||||
}
|
||||
|
||||
hash_Transform(buffer1, (uint*)buffer3);
|
||||
source += temp;
|
||||
length -= temp;
|
||||
}
|
||||
|
||||
while(length >= 64) {
|
||||
for(uint index = 0; index < 64; index++) {
|
||||
buffer3[index] = source[index];
|
||||
}
|
||||
hash_Transform(buffer1, (uint*)buffer3);
|
||||
source += 64;
|
||||
length -= 64;
|
||||
}
|
||||
|
||||
for(uint index = 0; index < length; index++) {
|
||||
buffer3[index] = source[index];
|
||||
}
|
||||
|
||||
uint count = (buffer2[0] >> 3) & 0x3f;
|
||||
byte* ptr = buffer3 + count;
|
||||
*ptr++ = 0x80;
|
||||
|
||||
count = 63 - count;
|
||||
|
||||
if(count < 8) {
|
||||
for(uint index = 0; index < count; index++) {
|
||||
ptr[index] = 0;
|
||||
}
|
||||
hash_Transform(buffer1, (uint*)buffer3);
|
||||
|
||||
for(uint index = 0; index < 56; index++) {
|
||||
buffer3[index] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(uint index = 0; index < count - 8; index++) {
|
||||
ptr[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
((uint*)buffer3)[14] = buffer2[0];
|
||||
((uint*)buffer3)[15] = buffer2[1];
|
||||
|
||||
hash_Transform(buffer1, (uint*)buffer3);
|
||||
|
||||
byte digest[16];
|
||||
byte* bufferptr = (byte*)buffer1;
|
||||
for(uint index = 0; index < 16; index++) {
|
||||
digest[index] = bufferptr[index];
|
||||
}
|
||||
|
||||
char buffer[33] = {0};
|
||||
sprintf(buffer, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], digest[12], digest[13], digest[14], digest[15]);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
36
core/Hash.h
Executable file
36
core/Hash.h
Executable file
@ -0,0 +1,36 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Hash.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern std::string hash_Compute(const byte* source, uint length);
|
||||
|
||||
#endif
|
164
core/Logger.cpp
Executable file
164
core/Logger.cpp
Executable file
@ -0,0 +1,164 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Logger.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Logger.h"
|
||||
#define LOGGER_FILENAME "ProSystem.log"
|
||||
#include <iostream>
|
||||
|
||||
byte logger_level = LOGGER_LEVEL_DEBUG;
|
||||
static FILE* logger_file = NULL;
|
||||
char a[255]="";
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetTime
|
||||
// ----------------------------------------------------------------------------
|
||||
static std::string logger_GetTime( ) {
|
||||
time_t current;
|
||||
time(¤t);
|
||||
std::string timestring = ctime(¤t);
|
||||
return timestring.erase(timestring.find_first_of("\n"), 1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Log
|
||||
// ----------------------------------------------------------------------------
|
||||
static void logger_Log(std::string message, byte level, std::string source) {
|
||||
if(logger_file != NULL) {
|
||||
std::string entry = "[" + logger_GetTime( ) + "]";
|
||||
switch(level) {
|
||||
case LOGGER_LEVEL_ERROR:
|
||||
entry += "[ERROR]";
|
||||
break;
|
||||
case LOGGER_LEVEL_INFO:
|
||||
entry += "[INFO ]";
|
||||
break;
|
||||
default:
|
||||
entry += "[DEBUG]";
|
||||
break;
|
||||
}
|
||||
entry += " " + message;
|
||||
if(source.length( ) > 0) {
|
||||
entry += " " + source;
|
||||
}
|
||||
entry += "\n";
|
||||
fwrite(entry.c_str( ), 1, entry.length( ), logger_file);
|
||||
fflush(logger_file);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
bool logger_Initialize( ) {
|
||||
logger_file = fopen(LOGGER_FILENAME, "w");
|
||||
return (logger_file != NULL);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
bool logger_Initialize(std::string filename) {
|
||||
logger_file = fopen(filename.c_str( ), "w");
|
||||
return (logger_file != NULL);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogError //////////
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogError(int message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_ERROR || logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
// LoadString(GetModuleHandle(NULL),message, a, 180);
|
||||
// std::string b(a);
|
||||
// logger_Log(b, LOGGER_LEVEL_ERROR, source);
|
||||
logger_LogError(message, "");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogError
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogError(std::string message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_ERROR || logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_ERROR, source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogInfo
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogInfo(int message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
// LoadString(GetModuleHandle(NULL),message, a, 180);
|
||||
// std::string b(a);
|
||||
// logger_Log(b, LOGGER_LEVEL_INFO, source);
|
||||
logger_LogDebug(message, "");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogInfo /////////
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogInfo(std::string message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_INFO || logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_INFO, source);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogDebug ////////////
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogDebug(int message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
// LoadString(GetModuleHandle(NULL),message, a, 180);
|
||||
// std::string b(a);
|
||||
// logger_Log(b, LOGGER_LEVEL_DEBUG, source);
|
||||
logger_LogDebug(message, "");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LogDebug
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_LogDebug(std::string message, std::string source) {
|
||||
std::cerr << message << source << std::endl;
|
||||
if(logger_level == LOGGER_LEVEL_DEBUG) {
|
||||
logger_Log(message, LOGGER_LEVEL_DEBUG, source);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void logger_Release( ) {
|
||||
if(logger_file != NULL) {
|
||||
fclose(logger_file);
|
||||
}
|
||||
}
|
54
core/Logger.h
Executable file
54
core/Logger.h
Executable file
@ -0,0 +1,54 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Logger.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
#define LOGGER_LEVEL_DEBUG 0
|
||||
#define LOGGER_LEVEL_INFO 1
|
||||
#define LOGGER_LEVEL_ERROR 2
|
||||
//#define NULL 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
//#include "Windows.h"
|
||||
//#include "Resource.h"
|
||||
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern bool logger_Initialize( );
|
||||
extern bool logger_Initialize(std::string filename);
|
||||
extern void logger_LogError(std::string message, std::string source);
|
||||
extern void logger_LogError(int message, std::string source);
|
||||
extern void logger_LogInfo(std::string message, std::string source);
|
||||
extern void logger_LogInfo(int message, std::string source);
|
||||
extern void logger_LogDebug(std::string message, std::string source);
|
||||
extern void logger_LogDebug(int, std::string source);
|
||||
extern void logger_Release( );
|
||||
extern byte logger_level;
|
||||
|
||||
#endif
|
312
core/Maria.cpp
Executable file
312
core/Maria.cpp
Executable file
@ -0,0 +1,312 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Maria.c
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Maria.h"
|
||||
#define MARIA_LINERAM_SIZE 160
|
||||
|
||||
rect maria_displayArea = {0, 16, 319, 258};
|
||||
rect maria_visibleArea = {0, 26, 319, 248};
|
||||
byte maria_surface[MARIA_SURFACE_SIZE] = {0};
|
||||
word maria_scanline = 1;
|
||||
|
||||
static byte maria_lineRAM[MARIA_LINERAM_SIZE];
|
||||
static uint maria_cycles;
|
||||
static pair maria_dpp;
|
||||
static pair maria_dp;
|
||||
static pair maria_pp;
|
||||
static byte maria_horizontal;
|
||||
static byte maria_palette;
|
||||
static char maria_offset;
|
||||
static byte maria_h08;
|
||||
static byte maria_h16;
|
||||
static byte maria_wmode;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCell
|
||||
// ----------------------------------------------------------------------------
|
||||
static void maria_StoreCell(byte data) {
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE) {
|
||||
if(data) {
|
||||
maria_lineRAM[maria_horizontal] = maria_palette | data;
|
||||
}
|
||||
else {
|
||||
byte kmode = memory_ram[CTRL] & 4;
|
||||
if(kmode) {
|
||||
maria_lineRAM[maria_horizontal] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
maria_horizontal++;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreCell
|
||||
// ----------------------------------------------------------------------------
|
||||
static void maria_StoreCell(byte high, byte low) {
|
||||
if(maria_horizontal < MARIA_LINERAM_SIZE) {
|
||||
if(low || high) {
|
||||
maria_lineRAM[maria_horizontal] = (maria_palette & 16) | high | low;
|
||||
}
|
||||
else {
|
||||
byte kmode = memory_ram[CTRL] & 4;
|
||||
if(kmode) {
|
||||
maria_lineRAM[maria_horizontal] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
maria_horizontal++;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsHolyDMA
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool maria_IsHolyDMA( ) {
|
||||
if(maria_pp.w > 32767) {
|
||||
if(maria_h16 && (maria_pp.w & 4096)) {
|
||||
return true;
|
||||
}
|
||||
if(maria_h08 && (maria_pp.w & 2048)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetColor
|
||||
// ----------------------------------------------------------------------------
|
||||
static byte maria_GetColor(byte data) {
|
||||
if(data & 3) {
|
||||
return memory_ram[BACKGRND + data];
|
||||
}
|
||||
else {
|
||||
return memory_ram[BACKGRND];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreGraphic
|
||||
// ----------------------------------------------------------------------------
|
||||
static void maria_StoreGraphic( ) {
|
||||
byte data = memory_ram[maria_pp.w];
|
||||
if(maria_wmode) {
|
||||
if(maria_IsHolyDMA( )) {
|
||||
maria_StoreCell(0, 0);
|
||||
maria_StoreCell(0, 0);
|
||||
}
|
||||
else {
|
||||
maria_StoreCell((data & 12), (data & 192) >> 6);
|
||||
maria_StoreCell((data & 48) >> 4, (data & 3) << 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(maria_IsHolyDMA( )) {
|
||||
maria_StoreCell(0);
|
||||
maria_StoreCell(0);
|
||||
maria_StoreCell(0);
|
||||
maria_StoreCell(0);
|
||||
}
|
||||
else {
|
||||
maria_StoreCell((data & 192) >> 6);
|
||||
maria_StoreCell((data & 48) >> 4);
|
||||
maria_StoreCell((data & 12) >> 2);
|
||||
maria_StoreCell(data & 3);
|
||||
}
|
||||
}
|
||||
maria_pp.w++;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteLineRAM
|
||||
// ----------------------------------------------------------------------------
|
||||
static void maria_WriteLineRAM(byte* buffer) {
|
||||
byte rmode = memory_ram[CTRL] & 3;
|
||||
if(rmode == 0) {
|
||||
int pixel = 0;
|
||||
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
|
||||
byte color;
|
||||
color = maria_GetColor(maria_lineRAM[index + 0]);
|
||||
buffer[pixel++] = color;
|
||||
buffer[pixel++] = color;
|
||||
color = maria_GetColor(maria_lineRAM[index + 1]);
|
||||
buffer[pixel++] = color;
|
||||
buffer[pixel++] = color;
|
||||
color = maria_GetColor(maria_lineRAM[index + 2]);
|
||||
buffer[pixel++] = color;
|
||||
buffer[pixel++] = color;
|
||||
color = maria_GetColor(maria_lineRAM[index + 3]);
|
||||
buffer[pixel++] = color;
|
||||
buffer[pixel++] = color;
|
||||
}
|
||||
}
|
||||
else if(rmode == 2) {
|
||||
int pixel = 0;
|
||||
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 16) | ((maria_lineRAM[index + 0] & 8) >> 3) | ((maria_lineRAM[index + 0] & 2)));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 16) | ((maria_lineRAM[index + 0] & 4) >> 2) | ((maria_lineRAM[index + 0] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 1] & 16) | ((maria_lineRAM[index + 1] & 8) >> 3) | ((maria_lineRAM[index + 1] & 2)));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 1] & 16) | ((maria_lineRAM[index + 1] & 4) >> 2) | ((maria_lineRAM[index + 1] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 2] & 16) | ((maria_lineRAM[index + 2] & 8) >> 3) | ((maria_lineRAM[index + 2] & 2)));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 2] & 16) | ((maria_lineRAM[index + 2] & 4) >> 2) | ((maria_lineRAM[index + 2] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 3] & 16) | ((maria_lineRAM[index + 3] & 8) >> 3) | ((maria_lineRAM[index + 3] & 2)));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 3] & 16) | ((maria_lineRAM[index + 3] & 4) >> 2) | ((maria_lineRAM[index + 3] & 1) << 1));
|
||||
}
|
||||
}
|
||||
else if(rmode == 3) {
|
||||
int pixel = 0;
|
||||
for(int index = 0; index < MARIA_LINERAM_SIZE; index += 4) {
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 30));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 0] & 28) | ((maria_lineRAM[index + 0] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 1] & 30));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 1] & 28) | ((maria_lineRAM[index + 1] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 2] & 30));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 2] & 28) | ((maria_lineRAM[index + 2] & 1) << 1));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 3] & 30));
|
||||
buffer[pixel++] = maria_GetColor((maria_lineRAM[index + 3] & 28) | ((maria_lineRAM[index + 3] & 1) << 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// StoreLineRAM
|
||||
// ----------------------------------------------------------------------------
|
||||
static void maria_StoreLineRAM( ) {
|
||||
for(int index = 0; index < MARIA_LINERAM_SIZE; index++) {
|
||||
maria_lineRAM[index] = 0;
|
||||
}
|
||||
|
||||
byte mode = memory_ram[maria_dp.w + 1];
|
||||
while(mode & 0x5f) {
|
||||
byte width;
|
||||
byte indirect = 0;
|
||||
|
||||
maria_pp.b.l = memory_ram[maria_dp.w];
|
||||
maria_pp.b.h = memory_ram[maria_dp.w + 2];
|
||||
|
||||
if(mode & 31) {
|
||||
maria_cycles += 8;
|
||||
maria_palette = (memory_ram[maria_dp.w + 1] & 224) >> 3;
|
||||
maria_horizontal = memory_ram[maria_dp.w + 3];
|
||||
width = memory_ram[maria_dp.w + 1] & 31;
|
||||
width = ((~width) & 31) + 1;
|
||||
maria_dp.w += 4;
|
||||
}
|
||||
else {
|
||||
maria_cycles += 10;
|
||||
maria_palette = (memory_ram[maria_dp.w + 3] & 224) >> 3;
|
||||
maria_horizontal = memory_ram[maria_dp.w + 4];
|
||||
indirect = memory_ram[maria_dp.w + 1] & 32;
|
||||
maria_wmode = memory_ram[maria_dp.w + 1] & 128;
|
||||
width = memory_ram[maria_dp.w + 3] & 31;
|
||||
width = (width == 0)? 32: ((~width) & 31) + 1;
|
||||
maria_dp.w += 5;
|
||||
}
|
||||
|
||||
if(!indirect) {
|
||||
maria_pp.b.h += maria_offset;
|
||||
for(int index = 0; index < width; index++) {
|
||||
maria_cycles += 3;
|
||||
maria_StoreGraphic( );
|
||||
}
|
||||
}
|
||||
else {
|
||||
byte cwidth = memory_ram[CTRL] & 16;
|
||||
pair basePP = maria_pp;
|
||||
for(int index = 0; index < width; index++) {
|
||||
maria_cycles += 3;
|
||||
maria_pp.b.l = memory_ram[basePP.w++];
|
||||
maria_pp.b.h = memory_ram[CHARBASE] + maria_offset;
|
||||
|
||||
maria_cycles += 6;
|
||||
maria_StoreGraphic( );
|
||||
if(cwidth) {
|
||||
maria_cycles += 3;
|
||||
maria_StoreGraphic( );
|
||||
}
|
||||
}
|
||||
}
|
||||
mode = memory_ram[maria_dp.w + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void maria_Reset( ) {
|
||||
maria_scanline = 1;
|
||||
for(int index = 0; index < MARIA_SURFACE_SIZE; index++) {
|
||||
maria_surface[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RenderScanline
|
||||
// ----------------------------------------------------------------------------
|
||||
uint maria_RenderScanline( ) {
|
||||
maria_cycles = 0;
|
||||
if((memory_ram[CTRL] & 96) == 64 && maria_scanline >= maria_displayArea.top && maria_scanline <= maria_displayArea.bottom) {
|
||||
maria_cycles += 31;
|
||||
if(maria_scanline == maria_displayArea.top) {
|
||||
maria_cycles += 7;
|
||||
maria_dpp.b.l = memory_ram[DPPL];
|
||||
maria_dpp.b.h = memory_ram[DPPH];
|
||||
maria_h08 = memory_ram[maria_dpp.w] & 32;
|
||||
maria_h16 = memory_ram[maria_dpp.w] & 64;
|
||||
maria_offset = memory_ram[maria_dpp.w] & 15;
|
||||
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
|
||||
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
|
||||
if(memory_ram[maria_dpp.w] & 128) {
|
||||
sally_ExecuteNMI( );
|
||||
}
|
||||
}
|
||||
else if(maria_scanline >= maria_visibleArea.top && maria_scanline <= maria_visibleArea.bottom) {
|
||||
maria_WriteLineRAM(maria_surface + ((maria_scanline - maria_displayArea.top) * maria_displayArea.GetLength( )));
|
||||
}
|
||||
if(maria_scanline != maria_displayArea.bottom) {
|
||||
maria_dp.b.l = memory_ram[maria_dpp.w + 2];
|
||||
maria_dp.b.h = memory_ram[maria_dpp.w + 1];
|
||||
maria_StoreLineRAM( );
|
||||
maria_offset--;
|
||||
if(maria_offset < 0) {
|
||||
maria_dpp.w += 3;
|
||||
maria_h08 = memory_ram[maria_dpp.w] & 32;
|
||||
maria_h16 = memory_ram[maria_dpp.w] & 64;
|
||||
maria_offset = memory_ram[maria_dpp.w] & 15;
|
||||
if(memory_ram[maria_dpp.w] & 128) {
|
||||
sally_ExecuteNMI( );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maria_cycles;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void maria_Clear( ) {
|
||||
for(int index = 0; index < MARIA_SURFACE_SIZE; index++) {
|
||||
maria_surface[index] = 0;
|
||||
}
|
||||
}
|
47
core/Maria.h
Executable file
47
core/Maria.h
Executable file
@ -0,0 +1,47 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Maria.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef MARIA_H
|
||||
#define MARIA_H
|
||||
#define MARIA_SURFACE_SIZE 93440
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Pair.h"
|
||||
#include "Memory.h"
|
||||
#include "Rect.h"
|
||||
#include "Sally.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void maria_Reset( );
|
||||
extern uint maria_RenderScanline( );
|
||||
extern void maria_Clear( );
|
||||
extern rect maria_displayArea;
|
||||
extern rect maria_visibleArea;
|
||||
extern byte maria_surface[MARIA_SURFACE_SIZE];
|
||||
extern word maria_scanline;
|
||||
|
||||
#endif
|
185
core/Memory.cpp
Executable file
185
core/Memory.cpp
Executable file
@ -0,0 +1,185 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Memory.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Memory.h"
|
||||
|
||||
byte memory_ram[MEMORY_SIZE] = {0};
|
||||
byte memory_rom[MEMORY_SIZE] = {0};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_Reset( ) {
|
||||
uint index;
|
||||
for(index = 0; index < MEMORY_SIZE; index++) {
|
||||
memory_ram[index] = 0;
|
||||
memory_rom[index] = 1;
|
||||
}
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_rom[index] = 0;
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// Read
|
||||
// ----------------------------------------------------------------------------
|
||||
byte memory_Read(word address) {
|
||||
byte tmp_byte;
|
||||
|
||||
switch ( address ) {
|
||||
case INTIM:
|
||||
case INTIM | 0x2:
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return memory_ram[INTIM];
|
||||
break;
|
||||
case INTFLG:
|
||||
case INTFLG | 0x2:
|
||||
tmp_byte = memory_ram[INTFLG];
|
||||
memory_ram[INTFLG] &= 0x7f;
|
||||
return tmp_byte;
|
||||
break;
|
||||
default:
|
||||
return memory_ram[address];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Write
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_Write(word address, byte data) {
|
||||
|
||||
if(!memory_rom[address]) {
|
||||
switch(address) {
|
||||
case WSYNC:
|
||||
if(!(cartridge_flags & 128)) {
|
||||
memory_ram[WSYNC] = true;
|
||||
}
|
||||
break;
|
||||
case INPTCTRL:
|
||||
if(data == 22 && cartridge_IsLoaded( )) {
|
||||
cartridge_Store( );
|
||||
}
|
||||
else if(data == 2 && bios_enabled) {
|
||||
bios_Store( );
|
||||
}
|
||||
break;
|
||||
case INPT0:
|
||||
break;
|
||||
case INPT1:
|
||||
break;
|
||||
case INPT2:
|
||||
break;
|
||||
case INPT3:
|
||||
break;
|
||||
case INPT4:
|
||||
break;
|
||||
case INPT5:
|
||||
break;
|
||||
case AUDC0:
|
||||
tia_SetRegister(AUDC0, data);
|
||||
break;
|
||||
case AUDC1:
|
||||
tia_SetRegister(AUDC1, data);
|
||||
break;
|
||||
case AUDF0:
|
||||
tia_SetRegister(AUDF0, data);
|
||||
break;
|
||||
case AUDF1:
|
||||
tia_SetRegister(AUDF1, data);
|
||||
break;
|
||||
case AUDV0:
|
||||
tia_SetRegister(AUDV0, data);
|
||||
break;
|
||||
case AUDV1:
|
||||
tia_SetRegister(AUDV1, data);
|
||||
break;
|
||||
case SWCHA: /*gdement: Writing here actually writes to DRA inside the RIOT chip.
|
||||
This value only indirectly affects output of SWCHA. Ditto for SWCHB.*/
|
||||
riot_SetDRA(data);
|
||||
break;
|
||||
case SWCHB:
|
||||
riot_SetDRB(data);
|
||||
break;
|
||||
case TIM1T:
|
||||
case TIM1T | 0x8:
|
||||
riot_SetTimer(TIM1T, data);
|
||||
break;
|
||||
case TIM8T:
|
||||
case TIM8T | 0x8:
|
||||
riot_SetTimer(TIM8T, data);
|
||||
break;
|
||||
case TIM64T:
|
||||
case TIM64T | 0x8:
|
||||
riot_SetTimer(TIM64T, data);
|
||||
break;
|
||||
case T1024T:
|
||||
case T1024T | 0x8:
|
||||
riot_SetTimer(T1024T, data);
|
||||
break;
|
||||
default:
|
||||
memory_ram[address] = data;
|
||||
if(address >= 8256 && address <= 8447) {
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
else if(address >= 8512 && address <= 8702) {
|
||||
memory_ram[address - 8192] = data;
|
||||
}
|
||||
else if(address >= 64 && address <= 255) {
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
else if(address >= 320 && address <= 511) {
|
||||
memory_ram[address + 8192] = data;
|
||||
}
|
||||
break;
|
||||
/*TODO: gdement: test here for debug port. Don't put it in the switch because that will change behavior.*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
cartridge_Write(address, data);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// WriteROM
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_WriteROM(word address, word size, const byte* data) {
|
||||
if((address + size) <= MEMORY_SIZE && data != NULL) {
|
||||
for(uint index = 0; index < size; index++) {
|
||||
memory_ram[address + index] = data[index];
|
||||
memory_rom[address + index] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ClearROM
|
||||
// ----------------------------------------------------------------------------
|
||||
void memory_ClearROM(word address, word size) {
|
||||
if((address + size) <= MEMORY_SIZE) {
|
||||
for(uint index = 0; index < size; index++) {
|
||||
memory_ram[address + index] = 0;
|
||||
memory_rom[address + index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
48
core/Memory.h
Executable file
48
core/Memory.h
Executable file
@ -0,0 +1,48 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Memory.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
#define MEMORY_SIZE 65536
|
||||
//#define NULL 0
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Tia.h"
|
||||
#include "Riot.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void memory_Reset( );
|
||||
extern byte memory_Read(word address);
|
||||
extern void memory_Write(word address, byte data);
|
||||
extern void memory_WriteROM(word address, word size, const byte* data);
|
||||
extern void memory_ClearROM(word address, word size);
|
||||
extern byte memory_ram[MEMORY_SIZE];
|
||||
extern byte memory_rom[MEMORY_SIZE];
|
||||
|
||||
#endif
|
41
core/Pair.h
Executable file
41
core/Pair.h
Executable file
@ -0,0 +1,41 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pair.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef PAIR_H
|
||||
#define PAIR_H
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
union Pair {
|
||||
word w;
|
||||
struct Join {
|
||||
byte l;
|
||||
byte h;
|
||||
} b;
|
||||
};
|
||||
|
||||
typedef Pair pair;
|
||||
#endif
|
132
core/Palette.cpp
Executable file
132
core/Palette.cpp
Executable file
@ -0,0 +1,132 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Palette.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Palette.h"
|
||||
#define PALETTE_SOURCE "Palette.cpp"
|
||||
|
||||
std::string palette_filename;
|
||||
bool palette_default = true;
|
||||
byte palette_data[PALETTE_SIZE] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
0xA7,0xA7,0xA7,0xB9,0xB9,0xB9,0xC5,0xC5,0xC5,0xD0,0xD0,0xD0,
|
||||
0xD7,0xD7,0xD7,0xE1,0xE1,0xE1,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,
|
||||
0x4C,0x32,0x00,0x62,0x3A,0x00,0x7B,0x4A,0x00,0x9A,0x60,0x00,
|
||||
0xB5,0x74,0x00,0xCC,0x85,0x00,0xE7,0x9E,0x08,0xF7,0xAF,0x10,
|
||||
0xFF,0xC3,0x18,0xFF,0xD0,0x20,0xFF,0xD8,0x28,0xFF,0xDF,0x30,
|
||||
0xFF,0xE6,0x3B,0xFF,0xF4,0x40,0xFF,0xFA,0x4B,0xFF,0xFF,0x50,
|
||||
0x99,0x25,0x00,0xAA,0x25,0x00,0xB4,0x25,0x00,0xD3,0x30,0x00,
|
||||
0xDD,0x48,0x02,0xE2,0x50,0x09,0xF4,0x67,0x00,0xF4,0x75,0x10,
|
||||
0xFF,0x9E,0x10,0xFF,0xAC,0x20,0xFF,0xBA,0x3A,0xFF,0xBF,0x50,
|
||||
0xFF,0xC6,0x6D,0xFF,0xD5,0x80,0xFF,0xE4,0x90,0xFF,0xE6,0x99,
|
||||
0x98,0x0C,0x0C,0x99,0x0C,0x0C,0xC2,0x13,0x00,0xD3,0x13,0x00,
|
||||
0xE2,0x35,0x00,0xE3,0x40,0x00,0xE4,0x40,0x20,0xE5,0x52,0x30,
|
||||
0xFD,0x78,0x54,0xFF,0x8A,0x6A,0xFF,0x98,0x7C,0xFF,0xA4,0x8B,
|
||||
0xFF,0xB3,0x9E,0xFF,0xC2,0xB2,0xFF,0xD0,0xBA,0xFF,0xD7,0xC0,
|
||||
0x99,0x00,0x00,0xA9,0x00,0x00,0xC2,0x04,0x00,0xD3,0x04,0x00,
|
||||
0xDA,0x04,0x00,0xDB,0x08,0x00,0xE4,0x20,0x20,0xF6,0x40,0x40,
|
||||
0xFB,0x70,0x70,0xFB,0x7E,0x7E,0xFB,0x8F,0x8F,0xFF,0x9F,0x9F,
|
||||
0xFF,0xAB,0xAB,0xFF,0xB9,0xB9,0xFF,0xC9,0xC9,0xFF,0xCF,0xCF,
|
||||
0x7E,0x00,0x50,0x80,0x00,0x50,0x80,0x00,0x5F,0x95,0x0B,0x74,
|
||||
0xAA,0x22,0x88,0xBB,0x2F,0x9A,0xCE,0x3F,0xAD,0xD7,0x5A,0xB6,
|
||||
0xE4,0x67,0xC3,0xEF,0x72,0xCE,0xFB,0x7E,0xDA,0xFF,0x8D,0xE1,
|
||||
0xFF,0x9D,0xE5,0xFF,0xA5,0xE7,0xFF,0xAF,0xEA,0xFF,0xB8,0xEC,
|
||||
0x48,0x00,0x6C,0x5C,0x04,0x88,0x65,0x0D,0x90,0x7B,0x23,0xA7,
|
||||
0x93,0x3B,0xBF,0x9D,0x45,0xC9,0xA7,0x4F,0xD3,0xB2,0x5A,0xDE,
|
||||
0xBD,0x65,0xE9,0xC5,0x6D,0xF1,0xCE,0x76,0xFA,0xD5,0x83,0xFF,
|
||||
0xDA,0x90,0xFF,0xDE,0x9C,0xFF,0xE2,0xA9,0xFF,0xE6,0xB6,0xFF,
|
||||
0x1B,0x00,0x70,0x22,0x1B,0x8D,0x37,0x30,0xA2,0x48,0x41,0xB3,
|
||||
0x59,0x52,0xC4,0x63,0x5C,0xCE,0x6F,0x68,0xDA,0x7D,0x76,0xE8,
|
||||
0x87,0x80,0xF8,0x93,0x8C,0xFF,0x9D,0x97,0xFF,0xA8,0xA3,0xFF,
|
||||
0xB3,0xAF,0xFF,0xBC,0xB8,0xFF,0xC4,0xC1,0xFF,0xDA,0xD1,0xFF,
|
||||
0x00,0x0D,0x7F,0x00,0x12,0xA7,0x00,0x18,0xC0,0x0A,0x2B,0xD1,
|
||||
0x1B,0x4A,0xE3,0x2F,0x58,0xF0,0x37,0x68,0xFF,0x49,0x79,0xFF,
|
||||
0x5B,0x85,0xFF,0x6D,0x96,0xFF,0x7F,0xA3,0xFF,0x8C,0xAD,0xFF,
|
||||
0x96,0xB4,0xFF,0xA8,0xC0,0xFF,0xB7,0xCB,0xFF,0xC6,0xD6,0xFF,
|
||||
0x00,0x29,0x5A,0x00,0x38,0x76,0x00,0x48,0x92,0x00,0x5C,0xAC,
|
||||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
0x45,0x8C,0x11,0x5A,0xA5,0x13,0x1B,0xD2,0x09,0x1F,0xDD,0x00,
|
||||
0x3D,0xCD,0x2D,0x3D,0xCD,0x30,0x58,0xCC,0x40,0x60,0xD3,0x50,
|
||||
0xA2,0xEC,0x55,0xB3,0xF2,0x4A,0xBB,0xF6,0x5D,0xC4,0xF8,0x70,
|
||||
0x2E,0x3F,0x0C,0x36,0x4A,0x0F,0x40,0x56,0x15,0x46,0x5F,0x17,
|
||||
0x57,0x77,0x1A,0x65,0x85,0x1C,0x74,0x93,0x1D,0x8F,0xA5,0x25,
|
||||
0xAD,0xB7,0x2C,0xBC,0xC7,0x30,0xC9,0xD5,0x33,0xD4,0xE0,0x3B,
|
||||
0xE0,0xEC,0x42,0xEA,0xF6,0x45,0xF0,0xFD,0x47,0xF4,0xFF,0x6F,
|
||||
0x55,0x24,0x00,0x5A,0x2C,0x00,0x6C,0x3B,0x00,0x79,0x4B,0x00,
|
||||
0xB9,0x75,0x00,0xBB,0x85,0x00,0xC1,0xA1,0x20,0xD0,0xB0,0x2F,
|
||||
0xDE,0xBE,0x3F,0xE6,0xC6,0x45,0xED,0xCD,0x57,0xF5,0xDB,0x62,
|
||||
0xFB,0xE5,0x69,0xFC,0xEE,0x6F,0xFD,0xF3,0x77,0xFD,0xF3,0x7F,
|
||||
0x5C,0x27,0x00,0x5C,0x2F,0x00,0x71,0x3B,0x00,0x7B,0x48,0x00,
|
||||
0xB9,0x68,0x20,0xBB,0x72,0x20,0xC5,0x86,0x29,0xD7,0x96,0x33,
|
||||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool palette_Load(std::string filename) {
|
||||
if(filename.empty( ) || filename.length( ) == 0) {
|
||||
logger_LogError("Palette filename is invalid.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger_LogInfo("Opening palette file " + filename + ".", PALETTE_SOURCE);
|
||||
|
||||
FILE* file = fopen(filename.c_str( ), "rb");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the palette file " + filename + " for reading.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fread(palette_data, 1, PALETTE_SIZE, file) != PALETTE_SIZE) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the palette data.", PALETTE_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
palette_filename = filename;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
void palette_Load(const byte* data) {
|
||||
for(int index = 0; index < PALETTE_SIZE; index++) {
|
||||
palette_data[index] = data[index];
|
||||
}
|
||||
}
|
43
core/Palette.h
Executable file
43
core/Palette.h
Executable file
@ -0,0 +1,43 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Palette.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef PALETTE_H
|
||||
#define PALETTE_H
|
||||
#define PALETTE_SIZE 768
|
||||
//#define NULL 0
|
||||
|
||||
#include <string>
|
||||
#include "Logger.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern bool palette_Load(std::string filename);
|
||||
extern void palette_Load(const byte* data);
|
||||
extern std::string palette_filename;
|
||||
extern byte palette_data[PALETTE_SIZE];
|
||||
extern bool palette_default;
|
||||
|
||||
#endif
|
365
core/Pokey.cpp
Executable file
365
core/Pokey.cpp
Executable file
@ -0,0 +1,365 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// PokeySound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pokey.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include <stdlib.h>
|
||||
#include "Pokey.h"
|
||||
#define POKEY_NOTPOLY5 0x80
|
||||
#define POKEY_POLY4 0x40
|
||||
#define POKEY_PURE 0x20
|
||||
#define POKEY_VOLUME_ONLY 0x10
|
||||
#define POKEY_VOLUME_MASK 0x0f
|
||||
#define POKEY_POLY9 0x80
|
||||
#define POKEY_CH1_179 0x40
|
||||
#define POKEY_CH3_179 0x20
|
||||
#define POKEY_CH1_CH2 0x10
|
||||
#define POKEY_CH3_CH4 0x08
|
||||
#define POKEY_CH1_FILTER 0x04
|
||||
#define POKEY_CH2_FILTER 0x02
|
||||
#define POKEY_CLOCK_15 0x01
|
||||
#define POKEY_DIV_64 28
|
||||
#define POKEY_DIV_15 114
|
||||
#define POKEY_POLY4_SIZE 0x000f
|
||||
#define POKEY_POLY5_SIZE 0x001f
|
||||
#define POKEY_POLY9_SIZE 0x01ff
|
||||
#define POKEY_POLY17_SIZE 0x0001ffff
|
||||
#define POKEY_CHANNEL1 0
|
||||
#define POKEY_CHANNEL2 1
|
||||
#define POKEY_CHANNEL3 2
|
||||
#define POKEY_CHANNEL4 3
|
||||
#define POKEY_SAMPLE 4
|
||||
|
||||
byte pokey_buffer[POKEY_BUFFER_SIZE] = {0};
|
||||
uint pokey_size = 524;
|
||||
|
||||
static uint pokey_frequency = 1787520;
|
||||
static uint pokey_sampleRate = 31440;
|
||||
static uint pokey_soundCntr = 0;
|
||||
static byte pokey_audf[4];
|
||||
static byte pokey_audc[4];
|
||||
static byte pokey_audctl;
|
||||
static byte pokey_output[4];
|
||||
static byte pokey_outVol[4];
|
||||
static byte pokey_poly04[POKEY_POLY4_SIZE] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
|
||||
static byte pokey_poly05[POKEY_POLY5_SIZE] = {0,0,1,1,0,0,0,1,1,1,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,0,0,0,0,0,1};
|
||||
static byte pokey_poly17[POKEY_POLY17_SIZE];
|
||||
static uint pokey_poly17Size;
|
||||
static uint pokey_polyAdjust;
|
||||
static uint pokey_poly04Cntr;
|
||||
static uint pokey_poly05Cntr;
|
||||
static uint pokey_poly17Cntr;
|
||||
static uint pokey_divideMax[4];
|
||||
static uint pokey_divideCount[4];
|
||||
static uint pokey_sampleMax;
|
||||
static uint pokey_sampleCount[2];
|
||||
static uint pokey_baseMultiplier;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_Reset( ) {
|
||||
for(int index = 0; index < POKEY_POLY17_SIZE; index++) {
|
||||
pokey_poly17[index] = rand( ) & 1;
|
||||
}
|
||||
pokey_polyAdjust = 0;
|
||||
pokey_poly04Cntr = 0;
|
||||
pokey_poly05Cntr = 0;
|
||||
pokey_poly17Cntr = 0;
|
||||
|
||||
pokey_sampleMax = ((uint)pokey_frequency << 8) / pokey_sampleRate;
|
||||
|
||||
pokey_sampleCount[0] = 0;
|
||||
pokey_sampleCount[1] = 0;
|
||||
|
||||
pokey_poly17Size = POKEY_POLY17_SIZE;
|
||||
|
||||
for(int channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_outVol[channel] = 0;
|
||||
pokey_output[channel] = 0;
|
||||
pokey_divideCount[channel] = 0;
|
||||
pokey_divideMax[channel] = 0x7fffffffL;
|
||||
pokey_audc[channel] = 0;
|
||||
pokey_audf[channel] = 0;
|
||||
}
|
||||
|
||||
pokey_audctl = 0;
|
||||
pokey_baseMultiplier = POKEY_DIV_64;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetRegister
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_SetRegister(word address, byte value) {
|
||||
byte channelMask;
|
||||
switch(address) {
|
||||
case POKEY_AUDF1:
|
||||
pokey_audf[POKEY_CHANNEL1] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL1;
|
||||
if(pokey_audctl & POKEY_CH1_CH2) {
|
||||
channelMask |= 1 << POKEY_CHANNEL2;
|
||||
}
|
||||
break;
|
||||
|
||||
case POKEY_AUDC1:
|
||||
pokey_audc[POKEY_CHANNEL1] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL1;
|
||||
break;
|
||||
|
||||
case POKEY_AUDF2:
|
||||
pokey_audf[POKEY_CHANNEL2] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL2;
|
||||
break;
|
||||
|
||||
case POKEY_AUDC2:
|
||||
pokey_audc[POKEY_CHANNEL2] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL2;
|
||||
break;
|
||||
|
||||
case POKEY_AUDF3:
|
||||
pokey_audf[POKEY_CHANNEL3] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL3;
|
||||
|
||||
if(pokey_audctl & POKEY_CH3_CH4) {
|
||||
channelMask |= 1 << POKEY_CHANNEL4;
|
||||
}
|
||||
break;
|
||||
|
||||
case POKEY_AUDC3:
|
||||
pokey_audc[POKEY_CHANNEL3] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL3;
|
||||
break;
|
||||
|
||||
case POKEY_AUDF4:
|
||||
pokey_audf[POKEY_CHANNEL4] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL4;
|
||||
break;
|
||||
|
||||
case POKEY_AUDC4:
|
||||
pokey_audc[POKEY_CHANNEL4] = value;
|
||||
channelMask = 1 << POKEY_CHANNEL4;
|
||||
break;
|
||||
|
||||
case POKEY_AUDCTL:
|
||||
pokey_audctl = value;
|
||||
channelMask = 15;
|
||||
if(pokey_audctl & POKEY_POLY9) {
|
||||
pokey_poly17Size = POKEY_POLY9_SIZE;
|
||||
}
|
||||
else {
|
||||
pokey_poly17Size = POKEY_POLY17_SIZE;
|
||||
}
|
||||
if(pokey_audctl & POKEY_CLOCK_15) {
|
||||
pokey_baseMultiplier = POKEY_DIV_15;
|
||||
}
|
||||
else {
|
||||
pokey_baseMultiplier = POKEY_DIV_64;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
channelMask = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
uint newValue = 0;
|
||||
|
||||
if(channelMask & (1 << POKEY_CHANNEL1)) {
|
||||
if(pokey_audctl & POKEY_CH1_179) {
|
||||
newValue = pokey_audf[POKEY_CHANNEL1] + 4;
|
||||
}
|
||||
else {
|
||||
newValue = (pokey_audf[POKEY_CHANNEL1] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
|
||||
if(newValue != pokey_divideMax[POKEY_CHANNEL1]) {
|
||||
pokey_divideMax[POKEY_CHANNEL1] = newValue;
|
||||
if(pokey_divideCount[POKEY_CHANNEL1] > newValue) {
|
||||
pokey_divideCount[POKEY_CHANNEL1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(channelMask & (1 << POKEY_CHANNEL2)) {
|
||||
if(pokey_audctl & POKEY_CH1_CH2) {
|
||||
if(pokey_audctl & POKEY_CH1_179) {
|
||||
newValue = pokey_audf[POKEY_CHANNEL2] * 256 + pokey_audf[POKEY_CHANNEL1] + 7;
|
||||
}
|
||||
else {
|
||||
newValue = (pokey_audf[POKEY_CHANNEL2] * 256 + pokey_audf[POKEY_CHANNEL1] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newValue = (pokey_audf[POKEY_CHANNEL2] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
if(newValue != pokey_divideMax[POKEY_CHANNEL2]) {
|
||||
pokey_divideMax[POKEY_CHANNEL2] = newValue;
|
||||
if(pokey_divideCount[POKEY_CHANNEL2] > newValue) {
|
||||
pokey_divideCount[POKEY_CHANNEL2] = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(channelMask & (1 << POKEY_CHANNEL3)) {
|
||||
if(pokey_audctl & POKEY_CH3_179) {
|
||||
newValue = pokey_audf[POKEY_CHANNEL3] + 4;
|
||||
}
|
||||
else {
|
||||
newValue= (pokey_audf[POKEY_CHANNEL3] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
if(newValue!= pokey_divideMax[POKEY_CHANNEL3]) {
|
||||
pokey_divideMax[POKEY_CHANNEL3] = newValue;
|
||||
if(pokey_divideCount[POKEY_CHANNEL3] > newValue) {
|
||||
pokey_divideCount[POKEY_CHANNEL3] = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(channelMask & (1 << POKEY_CHANNEL4)) {
|
||||
if(pokey_audctl & POKEY_CH3_CH4) {
|
||||
if(pokey_audctl & POKEY_CH3_179) {
|
||||
newValue = pokey_audf[POKEY_CHANNEL4] * 256 + pokey_audf[POKEY_CHANNEL3] + 7;
|
||||
}
|
||||
else {
|
||||
newValue = (pokey_audf[POKEY_CHANNEL4] * 256 + pokey_audf[POKEY_CHANNEL3] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newValue = (pokey_audf[POKEY_CHANNEL4] + 1) * pokey_baseMultiplier;
|
||||
}
|
||||
if(newValue != pokey_divideMax[POKEY_CHANNEL4]) {
|
||||
pokey_divideMax[POKEY_CHANNEL4] = newValue;
|
||||
if(pokey_divideCount[POKEY_CHANNEL4] > newValue) {
|
||||
pokey_divideCount[POKEY_CHANNEL4] = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(byte channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(channelMask & (1 << channel)) {
|
||||
if((pokey_audc[channel] & POKEY_VOLUME_ONLY) || ((pokey_audc[channel] & POKEY_VOLUME_MASK) == 0) || (pokey_divideMax[channel] < (pokey_sampleMax >> 8))) {
|
||||
pokey_outVol[channel] = pokey_audc[channel] & POKEY_VOLUME_MASK;
|
||||
pokey_divideCount[channel] = 0x7fffffff;
|
||||
pokey_divideMax[channel] = 0x7fffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Process
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_Process(uint length) {
|
||||
byte* buffer = pokey_buffer + pokey_soundCntr;
|
||||
uint* sampleCntrPtr = (uint*)((byte*)(&pokey_sampleCount[0]) + 1);
|
||||
uint size = length;
|
||||
|
||||
while(length) {
|
||||
byte currentValue;
|
||||
byte nextEvent = POKEY_SAMPLE;
|
||||
uint eventMin = *sampleCntrPtr;
|
||||
|
||||
byte channel;
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
if(pokey_divideCount[channel] <= eventMin) {
|
||||
eventMin = pokey_divideCount[channel];
|
||||
nextEvent = channel;
|
||||
}
|
||||
}
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
pokey_divideCount[channel] -= eventMin;
|
||||
}
|
||||
|
||||
*sampleCntrPtr -= eventMin;
|
||||
pokey_polyAdjust += eventMin;
|
||||
|
||||
if(nextEvent != POKEY_SAMPLE) {
|
||||
pokey_poly04Cntr = (pokey_poly04Cntr + pokey_polyAdjust) % POKEY_POLY4_SIZE;
|
||||
pokey_poly05Cntr = (pokey_poly05Cntr + pokey_polyAdjust) % POKEY_POLY5_SIZE;
|
||||
pokey_poly17Cntr = (pokey_poly17Cntr + pokey_polyAdjust) % pokey_poly17Size;
|
||||
pokey_polyAdjust = 0;
|
||||
pokey_divideCount[nextEvent] += pokey_divideMax[nextEvent];
|
||||
|
||||
if((pokey_audc[nextEvent] & POKEY_NOTPOLY5) || pokey_poly05[pokey_poly05Cntr]) {
|
||||
if(pokey_audc[nextEvent] & POKEY_PURE) {
|
||||
pokey_output[nextEvent] = !pokey_output[nextEvent];
|
||||
}
|
||||
else if (pokey_audc[nextEvent] & POKEY_POLY4) {
|
||||
pokey_output[nextEvent] = pokey_poly04[pokey_poly04Cntr];
|
||||
}
|
||||
else {
|
||||
pokey_output[nextEvent] = pokey_poly17[pokey_poly17Cntr];
|
||||
}
|
||||
}
|
||||
|
||||
if(pokey_output[nextEvent]) {
|
||||
pokey_outVol[nextEvent] = pokey_audc[nextEvent] & POKEY_VOLUME_MASK;
|
||||
}
|
||||
else {
|
||||
pokey_outVol[nextEvent] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*pokey_sampleCount += pokey_sampleMax;
|
||||
currentValue = 0;
|
||||
|
||||
for(channel = POKEY_CHANNEL1; channel <= POKEY_CHANNEL4; channel++) {
|
||||
currentValue += pokey_outVol[channel];
|
||||
}
|
||||
|
||||
currentValue = (currentValue << 2) + 8;
|
||||
*buffer++ = currentValue;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
pokey_soundCntr += size;
|
||||
if(pokey_soundCntr >= pokey_size) {
|
||||
pokey_soundCntr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void pokey_Clear( ) {
|
||||
for(int index = 0; index < POKEY_BUFFER_SIZE; index++) {
|
||||
pokey_buffer[index] = 0;
|
||||
}
|
||||
}
|
65
core/Pokey.h
Executable file
65
core/Pokey.h
Executable file
@ -0,0 +1,65 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// PokeySound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pokey.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef POKEY_H
|
||||
#define POKEY_H
|
||||
#define POKEY_BUFFER_SIZE 624
|
||||
#define POKEY_AUDF1 0x4000
|
||||
#define POKEY_AUDC1 0x4001
|
||||
#define POKEY_AUDF2 0x4002
|
||||
#define POKEY_AUDC2 0x4003
|
||||
#define POKEY_AUDF3 0x4004
|
||||
#define POKEY_AUDC3 0x4005
|
||||
#define POKEY_AUDF4 0x4006
|
||||
#define POKEY_AUDC4 0x4007
|
||||
#define POKEY_AUDCTL 0x4008
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void pokey_Reset( );
|
||||
extern void pokey_SetRegister(word address, byte value);
|
||||
extern void pokey_Process(uint length);
|
||||
extern void pokey_Clear( );
|
||||
extern byte pokey_buffer[POKEY_BUFFER_SIZE];
|
||||
extern uint pokey_size;
|
||||
|
||||
#endif
|
329
core/ProSystem.cpp
Executable file
329
core/ProSystem.cpp
Executable file
@ -0,0 +1,329 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2003, 2004 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProSystem.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "ProSystem.h"
|
||||
#define PRO_SYSTEM_STATE_HEADER "PRO-SYSTEM STATE"
|
||||
#define PRO_SYSTEM_SOURCE "ProSystem.cpp"
|
||||
|
||||
bool prosystem_active = false;
|
||||
bool prosystem_paused = false;
|
||||
word prosystem_frequency = 60;
|
||||
byte prosystem_frame = 0;
|
||||
word prosystem_scanlines = 262;
|
||||
uint prosystem_cycles = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Reset( ) {
|
||||
if(cartridge_IsLoaded( )) {
|
||||
prosystem_paused = false;
|
||||
prosystem_frame = 0;
|
||||
region_Reset( );
|
||||
tia_Clear( );
|
||||
tia_Reset( );
|
||||
pokey_Clear( );
|
||||
pokey_Reset( );
|
||||
memory_Reset( );
|
||||
maria_Clear( );
|
||||
maria_Reset( );
|
||||
riot_Reset ( );
|
||||
if(bios_enabled) {
|
||||
bios_Store( );
|
||||
}
|
||||
else {
|
||||
cartridge_Store( );
|
||||
}
|
||||
prosystem_cycles = sally_ExecuteRES( );
|
||||
prosystem_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ExecuteFrame
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_ExecuteFrame(const byte* input) {
|
||||
riot_SetInput(input);
|
||||
|
||||
for(maria_scanline = 1; maria_scanline <= prosystem_scanlines; maria_scanline++) {
|
||||
if(maria_scanline == maria_displayArea.top) {
|
||||
memory_ram[MSTAT] = 0;
|
||||
}
|
||||
if(maria_scanline == maria_displayArea.bottom) {
|
||||
memory_ram[MSTAT] = 128;
|
||||
}
|
||||
|
||||
uint cycles;
|
||||
prosystem_cycles %= 456;
|
||||
while(prosystem_cycles < 28) {
|
||||
cycles = sally_ExecuteInstruction( );
|
||||
prosystem_cycles += (cycles << 2);
|
||||
if(riot_timing) {
|
||||
riot_UpdateTimer(cycles);
|
||||
}
|
||||
if(memory_ram[WSYNC] && !(cartridge_flags & CARTRIDGE_WSYNC_MASK)) {
|
||||
prosystem_cycles = 456;
|
||||
memory_ram[WSYNC] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cycles = maria_RenderScanline( );
|
||||
if(cartridge_flags & CARTRIDGE_CYCLE_STEALING_MASK) {
|
||||
prosystem_cycles += cycles;
|
||||
}
|
||||
|
||||
while(prosystem_cycles < 456) {
|
||||
cycles = sally_ExecuteInstruction( );
|
||||
prosystem_cycles += (cycles << 2);
|
||||
if(riot_timing) {
|
||||
riot_UpdateTimer(cycles);
|
||||
}
|
||||
if(memory_ram[WSYNC] && !(cartridge_flags & CARTRIDGE_WSYNC_MASK)) {
|
||||
prosystem_cycles = 456;
|
||||
memory_ram[WSYNC] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tia_Process(2);
|
||||
if(cartridge_pokey) {
|
||||
pokey_Process(2);
|
||||
}
|
||||
}
|
||||
prosystem_frame++;
|
||||
if(prosystem_frame >= prosystem_frequency) {
|
||||
prosystem_frame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Save
|
||||
// ----------------------------------------------------------------------------
|
||||
bool prosystem_Save(std::string filename, bool compress) {
|
||||
if(filename.empty( ) || filename.length( ) == 0) {
|
||||
logger_LogError("Filename is invalid.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger_LogInfo("Saving game state to file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
|
||||
byte buffer[32829] = {0};
|
||||
uint size = 0;
|
||||
|
||||
uint index;
|
||||
for(index = 0; index < 16; index++) {
|
||||
buffer[size + index] = PRO_SYSTEM_STATE_HEADER[index];
|
||||
}
|
||||
size += 16;
|
||||
|
||||
buffer[size++] = 1;
|
||||
for(index = 0; index < 4; index++) {
|
||||
buffer[size + index] = 0;
|
||||
}
|
||||
size += 4;
|
||||
|
||||
for(index = 0; index < 32; index++) {
|
||||
buffer[size + index] = cartridge_digest[index];
|
||||
}
|
||||
size += 32;
|
||||
|
||||
buffer[size++] = sally_a;
|
||||
buffer[size++] = sally_x;
|
||||
buffer[size++] = sally_y;
|
||||
buffer[size++] = sally_p;
|
||||
buffer[size++] = sally_s;
|
||||
buffer[size++] = sally_pc.b.l;
|
||||
buffer[size++] = sally_pc.b.h;
|
||||
buffer[size++] = cartridge_bank;
|
||||
|
||||
for(index = 0; index < 16384; index++) {
|
||||
buffer[size + index] = memory_ram[index];
|
||||
}
|
||||
size += 16384;
|
||||
|
||||
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
|
||||
for(index = 0; index < 16384; index++) {
|
||||
buffer[size + index] = memory_ram[16384 + index];
|
||||
}
|
||||
size += 16384;
|
||||
}
|
||||
|
||||
if(!compress) {
|
||||
FILE* file = fopen(filename.c_str( ), "wb");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the file " + filename + " for writing.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fwrite(buffer, 1, size, file) != size) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to write the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else {
|
||||
if(!archive_Compress(filename.c_str( ), "Save.sav", buffer, size)) {
|
||||
logger_LogError("Failed to compress the save state data to the file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Load
|
||||
// ----------------------------------------------------------------------------
|
||||
bool prosystem_Load(const std::string filename) {
|
||||
if(filename.empty( ) || filename.length( ) == 0) {
|
||||
logger_LogError("Filename is invalid.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
logger_LogInfo("Loading game state from file " + filename + ".", PRO_SYSTEM_SOURCE);
|
||||
|
||||
byte buffer[32829] = {0};
|
||||
uint size = archive_GetUncompressedFileSize(filename);
|
||||
if(size == 0) {
|
||||
FILE* file = fopen(filename.c_str( ), "rb");
|
||||
if(file == NULL) {
|
||||
logger_LogError("Failed to open the file " + filename + " for reading.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fseek(file, 0, SEEK_END)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the end of the file.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
size = ftell(file);
|
||||
if(fseek(file, 0, SEEK_SET)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to find the size of the file.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(size != 16445 && size != 32829) {
|
||||
fclose(file);
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fread(buffer, 1, size, file) != size && ferror(file)) {
|
||||
fclose(file);
|
||||
logger_LogError("Failed to read the file data.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
else if(size == 16445 || size == 32829) {
|
||||
archive_Uncompress(filename, buffer, size);
|
||||
}
|
||||
else {
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint offset = 0;
|
||||
uint index;
|
||||
for(index = 0; index < 16; index++) {
|
||||
if(buffer[offset + index] != PRO_SYSTEM_STATE_HEADER[index]) {
|
||||
logger_LogError("File is not a valid ProSystem save state.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
offset += 16;
|
||||
byte version = buffer[offset++];
|
||||
|
||||
uint date = 0;
|
||||
for(index = 0; index < 4; index++) {
|
||||
}
|
||||
offset += 4;
|
||||
|
||||
prosystem_Reset( );
|
||||
|
||||
char digest[33] = {0};
|
||||
for(index = 0; index < 32; index++) {
|
||||
digest[index] = buffer[offset + index];
|
||||
}
|
||||
offset += 32;
|
||||
if(cartridge_digest != std::string(digest)) {
|
||||
logger_LogError("Load state digest [" + std::string(digest) + "] does not match loaded cartridge digest [" + cartridge_digest + "].", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
|
||||
sally_a = buffer[offset++];
|
||||
sally_x = buffer[offset++];
|
||||
sally_y = buffer[offset++];
|
||||
sally_p = buffer[offset++];
|
||||
sally_s = buffer[offset++];
|
||||
sally_pc.b.l = buffer[offset++];
|
||||
sally_pc.b.h = buffer[offset++];
|
||||
|
||||
cartridge_StoreBank(buffer[offset++]);
|
||||
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_ram[index] = buffer[offset + index];
|
||||
}
|
||||
offset += 16384;
|
||||
|
||||
if(cartridge_type == CARTRIDGE_TYPE_SUPERCART_RAM) {
|
||||
if(size != 32829) {
|
||||
logger_LogError("Save state file has an invalid size.", PRO_SYSTEM_SOURCE);
|
||||
return false;
|
||||
}
|
||||
for(index = 0; index < 16384; index++) {
|
||||
memory_ram[16384 + index] = buffer[offset + index];
|
||||
}
|
||||
offset += 16384;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pause
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Pause(bool pause) {
|
||||
if(prosystem_active) {
|
||||
prosystem_paused = pause;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Close
|
||||
// ----------------------------------------------------------------------------
|
||||
void prosystem_Close( ) {
|
||||
prosystem_active = false;
|
||||
prosystem_paused = false;
|
||||
cartridge_Release( );
|
||||
maria_Reset( );
|
||||
maria_Clear( );
|
||||
memory_Reset( );
|
||||
tia_Reset( );
|
||||
tia_Clear( );
|
||||
}
|
60
core/ProSystem.h
Executable file
60
core/ProSystem.h
Executable file
@ -0,0 +1,60 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProSystem.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef PRO_SYSTEM_H
|
||||
#define PRO_SYSTEM_H
|
||||
//#define NULL 0
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include "Equates.h"
|
||||
#include "Bios.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Maria.h"
|
||||
#include "Memory.h"
|
||||
#include "Region.h"
|
||||
#include "Riot.h"
|
||||
#include "Sally.h"
|
||||
#include "Archive.h"
|
||||
#include "Tia.h"
|
||||
#include "Pokey.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void prosystem_Reset( );
|
||||
extern void prosystem_ExecuteFrame(const byte* input);
|
||||
extern bool prosystem_Save(std::string filename, bool compress);
|
||||
extern bool prosystem_Load(std::string filename);
|
||||
extern void prosystem_Pause(bool pause);
|
||||
extern void prosystem_Close( );
|
||||
extern bool prosystem_active;
|
||||
extern bool prosystem_paused;
|
||||
extern word prosystem_frequency;
|
||||
extern byte prosystem_frame;
|
||||
extern word prosystem_scanlines;
|
||||
extern uint prosystem_cycles;
|
||||
|
||||
#endif
|
52
core/Rect.h
Executable file
52
core/Rect.h
Executable file
@ -0,0 +1,52 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Rect.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef RECT_H
|
||||
#define RECT_H
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
struct Rects {
|
||||
uint left;
|
||||
uint top;
|
||||
uint right;
|
||||
uint bottom;
|
||||
|
||||
uint GetArea( ) {
|
||||
return GetLength( ) * GetHeight( );
|
||||
}
|
||||
|
||||
uint GetLength( ) {
|
||||
return (right - left) + 1;
|
||||
}
|
||||
|
||||
uint GetHeight( ) {
|
||||
return (bottom - top) + 1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef Rects rect;
|
||||
#endif
|
202
core/Region.cpp
Executable file
202
core/Region.cpp
Executable file
@ -0,0 +1,202 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Region.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Region.h"
|
||||
|
||||
byte region_type = REGION_AUTO;
|
||||
|
||||
static const rect REGION_VISIBLE_AREA_NTSC = {0, 26, 319, 248};
|
||||
static const rect REGION_VISIBLE_AREA_PAL = {0, 26, 319, 297};
|
||||
static const rect REGION_DISPLAY_AREA_NTSC = {0, 16, 319, 258};
|
||||
static const rect REGION_DISPLAY_AREA_PAL = {0, 16, 319, 306};
|
||||
static const byte REGION_FREQUENCY_NTSC = 60;
|
||||
static const word REGION_SCANLINES_NTSC = 262;
|
||||
static const byte REGION_FREQUENCY_PAL = 50;
|
||||
static const word REGION_SCANLINES_PAL = 312;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// PALETTE NTSC
|
||||
// ----------------------------------------------------------------------------
|
||||
static const byte REGION_PALETTE_NTSC[ ] = {
|
||||
0x00,0x00,0x00,0x25,0x25,0x25,0x34,0x34,0x34,0x4F,0x4F,0x4F,
|
||||
0x5B,0x5B,0x5B,0x69,0x69,0x69,0x7B,0x7B,0x7B,0x8A,0x8A,0x8A,
|
||||
0xA7,0xA7,0xA7,0xB9,0xB9,0xB9,0xC5,0xC5,0xC5,0xD0,0xD0,0xD0,
|
||||
0xD7,0xD7,0xD7,0xE1,0xE1,0xE1,0xF4,0xF4,0xF4,0xFF,0xFF,0xFF,
|
||||
0x4C,0x32,0x00,0x62,0x3A,0x00,0x7B,0x4A,0x00,0x9A,0x60,0x00,
|
||||
0xB5,0x74,0x00,0xCC,0x85,0x00,0xE7,0x9E,0x08,0xF7,0xAF,0x10,
|
||||
0xFF,0xC3,0x18,0xFF,0xD0,0x20,0xFF,0xD8,0x28,0xFF,0xDF,0x30,
|
||||
0xFF,0xE6,0x3B,0xFF,0xF4,0x40,0xFF,0xFA,0x4B,0xFF,0xFF,0x50,
|
||||
0x99,0x25,0x00,0xAA,0x25,0x00,0xB4,0x25,0x00,0xD3,0x30,0x00,
|
||||
0xDD,0x48,0x02,0xE2,0x50,0x09,0xF4,0x67,0x00,0xF4,0x75,0x10,
|
||||
0xFF,0x9E,0x10,0xFF,0xAC,0x20,0xFF,0xBA,0x3A,0xFF,0xBF,0x50,
|
||||
0xFF,0xC6,0x6D,0xFF,0xD5,0x80,0xFF,0xE4,0x90,0xFF,0xE6,0x99,
|
||||
0x98,0x0C,0x0C,0x99,0x0C,0x0C,0xC2,0x13,0x00,0xD3,0x13,0x00,
|
||||
0xE2,0x35,0x00,0xE3,0x40,0x00,0xE4,0x40,0x20,0xE5,0x52,0x30,
|
||||
0xFD,0x78,0x54,0xFF,0x8A,0x6A,0xFF,0x98,0x7C,0xFF,0xA4,0x8B,
|
||||
0xFF,0xB3,0x9E,0xFF,0xC2,0xB2,0xFF,0xD0,0xBA,0xFF,0xD7,0xC0,
|
||||
0x99,0x00,0x00,0xA9,0x00,0x00,0xC2,0x04,0x00,0xD3,0x04,0x00,
|
||||
0xDA,0x04,0x00,0xDB,0x08,0x00,0xE4,0x20,0x20,0xF6,0x40,0x40,
|
||||
0xFB,0x70,0x70,0xFB,0x7E,0x7E,0xFB,0x8F,0x8F,0xFF,0x9F,0x9F,
|
||||
0xFF,0xAB,0xAB,0xFF,0xB9,0xB9,0xFF,0xC9,0xC9,0xFF,0xCF,0xCF,
|
||||
0x7E,0x00,0x50,0x80,0x00,0x50,0x80,0x00,0x5F,0x95,0x0B,0x74,
|
||||
0xAA,0x22,0x88,0xBB,0x2F,0x9A,0xCE,0x3F,0xAD,0xD7,0x5A,0xB6,
|
||||
0xE4,0x67,0xC3,0xEF,0x72,0xCE,0xFB,0x7E,0xDA,0xFF,0x8D,0xE1,
|
||||
0xFF,0x9D,0xE5,0xFF,0xA5,0xE7,0xFF,0xAF,0xEA,0xFF,0xB8,0xEC,
|
||||
0x48,0x00,0x6C,0x5C,0x04,0x88,0x65,0x0D,0x90,0x7B,0x23,0xA7,
|
||||
0x93,0x3B,0xBF,0x9D,0x45,0xC9,0xA7,0x4F,0xD3,0xB2,0x5A,0xDE,
|
||||
0xBD,0x65,0xE9,0xC5,0x6D,0xF1,0xCE,0x76,0xFA,0xD5,0x83,0xFF,
|
||||
0xDA,0x90,0xFF,0xDE,0x9C,0xFF,0xE2,0xA9,0xFF,0xE6,0xB6,0xFF,
|
||||
0x1B,0x00,0x70,0x22,0x1B,0x8D,0x37,0x30,0xA2,0x48,0x41,0xB3,
|
||||
0x59,0x52,0xC4,0x63,0x5C,0xCE,0x6F,0x68,0xDA,0x7D,0x76,0xE8,
|
||||
0x87,0x80,0xF8,0x93,0x8C,0xFF,0x9D,0x97,0xFF,0xA8,0xA3,0xFF,
|
||||
0xB3,0xAF,0xFF,0xBC,0xB8,0xFF,0xC4,0xC1,0xFF,0xDA,0xD1,0xFF,
|
||||
0x00,0x0D,0x7F,0x00,0x12,0xA7,0x00,0x18,0xC0,0x0A,0x2B,0xD1,
|
||||
0x1B,0x4A,0xE3,0x2F,0x58,0xF0,0x37,0x68,0xFF,0x49,0x79,0xFF,
|
||||
0x5B,0x85,0xFF,0x6D,0x96,0xFF,0x7F,0xA3,0xFF,0x8C,0xAD,0xFF,
|
||||
0x96,0xB4,0xFF,0xA8,0xC0,0xFF,0xB7,0xCB,0xFF,0xC6,0xD6,0xFF,
|
||||
0x00,0x29,0x5A,0x00,0x38,0x76,0x00,0x48,0x92,0x00,0x5C,0xAC,
|
||||
0x00,0x71,0xC6,0x00,0x86,0xD0,0x0A,0x9B,0xDF,0x1A,0xA8,0xEC,
|
||||
0x2B,0xB6,0xFF,0x3F,0xC2,0xFF,0x45,0xCB,0xFF,0x59,0xD3,0xFF,
|
||||
0x7F,0xDA,0xFF,0x8F,0xDE,0xFF,0xA0,0xE2,0xFF,0xB0,0xEB,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x4C,0x00,0x00,0x6A,0x20,0x50,0x8E,0x79,
|
||||
0x40,0x99,0x99,0x00,0x9C,0xAA,0x00,0xA1,0xBB,0x01,0xA4,0xCC,
|
||||
0x03,0xA5,0xD7,0x05,0xDA,0xE2,0x18,0xE5,0xFF,0x34,0xEA,0xFF,
|
||||
0x49,0xEF,0xFF,0x66,0xF2,0xFF,0x84,0xF4,0xFF,0x9E,0xF9,0xFF,
|
||||
0x00,0x4A,0x00,0x00,0x5D,0x00,0x00,0x70,0x00,0x00,0x83,0x00,
|
||||
0x00,0x95,0x00,0x00,0xAB,0x00,0x07,0xBD,0x07,0x0A,0xD0,0x0A,
|
||||
0x1A,0xD5,0x40,0x5A,0xF1,0x77,0x82,0xEF,0xA7,0x84,0xED,0xD1,
|
||||
0x89,0xFF,0xED,0x7D,0xFF,0xFF,0x93,0xFF,0xFF,0x9B,0xFF,0xFF,
|
||||
0x22,0x4A,0x03,0x27,0x53,0x04,0x30,0x64,0x05,0x3C,0x77,0x0C,
|
||||
0x45,0x8C,0x11,0x5A,0xA5,0x13,0x1B,0xD2,0x09,0x1F,0xDD,0x00,
|
||||
0x3D,0xCD,0x2D,0x3D,0xCD,0x30,0x58,0xCC,0x40,0x60,0xD3,0x50,
|
||||
0xA2,0xEC,0x55,0xB3,0xF2,0x4A,0xBB,0xF6,0x5D,0xC4,0xF8,0x70,
|
||||
0x2E,0x3F,0x0C,0x36,0x4A,0x0F,0x40,0x56,0x15,0x46,0x5F,0x17,
|
||||
0x57,0x77,0x1A,0x65,0x85,0x1C,0x74,0x93,0x1D,0x8F,0xA5,0x25,
|
||||
0xAD,0xB7,0x2C,0xBC,0xC7,0x30,0xC9,0xD5,0x33,0xD4,0xE0,0x3B,
|
||||
0xE0,0xEC,0x42,0xEA,0xF6,0x45,0xF0,0xFD,0x47,0xF4,0xFF,0x6F,
|
||||
0x55,0x24,0x00,0x5A,0x2C,0x00,0x6C,0x3B,0x00,0x79,0x4B,0x00,
|
||||
0xB9,0x75,0x00,0xBB,0x85,0x00,0xC1,0xA1,0x20,0xD0,0xB0,0x2F,
|
||||
0xDE,0xBE,0x3F,0xE6,0xC6,0x45,0xED,0xCD,0x57,0xF5,0xDB,0x62,
|
||||
0xFB,0xE5,0x69,0xFC,0xEE,0x6F,0xFD,0xF3,0x77,0xFD,0xF3,0x7F,
|
||||
0x5C,0x27,0x00,0x5C,0x2F,0x00,0x71,0x3B,0x00,0x7B,0x48,0x00,
|
||||
0xB9,0x68,0x20,0xBB,0x72,0x20,0xC5,0x86,0x29,0xD7,0x96,0x33,
|
||||
0xE6,0xA4,0x40,0xF4,0xB1,0x4B,0xFD,0xC1,0x58,0xFF,0xCC,0x55,
|
||||
0xFF,0xD4,0x61,0xFF,0xDD,0x69,0xFF,0xE6,0x79,0xFF,0xEA,0x98
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// PALETTE PAL
|
||||
// --------------------------------------------------------------------------------------
|
||||
static const byte REGION_PALETTE_PAL[ ] = {
|
||||
0x00,0x00,0x00,0x1c,0x1c,0x1c,0x39,0x39,0x39,0x59,0x59,0x59,
|
||||
0x79,0x79,0x79,0x92,0x92,0x92,0xab,0xab,0xab,0xbc,0xbc,0xbc,
|
||||
0xcd,0xcd,0xcd,0xd9,0xd9,0xd9,0xe6,0xe6,0xe6,0xec,0xec,0xec,
|
||||
0xf2,0xf2,0xf2,0xf8,0xf8,0xf8,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x26,0x30,0x01,0x24,0x38,0x03,0x23,0x40,0x05,0x51,0x54,0x1b,
|
||||
0x80,0x69,0x31,0x97,0x81,0x35,0xaf,0x99,0x3a,0xc2,0xa7,0x3e,
|
||||
0xd5,0xb5,0x43,0xdb,0xc0,0x3d,0xe1,0xcb,0x38,0xe2,0xd8,0x36,
|
||||
0xe3,0xe5,0x34,0xef,0xf2,0x58,0xfb,0xff,0x7d,0xfb,0xff,0x7d,
|
||||
0x39,0x17,0x01,0x5e,0x23,0x04,0x83,0x30,0x08,0xa5,0x47,0x16,
|
||||
0xc8,0x5f,0x24,0xe3,0x78,0x20,0xff,0x91,0x1d,0xff,0xab,0x1d,
|
||||
0xff,0xc5,0x1d,0xff,0xce,0x34,0xff,0xd8,0x4c,0xff,0xe6,0x51,
|
||||
0xff,0xf4,0x56,0xff,0xf9,0x77,0xff,0xff,0x98,0xff,0xff,0x98,
|
||||
0x45,0x19,0x04,0x72,0x1e,0x11,0x9f,0x24,0x1e,0xb3,0x3a,0x20,
|
||||
0xc8,0x51,0x22,0xe3,0x69,0x20,0xff,0x81,0x1e,0xff,0x8c,0x25,
|
||||
0xff,0x98,0x2c,0xff,0xae,0x38,0xff,0xc5,0x45,0xff,0xc5,0x59,
|
||||
0xff,0xc6,0x6d,0xff,0xd5,0x87,0xff,0xe4,0xa1,0xff,0xe4,0xa1,
|
||||
0x4a,0x17,0x04,0x7e,0x1a,0x0d,0xb2,0x1d,0x17,0xc8,0x21,0x19,
|
||||
0xdf,0x25,0x1c,0xec,0x3b,0x38,0xfa,0x52,0x55,0xfc,0x61,0x61,
|
||||
0xff,0x70,0x6e,0xff,0x7f,0x7e,0xff,0x8f,0x8f,0xff,0x9d,0x9e,
|
||||
0xff,0xab,0xad,0xff,0xb9,0xbd,0xff,0xc7,0xce,0xff,0xc7,0xce,
|
||||
0x05,0x05,0x68,0x3b,0x13,0x6d,0x71,0x22,0x72,0x8b,0x2a,0x8c,
|
||||
0xa5,0x32,0xa6,0xb9,0x38,0xba,0xcd,0x3e,0xcf,0xdb,0x47,0xdd,
|
||||
0xea,0x51,0xeb,0xf4,0x5f,0xf5,0xfe,0x6d,0xff,0xfe,0x7a,0xfd,
|
||||
0xff,0x87,0xfb,0xff,0x95,0xfd,0xff,0xa4,0xff,0xff,0xa4,0xff,
|
||||
0x28,0x04,0x79,0x40,0x09,0x84,0x59,0x0f,0x90,0x70,0x24,0x9d,
|
||||
0x88,0x39,0xaa,0xa4,0x41,0xc3,0xc0,0x4a,0xdc,0xd0,0x54,0xed,
|
||||
0xe0,0x5e,0xff,0xe9,0x6d,0xff,0xf2,0x7c,0xff,0xf8,0x8a,0xff,
|
||||
0xff,0x98,0xff,0xfe,0xa1,0xff,0xfe,0xab,0xff,0xfe,0xab,0xff,
|
||||
0x35,0x08,0x8a,0x42,0x0a,0xad,0x50,0x0c,0xd0,0x64,0x28,0xd0,
|
||||
0x79,0x45,0xd0,0x8d,0x4b,0xd4,0xa2,0x51,0xd9,0xb0,0x58,0xec,
|
||||
0xbe,0x60,0xff,0xc5,0x6b,0xff,0xcc,0x77,0xff,0xd1,0x83,0xff,
|
||||
0xd7,0x90,0xff,0xdb,0x9d,0xff,0xdf,0xaa,0xff,0xdf,0xaa,0xff,
|
||||
0x05,0x1e,0x81,0x06,0x26,0xa5,0x08,0x2f,0xca,0x26,0x3d,0xd4,
|
||||
0x44,0x4c,0xde,0x4f,0x5a,0xee,0x5a,0x68,0xff,0x65,0x75,0xff,
|
||||
0x71,0x83,0xff,0x80,0x91,0xff,0x90,0xa0,0xff,0x97,0xa9,0xff,
|
||||
0x9f,0xb2,0xff,0xaf,0xbe,0xff,0xc0,0xcb,0xff,0xc0,0xcb,0xff,
|
||||
0x05,0x1e,0x81,0x06,0x26,0xa5,0x08,0x2f,0xca,0x26,0x3d,0xd4,
|
||||
0x44,0x4c,0xde,0x4f,0x5a,0xee,0x5a,0x68,0xff,0x65,0x75,0xff,
|
||||
0x71,0x83,0xff,0x80,0x91,0xff,0x90,0xa0,0xff,0x97,0xa9,0xff,
|
||||
0x9f,0xb2,0xff,0xaf,0xbe,0xff,0xc0,0xcb,0xff,0xc0,0xcb,0xff,
|
||||
0x0c,0x04,0x8b,0x22,0x18,0xa0,0x38,0x2d,0xb5,0x48,0x3e,0xc7,
|
||||
0x58,0x4f,0xda,0x61,0x59,0xec,0x6b,0x64,0xff,0x7a,0x74,0xff,
|
||||
0x8a,0x84,0xff,0x91,0x8e,0xff,0x99,0x98,0xff,0xa5,0xa3,0xff,
|
||||
0xb1,0xae,0xff,0xb8,0xb8,0xff,0xc0,0xc2,0xff,0xc0,0xc2,0xff,
|
||||
0x1d,0x29,0x5a,0x1d,0x38,0x76,0x1d,0x48,0x92,0x1c,0x5c,0xac,
|
||||
0x1c,0x71,0xc6,0x32,0x86,0xcf,0x48,0x9b,0xd9,0x4e,0xa8,0xec,
|
||||
0x55,0xb6,0xff,0x70,0xc7,0xff,0x8c,0xd8,0xff,0x93,0xdb,0xff,
|
||||
0x9b,0xdf,0xff,0xaf,0xe4,0xff,0xc3,0xe9,0xff,0xc3,0xe9,0xff,
|
||||
0x2f,0x43,0x02,0x39,0x52,0x02,0x44,0x61,0x03,0x41,0x7a,0x12,
|
||||
0x3e,0x94,0x21,0x4a,0x9f,0x2e,0x57,0xab,0x3b,0x5c,0xbd,0x55,
|
||||
0x61,0xd0,0x70,0x69,0xe2,0x7a,0x72,0xf5,0x84,0x7c,0xfa,0x8d,
|
||||
0x87,0xff,0x97,0x9a,0xff,0xa6,0xad,0xff,0xb6,0xad,0xff,0xb6,
|
||||
0x0a,0x41,0x08,0x0d,0x54,0x0a,0x10,0x68,0x0d,0x13,0x7d,0x0f,
|
||||
0x16,0x92,0x12,0x19,0xa5,0x14,0x1c,0xb9,0x17,0x1e,0xc9,0x19,
|
||||
0x21,0xd9,0x1b,0x47,0xe4,0x2d,0x6e,0xf0,0x40,0x78,0xf7,0x4d,
|
||||
0x83,0xff,0x5b,0x9a,0xff,0x7a,0xb2,0xff,0x9a,0xb2,0xff,0x9a,
|
||||
0x04,0x41,0x0b,0x05,0x53,0x0e,0x06,0x66,0x11,0x07,0x77,0x14,
|
||||
0x08,0x88,0x17,0x09,0x9b,0x1a,0x0b,0xaf,0x1d,0x48,0xc4,0x1f,
|
||||
0x86,0xd9,0x22,0x8f,0xe9,0x24,0x99,0xf9,0x27,0xa8,0xfc,0x41,
|
||||
0xb7,0xff,0x5b,0xc9,0xff,0x6e,0xdc,0xff,0x81,0xdc,0xff,0x81,
|
||||
0x02,0x35,0x0f,0x07,0x3f,0x15,0x0c,0x4a,0x1c,0x2d,0x5f,0x1e,
|
||||
0x4f,0x74,0x20,0x59,0x83,0x24,0x64,0x92,0x28,0x82,0xa1,0x2e,
|
||||
0xa1,0xb0,0x34,0xa9,0xc1,0x3a,0xb2,0xd2,0x41,0xc4,0xd9,0x45,
|
||||
0xd6,0xe1,0x49,0xe4,0xf0,0x4e,0xf2,0xff,0x53,0xf2,0xff,0x53,
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void region_Reset( ) {
|
||||
if(region_type == REGION_PAL || (region_type == REGION_AUTO && cartridge_region == REGION_PAL)) {
|
||||
maria_displayArea = REGION_DISPLAY_AREA_PAL;
|
||||
maria_visibleArea = REGION_VISIBLE_AREA_PAL;
|
||||
if(palette_default)
|
||||
palette_Load(REGION_PALETTE_PAL); // Added check for default - bberlin
|
||||
prosystem_frequency = REGION_FREQUENCY_PAL;
|
||||
prosystem_scanlines = REGION_SCANLINES_PAL;
|
||||
tia_size = 624;
|
||||
pokey_size = 624;
|
||||
}
|
||||
else {
|
||||
maria_displayArea = REGION_DISPLAY_AREA_NTSC;
|
||||
maria_visibleArea = REGION_VISIBLE_AREA_NTSC;
|
||||
if(palette_default)
|
||||
palette_Load(REGION_PALETTE_NTSC); // Added check for default - bberlin
|
||||
prosystem_frequency = REGION_FREQUENCY_NTSC;
|
||||
prosystem_scanlines = REGION_SCANLINES_NTSC;
|
||||
tia_size = 524;
|
||||
pokey_size = 524;
|
||||
}
|
||||
}
|
44
core/Region.h
Executable file
44
core/Region.h
Executable file
@ -0,0 +1,44 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Region.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef REGION_H
|
||||
#define REGION_H
|
||||
#define REGION_NTSC 0
|
||||
#define REGION_PAL 1
|
||||
#define REGION_AUTO 2
|
||||
|
||||
#include "Cartridge.h"
|
||||
#include "ProSystem.h"
|
||||
#include "Maria.h"
|
||||
#include "Palette.h"
|
||||
#include "Tia.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void region_Reset( );
|
||||
extern byte region_type;
|
||||
|
||||
#endif
|
258
core/Riot.cpp
Executable file
258
core/Riot.cpp
Executable file
@ -0,0 +1,258 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Riot.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Riot.h"
|
||||
|
||||
bool riot_timing = false;
|
||||
word riot_timer = TIM64T;
|
||||
byte riot_intervals;
|
||||
|
||||
static byte riot_dra = 0;
|
||||
static byte riot_drb = 0;
|
||||
static bool riot_elapsed;
|
||||
static int riot_currentTime;
|
||||
static word riot_clocks;
|
||||
|
||||
void riot_Reset(void) {
|
||||
riot_SetDRA(0);
|
||||
riot_SetDRB(0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetInput
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
// | Offset | Controller | Control
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
// | 00 | Joystick 1 | Right
|
||||
// | 01 | Joystick 1 | Left
|
||||
// | 02 | Joystick 1 | Down
|
||||
// | 03 | Joystick 1 | Up
|
||||
// | 04 | Joystick 1 | Button 1
|
||||
// | 05 | Joystick 1 | Button 2
|
||||
// | 06 | Joystick 2 | Right
|
||||
// | 07 | Joystick 2 | Left
|
||||
// | 08 | Joystick 2 | Down
|
||||
// | 09 | Joystick 2 | Up
|
||||
// | 10 | Joystick 2 | Button 1
|
||||
// | 11 | Joystick 2 | Button 2
|
||||
// | 12 | Console | Reset
|
||||
// | 13 | Console | Select
|
||||
// | 14 | Console | Pause
|
||||
// | 15 | Console | Left Difficulty
|
||||
// | 16 | Console | Right Difficulty
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
void riot_SetInput(const byte* input) {
|
||||
|
||||
/*gdement: Comments are messy, but wanted to document how this all works.
|
||||
Changed this routine to support 1 vs 2 button modes.
|
||||
Also added the interaction of CTLSWA and DRA on the SWCHA output, and same for SWCHB.
|
||||
SWCHA is directionals. SWCHB is console switches and button mode.
|
||||
button signals are in high bits of INPT0-5.*/
|
||||
|
||||
memory_ram[SWCHA] = ((~memory_ram[CTLSWA]) | riot_dra); /*SWCHA as driven by RIOT*/
|
||||
/*now console switches will force bits to ground:*/
|
||||
if (input[0x00]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x80;
|
||||
if (input[0x01]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x40;
|
||||
if (input[0x02]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x20;
|
||||
if (input[0x03]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x10;
|
||||
if (input[0x06]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x08;
|
||||
if (input[0x07]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x04;
|
||||
if (input[0x08]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x02;
|
||||
if (input[0x09]) memory_ram[SWCHA] = memory_ram[SWCHA] &~ 0x01;
|
||||
/*Switches can always push the appropriate bit of SWCHA to ground, as in above code block.
|
||||
In addition, RIOT can be configured to drive ground even when switch is open.
|
||||
By doing this it's possible for real hardware to behave as if switches are permanently held (tested this).*/
|
||||
|
||||
|
||||
/*As with swcha, the value seen at SWCHB is derived from CTLSWB and DRB (an internal RIOT register)
|
||||
(Any write to SWCHB actually gets stored in DRB)
|
||||
If a given bit in CTLSWB is 0 (input mode), then RIOT puts a 1 on SWCHB.
|
||||
If bit in CTLSWB is 1 (output mode), then RIOT puts stored DRB value on SWCHB.
|
||||
The SWCHB outputs from RIOT can be overdriven to 0 by console switches.
|
||||
The CTLSWB/DRB interaction is important at bits 2 and 4, which control button mode for each player.
|
||||
Bit 5 appears unused, and other bits are the console switches.
|
||||
|
||||
CTLSWB DRB SWCHB result on button mode (for bits 2 and 4)
|
||||
------- --- ----- -----------------------------------------
|
||||
0 0 1 1 button mode - this is default state after boot
|
||||
0 1 1 1 button mode
|
||||
1 0 0 2 button mode
|
||||
1 1 1 1 button mode
|
||||
This chart was confirmed on hardware
|
||||
From the default state after boot, simply changing CTLSWB to 1 will result in 2 button mode.
|
||||
Some games rely on this, and don't actually store anything to SWCHB.*/
|
||||
|
||||
memory_ram[SWCHB] = ((~memory_ram[CTLSWB]) | riot_drb); /*SWCHB as driven by RIOT*/
|
||||
/*now the console switches can force certain bits to ground:*/
|
||||
if (input[0x0c]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x01;
|
||||
if (input[0x0d]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x02;
|
||||
if (input[0x0e]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x08;
|
||||
if (input[0x0f]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x40;
|
||||
if (input[0x10]) memory_ram[SWCHB] = memory_ram[SWCHB] &~ 0x80;
|
||||
|
||||
/*When in 1 button mode, only the legacy 2600 button signal is active. The others stay off.
|
||||
When in 2 button mode, only the new signals are active. 2600 button stays off. (tested)
|
||||
see: http://www.atariage.com/forums/index.php?showtopic=127162
|
||||
also see 7800 schematic and RIOT datasheet */
|
||||
|
||||
if(memory_ram[SWCHB] & 0x04) //first player in 1 button mode
|
||||
{
|
||||
memory_ram[INPT0] &= 0x7f; //new style buttons are always off in this mode
|
||||
memory_ram[INPT1] &= 0x7f;
|
||||
if(input[0x04] || input[0x05]) //in this mode, either button triggers only the legacy button signal
|
||||
{
|
||||
memory_ram[INPT4] &= 0x7f; //this button signal activates by turning off the high bit
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT4] |= 0x80;
|
||||
}
|
||||
}
|
||||
else //first player in 2 button mode
|
||||
{
|
||||
memory_ram[INPT4] |= 0x80; //2600 button is always off in this mode
|
||||
if(input[0x04]) //left button (button 1)
|
||||
{
|
||||
memory_ram[INPT1] |= 0x80; //these buttons activate by turning on the high bit.
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT1] &= 0x7f;
|
||||
}
|
||||
if(input[0x05]) //right button (button 2)
|
||||
{
|
||||
memory_ram[INPT0] |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT0] &= 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
/*now repeat for 2nd player*/
|
||||
if(memory_ram[SWCHB] & 0x10)
|
||||
{
|
||||
memory_ram[INPT2] &= 0x7f;
|
||||
memory_ram[INPT3] &= 0x7f;
|
||||
if(input[0x0a] || input[0x0b])
|
||||
{
|
||||
memory_ram[INPT5] &= 0x7f;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT5] |= 0x80;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT5] |= 0x80;
|
||||
if(input[0x0a])
|
||||
{
|
||||
memory_ram[INPT3] |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT3] &= 0x7f;
|
||||
}
|
||||
if(input[0x0b])
|
||||
{
|
||||
memory_ram[INPT2] |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
memory_ram[INPT2] &= 0x7f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* riot_setDRA(byte data) and riot_setDRB(byte data) gdement
|
||||
* -------------------------------------------------
|
||||
* Stores a value written to SWCHA/SWCHB into the RIOT's internal DRA/DRB registers.
|
||||
* These are distinct from what you see when reading SWCHA/SWCHB.
|
||||
***********************************************************************************/
|
||||
void riot_SetDRA(byte data) {
|
||||
riot_dra=data;
|
||||
}
|
||||
void riot_SetDRB(byte data) {
|
||||
riot_drb=data;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetTimer
|
||||
// ----------------------------------------------------------------------------
|
||||
void riot_SetTimer(word timer, byte intervals) {
|
||||
riot_timer = timer;
|
||||
riot_intervals = intervals;
|
||||
switch(timer) {
|
||||
case T1024T:
|
||||
riot_clocks = 1024;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM1T:
|
||||
riot_clocks = 1;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM8T:
|
||||
riot_clocks = 8;
|
||||
riot_timing = true;
|
||||
break;
|
||||
case TIM64T:
|
||||
riot_clocks = 64;
|
||||
riot_timing = true;
|
||||
break;
|
||||
}
|
||||
if(riot_timing) {
|
||||
riot_currentTime = riot_clocks * intervals;
|
||||
riot_elapsed = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// UpdateTimer
|
||||
// ----------------------------------------------------------------------------
|
||||
void riot_UpdateTimer(byte cycles) {
|
||||
riot_currentTime -= cycles;
|
||||
if(!riot_elapsed && riot_currentTime > 0) {
|
||||
memory_Write(INTIM, riot_currentTime / riot_clocks);
|
||||
}
|
||||
else {
|
||||
if(riot_elapsed) {
|
||||
if(riot_currentTime >= -255) {
|
||||
memory_Write(INTIM, riot_currentTime);
|
||||
}
|
||||
else {
|
||||
memory_Write(INTIM, 0);
|
||||
riot_timing = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
riot_currentTime = riot_clocks;
|
||||
memory_Write(INTIM, 0);
|
||||
memory_ram[INTFLG] |= 0x80;
|
||||
riot_elapsed = true;
|
||||
}
|
||||
}
|
||||
}
|
45
core/Riot.h
Executable file
45
core/Riot.h
Executable file
@ -0,0 +1,45 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Riot.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef RIOT_H
|
||||
#define RIOT_H
|
||||
|
||||
#include "Equates.h"
|
||||
#include "Memory.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void riot_Reset(void);
|
||||
extern void riot_SetInput(const byte* input);
|
||||
extern void riot_SetDRA(byte data);
|
||||
extern void riot_SetDRB(byte data);
|
||||
extern void riot_SetTimer(word timer, byte intervals);
|
||||
extern void riot_UpdateTimer(byte cycles);
|
||||
extern bool riot_timing;
|
||||
extern word riot_timer;
|
||||
extern byte riot_intervals;
|
||||
|
||||
#endif
|
1736
core/Sally.cpp
Executable file
1736
core/Sally.cpp
Executable file
File diff suppressed because it is too large
Load Diff
47
core/Sally.h
Executable file
47
core/Sally.h
Executable file
@ -0,0 +1,47 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Sally.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef SALLY_H
|
||||
#define SALLY_H
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Pair.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void sally_Reset( );
|
||||
extern uint sally_ExecuteInstruction( );
|
||||
extern uint sally_ExecuteRES( );
|
||||
extern uint sally_ExecuteNMI( );
|
||||
extern uint sally_ExecuteIRQ( );
|
||||
extern byte sally_a;
|
||||
extern byte sally_x;
|
||||
extern byte sally_y;
|
||||
extern byte sally_p;
|
||||
extern byte sally_s;
|
||||
extern pair sally_pc;
|
||||
|
||||
#endif
|
433
core/Sound.cpp
Executable file
433
core/Sound.cpp
Executable file
@ -0,0 +1,433 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Sound.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Sound.h"
|
||||
#define SOUND_LATENCY_SCALE 4
|
||||
|
||||
byte sound_latency = SOUND_LATENCY_VERY_LOW;
|
||||
|
||||
static const WAVEFORMATEX SOUND_DEFAULT_FORMAT = {WAVE_FORMAT_PCM, 1, 44100, 44100, 1, 8, 0};
|
||||
static LPDIRECTSOUND sound_dsound = NULL;
|
||||
static LPDIRECTSOUNDBUFFER sound_primaryBuffer = NULL;
|
||||
static LPDIRECTSOUNDBUFFER sound_buffer = NULL;
|
||||
static WAVEFORMATEX sound_format = SOUND_DEFAULT_FORMAT;
|
||||
static uint sound_counter = 0;
|
||||
static bool sound_muted = false;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSampleLength
|
||||
// ----------------------------------------------------------------------------
|
||||
static uint sound_GetSampleLength(uint length, uint unit, uint unitMax) {
|
||||
uint sampleLength = length / unitMax;
|
||||
uint sampleRemain = length % unitMax;
|
||||
if(sampleRemain != 0 && sampleRemain >= unit) {
|
||||
sampleLength++;
|
||||
}
|
||||
return sampleLength;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Resample
|
||||
// ----------------------------------------------------------------------------
|
||||
static void sound_Resample(const byte* source, byte* target, int length) {
|
||||
int measurement = sound_format.nSamplesPerSec;
|
||||
int sourceIndex = 0;
|
||||
int targetIndex = 0;
|
||||
|
||||
while(targetIndex < length) {
|
||||
if(measurement >= 31440) {
|
||||
target[targetIndex++] = source[sourceIndex];
|
||||
measurement -= 31440;
|
||||
}
|
||||
else {
|
||||
sourceIndex++;
|
||||
measurement += sound_format.nSamplesPerSec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// RestoreBuffer
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool sound_RestoreBuffer( ) {
|
||||
if(sound_buffer != NULL) {
|
||||
HRESULT hr = sound_buffer->Restore( );
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND1,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ReleaseBuffer
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool sound_ReleaseBuffer(LPDIRECTSOUNDBUFFER buffer) {
|
||||
if(buffer != NULL) {
|
||||
HRESULT hr = buffer->Release( );
|
||||
sound_buffer = NULL;
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND2,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ReleaseSound
|
||||
// ----------------------------------------------------------------------------
|
||||
static bool sound_ReleaseSound( ) {
|
||||
if(sound_dsound != NULL) {
|
||||
HRESULT hr = sound_dsound->Release( );
|
||||
sound_dsound = NULL;
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND3,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_Initialize(HWND hWnd) {
|
||||
if(hWnd == NULL) {
|
||||
logger_LogError(IDS_INPUT1,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = DirectSoundCreate(NULL, &sound_dsound, NULL);
|
||||
if(FAILED(hr) || sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND4,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = sound_dsound->SetCooperativeLevel(hWnd, DSSCL_PRIORITY);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_INPUT6,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
DSBUFFERDESC primaryDesc;
|
||||
primaryDesc.dwReserved = 0;
|
||||
primaryDesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
primaryDesc.dwBufferBytes = 0;
|
||||
primaryDesc.lpwfxFormat = NULL;
|
||||
|
||||
hr = sound_dsound->CreateSoundBuffer(&primaryDesc, &sound_primaryBuffer, NULL);
|
||||
if(FAILED(hr) || sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND5,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!sound_SetFormat(SOUND_DEFAULT_FORMAT)) {
|
||||
logger_LogError(IDS_SOUND6,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Leonis
|
||||
sound_SetSampleRate(samplerate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetFormat
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_SetFormat(WAVEFORMATEX format) {
|
||||
if(sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND7,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND8,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = sound_primaryBuffer->SetFormat(&format);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND9,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
DSBUFFERDESC secondaryDesc;
|
||||
secondaryDesc.dwReserved = 0;
|
||||
secondaryDesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS;
|
||||
secondaryDesc.dwBufferBytes = format.nSamplesPerSec;
|
||||
secondaryDesc.lpwfxFormat = &format;
|
||||
|
||||
hr = sound_dsound->CreateSoundBuffer(&secondaryDesc, &sound_buffer, NULL);
|
||||
if(FAILED(hr) || sound_buffer == NULL) {
|
||||
logger_LogError(IDS_SOUND10,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
sound_format = format;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Store
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_Store( ) {
|
||||
if(sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND7,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND8,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_buffer == NULL) {
|
||||
logger_LogError(IDS_SOUND11,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
byte sample[1920];
|
||||
uint length = sound_GetSampleLength(sound_format.nSamplesPerSec, prosystem_frame, prosystem_frequency);
|
||||
sound_Resample(tia_buffer, sample, length);
|
||||
|
||||
if(cartridge_pokey) {
|
||||
byte pokeySample[1920];
|
||||
sound_Resample(pokey_buffer, pokeySample, length);
|
||||
for(int index = 0; index < length; index++) {
|
||||
sample[index] += pokeySample[index];
|
||||
sample[index] = sample[index] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD lockCount = 0;
|
||||
byte* lockStream = NULL;
|
||||
DWORD wrapCount = 0;
|
||||
byte* wrapStream = NULL;
|
||||
|
||||
HRESULT hr = sound_buffer->Lock(sound_counter, length, (void**)&lockStream, &lockCount, (void**)&wrapStream, &wrapCount, 0);
|
||||
if(FAILED(hr) || lockStream == NULL) {
|
||||
logger_LogError(IDS_SOUND12,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint bufferCounter = 0;
|
||||
for(uint lockIndex = 0; lockIndex < lockCount; lockIndex++) {
|
||||
lockStream[lockIndex] = sample[bufferCounter++];
|
||||
}
|
||||
|
||||
for(uint wrapIndex = 0; wrapIndex < wrapCount; wrapIndex++) {
|
||||
wrapStream[wrapIndex] = sample[bufferCounter++];
|
||||
}
|
||||
|
||||
hr = sound_buffer->Unlock(lockStream, lockCount, wrapStream, wrapCount);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND13,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
sound_counter += length;
|
||||
if(sound_counter >= sound_format.nSamplesPerSec) {
|
||||
sound_counter -= sound_format.nSamplesPerSec;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_Clear( ) {
|
||||
if(sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND7,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND8,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_buffer == NULL) {
|
||||
logger_LogError(IDS_SOUND11,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
byte* lockStream = NULL;
|
||||
DWORD lockCount = 0;
|
||||
HRESULT hr = sound_buffer->Lock(0, sound_format.nSamplesPerSec, (void**)&lockStream, &lockCount, NULL, NULL, DSBLOCK_ENTIREBUFFER);
|
||||
if(FAILED(hr) || lockStream == NULL) {
|
||||
logger_LogError(IDS_SOUND12,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint lockIndex = 0; lockIndex < lockCount; lockIndex++) {
|
||||
lockStream[lockIndex] = 0;
|
||||
}
|
||||
|
||||
hr = sound_buffer->Unlock(lockStream, lockCount, NULL, NULL);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND13,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Play
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_Play( ) {
|
||||
if(sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND7,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND8,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_buffer == NULL) {
|
||||
logger_LogError(IDS_SOUND11,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!sound_muted) {
|
||||
HRESULT hr = sound_buffer->SetCurrentPosition(0);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND14,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = sound_buffer->Play(0, 0, DSBPLAY_LOOPING);
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND15,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
sound_counter = (sound_format.nSamplesPerSec / prosystem_frequency) * (sound_latency * SOUND_LATENCY_SCALE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Stop
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_Stop( ) {
|
||||
if(sound_dsound == NULL) {
|
||||
logger_LogError(IDS_SOUND7,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_primaryBuffer == NULL) {
|
||||
logger_LogError(IDS_SOUND8,"");
|
||||
return false;
|
||||
}
|
||||
if(sound_buffer == NULL) {
|
||||
logger_LogError(IDS_SOUND11,"");
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = sound_buffer->Stop( );
|
||||
if(FAILED(hr)) {
|
||||
logger_LogError(IDS_SOUND16,"");
|
||||
logger_LogError("",common_Format(hr));
|
||||
if(hr != DSERR_BUFFERLOST || !sound_RestoreBuffer( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetSampleRate
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_SetSampleRate(uint rate) {
|
||||
sound_format.nSamplesPerSec = rate;
|
||||
sound_format.nAvgBytesPerSec = rate;
|
||||
return sound_SetFormat(sound_format);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GetSampleRate
|
||||
// ----------------------------------------------------------------------------
|
||||
uint sound_GetSampleRate( ) {
|
||||
return sound_format.nSamplesPerSec;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetMuted
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_SetMuted(bool muted) {
|
||||
if(sound_muted != muted) {
|
||||
if(!muted) {
|
||||
if(!sound_Play( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!sound_Stop( )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
sound_muted = muted;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsMuted
|
||||
// ----------------------------------------------------------------------------
|
||||
bool sound_IsMuted( ) {
|
||||
return sound_muted;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Release
|
||||
// ----------------------------------------------------------------------------
|
||||
void sound_Release( ) {
|
||||
sound_ReleaseBuffer(sound_buffer);
|
||||
sound_ReleaseBuffer(sound_primaryBuffer);
|
||||
sound_ReleaseSound( );
|
||||
}
|
60
core/Sound.h
Executable file
60
core/Sound.h
Executable file
@ -0,0 +1,60 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Sound.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
#define SOUND_LATENCY_NONE 0
|
||||
#define SOUND_LATENCY_VERY_LOW 1
|
||||
#define SOUND_LATENCY_LOW 2
|
||||
#define SOUND_LATENCY_MEDIUM 3
|
||||
#define SOUND_LATENCY_HIGH 4
|
||||
#define SOUND_LATENCY_VERY_HIGH 5
|
||||
//#define NULL 0
|
||||
|
||||
//#include <DSound.h>
|
||||
#include "Common.h"
|
||||
#include "Logger.h"
|
||||
#include "ProSystem.h"
|
||||
#include "Configuration.h"
|
||||
#include "Tia.h"
|
||||
#include "Pokey.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern bool sound_Initialize(HWND hWnd);
|
||||
extern bool sound_Store( );
|
||||
extern bool sound_Clear( );
|
||||
extern bool sound_SetFormat(WAVEFORMATEX format);
|
||||
extern bool sound_Play( );
|
||||
extern bool sound_Stop( );
|
||||
extern bool sound_SetSampleRate(uint rate);
|
||||
extern uint sound_GetSampleRate( );
|
||||
extern bool sound_SetMuted(bool muted);
|
||||
extern bool sound_IsMuted( );
|
||||
extern void sound_Release( );
|
||||
extern byte sound_latency;
|
||||
|
||||
#endif
|
206
core/Tia.cpp
Executable file
206
core/Tia.cpp
Executable file
@ -0,0 +1,206 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// TiaSound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tia.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Tia.h"
|
||||
#define TIA_POLY4_SIZE 15
|
||||
#define TIA_POLY5_SIZE 31
|
||||
#define TIA_POLY9_SIZE 511
|
||||
|
||||
byte tia_buffer[TIA_BUFFER_SIZE] = {0};
|
||||
uint tia_size = 524;
|
||||
|
||||
static const byte TIA_POLY4[ ] = {1,1,0,1,1,1,0,0,0,0,1,0,1,0,0};
|
||||
static const byte TIA_POLY5[ ] = {0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1};
|
||||
static const byte TIA_POLY9[ ] = {0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,0,1,0,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,0,1,1,1,0,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,1,1,0,0,1,1,0,1,1,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1,1,0,1,0,0,0,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,0,0,1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,1,1,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,1,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,1,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,0,1,1,0,1,0,0,0,0,0,1,1,1,1,0,0,1,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,0,1,0,0,1,0,1,0,1,0,1,1,1,0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0};
|
||||
static const byte TIA_DIV31[ ] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
static byte tia_volume[2] = {0};
|
||||
static byte tia_counterMax[2] = {0};
|
||||
static byte tia_counter[2] = {0};
|
||||
static byte tia_audc[2] = {0};
|
||||
static byte tia_audf[2] = {0};
|
||||
static byte tia_audv[2] = {0};
|
||||
static uint tia_poly4Cntr[2] = {0};
|
||||
static uint tia_poly5Cntr[2] = {0};
|
||||
static uint tia_poly9Cntr[2] = {0};
|
||||
static uint tia_soundCntr = 0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ProcessChannel
|
||||
// ----------------------------------------------------------------------------
|
||||
static void tia_ProcessChannel(byte channel) {
|
||||
tia_poly5Cntr[channel]++;
|
||||
if(tia_poly5Cntr[channel] == TIA_POLY5_SIZE) {
|
||||
tia_poly5Cntr[channel] = 0;
|
||||
}
|
||||
if(((tia_audc[channel] & 2) == 0) || (((tia_audc[channel] & 1) == 0) && TIA_DIV31[tia_poly5Cntr[channel]]) || (((tia_audc[channel] & 1) == 1) && TIA_POLY5[tia_poly5Cntr[channel]])) {
|
||||
if(tia_audc[channel] & 4) {
|
||||
tia_volume[channel] = (!tia_volume[channel])? tia_audv[channel]: 0;
|
||||
}
|
||||
else if(tia_audc[channel] & 8) {
|
||||
if(tia_audc[channel] == 8) {
|
||||
tia_poly9Cntr[channel]++;
|
||||
if(tia_poly9Cntr[channel] == TIA_POLY9_SIZE) {
|
||||
tia_poly9Cntr[channel] = 0;
|
||||
}
|
||||
tia_volume[channel] = (TIA_POLY9[tia_poly9Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
else {
|
||||
tia_volume[channel] = (TIA_POLY5[tia_poly5Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tia_poly4Cntr[channel]++;
|
||||
if(tia_poly4Cntr[channel] == TIA_POLY4_SIZE) {
|
||||
tia_poly4Cntr[channel] = 0;
|
||||
}
|
||||
tia_volume[channel] = (TIA_POLY4[tia_poly4Cntr[channel]])? tia_audv[channel]: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Reset( ) {
|
||||
tia_soundCntr = 0;
|
||||
for(int index = 0; index < 2; index++) {
|
||||
tia_volume[index] = 0;
|
||||
tia_counterMax[index] = 0;
|
||||
tia_counter[index] = 0;
|
||||
tia_audc[index] = 0;
|
||||
tia_audf[index] = 0;
|
||||
tia_audv[index] = 0;
|
||||
tia_poly4Cntr[index] = 0;
|
||||
tia_poly5Cntr[index] = 0;
|
||||
tia_poly9Cntr[index] = 0;
|
||||
}
|
||||
tia_Clear( );
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Clear
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_Clear( ) {
|
||||
for(int index = 0; index < TIA_BUFFER_SIZE; index++) {
|
||||
tia_buffer[index] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetRegister
|
||||
// ----------------------------------------------------------------------------
|
||||
void tia_SetRegister(word address, byte data) {
|
||||
byte channel;
|
||||
byte frequency;
|
||||
|
||||
switch(address) {
|
||||
case AUDC0:
|
||||
tia_audc[0] = data & 15;
|
||||
channel = 0;
|
||||
break;
|
||||
case AUDC1:
|
||||
tia_audc[1] = data & 15;
|
||||
channel = 1;
|
||||
break;
|
||||
case AUDF0:
|
||||
tia_audf[0] = data & 31;
|
||||
channel = 0;
|
||||
break;
|
||||
case AUDF1:
|
||||
tia_audf[1] = data & 31;
|
||||
channel = 1;
|
||||
break;
|
||||
case AUDV0:
|
||||
tia_audv[0] = (data & 15) << 2;
|
||||
channel = 0;
|
||||
break;
|
||||
case AUDV1:
|
||||
tia_audv[1] = (data & 15) << 2;
|
||||
channel = 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if(tia_audc[channel] == 0) {
|
||||
frequency = 0;
|
||||
tia_volume[channel] = tia_audv[channel];
|
||||
}
|
||||
else {
|
||||
frequency = tia_audf[channel] + 1;
|
||||
if(tia_audc[channel] > 11) {
|
||||
frequency *= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(frequency != tia_counterMax[channel]) {
|
||||
tia_counterMax[channel] = frequency;
|
||||
if(tia_counter[channel] == 0 || frequency == 0) {
|
||||
tia_counter[channel] = frequency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Process
|
||||
// --------------------------------------------------------------------------------------
|
||||
void tia_Process(uint length) {
|
||||
for(uint index = 0; index < length; index++) {
|
||||
if(tia_counter[0] > 1) {
|
||||
tia_counter[0]--;
|
||||
}
|
||||
else if(tia_counter[0] == 1) {
|
||||
tia_counter[0] = tia_counterMax[0];
|
||||
tia_ProcessChannel(0);
|
||||
}
|
||||
if(tia_counter[1] > 1) {
|
||||
tia_counter[1]--;
|
||||
}
|
||||
else if(tia_counter[1] == 1) {
|
||||
tia_counter[1] = tia_counterMax[1];
|
||||
tia_ProcessChannel(1);
|
||||
}
|
||||
tia_buffer[tia_soundCntr++] = tia_volume[0] + tia_volume[1];
|
||||
if(tia_soundCntr >= tia_size) {
|
||||
tia_soundCntr = 0;
|
||||
}
|
||||
}
|
||||
}
|
58
core/Tia.h
Executable file
58
core/Tia.h
Executable file
@ -0,0 +1,58 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// TiaSound is Copyright(c) 1997 by Ron Fries
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of version 2 of the GNU Library General Public License
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
|
||||
// General Public License for more details.
|
||||
// To obtain a copy of the GNU Library General Public License, write to the
|
||||
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// Any permitted reproduction of these routines, in whole or in part, must
|
||||
// bear this legend.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Tia.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef TIA_H
|
||||
#define TIA_H
|
||||
#define TIA_BUFFER_SIZE 624
|
||||
|
||||
#include "Equates.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int uint;
|
||||
|
||||
extern void tia_Reset( );
|
||||
extern void tia_SetRegister(word address, byte data);
|
||||
extern void tia_Clear( );
|
||||
extern void tia_Process(uint length);
|
||||
extern byte tia_buffer[TIA_BUFFER_SIZE];
|
||||
extern uint tia_size;
|
||||
|
||||
#endif
|
76
core/Timer.cpp
Executable file
76
core/Timer.cpp
Executable file
@ -0,0 +1,76 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Timer.cpp
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Timer.h"
|
||||
|
||||
typedef unsigned long long uInt64;
|
||||
|
||||
static uInt64 timer_currentTime;
|
||||
static uInt64 timer_nextTime;
|
||||
static uInt64 timer_counterFrequency;
|
||||
static uint timer_frameTime;
|
||||
static bool timer_usingCounter = false;
|
||||
# if 0
|
||||
// ----------------------------------------------------------------------------
|
||||
// Initialize
|
||||
// ----------------------------------------------------------------------------
|
||||
void timer_Initialize( ) {
|
||||
timer_usingCounter = (QueryPerformanceFrequency((LARGE_INTEGER*)&timer_counterFrequency))? true: false;
|
||||
timeBeginPeriod(1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset
|
||||
// ----------------------------------------------------------------------------
|
||||
void timer_Reset( ) {
|
||||
if(timer_usingCounter) {
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&timer_nextTime);
|
||||
timer_frameTime = timer_counterFrequency / prosystem_frequency;
|
||||
timer_nextTime += timer_frameTime;
|
||||
}
|
||||
else {
|
||||
timer_frameTime = (1000.0 / (double)prosystem_frequency) * 1000;
|
||||
timer_currentTime = timeGetTime( ) * 1000;
|
||||
timer_nextTime = timer_currentTime + timer_frameTime;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// IsTime
|
||||
// ----------------------------------------------------------------------------
|
||||
bool timer_IsTime( ) {
|
||||
if(timer_usingCounter) {
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&timer_currentTime);
|
||||
}
|
||||
else {
|
||||
timer_currentTime = timeGetTime( ) * 1000;
|
||||
}
|
||||
|
||||
if(timer_currentTime >= timer_nextTime) {
|
||||
timer_nextTime += timer_frameTime;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
# endif
|
36
core/Timer.h
Executable file
36
core/Timer.h
Executable file
@ -0,0 +1,36 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// ___ ___ ___ ___ ___ ____ ___ _ _
|
||||
// /__/ /__/ / / /__ /__/ /__ / /_ / |/ /
|
||||
// / / \ /__/ ___/ ___/ ___/ / /__ / / emulator
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright 2005 Greg Stanton
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
// ----------------------------------------------------------------------------
|
||||
// Timer.h
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include "ProSystem.h"
|
||||
#include "Logger.h"
|
||||
#include "Common.h"
|
||||
|
||||
extern void timer_Initialize( );
|
||||
extern void timer_Reset( );
|
||||
extern bool timer_IsTime( );
|
||||
|
||||
#endif
|
132
core/lib/Crypt.h
Executable file
132
core/lib/Crypt.h
Executable file
@ -0,0 +1,132 @@
|
||||
/* crypt.h -- base code for crypt/uncrypt ZIPfile
|
||||
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This code is a modified version of crypting code in Infozip distribution
|
||||
|
||||
The encryption/decryption parts of this source code (as opposed to the
|
||||
non-echoing password parts) were originally written in Europe. The
|
||||
whole source package can be freely distributed, including from the USA.
|
||||
(Prior to January 2000, re-export from the US was a violation of US law.)
|
||||
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
|
||||
If you don't need crypting in your application, just define symbols
|
||||
NOCRYPT and NOUNCRYPT.
|
||||
|
||||
This code support the "Traditional PKWARE Encryption".
|
||||
|
||||
The new AES encryption added on Zip format by Winzip (see the page
|
||||
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
|
||||
Encryption is not supported.
|
||||
*/
|
||||
|
||||
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)
|
||||
{
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
|
||||
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
|
||||
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Update the encryption keys with the next byte of plain text
|
||||
*/
|
||||
static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
|
||||
{
|
||||
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
|
||||
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
|
||||
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
|
||||
{
|
||||
register int keyshift = (int)((*(pkeys+1)) >> 24);
|
||||
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialize the encryption keys and the random header according to
|
||||
* the given password.
|
||||
*/
|
||||
static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
|
||||
{
|
||||
*(pkeys+0) = 305419896L;
|
||||
*(pkeys+1) = 591751049L;
|
||||
*(pkeys+2) = 878082192L;
|
||||
while (*passwd != '\0') {
|
||||
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
|
||||
passwd++;
|
||||
}
|
||||
}
|
||||
|
||||
#define zdecode(pkeys,pcrc_32_tab,c) \
|
||||
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
|
||||
|
||||
#define zencode(pkeys,pcrc_32_tab,c,t) \
|
||||
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
|
||||
|
||||
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
|
||||
|
||||
#define RAND_HEAD_LEN 12
|
||||
/* "last resort" source for second part of crypt seed pattern */
|
||||
# ifndef ZCR_SEED2
|
||||
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
|
||||
# endif
|
||||
|
||||
static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
|
||||
const char *passwd; /* password string */
|
||||
unsigned char *buf; /* where to write header */
|
||||
int bufSize;
|
||||
unsigned long* pkeys;
|
||||
const unsigned long* pcrc_32_tab;
|
||||
unsigned long crcForCrypting;
|
||||
{
|
||||
int n; /* index in random header */
|
||||
int t; /* temporary */
|
||||
int c; /* random byte */
|
||||
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
|
||||
static unsigned calls = 0; /* ensure different random header each time */
|
||||
|
||||
if (bufSize<RAND_HEAD_LEN)
|
||||
return 0;
|
||||
|
||||
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
|
||||
* output of rand() to get less predictability, since rand() is
|
||||
* often poorly implemented.
|
||||
*/
|
||||
if (++calls == 1)
|
||||
{
|
||||
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
|
||||
}
|
||||
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++)
|
||||
{
|
||||
c = (rand() >> 7) & 0xff;
|
||||
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
|
||||
}
|
||||
/* Encrypt random header (last two bytes is high word of crc) */
|
||||
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++)
|
||||
{
|
||||
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
|
||||
}
|
||||
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
|
||||
buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
426
core/lib/HtmlHelp.h
Executable file
426
core/lib/HtmlHelp.h
Executable file
@ -0,0 +1,426 @@
|
||||
/****************************************************************************
|
||||
* *
|
||||
* HtmlHelp.h *
|
||||
* *
|
||||
* Copyright (c) 1996-1997, Microsoft Corp. All rights reserved. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef __HTMLHELP_H__
|
||||
#define __HTMLHELP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Defines for Win64
|
||||
#ifndef _WIN64
|
||||
#define DWORD_PTR DWORD
|
||||
#endif
|
||||
|
||||
// Commands to pass to HtmlHelp()
|
||||
|
||||
#define HH_DISPLAY_TOPIC 0x0000
|
||||
#define HH_HELP_FINDER 0x0000 // WinHelp equivalent
|
||||
#define HH_DISPLAY_TOC 0x0001
|
||||
#define HH_DISPLAY_INDEX 0x0002
|
||||
#define HH_DISPLAY_SEARCH 0x0003
|
||||
#define HH_SET_WIN_TYPE 0x0004
|
||||
#define HH_GET_WIN_TYPE 0x0005
|
||||
#define HH_GET_WIN_HANDLE 0x0006
|
||||
#define HH_ENUM_INFO_TYPE 0x0007 // Get Info type name, call repeatedly to enumerate, -1 at end
|
||||
#define HH_SET_INFO_TYPE 0x0008 // Add Info type to filter.
|
||||
#define HH_SYNC 0x0009
|
||||
#define HH_RESERVED1 0x000A
|
||||
#define HH_RESERVED2 0x000B
|
||||
#define HH_RESERVED3 0x000C
|
||||
#define HH_KEYWORD_LOOKUP 0x000D
|
||||
#define HH_DISPLAY_TEXT_POPUP 0x000E // display string resource id or text in a popup window
|
||||
#define HH_HELP_CONTEXT 0x000F // display mapped numeric value in dwData
|
||||
#define HH_TP_HELP_CONTEXTMENU 0x0010 // text popup help, same as WinHelp HELP_CONTEXTMENU
|
||||
#define HH_TP_HELP_WM_HELP 0x0011 // text popup help, same as WinHelp HELP_WM_HELP
|
||||
#define HH_CLOSE_ALL 0x0012 // close all windows opened directly or indirectly by the caller
|
||||
#define HH_ALINK_LOOKUP 0x0013 // ALink version of HH_KEYWORD_LOOKUP
|
||||
#define HH_GET_LAST_ERROR 0x0014 // not currently implemented // See HHERROR.h
|
||||
#define HH_ENUM_CATEGORY 0x0015 // Get category name, call repeatedly to enumerate, -1 at end
|
||||
#define HH_ENUM_CATEGORY_IT 0x0016 // Get category info type members, call repeatedly to enumerate, -1 at end
|
||||
#define HH_RESET_IT_FILTER 0x0017 // Clear the info type filter of all info types.
|
||||
#define HH_SET_INCLUSIVE_FILTER 0x0018 // set inclusive filtering method for untyped topics to be included in display
|
||||
#define HH_SET_EXCLUSIVE_FILTER 0x0019 // set exclusive filtering method for untyped topics to be excluded from display
|
||||
#define HH_INITIALIZE 0x001C // Initializes the help system.
|
||||
#define HH_UNINITIALIZE 0x001D // Uninitializes the help system.
|
||||
#define HH_PRETRANSLATEMESSAGE 0x00fd // Pumps messages. (NULL, NULL, MSG*).
|
||||
#define HH_SET_GLOBAL_PROPERTY 0x00fc // Set a global property. (NULL, NULL, HH_GPROP)
|
||||
|
||||
#define HHWIN_PROP_TAB_AUTOHIDESHOW (1 << 0) // Automatically hide/show tri-pane window
|
||||
#define HHWIN_PROP_ONTOP (1 << 1) // Top-most window
|
||||
#define HHWIN_PROP_NOTITLEBAR (1 << 2) // no title bar
|
||||
#define HHWIN_PROP_NODEF_STYLES (1 << 3) // no default window styles (only HH_WINTYPE.dwStyles)
|
||||
#define HHWIN_PROP_NODEF_EXSTYLES (1 << 4) // no default extended window styles (only HH_WINTYPE.dwExStyles)
|
||||
#define HHWIN_PROP_TRI_PANE (1 << 5) // use a tri-pane window
|
||||
#define HHWIN_PROP_NOTB_TEXT (1 << 6) // no text on toolbar buttons
|
||||
#define HHWIN_PROP_POST_QUIT (1 << 7) // post WM_QUIT message when window closes
|
||||
#define HHWIN_PROP_AUTO_SYNC (1 << 8) // automatically ssync contents and index
|
||||
#define HHWIN_PROP_TRACKING (1 << 9) // send tracking notification messages
|
||||
#define HHWIN_PROP_TAB_SEARCH (1 << 10) // include search tab in navigation pane
|
||||
#define HHWIN_PROP_TAB_HISTORY (1 << 11) // include history tab in navigation pane
|
||||
#define HHWIN_PROP_TAB_FAVORITES (1 << 12) // include favorites tab in navigation pane
|
||||
#define HHWIN_PROP_CHANGE_TITLE (1 << 13) // Put current HTML title in title bar
|
||||
#define HHWIN_PROP_NAV_ONLY_WIN (1 << 14) // Only display the navigation window
|
||||
#define HHWIN_PROP_NO_TOOLBAR (1 << 15) // Don't display a toolbar
|
||||
#define HHWIN_PROP_MENU (1 << 16) // Menu
|
||||
#define HHWIN_PROP_TAB_ADVSEARCH (1 << 17) // Advanced FTS UI.
|
||||
#define HHWIN_PROP_USER_POS (1 << 18) // After initial creation, user controls window size/position
|
||||
#define HHWIN_PROP_TAB_CUSTOM1 (1 << 19) // Use custom tab #1
|
||||
#define HHWIN_PROP_TAB_CUSTOM2 (1 << 20) // Use custom tab #2
|
||||
#define HHWIN_PROP_TAB_CUSTOM3 (1 << 21) // Use custom tab #3
|
||||
#define HHWIN_PROP_TAB_CUSTOM4 (1 << 22) // Use custom tab #4
|
||||
#define HHWIN_PROP_TAB_CUSTOM5 (1 << 23) // Use custom tab #5
|
||||
#define HHWIN_PROP_TAB_CUSTOM6 (1 << 24) // Use custom tab #6
|
||||
#define HHWIN_PROP_TAB_CUSTOM7 (1 << 25) // Use custom tab #7
|
||||
#define HHWIN_PROP_TAB_CUSTOM8 (1 << 26) // Use custom tab #8
|
||||
#define HHWIN_PROP_TAB_CUSTOM9 (1 << 27) // Use custom tab #9
|
||||
#define HHWIN_TB_MARGIN (1 << 28) // the window type has a margin
|
||||
|
||||
#define HHWIN_PARAM_PROPERTIES (1 << 1) // valid fsWinProperties
|
||||
#define HHWIN_PARAM_STYLES (1 << 2) // valid dwStyles
|
||||
#define HHWIN_PARAM_EXSTYLES (1 << 3) // valid dwExStyles
|
||||
#define HHWIN_PARAM_RECT (1 << 4) // valid rcWindowPos
|
||||
#define HHWIN_PARAM_NAV_WIDTH (1 << 5) // valid iNavWidth
|
||||
#define HHWIN_PARAM_SHOWSTATE (1 << 6) // valid nShowState
|
||||
#define HHWIN_PARAM_INFOTYPES (1 << 7) // valid apInfoTypes
|
||||
#define HHWIN_PARAM_TB_FLAGS (1 << 8) // valid fsToolBarFlags
|
||||
#define HHWIN_PARAM_EXPANSION (1 << 9) // valid fNotExpanded
|
||||
#define HHWIN_PARAM_TABPOS (1 << 10) // valid tabpos
|
||||
#define HHWIN_PARAM_TABORDER (1 << 11) // valid taborder
|
||||
#define HHWIN_PARAM_HISTORY_COUNT (1 << 12) // valid cHistory
|
||||
#define HHWIN_PARAM_CUR_TAB (1 << 13) // valid curNavType
|
||||
|
||||
#define HHWIN_BUTTON_EXPAND (1 << 1) // Expand/contract button
|
||||
#define HHWIN_BUTTON_BACK (1 << 2) // Back button
|
||||
#define HHWIN_BUTTON_FORWARD (1 << 3) // Forward button
|
||||
#define HHWIN_BUTTON_STOP (1 << 4) // Stop button
|
||||
#define HHWIN_BUTTON_REFRESH (1 << 5) // Refresh button
|
||||
#define HHWIN_BUTTON_HOME (1 << 6) // Home button
|
||||
#define HHWIN_BUTTON_BROWSE_FWD (1 << 7) // not implemented
|
||||
#define HHWIN_BUTTON_BROWSE_BCK (1 << 8) // not implemented
|
||||
#define HHWIN_BUTTON_NOTES (1 << 9) // not implemented
|
||||
#define HHWIN_BUTTON_CONTENTS (1 << 10) // not implemented
|
||||
#define HHWIN_BUTTON_SYNC (1 << 11) // Sync button
|
||||
#define HHWIN_BUTTON_OPTIONS (1 << 12) // Options button
|
||||
#define HHWIN_BUTTON_PRINT (1 << 13) // Print button
|
||||
#define HHWIN_BUTTON_INDEX (1 << 14) // not implemented
|
||||
#define HHWIN_BUTTON_SEARCH (1 << 15) // not implemented
|
||||
#define HHWIN_BUTTON_HISTORY (1 << 16) // not implemented
|
||||
#define HHWIN_BUTTON_FAVORITES (1 << 17) // not implemented
|
||||
#define HHWIN_BUTTON_JUMP1 (1 << 18)
|
||||
#define HHWIN_BUTTON_JUMP2 (1 << 19)
|
||||
#define HHWIN_BUTTON_ZOOM (1 << 20)
|
||||
#define HHWIN_BUTTON_TOC_NEXT (1 << 21)
|
||||
#define HHWIN_BUTTON_TOC_PREV (1 << 22)
|
||||
|
||||
#define HHWIN_DEF_BUTTONS \
|
||||
(HHWIN_BUTTON_EXPAND | \
|
||||
HHWIN_BUTTON_BACK | \
|
||||
HHWIN_BUTTON_OPTIONS | \
|
||||
HHWIN_BUTTON_PRINT)
|
||||
|
||||
// Button IDs
|
||||
|
||||
#define IDTB_EXPAND 200
|
||||
#define IDTB_CONTRACT 201
|
||||
#define IDTB_STOP 202
|
||||
#define IDTB_REFRESH 203
|
||||
#define IDTB_BACK 204
|
||||
#define IDTB_HOME 205
|
||||
#define IDTB_SYNC 206
|
||||
#define IDTB_PRINT 207
|
||||
#define IDTB_OPTIONS 208
|
||||
#define IDTB_FORWARD 209
|
||||
#define IDTB_NOTES 210 // not implemented
|
||||
#define IDTB_BROWSE_FWD 211
|
||||
#define IDTB_BROWSE_BACK 212
|
||||
#define IDTB_CONTENTS 213 // not implemented
|
||||
#define IDTB_INDEX 214 // not implemented
|
||||
#define IDTB_SEARCH 215 // not implemented
|
||||
#define IDTB_HISTORY 216 // not implemented
|
||||
#define IDTB_FAVORITES 217 // not implemented
|
||||
#define IDTB_JUMP1 218
|
||||
#define IDTB_JUMP2 219
|
||||
#define IDTB_CUSTOMIZE 221
|
||||
#define IDTB_ZOOM 222
|
||||
#define IDTB_TOC_NEXT 223
|
||||
#define IDTB_TOC_PREV 224
|
||||
|
||||
// Notification codes
|
||||
|
||||
#define HHN_FIRST (0U-860U)
|
||||
#define HHN_LAST (0U-879U)
|
||||
|
||||
#define HHN_NAVCOMPLETE (HHN_FIRST-0)
|
||||
#define HHN_TRACK (HHN_FIRST-1)
|
||||
#define HHN_WINDOW_CREATE (HHN_FIRST-2)
|
||||
|
||||
typedef struct tagHHN_NOTIFY
|
||||
{
|
||||
NMHDR hdr;
|
||||
PCSTR pszUrl; // Multi-byte, null-terminated string
|
||||
} HHN_NOTIFY;
|
||||
|
||||
typedef struct tagHH_POPUP
|
||||
{
|
||||
int cbStruct; // sizeof this structure
|
||||
HINSTANCE hinst; // instance handle for string resource
|
||||
UINT idString; // string resource id, or text id if pszFile is specified in HtmlHelp call
|
||||
LPCTSTR pszText; // used if idString is zero
|
||||
POINT pt; // top center of popup window
|
||||
COLORREF clrForeground; // use -1 for default
|
||||
COLORREF clrBackground; // use -1 for default
|
||||
RECT rcMargins; // amount of space between edges of window and text, -1 for each member to ignore
|
||||
LPCTSTR pszFont; // facename, point size, char set, BOLD ITALIC UNDERLINE
|
||||
} HH_POPUP;
|
||||
|
||||
typedef struct tagHH_AKLINK
|
||||
{
|
||||
int cbStruct; // sizeof this structure
|
||||
BOOL fReserved; // must be FALSE (really!)
|
||||
LPCTSTR pszKeywords; // semi-colon separated keywords
|
||||
LPCTSTR pszUrl; // URL to jump to if no keywords found (may be NULL)
|
||||
LPCTSTR pszMsgText; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
|
||||
LPCTSTR pszMsgTitle; // Message text to display in MessageBox if pszUrl is NULL and no keyword match
|
||||
LPCTSTR pszWindow; // Window to display URL in
|
||||
BOOL fIndexOnFail; // Displays index if keyword lookup fails.
|
||||
} HH_AKLINK;
|
||||
|
||||
enum {
|
||||
HHWIN_NAVTYPE_TOC,
|
||||
HHWIN_NAVTYPE_INDEX,
|
||||
HHWIN_NAVTYPE_SEARCH,
|
||||
HHWIN_NAVTYPE_FAVORITES,
|
||||
HHWIN_NAVTYPE_HISTORY, // not implemented
|
||||
HHWIN_NAVTYPE_AUTHOR,
|
||||
HHWIN_NAVTYPE_CUSTOM_FIRST = 11
|
||||
};
|
||||
|
||||
enum {
|
||||
IT_INCLUSIVE,
|
||||
IT_EXCLUSIVE,
|
||||
IT_HIDDEN,
|
||||
};
|
||||
|
||||
typedef struct tagHH_ENUM_IT
|
||||
{
|
||||
int cbStruct; // size of this structure
|
||||
int iType; // the type of the information type ie. Inclusive, Exclusive, or Hidden
|
||||
LPCSTR pszCatName; // Set to the name of the Category to enumerate the info types in a category; else NULL
|
||||
LPCSTR pszITName; // volitile pointer to the name of the infotype. Allocated by call. Caller responsible for freeing
|
||||
LPCSTR pszITDescription; // volitile pointer to the description of the infotype.
|
||||
} HH_ENUM_IT, *PHH_ENUM_IT;
|
||||
|
||||
typedef struct tagHH_ENUM_CAT
|
||||
{
|
||||
int cbStruct; // size of this structure
|
||||
LPCSTR pszCatName; // volitile pointer to the category name
|
||||
LPCSTR pszCatDescription; // volitile pointer to the category description
|
||||
} HH_ENUM_CAT, *PHH_ENUM_CAT;
|
||||
|
||||
typedef struct tagHH_SET_INFOTYPE
|
||||
{
|
||||
int cbStruct; // the size of this structure
|
||||
LPCSTR pszCatName; // the name of the category, if any, the InfoType is a member of.
|
||||
LPCSTR pszInfoTypeName; // the name of the info type to add to the filter
|
||||
} HH_SET_INFOTYPE, *PHH_SET_INFOTYPE;
|
||||
|
||||
typedef DWORD HH_INFOTYPE;
|
||||
typedef HH_INFOTYPE* PHH_INFOTYPE;
|
||||
|
||||
enum {
|
||||
HHWIN_NAVTAB_TOP,
|
||||
HHWIN_NAVTAB_LEFT,
|
||||
HHWIN_NAVTAB_BOTTOM,
|
||||
};
|
||||
|
||||
#define HH_MAX_TABS 19 // maximum number of tabs
|
||||
|
||||
enum {
|
||||
HH_TAB_CONTENTS,
|
||||
HH_TAB_INDEX,
|
||||
HH_TAB_SEARCH,
|
||||
HH_TAB_FAVORITES,
|
||||
HH_TAB_HISTORY,
|
||||
HH_TAB_AUTHOR,
|
||||
|
||||
HH_TAB_CUSTOM_FIRST = 11,
|
||||
HH_TAB_CUSTOM_LAST = HH_MAX_TABS
|
||||
};
|
||||
|
||||
#define HH_MAX_TABS_CUSTOM (HH_TAB_CUSTOM_LAST - HH_TAB_CUSTOM_FIRST + 1)
|
||||
|
||||
// HH_DISPLAY_SEARCH Command Related Structures and Constants
|
||||
|
||||
#define HH_FTS_DEFAULT_PROXIMITY (-1)
|
||||
|
||||
typedef struct tagHH_FTS_QUERY
|
||||
{
|
||||
int cbStruct; // Sizeof structure in bytes.
|
||||
BOOL fUniCodeStrings; // TRUE if all strings are unicode.
|
||||
LPCTSTR pszSearchQuery; // String containing the search query.
|
||||
LONG iProximity; // Word proximity.
|
||||
BOOL fStemmedSearch; // TRUE for StemmedSearch only.
|
||||
BOOL fTitleOnly; // TRUE for Title search only.
|
||||
BOOL fExecute; // TRUE to initiate the search.
|
||||
LPCTSTR pszWindow; // Window to display in
|
||||
} HH_FTS_QUERY;
|
||||
|
||||
// HH_WINTYPE Structure
|
||||
|
||||
typedef struct tagHH_WINTYPE {
|
||||
int cbStruct; // IN: size of this structure including all Information Types
|
||||
BOOL fUniCodeStrings; // IN/OUT: TRUE if all strings are in UNICODE
|
||||
LPCTSTR pszType; // IN/OUT: Name of a type of window
|
||||
DWORD fsValidMembers; // IN: Bit flag of valid members (HHWIN_PARAM_)
|
||||
DWORD fsWinProperties; // IN/OUT: Properties/attributes of the window (HHWIN_)
|
||||
|
||||
LPCTSTR pszCaption; // IN/OUT: Window title
|
||||
DWORD dwStyles; // IN/OUT: Window styles
|
||||
DWORD dwExStyles; // IN/OUT: Extended Window styles
|
||||
RECT rcWindowPos; // IN: Starting position, OUT: current position
|
||||
int nShowState; // IN: show state (e.g., SW_SHOW)
|
||||
|
||||
HWND hwndHelp; // OUT: window handle
|
||||
HWND hwndCaller; // OUT: who called this window
|
||||
|
||||
HH_INFOTYPE* paInfoTypes; // IN: Pointer to an array of Information Types
|
||||
|
||||
// The following members are only valid if HHWIN_PROP_TRI_PANE is set
|
||||
|
||||
HWND hwndToolBar; // OUT: toolbar window in tri-pane window
|
||||
HWND hwndNavigation; // OUT: navigation window in tri-pane window
|
||||
HWND hwndHTML; // OUT: window displaying HTML in tri-pane window
|
||||
int iNavWidth; // IN/OUT: width of navigation window
|
||||
RECT rcHTML; // OUT: HTML window coordinates
|
||||
|
||||
LPCTSTR pszToc; // IN: Location of the table of contents file
|
||||
LPCTSTR pszIndex; // IN: Location of the index file
|
||||
LPCTSTR pszFile; // IN: Default location of the html file
|
||||
LPCTSTR pszHome; // IN/OUT: html file to display when Home button is clicked
|
||||
DWORD fsToolBarFlags; // IN: flags controling the appearance of the toolbar
|
||||
BOOL fNotExpanded; // IN: TRUE/FALSE to contract or expand, OUT: current state
|
||||
int curNavType; // IN/OUT: UI to display in the navigational pane
|
||||
int tabpos; // IN/OUT: HHWIN_NAVTAB_TOP, HHWIN_NAVTAB_LEFT, or HHWIN_NAVTAB_BOTTOM
|
||||
int idNotify; // IN: ID to use for WM_NOTIFY messages
|
||||
BYTE tabOrder[HH_MAX_TABS + 1]; // IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs
|
||||
int cHistory; // IN/OUT: number of history items to keep (default is 30)
|
||||
LPCTSTR pszJump1; // Text for HHWIN_BUTTON_JUMP1
|
||||
LPCTSTR pszJump2; // Text for HHWIN_BUTTON_JUMP2
|
||||
LPCTSTR pszUrlJump1; // URL for HHWIN_BUTTON_JUMP1
|
||||
LPCTSTR pszUrlJump2; // URL for HHWIN_BUTTON_JUMP2
|
||||
RECT rcMinSize; // Minimum size for window (ignored in version 1)
|
||||
int cbInfoTypes; // size of paInfoTypes;
|
||||
LPCTSTR pszCustomTabs; // multiple zero-terminated strings
|
||||
} HH_WINTYPE, *PHH_WINTYPE;
|
||||
|
||||
enum {
|
||||
HHACT_TAB_CONTENTS,
|
||||
HHACT_TAB_INDEX,
|
||||
HHACT_TAB_SEARCH,
|
||||
HHACT_TAB_HISTORY,
|
||||
HHACT_TAB_FAVORITES,
|
||||
|
||||
HHACT_EXPAND,
|
||||
HHACT_CONTRACT,
|
||||
HHACT_BACK,
|
||||
HHACT_FORWARD,
|
||||
HHACT_STOP,
|
||||
HHACT_REFRESH,
|
||||
HHACT_HOME,
|
||||
HHACT_SYNC,
|
||||
HHACT_OPTIONS,
|
||||
HHACT_PRINT,
|
||||
HHACT_HIGHLIGHT,
|
||||
HHACT_CUSTOMIZE,
|
||||
HHACT_JUMP1,
|
||||
HHACT_JUMP2,
|
||||
HHACT_ZOOM,
|
||||
HHACT_TOC_NEXT,
|
||||
HHACT_TOC_PREV,
|
||||
HHACT_NOTES,
|
||||
|
||||
HHACT_LAST_ENUM,
|
||||
};
|
||||
|
||||
typedef struct tagHHNTRACK
|
||||
{
|
||||
NMHDR hdr;
|
||||
PCSTR pszCurUrl; // Multi-byte, null-terminated string
|
||||
int idAction; // HHACT_ value
|
||||
HH_WINTYPE* phhWinType; // Current window type structure
|
||||
} HHNTRACK;
|
||||
|
||||
HWND
|
||||
WINAPI
|
||||
HtmlHelpA(
|
||||
HWND hwndCaller,
|
||||
LPCSTR pszFile,
|
||||
UINT uCommand,
|
||||
DWORD_PTR dwData
|
||||
);
|
||||
|
||||
HWND
|
||||
WINAPI
|
||||
HtmlHelpW(
|
||||
HWND hwndCaller,
|
||||
LPCWSTR pszFile,
|
||||
UINT uCommand,
|
||||
DWORD_PTR dwData
|
||||
);
|
||||
#ifdef UNICODE
|
||||
#define HtmlHelp HtmlHelpW
|
||||
#else
|
||||
#define HtmlHelp HtmlHelpA
|
||||
#endif // !UNICODE
|
||||
|
||||
// Use the following for GetProcAddress to load from hhctrl.ocx
|
||||
|
||||
#define ATOM_HTMLHELP_API_ANSI (LPTSTR)((DWORD)((WORD)(14)))
|
||||
#define ATOM_HTMLHELP_API_UNICODE (LPTSTR)((DWORD)((WORD)(15)))
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Control Properties.
|
||||
//
|
||||
typedef enum tagHH_GPROPID
|
||||
{
|
||||
HH_GPROPID_SINGLETHREAD=1, // VARIANT_BOOL: True for single thread
|
||||
HH_GPROPID_TOOLBAR_MARGIN=2, // long: Provides a left/right margin around the toolbar.
|
||||
HH_GPROPID_UI_LANGUAGE=3, // long: LangId of the UI.
|
||||
HH_GPROPID_CURRENT_SUBSET=4, // BSTR: Current subset.
|
||||
HH_GPROPID_CONTENT_LANGUAGE=5 // long: LandId for desired content.
|
||||
} HH_GPROPID;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Global Property structure
|
||||
//
|
||||
#ifdef __oaidl_h__
|
||||
|
||||
#pragma pack(push, 8)
|
||||
|
||||
typedef struct tagHH_GLOBAL_PROPERTY
|
||||
{
|
||||
HH_GPROPID id;
|
||||
VARIANT var;
|
||||
} HH_GLOBAL_PROPERTY ;
|
||||
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __HTMLHELP_H__
|
75
core/lib/Ioapi.h
Executable file
75
core/lib/Ioapi.h
Executable file
@ -0,0 +1,75 @@
|
||||
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
*/
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#define _ZLIBIOAPI_H
|
||||
|
||||
|
||||
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
||||
#define ZLIB_FILEFUNC_SEEK_END (2)
|
||||
#define ZLIB_FILEFUNC_SEEK_SET (0)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_READ (1)
|
||||
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
||||
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
||||
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
||||
|
||||
|
||||
#ifndef ZCALLBACK
|
||||
|
||||
#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
|
||||
#define ZCALLBACK CALLBACK
|
||||
#else
|
||||
#define ZCALLBACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
|
||||
|
||||
typedef struct zlib_filefunc_def_s
|
||||
{
|
||||
open_file_func zopen_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell_file_func ztell_file;
|
||||
seek_file_func zseek_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
} zlib_filefunc_def;
|
||||
|
||||
|
||||
|
||||
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
|
||||
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
|
||||
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
1299
core/lib/Unzip.c
Executable file
1299
core/lib/Unzip.c
Executable file
File diff suppressed because it is too large
Load Diff
323
core/lib/Zconf.h
Executable file
323
core/lib/Zconf.h
Executable file
@ -0,0 +1,323 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
#define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
1220
core/lib/Zip.c
Executable file
1220
core/lib/Zip.c
Executable file
File diff suppressed because it is too large
Load Diff
235
core/lib/Zip.h
Executable file
235
core/lib/Zip.h
Executable file
@ -0,0 +1,235 @@
|
||||
/* zip.h -- IO for compress .zip files using zlib
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This unzip package allow creates .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
Multi volume ZipFile (span) are not supported.
|
||||
Encryption compatible with pkzip 2.04g only supported
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
For uncompress .zip file, look at unzip.h
|
||||
|
||||
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.html for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* for more info about .ZIP format, see
|
||||
http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
|
||||
http://www.info-zip.org/pub/infozip/doc/
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip
|
||||
*/
|
||||
|
||||
#ifndef _zip_H
|
||||
#define _zip_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#include "ioapi.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagzipFile__ { int unused; } zipFile__;
|
||||
typedef zipFile__ *zipFile;
|
||||
#else
|
||||
typedef voidp zipFile;
|
||||
#endif
|
||||
|
||||
#define ZIP_OK (0)
|
||||
#define ZIP_EOF (0)
|
||||
#define ZIP_ERRNO (Z_ERRNO)
|
||||
#define ZIP_PARAMERROR (-102)
|
||||
#define ZIP_BADZIPFILE (-103)
|
||||
#define ZIP_INTERNALERROR (-104)
|
||||
|
||||
#ifndef DEF_MEM_LEVEL
|
||||
# if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 8
|
||||
# else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
# endif
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
/* tm_zip contain date/time info */
|
||||
typedef struct tm_zip_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_zip;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
tm_zip tmz_date; /* date in understandable format */
|
||||
uLong dosDate; /* if dos_date == 0, tmu_date is used */
|
||||
/* uLong flag; */ /* general purpose bit flag 2 bytes */
|
||||
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
} zip_fileinfo;
|
||||
|
||||
typedef const char* zipcharpc;
|
||||
|
||||
|
||||
#define APPEND_STATUS_CREATE (0)
|
||||
#define APPEND_STATUS_CREATEAFTER (1)
|
||||
#define APPEND_STATUS_ADDINZIP (2)
|
||||
|
||||
extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
|
||||
/*
|
||||
Create a zipfile.
|
||||
pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
|
||||
an Unix computer "zlib/zlib113.zip".
|
||||
if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
|
||||
will be created at the end of the file.
|
||||
(useful if the file contain a self extractor code)
|
||||
if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
|
||||
add files in existing zip (be sure you don't add file that doesn't exist)
|
||||
If the zipfile cannot be opened, the return value is NULL.
|
||||
Else, the return value is a zipFile Handle, usable with other function
|
||||
of this zip package.
|
||||
*/
|
||||
|
||||
/* Note : there is no delete function into a zipfile.
|
||||
If you want delete file into a zipfile, you must open a zipfile, and create another
|
||||
Of couse, you can use RAW reading and writing to copy the file you did not want delte
|
||||
*/
|
||||
|
||||
extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
|
||||
int append,
|
||||
zipcharpc* globalcomment,
|
||||
zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level));
|
||||
/*
|
||||
Open a file in the ZIP for writing.
|
||||
filename : the filename in zip (if NULL, '-' without quote will be used
|
||||
*zipfi contain supplemental information
|
||||
if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
|
||||
contains the extrafield data the the local header
|
||||
if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
|
||||
contains the extrafield data the the local header
|
||||
if comment != NULL, comment contain the comment string
|
||||
method contain the compression method (0 for store, Z_DEFLATED for deflate)
|
||||
level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level,
|
||||
int raw));
|
||||
|
||||
/*
|
||||
Same than zipOpenNewFileInZip, except if raw=1, we write raw file
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
|
||||
const char* filename,
|
||||
const zip_fileinfo* zipfi,
|
||||
const void* extrafield_local,
|
||||
uInt size_extrafield_local,
|
||||
const void* extrafield_global,
|
||||
uInt size_extrafield_global,
|
||||
const char* comment,
|
||||
int method,
|
||||
int level,
|
||||
int raw,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy,
|
||||
const char* password,
|
||||
uLong crcForCtypting));
|
||||
|
||||
/*
|
||||
Same than zipOpenNewFileInZip2, except
|
||||
windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
|
||||
password : crypting password (NULL for no crypting)
|
||||
crcForCtypting : crc of file to compress (needed for crypting)
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
|
||||
const void* buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Write data in the zipfile
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
|
||||
/*
|
||||
Close the current file in the zipfile
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
|
||||
uLong uncompressed_size,
|
||||
uLong crc32));
|
||||
/*
|
||||
Close the current file in the zipfile, for fiel opened with
|
||||
parameter raw=1 in zipOpenNewFileInZip2
|
||||
uncompressed_size and crc32 are value for the uncompressed size
|
||||
*/
|
||||
|
||||
extern int ZEXPORT zipClose OF((zipFile file,
|
||||
const char* global_comment));
|
||||
/*
|
||||
Close the zipfile
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _zip_H */
|
1200
core/lib/Zlib.h
Executable file
1200
core/lib/Zlib.h
Executable file
File diff suppressed because it is too large
Load Diff
26
core/lib/miniunz.h
Executable file
26
core/lib/miniunz.h
Executable file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef MINIUNZ_H
|
||||
#define MINIUNZ_H
|
||||
|
||||
//! Look for possible filename in zip archive
|
||||
char *find_possible_filename_in_zip (char *zipfilename, const char* extstr);
|
||||
|
||||
//! Extract file content from zip archive
|
||||
int extract_file_in_memory (char *zipfilename, char *archivedfile,
|
||||
size_t * unzipped_size);
|
||||
|
||||
#endif
|
275
core/lib/unzip.h
Executable file
275
core/lib/unzip.h
Executable file
@ -0,0 +1,275 @@
|
||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||
Version 0.15 beta, Mar 19th, 1998,
|
||||
|
||||
Copyright (C) 1998 Gilles Vollant
|
||||
|
||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
Encryption and multi volume ZipFile (span) are not supported.
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
||||
CAN CHANGE IN FUTURE VERSION !!
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
/* for more info about .ZIP format, see
|
||||
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip */
|
||||
|
||||
#ifndef _unz_H
|
||||
#define _unz_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
||||
typedef unzFile__ *unzFile;
|
||||
#else
|
||||
typedef voidp unzFile;
|
||||
#endif
|
||||
|
||||
|
||||
#define UNZ_OK (0)
|
||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||
#define UNZ_ERRNO (Z_ERRNO)
|
||||
#define UNZ_EOF (0)
|
||||
#define UNZ_PARAMERROR (-102)
|
||||
#define UNZ_BADZIPFILE (-103)
|
||||
#define UNZ_INTERNALERROR (-104)
|
||||
#define UNZ_CRCERROR (-105)
|
||||
|
||||
/* tm_unz contain date/time info */
|
||||
typedef struct tm_unz_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_unz;
|
||||
|
||||
/* unz_global_info structure contain global data about the ZIPfile
|
||||
These data comes from the end of central dir */
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
uLong number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
uLong version; /* version made by 2 bytes */
|
||||
uLong version_needed; /* version needed to extract 2 bytes */
|
||||
uLong flag; /* general purpose bit flag 2 bytes */
|
||||
uLong compression_method; /* compression method 2 bytes */
|
||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
uLong crc; /* crc-32 4 bytes */
|
||||
uLong compressed_size; /* compressed size 4 bytes */
|
||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
||||
uLong size_filename; /* filename length 2 bytes */
|
||||
uLong size_file_extra; /* extra field length 2 bytes */
|
||||
uLong size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uLong disk_num_start; /* disk number start 2 bytes */
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||
/*
|
||||
Open a Zip file. path contain the full pathname (by example,
|
||||
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
||||
"zlib/zlib111.zip".
|
||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
||||
return value is NULL.
|
||||
Else, the return value is a unzFile Handle, usable with other function
|
||||
of this unzip package.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzClose OF((unzFile file));
|
||||
/*
|
||||
Close a ZipFile opened with unzipOpen.
|
||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||
unz_global_info *pglobal_info));
|
||||
/*
|
||||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf));
|
||||
/*
|
||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0
|
||||
*/
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Unzip package allow you browse the directory of the zipfile */
|
||||
|
||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the next file.
|
||||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Try locate the file szFileName in the zipfile.
|
||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||
|
||||
return value :
|
||||
UNZ_OK if the file is found. It becomes the current file.
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
/*
|
||||
Get Info about the current file
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||
the current file
|
||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||
(fileNameBufferSize is the size of the buffer)
|
||||
if extraField!=NULL, the extra field information will be copied in extraField
|
||||
(extraFieldBufferSize is the size of the buffer).
|
||||
This is the Central-header version of the extra field
|
||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
||||
(commentBufferSize is the size of the buffer)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
/* for reading the content of the current zipfile, you can open it, read data
|
||||
from it, and close it (you can close it before reading all the file)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
|
||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzeof OF((unzFile file));
|
||||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||
This is the local-header version of the extra field (sometimes, there is
|
||||
more info in the local-header version than in the central-header)
|
||||
|
||||
if buf==NULL, it return the size of the local extra field
|
||||
|
||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
||||
buf.
|
||||
the return value is the number of bytes copied in buf, or (if <0)
|
||||
the error code
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _unz_H */
|
384
libretro.cpp
Normal file
384
libretro.cpp
Normal file
@ -0,0 +1,384 @@
|
||||
#ifndef _MSC_VER
|
||||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define snprintf _snprintf
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
#include "libretro.h"
|
||||
|
||||
#include "Cartridge.h"
|
||||
#include "Database.h"
|
||||
#include "Maria.h"
|
||||
#include "Palette.h"
|
||||
#include "Pokey.h"
|
||||
#include "ProSystem.h"
|
||||
#include "Tia.h"
|
||||
|
||||
static uint32_t videoBuffer[320*292*4];
|
||||
static int videoWidth = 320;
|
||||
static int videoHeight = 240;
|
||||
static uint display_palette32[256] = {0};
|
||||
static byte keyboard_data[17] = {0};
|
||||
|
||||
static retro_log_printf_t log_cb;
|
||||
static retro_video_refresh_t video_cb;
|
||||
static retro_input_poll_t input_poll_cb;
|
||||
static retro_input_state_t input_state_cb;
|
||||
static retro_environment_t environ_cb;
|
||||
static retro_audio_sample_t audio_cb;
|
||||
static retro_audio_sample_batch_t audio_batch_cb;
|
||||
|
||||
void retro_set_environment(retro_environment_t cb) { environ_cb = cb; }
|
||||
void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
|
||||
void retro_set_audio_sample(retro_audio_sample_t cb) { audio_cb = cb; }
|
||||
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }
|
||||
void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; }
|
||||
void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; }
|
||||
|
||||
static void display_ResetPalette32() {
|
||||
for(uint index = 0; index < 256; index++) {
|
||||
uint r = palette_data[(index * 3) + 0] << 16;
|
||||
uint g = palette_data[(index * 3) + 1] << 8;
|
||||
uint b = palette_data[(index * 3) + 2];
|
||||
display_palette32[index] = r | g | b;
|
||||
}
|
||||
}
|
||||
|
||||
static uint sound_GetSampleLength(uint length, uint unit, uint unitMax) {
|
||||
uint sampleLength = length / unitMax;
|
||||
uint sampleRemain = length % unitMax;
|
||||
if(sampleRemain != 0 && sampleRemain >= unit) {
|
||||
sampleLength++;
|
||||
}
|
||||
return sampleLength;
|
||||
}
|
||||
|
||||
static void sound_Resample(const byte* source, byte* target, int length) {
|
||||
typedef struct {
|
||||
word wFormatTag;
|
||||
word nChannels;
|
||||
uint nSamplesPerSec;
|
||||
uint nAvgBytesPerSec;
|
||||
word nBlockAlign;
|
||||
word wBitsPerSample;
|
||||
word cbSize;
|
||||
} WAVEFORMATEX;
|
||||
|
||||
//# define WAVE_FORMAT_PCM 0
|
||||
|
||||
static const WAVEFORMATEX SOUND_DEFAULT_FORMAT = {0, 1, 48000, 48000, 1, 8, 0};
|
||||
static WAVEFORMATEX sound_format = SOUND_DEFAULT_FORMAT;
|
||||
|
||||
int measurement = sound_format.nSamplesPerSec;
|
||||
int sourceIndex = 0;
|
||||
int targetIndex = 0;
|
||||
|
||||
int max = ((prosystem_frequency * prosystem_scanlines) << 1);
|
||||
while(targetIndex < length) {
|
||||
if(measurement >= max) {
|
||||
target[targetIndex++] = source[sourceIndex];
|
||||
measurement -= max;
|
||||
}
|
||||
else {
|
||||
sourceIndex++;
|
||||
measurement += sound_format.nSamplesPerSec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sound_Store() {
|
||||
//#define MAX_BUFFER_SIZE 8192
|
||||
|
||||
byte sample[8192];
|
||||
memset(sample, 0, 8192);
|
||||
uint length = 48000 / prosystem_frequency; /* sound_GetSampleLength(sound_format.nSamplesPerSec, prosystem_frame, prosystem_frequency); */ /* 48000 / prosystem_frequency */
|
||||
sound_Resample(tia_buffer, sample, length);
|
||||
|
||||
// Ballblazer, Commando, various homebrew and hacks
|
||||
if(cartridge_pokey) {
|
||||
byte pokeySample[8192];
|
||||
memset(pokeySample, 0, 8192);
|
||||
sound_Resample(pokey_buffer, pokeySample, length);
|
||||
for(uint index = 0; index < length; index++) {
|
||||
sample[index] += pokeySample[index];
|
||||
sample[index] = sample[index] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert 8u to 16s
|
||||
for(int i = 0; i != length; i ++)
|
||||
{
|
||||
int16_t sample16 = (sample[i] << 8) - 32768;
|
||||
int16_t frame[2] = {sample16, sample16};
|
||||
|
||||
audio_cb((int16_t)frame[0], (int16_t)frame[1]);
|
||||
//audio_batch_cb(frame, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_input()
|
||||
{
|
||||
// ----------------------------------------------------------------------------
|
||||
// SetInput
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
// | Offset | Controller | Control
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
// | 00 | Joystick 1 | Right
|
||||
// | 01 | Joystick 1 | Left
|
||||
// | 02 | Joystick 1 | Down
|
||||
// | 03 | Joystick 1 | Up
|
||||
// | 04 | Joystick 1 | Button 1
|
||||
// | 05 | Joystick 1 | Button 2
|
||||
// | 06 | Joystick 2 | Right
|
||||
// | 07 | Joystick 2 | Left
|
||||
// | 08 | Joystick 2 | Down
|
||||
// | 09 | Joystick 2 | Up
|
||||
// | 10 | Joystick 2 | Button 1
|
||||
// | 11 | Joystick 2 | Button 2
|
||||
// | 12 | Console | Reset
|
||||
// | 13 | Console | Select
|
||||
// | 14 | Console | Pause
|
||||
// | 15 | Console | Left Difficulty
|
||||
// | 16 | Console | Right Difficulty
|
||||
// +----------+--------------+-------------------------------------------------
|
||||
|
||||
if (!input_poll_cb)
|
||||
return;
|
||||
|
||||
input_poll_cb();
|
||||
|
||||
keyboard_data[0] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
|
||||
keyboard_data[1] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
|
||||
keyboard_data[2] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
|
||||
keyboard_data[3] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
|
||||
keyboard_data[4] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
|
||||
keyboard_data[5] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
|
||||
keyboard_data[6] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT);
|
||||
keyboard_data[7] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT);
|
||||
keyboard_data[8] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN);
|
||||
keyboard_data[9] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP);
|
||||
keyboard_data[10] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B);
|
||||
keyboard_data[11] = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A);
|
||||
keyboard_data[12] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X);
|
||||
keyboard_data[13] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT);
|
||||
keyboard_data[14] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START);
|
||||
keyboard_data[15] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L);
|
||||
keyboard_data[16] = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R);
|
||||
}
|
||||
|
||||
/************************************
|
||||
* libretro implementation
|
||||
************************************/
|
||||
|
||||
static struct retro_system_av_info g_av_info;
|
||||
|
||||
void retro_get_system_info(struct retro_system_info *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->library_name = "ProSystem";
|
||||
info->library_version = "1.3e";
|
||||
info->need_fullpath = false;
|
||||
info->valid_extensions = "a78|bin";
|
||||
}
|
||||
|
||||
void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->timing.fps = cartridge_region == REGION_NTSC ? 60 : 50;
|
||||
info->timing.sample_rate = 48000;
|
||||
info->geometry.base_width = videoWidth;
|
||||
info->geometry.base_height = videoHeight;
|
||||
info->geometry.max_width = 320;
|
||||
info->geometry.max_height = 292;
|
||||
info->geometry.aspect_ratio = 4.0 / 3.0;
|
||||
}
|
||||
|
||||
void retro_set_controller_port_device(unsigned port, unsigned device)
|
||||
{
|
||||
(void)port;
|
||||
(void)device;
|
||||
}
|
||||
|
||||
size_t retro_serialize_size(void)
|
||||
{
|
||||
//return STATE_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool retro_serialize(void *data, size_t size)
|
||||
{
|
||||
//return prosystem_Save(fileName, false) ? true : false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool retro_unserialize(const void *data, size_t size)
|
||||
{
|
||||
//return prosystem_Load(fileName) ? true : false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void retro_cheat_reset(void)
|
||||
{}
|
||||
|
||||
void retro_cheat_set(unsigned index, bool enabled, const char *code)
|
||||
{
|
||||
(void)index;
|
||||
(void)enabled;
|
||||
(void)code;
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info *info)
|
||||
{
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_INFO, "[ProSystem]: XRGB8888 is not supported.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(keyboard_data, 0, sizeof(keyboard_data));
|
||||
|
||||
// Difficulty switches: Left position = (B)eginner, Right position = (A)dvanced
|
||||
// Left difficulty switch defaults to left position, "(B)eginner"
|
||||
keyboard_data[15] = 1;
|
||||
|
||||
// Right difficulty switch defaults to right position, "(A)dvanced", which fixes Tower Toppler
|
||||
keyboard_data[16] = 0;
|
||||
|
||||
const char *full_path;
|
||||
full_path = info->path;
|
||||
const char *system_directory_c = NULL;
|
||||
|
||||
if (cartridge_Load(full_path)) {
|
||||
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_directory_c);
|
||||
if (!system_directory_c)
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_WARN, "[ProSystem]: no system directory defined, unable to look for ProSystem.dat\n");
|
||||
database_enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string system_directory(system_directory_c);
|
||||
std::string database_file_path = system_directory + "/ProSystem.dat";
|
||||
std::ifstream database_file(database_file_path.c_str());
|
||||
if (!database_file.is_open())
|
||||
{
|
||||
if (log_cb)
|
||||
log_cb(RETRO_LOG_WARN, "[ProSystem]: ProSystem.dat not found, cannot load internal ROM database\n");
|
||||
database_enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
database_filename = database_file_path;
|
||||
database_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// BIOS is optional
|
||||
std::string system_directory(system_directory_c);
|
||||
std::string bios_file_path = system_directory + "/7800 BIOS (U).rom";
|
||||
if (bios_Load(bios_file_path))
|
||||
bios_enabled = true;
|
||||
|
||||
database_Load(cartridge_digest);
|
||||
prosystem_Reset();
|
||||
|
||||
display_ResetPalette32();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info)
|
||||
{
|
||||
(void)game_type;
|
||||
(void)info;
|
||||
(void)num_info;
|
||||
return false;
|
||||
}
|
||||
|
||||
void retro_unload_game(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned retro_get_region(void)
|
||||
{
|
||||
return cartridge_region == REGION_NTSC ? RETRO_REGION_NTSC : RETRO_REGION_PAL;
|
||||
}
|
||||
|
||||
unsigned retro_api_version(void)
|
||||
{
|
||||
return RETRO_API_VERSION;
|
||||
}
|
||||
|
||||
void *retro_get_memory_data(unsigned id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t retro_get_memory_size(unsigned id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void retro_init(void)
|
||||
{
|
||||
struct retro_log_callback log;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
|
||||
log_cb = log.log;
|
||||
else
|
||||
log_cb = NULL;
|
||||
}
|
||||
|
||||
void retro_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void retro_reset(void)
|
||||
{
|
||||
prosystem_Reset();
|
||||
}
|
||||
|
||||
void retro_run(void)
|
||||
{
|
||||
update_input();
|
||||
|
||||
prosystem_ExecuteFrame(keyboard_data); // wants input
|
||||
|
||||
videoWidth = maria_visibleArea.GetLength();
|
||||
videoHeight = maria_visibleArea.GetHeight();
|
||||
|
||||
const byte *buffer = maria_surface + ((maria_visibleArea.top - maria_displayArea.top) * maria_visibleArea.GetLength());
|
||||
|
||||
uint *surface = (uint*)videoBuffer;
|
||||
uint pitch = 320;
|
||||
for(uint indexY = 0; indexY < videoHeight; indexY++) {
|
||||
for(uint indexX = 0; indexX < videoWidth; indexX += 4) {
|
||||
surface[indexX + 0] = display_palette32[buffer[indexX + 0]];
|
||||
surface[indexX + 1] = display_palette32[buffer[indexX + 1]];
|
||||
surface[indexX + 2] = display_palette32[buffer[indexX + 2]];
|
||||
surface[indexX + 3] = display_palette32[buffer[indexX + 3]];
|
||||
}
|
||||
surface += pitch;
|
||||
buffer += videoWidth;
|
||||
}
|
||||
|
||||
video_cb(videoBuffer, videoWidth, videoHeight, videoWidth << 2);
|
||||
|
||||
sound_Store();
|
||||
}
|
1476
libretro.h
Executable file
1476
libretro.h
Executable file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user