mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 05:45:38 +00:00
build fixes for mac
This commit is contained in:
parent
858b84f424
commit
5e434e2644
|
@ -1,18 +1,13 @@
|
||||||
#
|
|
||||||
# TODO: MacOS port is probably broken. Someone with MacOS needs to figure out
|
|
||||||
# how to compile with SDL2.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Supermodel
|
## Supermodel
|
||||||
## A Sega Model 3 Arcade Emulator.
|
## A Sega Model 3 Arcade Emulator.
|
||||||
## Copyright 2011-2017 Bart Trzynadlowski, Nik Henson, Ian Curtis
|
## Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
## Harry Tuttle, and Spindizzi
|
||||||
##
|
##
|
||||||
## This file is part of Supermodel.
|
## This file is part of Supermodel.
|
||||||
##
|
##
|
||||||
## Supermodel is free software: you can redistribute it and/or modify it under
|
## Supermodel 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
|
## the terms of the GNU General Public License as published by the Free
|
||||||
## Software Foundation, either version 3 of the License, or (at your option)
|
## Software Foundation, either version 3 of the License, or (at your option)
|
||||||
## any later version.
|
## any later version.
|
||||||
##
|
##
|
||||||
|
@ -28,7 +23,7 @@
|
||||||
#
|
#
|
||||||
# Makefile.OSX
|
# Makefile.OSX
|
||||||
#
|
#
|
||||||
# Makefile for Mac OS X systems using gcc.
|
# Makefile for Mac OS X systems using clang.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,25 +40,33 @@ DELETE = rm -d -r -f
|
||||||
# Edit library and include paths as needed.
|
# Edit library and include paths as needed.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Must be included first
|
||||||
|
#
|
||||||
|
include Makefiles/Options.inc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Toolchain
|
# Toolchain
|
||||||
#
|
#
|
||||||
CC = gcc
|
CC = clang
|
||||||
CXX = g++
|
CXX = clang
|
||||||
LD = gcc
|
LD = clang
|
||||||
|
|
||||||
#
|
#
|
||||||
# SDL
|
# SDL
|
||||||
#
|
#
|
||||||
|
|
||||||
SDL_CFLAGS =
|
SDL_CFLAGS =
|
||||||
SDL_LIBS = -framework SDL2 -framework AGL -framework OpenGL -framework GLUT -framework Cocoa
|
SDL_LIBS = -framework SDL2 -framework AGL -framework OpenGL -framework GLUT -framework Cocoa
|
||||||
|
ifeq ($(strip $(NET_BOARD)),1)
|
||||||
|
SDL_LIBS += -framework SDL2_net
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# OSX-specific
|
# OSX-specific
|
||||||
#
|
#
|
||||||
|
|
||||||
PLATFORM_CFLAGS = $(SDL_CFLAGS) -DSUPERMODEL_OSX -DUSE_FILE32API -F/Library/Frameworks/
|
PLATFORM_CFLAGS = $(SDL_CFLAGS) -DSUPERMODEL_OSX -F/Library/Frameworks/
|
||||||
PLATFORM_LDFLAGS = $(SDL_LIBS) -lz -lm -lstdc++ -F/Library/Frameworks/
|
PLATFORM_LDFLAGS = $(SDL_LIBS) -lz -lm -lstdc++ -F/Library/Frameworks/
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,9 +74,9 @@ PLATFORM_LDFLAGS = $(SDL_LIBS) -lz -lm -lstdc++ -F/Library/Frameworks/
|
||||||
# Core Makefile
|
# Core Makefile
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
include Makefiles/Makefile.inc
|
include Makefiles/Rules.inc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(SILENT)echo Cleaning up \"$(BIN_DIR)\" and \"$(OBJ_DIR)\"...
|
$(SILENT)echo Cleaning up \"$(BIN_DIR)\" and \"$(OBJ_DIR)\"...
|
||||||
$(SILENT)$(DELETE) $(BIN_DIR)
|
$(SILENT)$(DELETE) $(BIN_DIR)
|
||||||
$(SILENT)$(DELETE) $(OBJ_DIR)
|
$(SILENT)$(DELETE) $(OBJ_DIR)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
##
|
##
|
||||||
## Supermodel
|
## Supermodel
|
||||||
## A Sega Model 3 Arcade Emulator.
|
## A Sega Model 3 Arcade Emulator.
|
||||||
## Copyright 2011-2017 Bart Trzynadlowski, Nik Henson, Ian Curtis
|
## Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
## Harry Tuttle, and Spindizzi
|
||||||
##
|
##
|
||||||
## This file is part of Supermodel.
|
## This file is part of Supermodel.
|
||||||
##
|
##
|
||||||
## Supermodel is free software: you can redistribute it and/or modify it under
|
## Supermodel 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
|
## the terms of the GNU General Public License as published by the Free
|
||||||
## Software Foundation, either version 3 of the License, or (at your option)
|
## Software Foundation, either version 3 of the License, or (at your option)
|
||||||
## any later version.
|
## any later version.
|
||||||
##
|
##
|
||||||
|
@ -39,6 +40,11 @@ DELETE = rm -d -r -f
|
||||||
# Edit library and include paths as needed.
|
# Edit library and include paths as needed.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Must be included first
|
||||||
|
#
|
||||||
|
include Makefiles/Options.inc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Toolchain
|
# Toolchain
|
||||||
#
|
#
|
||||||
|
@ -65,7 +71,7 @@ PLATFORM_LDFLAGS = $(SDL2_LIBS) -lGL -lGLU -lz -lm -lstdc++ -lpthread -lSDL2_net
|
||||||
# Core Makefile
|
# Core Makefile
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
include Makefiles/Makefile.inc
|
include Makefiles/Rules.inc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(SILENT)echo Cleaning up \"$(BIN_DIR)\" and \"$(OBJ_DIR)\"...
|
$(SILENT)echo Cleaning up \"$(BIN_DIR)\" and \"$(OBJ_DIR)\"...
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
##
|
##
|
||||||
## Supermodel
|
## Supermodel
|
||||||
## A Sega Model 3 Arcade Emulator.
|
## A Sega Model 3 Arcade Emulator.
|
||||||
## Copyright 2011-2017 Bart Trzynadlowski, Nik Henson, Ian Curtis
|
## Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
## Harry Tuttle, and Spindizzi
|
||||||
##
|
##
|
||||||
## This file is part of Supermodel.
|
## This file is part of Supermodel.
|
||||||
##
|
##
|
||||||
## Supermodel is free software: you can redistribute it and/or modify it under
|
## Supermodel 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
|
## the terms of the GNU General Public License as published by the Free
|
||||||
## Software Foundation, either version 3 of the License, or (at your option)
|
## Software Foundation, either version 3 of the License, or (at your option)
|
||||||
## any later version.
|
## any later version.
|
||||||
##
|
##
|
||||||
|
@ -36,6 +37,11 @@
|
||||||
# section as well, namely SDL2_LIBS and PLATFORM_LIBS.
|
# section as well, namely SDL2_LIBS and PLATFORM_LIBS.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Must be included first
|
||||||
|
#
|
||||||
|
include Makefiles/Options.inc
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bitness of build ('32' or '64')
|
# Bitness of build ('32' or '64')
|
||||||
#
|
#
|
||||||
|
@ -44,15 +50,12 @@ BITS = 64
|
||||||
#
|
#
|
||||||
# Path to SDL2
|
# Path to SDL2
|
||||||
#
|
#
|
||||||
SDL2_INCLUDE_DIR = c:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/SDL2
|
SDL2_INCLUDE_DIR = C:\TDM-GCC-64\x86_64-w64-mingw32\include\SDL2
|
||||||
SDL2_LIB_DIR = c:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/lib
|
SDL2_LIB_DIR = C:\TDM-GCC-64\x86_64-w64-mingw32\lib
|
||||||
#SDL2_INCLUDE_DIR = $(MINGW)/include/SDL2
|
|
||||||
#SDL2_LIB_DIR = $(MINGW)/lib
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Toolchain
|
# Toolchain
|
||||||
#
|
#
|
||||||
|
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
LD = g++
|
LD = g++
|
||||||
|
@ -78,8 +81,11 @@ endif
|
||||||
#
|
#
|
||||||
# SDL2
|
# SDL2
|
||||||
#
|
#
|
||||||
SDL2_LIBS = -lmingw32 -lSDL2main -lSDL2 -luser32 -lgdi32 -lwinmm -limm32 -lversion -lsetupapi -lsdl2_net -liphlpapi
|
SDL2_LIBS = -lmingw32 -lSDL2main -lSDL2 -luser32 -lgdi32 -lwinmm -limm32 -lversion -lsetupapi -liphlpapi
|
||||||
SDL2_CFLAGS =
|
SDL2_CFLAGS =
|
||||||
|
ifeq ($(strip $(NET_BOARD)),1)
|
||||||
|
SDL2_LIBS += -lSDL2_net
|
||||||
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
# MinGW/Windows-specific
|
# MinGW/Windows-specific
|
||||||
|
@ -100,9 +106,9 @@ PLATFORM_SRC_FILES = \
|
||||||
Src/OSD/Windows/DirectInputSystem.cpp \
|
Src/OSD/Windows/DirectInputSystem.cpp \
|
||||||
Src/OSD/Windows/WinOutputs.cpp
|
Src/OSD/Windows/WinOutputs.cpp
|
||||||
|
|
||||||
include Makefiles/Makefile.inc
|
include Makefiles/Rules.inc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(SILENT)echo Cleaning up $(BIN_DIR) and $(OBJ_DIR)...
|
$(SILENT)echo Cleaning up $(BIN_DIR) and $(OBJ_DIR)...
|
||||||
$(SILENT)$(DELETE) $(BIN_DIR)
|
$(SILENT)$(DELETE) $(BIN_DIR)
|
||||||
$(SILENT)$(DELETE) $(OBJ_DIR)
|
$(SILENT)$(DELETE) $(OBJ_DIR)
|
||||||
|
|
76
Makefiles/Options.inc
Normal file
76
Makefiles/Options.inc
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
##
|
||||||
|
## Supermodel
|
||||||
|
## A Sega Model 3 Arcade Emulator.
|
||||||
|
## Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
## Harry Tuttle, and Spindizzi
|
||||||
|
##
|
||||||
|
## This file is part of Supermodel.
|
||||||
|
##
|
||||||
|
## Supermodel 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 3 of the License, or (at your option)
|
||||||
|
## any later version.
|
||||||
|
##
|
||||||
|
## Supermodel 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 Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
#
|
||||||
|
# Options.inc
|
||||||
|
#
|
||||||
|
# Build options.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Build Options
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verbose progression
|
||||||
|
#
|
||||||
|
VERBOSE =
|
||||||
|
ifneq ($(filter $(strip $(VERBOSE)),0 1),$(strip $(VERBOSE)))
|
||||||
|
override VERBOSE =
|
||||||
|
endif
|
||||||
|
SILENT = @
|
||||||
|
ifeq ($(strip $(VERBOSE)),1)
|
||||||
|
SILENT =
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable render state analyser for the legacy 3D engine (will slow down emulation!)
|
||||||
|
#
|
||||||
|
DEBUG =
|
||||||
|
ifneq ($(filter $(strip $(DEBUG)),0 1),$(strip $(DEBUG)))
|
||||||
|
override DEBUG =
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable support for Model3 Net Board emulation
|
||||||
|
#
|
||||||
|
NET_BOARD =
|
||||||
|
ifneq ($(filter $(strip $(NET_BOARD)),0 1),$(strip $(NET_BOARD)))
|
||||||
|
override NET_BOARD =
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable Bart's new (experimental) Real3D frame timing
|
||||||
|
#
|
||||||
|
NEW_FRAME_TIMING =
|
||||||
|
ifneq ($(filter $(strip $(NEW_FRAME_TIMING)),0 1),$(strip $(NEW_FRAME_TIMING)))
|
||||||
|
override NEW_FRAME_TIMING =
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# Include console-based debugger in emulator ('yes' or 'no')
|
||||||
|
#
|
||||||
|
ENABLE_DEBUGGER =
|
||||||
|
ifneq ($(filter $(strip $(ENABLE_DEBUGGER)),0 1),$(strip $(ENABLE_DEBUGGER)))
|
||||||
|
override ENABLE_DEBUGGER =
|
||||||
|
endif
|
|
@ -1,12 +1,13 @@
|
||||||
##
|
##
|
||||||
## Supermodel
|
## Supermodel
|
||||||
## A Sega Model 3 Arcade Emulator.
|
## A Sega Model 3 Arcade Emulator.
|
||||||
## Copyright 2011-2017 Bart Trzynadlowski, Nik Henson, Ian Curtis
|
## Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
## Harry Tuttle, and Spindizzi
|
||||||
##
|
##
|
||||||
## This file is part of Supermodel.
|
## This file is part of Supermodel.
|
||||||
##
|
##
|
||||||
## Supermodel is free software: you can redistribute it and/or modify it under
|
## Supermodel 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
|
## the terms of the GNU General Public License as published by the Free
|
||||||
## Software Foundation, either version 3 of the License, or (at your option)
|
## Software Foundation, either version 3 of the License, or (at your option)
|
||||||
## any later version.
|
## any later version.
|
||||||
##
|
##
|
||||||
|
@ -20,61 +21,12 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
#
|
#
|
||||||
# Makefile.inc
|
# Rules.inc
|
||||||
#
|
#
|
||||||
# Core GNU Makefile, included by all (platform-specific) top-level Makefiles.
|
# Build rules, included by all (platform-specific) top-level Makefiles.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Build Options
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
#
|
|
||||||
# Verbose progression
|
|
||||||
#
|
|
||||||
VERBOSE =
|
|
||||||
ifneq ($(filter $(strip $(VERBOSE)),0 1),$(strip $(VERBOSE)))
|
|
||||||
override VERBOSE =
|
|
||||||
endif
|
|
||||||
SILENT = @
|
|
||||||
ifeq ($(strip $(VERBOSE)),1)
|
|
||||||
SILENT =
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Enable render state analyser for the legacy 3D engine (will slow down emulation!)
|
|
||||||
#
|
|
||||||
DEBUG =
|
|
||||||
ifneq ($(filter $(strip $(DEBUG)),0 1),$(strip $(DEBUG)))
|
|
||||||
override DEBUG =
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Enable support for Model3 Net Board emulation
|
|
||||||
#
|
|
||||||
NET_BOARD =
|
|
||||||
ifneq ($(filter $(strip $(NET_BOARD)),0 1),$(strip $(NET_BOARD)))
|
|
||||||
override NET_BOARD =
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Enable Bart's new (experimental) Real3D frame timing
|
|
||||||
#
|
|
||||||
NEW_FRAME_TIMING =
|
|
||||||
ifneq ($(filter $(strip $(NEW_FRAME_TIMING)),0 1),$(strip $(NEW_FRAME_TIMING)))
|
|
||||||
override NEW_FRAME_TIMING =
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Include console-based debugger in emulator ('yes' or 'no')
|
|
||||||
#
|
|
||||||
ENABLE_DEBUGGER =
|
|
||||||
ifneq ($(filter $(strip $(ENABLE_DEBUGGER)),0 1),$(strip $(ENABLE_DEBUGGER)))
|
|
||||||
override ENABLE_DEBUGGER =
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Source Files
|
# Source Files
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -185,7 +137,7 @@ endif
|
||||||
OBJ_FILES = $(foreach file,$(SRC_FILES),$(OBJ_DIR)/$(basename $(notdir $(file))).o)
|
OBJ_FILES = $(foreach file,$(SRC_FILES),$(OBJ_DIR)/$(basename $(notdir $(file))).o)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Deduce include directories from the source file list. The sort function
|
# Deduce include directories from the source file list. The sort function
|
||||||
# removes duplicates and is used to construct a set.
|
# removes duplicates and is used to construct a set.
|
||||||
#
|
#
|
||||||
INCLUDE_DIRS = $(sort $(foreach file,$(SRC_FILES),$(dir $(file))))
|
INCLUDE_DIRS = $(sort $(foreach file,$(SRC_FILES),$(dir $(file))))
|
||||||
|
@ -243,7 +195,7 @@ endif
|
||||||
# Targets
|
# Targets
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
#
|
#
|
||||||
# Default target: build Supermodel binary. Must be specified *before* the auto-
|
# Default target: build Supermodel binary. Must be specified *before* the auto-
|
||||||
# generated dependencies because otherwise, make gets confused for some reason
|
# generated dependencies because otherwise, make gets confused for some reason
|
||||||
# and thinks the default target is just one of the object files.
|
# and thinks the default target is just one of the object files.
|
||||||
|
@ -258,7 +210,7 @@ $(BIN_DIR)/$(OUTFILE): $(BIN_DIR) $(OBJ_DIR) $(OBJ_FILES)
|
||||||
|
|
||||||
$(BIN_DIR):
|
$(BIN_DIR):
|
||||||
$(info Creating directory : $(BIN_DIR))
|
$(info Creating directory : $(BIN_DIR))
|
||||||
$(SILENT)mkdir $(BIN_DIR)
|
$(SILENT)mkdir $(BIN_DIR)
|
||||||
|
|
||||||
$(OBJ_DIR):
|
$(OBJ_DIR):
|
||||||
$(info Creating directory : $(OBJ_DIR))
|
$(info Creating directory : $(OBJ_DIR))
|
||||||
|
@ -306,7 +258,7 @@ $(OBJ_DIR)/%.o: %.c
|
||||||
# All generated source files are emitted to the object directory. For MSVC,
|
# All generated source files are emitted to the object directory. For MSVC,
|
||||||
# INLINE must be redefined as "static __inline", which is the syntax in C mode.
|
# INLINE must be redefined as "static __inline", which is the syntax in C mode.
|
||||||
#
|
#
|
||||||
# The .exe suffix is absolutely required for native Windows non-MSYS builds!
|
# The .exe suffix is absolutely required for native Windows non-MSYS builds!
|
||||||
#
|
#
|
||||||
|
|
||||||
MUSASHI_OUTFILE = $(OBJ_DIR)/m68kmake.exe # do not remove the .exe suffix!
|
MUSASHI_OUTFILE = $(OBJ_DIR)/m68kmake.exe # do not remove the .exe suffix!
|
||||||
|
@ -323,23 +275,23 @@ $(MUSASHI_OUTFILE): Src/CPU/68K/Musashi/m68kmake.c Src/CPU/68K/Musashi/m68k_in.c
|
||||||
$(OBJ_DIR)/m68kops.h $(OBJ_DIR)/m68kops.c $(OBJ_DIR)/m68kopac.c $(OBJ_DIR)/m68kopdm.c $(OBJ_DIR)/m68kopnz.c: $(MUSASHI_OUTFILE) Src/CPU/68K/Musashi/m68k_in.c Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h
|
$(OBJ_DIR)/m68kops.h $(OBJ_DIR)/m68kops.c $(OBJ_DIR)/m68kopac.c $(OBJ_DIR)/m68kopdm.c $(OBJ_DIR)/m68kopnz.c: $(MUSASHI_OUTFILE) Src/CPU/68K/Musashi/m68k_in.c Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h
|
||||||
$(info Generating 68K emulator: $@)
|
$(info Generating 68K emulator: $@)
|
||||||
@$(MUSASHI_OUTFILE) $(OBJ_DIR) Src/CPU/68K/Musashi/m68k_in.c
|
@$(MUSASHI_OUTFILE) $(OBJ_DIR) Src/CPU/68K/Musashi/m68k_in.c
|
||||||
|
|
||||||
$(OBJ_DIR)/m68kcpu.o: Src/CPU/68K/Musashi/m68kcpu.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h
|
$(OBJ_DIR)/m68kcpu.o: Src/CPU/68K/Musashi/m68kcpu.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h
|
||||||
$(info Compiling : $< -> $@)
|
$(info Compiling : $< -> $@)
|
||||||
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $(OBJ_DIR)/m68kcpu.o
|
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $(OBJ_DIR)/m68kcpu.o
|
||||||
|
|
||||||
$(OBJ_DIR)/m68kops.o: $(OBJ_DIR)/m68kops.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
$(OBJ_DIR)/m68kops.o: $(OBJ_DIR)/m68kops.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
||||||
$(info Compiling : $< -> $@)
|
$(info Compiling : $< -> $@)
|
||||||
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
||||||
|
|
||||||
$(OBJ_DIR)/m68kopac.o: $(OBJ_DIR)/m68kopac.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
$(OBJ_DIR)/m68kopac.o: $(OBJ_DIR)/m68kopac.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
||||||
$(info Compiling : $< -> $@)
|
$(info Compiling : $< -> $@)
|
||||||
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
||||||
|
|
||||||
$(OBJ_DIR)/m68kopdm.o: $(OBJ_DIR)/m68kopdm.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
$(OBJ_DIR)/m68kopdm.o: $(OBJ_DIR)/m68kopdm.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
||||||
$(info Compiling : $< -> $@)
|
$(info Compiling : $< -> $@)
|
||||||
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
||||||
|
|
||||||
$(OBJ_DIR)/m68kopnz.o: $(OBJ_DIR)/m68kopnz.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
$(OBJ_DIR)/m68kopnz.o: $(OBJ_DIR)/m68kopnz.c $(OBJ_DIR)/m68kops.h Src/CPU/68K/Musashi/m68k.h Src/CPU/68K/Musashi/m68kconf.h $(MUSASHI_OUTFILE)
|
||||||
$(info Compiling : $< -> $@)
|
$(info Compiling : $< -> $@)
|
||||||
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
@$(CC) $< $(CFLAGS) $(MUSASHI_CFLAGS) -o $@
|
|
@ -18,7 +18,7 @@ bool GameLoader::LoadZipArchive(ZipArchive *zip, const std::string &zipfilename)
|
||||||
}
|
}
|
||||||
zip->zipfilenames.push_back(zipfilename);
|
zip->zipfilenames.push_back(zipfilename);
|
||||||
zip->zfs.push_back(zf);
|
zip->zfs.push_back(zf);
|
||||||
|
|
||||||
// Identify all files in zip archive
|
// Identify all files in zip archive
|
||||||
int err = UNZ_OK;
|
int err = UNZ_OK;
|
||||||
for (err = unzGoToFirstFile(zf); err == UNZ_OK; err = unzGoToNextFile(zf))
|
for (err = unzGoToFirstFile(zf); err == UNZ_OK; err = unzGoToNextFile(zf))
|
||||||
|
@ -50,7 +50,7 @@ bool GameLoader::FileExistsInZipArchive(const File::ptr_t &file, const ZipArchiv
|
||||||
auto it = zip.files_by_crc.find(file->crc32);
|
auto it = zip.files_by_crc.find(file->crc32);
|
||||||
return it != zip.files_by_crc.end();
|
return it != zip.files_by_crc.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to lookup by name
|
// Try to lookup by name
|
||||||
for (auto &v: zip.files_by_crc)
|
for (auto &v: zip.files_by_crc)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ const GameLoader::ZippedFile *GameLoader::LookupFile(const File::ptr_t &file, co
|
||||||
}
|
}
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to lookup by name
|
// Try to lookup by name
|
||||||
for (auto &v: zip.files_by_crc)
|
for (auto &v: zip.files_by_crc)
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ bool GameLoader::LoadZippedFile(std::shared_ptr<uint8_t> *buffer, size_t *file_s
|
||||||
ErrorLog("Unable to locate '%s' in '%s'. Is zip file corrupt?", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
ErrorLog("Unable to locate '%s' in '%s'. Is zip file corrupt?", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read it in
|
// Read it in
|
||||||
if (UNZ_OK != unzOpenCurrentFile(zipped_file->zf))
|
if (UNZ_OK != unzOpenCurrentFile(zipped_file->zf))
|
||||||
{
|
{
|
||||||
|
@ -109,14 +109,14 @@ bool GameLoader::LoadZippedFile(std::shared_ptr<uint8_t> *buffer, size_t *file_s
|
||||||
}
|
}
|
||||||
*file_size = zipped_file->uncompressed_size;
|
*file_size = zipped_file->uncompressed_size;
|
||||||
buffer->reset(new uint8_t[*file_size], std::default_delete<uint8_t[]>());
|
buffer->reset(new uint8_t[*file_size], std::default_delete<uint8_t[]>());
|
||||||
ZPOS64_T bytes_read = unzReadCurrentFile(zipped_file->zf, buffer->get(), *file_size);
|
size_t bytes_read = (size_t) unzReadCurrentFile(zipped_file->zf, buffer->get(), *file_size);
|
||||||
if (bytes_read != *file_size)
|
if (bytes_read != *file_size)
|
||||||
{
|
{
|
||||||
ErrorLog("Unable to read '%s' from '%s'. Is zip file corrupt?", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
ErrorLog("Unable to read '%s' from '%s'. Is zip file corrupt?", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
||||||
unzCloseCurrentFile(zipped_file->zf);
|
unzCloseCurrentFile(zipped_file->zf);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And close it
|
// And close it
|
||||||
if (UNZ_CRCERROR == unzCloseCurrentFile(zipped_file->zf))
|
if (UNZ_CRCERROR == unzCloseCurrentFile(zipped_file->zf))
|
||||||
ErrorLog("CRC error reading '%s' from '%s'. File may be corrupt.", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
ErrorLog("CRC error reading '%s' from '%s'. File may be corrupt.", zipped_file->filename.c_str(), zipped_file->zipfilename.c_str());
|
||||||
|
@ -284,7 +284,7 @@ bool GameLoader::LoadGamesFromXML(const Util::Config::Node &xml)
|
||||||
{
|
{
|
||||||
if (region_node.Key() != "region")
|
if (region_node.Key() != "region")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Look up region structure or create new one if needed
|
// Look up region structure or create new one if needed
|
||||||
std::string region_name = region_node["name"].Value<std::string>();
|
std::string region_name = region_node["name"].Value<std::string>();
|
||||||
auto it = regions_by_name.find(region_name);
|
auto it = regions_by_name.find(region_name);
|
||||||
|
@ -307,25 +307,25 @@ bool GameLoader::LoadGamesFromXML(const Util::Config::Node &xml)
|
||||||
continue;
|
continue;
|
||||||
files.push_back(file);
|
files.push_back(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to ensure that some files were defined in the region
|
// Check to ensure that some files were defined in the region
|
||||||
if (files.empty())
|
if (files.empty())
|
||||||
ErrorLog("%s: No files defined in region '%s' of '%s'.", m_xml_filename.c_str(), region->region_name.c_str(), game_name.c_str());
|
ErrorLog("%s: No files defined in region '%s' of '%s'.", m_xml_filename.c_str(), region->region_name.c_str(), game_name.c_str());
|
||||||
else
|
else
|
||||||
regions_by_name[region->region_name] = region;
|
regions_by_name[region->region_name] = region;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROM patches, if any
|
// ROM patches, if any
|
||||||
for (auto &patches_node: roms_node)
|
for (auto &patches_node: roms_node)
|
||||||
{
|
{
|
||||||
if (patches_node.Key() != "patches")
|
if (patches_node.Key() != "patches")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (auto &patch_node: patches_node)
|
for (auto &patch_node: patches_node)
|
||||||
{
|
{
|
||||||
if (MissingAttrib(*this, patch_node, "region") ||
|
if (MissingAttrib(*this, patch_node, "region") ||
|
||||||
MissingAttrib(*this, patch_node, "bits") ||
|
MissingAttrib(*this, patch_node, "bits") ||
|
||||||
MissingAttrib(*this, patch_node, "offset") ||
|
MissingAttrib(*this, patch_node, "offset") ||
|
||||||
MissingAttrib(*this, patch_node, "value"))
|
MissingAttrib(*this, patch_node, "value"))
|
||||||
continue;
|
continue;
|
||||||
std::string region = patch_node["region"].ValueAs<std::string>();
|
std::string region = patch_node["region"].ValueAs<std::string>();
|
||||||
|
@ -339,7 +339,7 @@ bool GameLoader::LoadGamesFromXML(const Util::Config::Node &xml)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to ensure that some ROM regions were defined for the game
|
// Check to ensure that some ROM regions were defined for the game
|
||||||
if (regions_by_name.empty())
|
if (regions_by_name.empty())
|
||||||
ErrorLog("%s: No ROM regions defined for '%s'.", m_xml_filename.c_str(), game_name.c_str());
|
ErrorLog("%s: No ROM regions defined for '%s'.", m_xml_filename.c_str(), game_name.c_str());
|
||||||
|
@ -371,7 +371,7 @@ bool GameLoader::MergeChildrenWithParents()
|
||||||
|
|
||||||
auto &child_regions = v1.second;
|
auto &child_regions = v1.second;
|
||||||
auto &parent_regions = m_regions_by_game[game.parent];
|
auto &parent_regions = m_regions_by_game[game.parent];
|
||||||
|
|
||||||
// Rebuild child regions by copying over all parent regions first, then
|
// Rebuild child regions by copying over all parent regions first, then
|
||||||
// merge in files from equivalent child regions
|
// merge in files from equivalent child regions
|
||||||
RegionsByName_t new_regions;
|
RegionsByName_t new_regions;
|
||||||
|
@ -382,7 +382,7 @@ bool GameLoader::MergeChildrenWithParents()
|
||||||
auto ®ion_name = v2.first;
|
auto ®ion_name = v2.first;
|
||||||
new_regions[region_name] = std::make_shared<Region>(*v2.second);
|
new_regions[region_name] = std::make_shared<Region>(*v2.second);
|
||||||
auto &new_region = new_regions[region_name];
|
auto &new_region = new_regions[region_name];
|
||||||
|
|
||||||
// Replace equivalent files from child in parent region, appending any
|
// Replace equivalent files from child in parent region, appending any
|
||||||
// new ones
|
// new ones
|
||||||
if (child_regions.find(region_name) != child_regions.end())
|
if (child_regions.find(region_name) != child_regions.end())
|
||||||
|
@ -403,7 +403,7 @@ bool GameLoader::MergeChildrenWithParents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simply append any region in child that does *not* exist in parent
|
// Simply append any region in child that does *not* exist in parent
|
||||||
for (auto &v2: child_regions)
|
for (auto &v2: child_regions)
|
||||||
{
|
{
|
||||||
|
@ -413,11 +413,11 @@ bool GameLoader::MergeChildrenWithParents()
|
||||||
new_regions[v2.first] = v2.second;
|
new_regions[v2.first] = v2.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the final result
|
// Save the final result
|
||||||
m_regions_by_merged_game[v1.first] = new_regions;
|
m_regions_by_merged_game[v1.first] = new_regions;
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,7 +518,7 @@ void GameLoader::IdentifyGamesInZipArchive(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Corner case: some child ROM sets legitimately share files, which can fool
|
* Corner case: some child ROM sets legitimately share files, which can fool
|
||||||
* us into thinking two games are partially present. Need to remove the one
|
* us into thinking two games are partially present. Need to remove the one
|
||||||
|
@ -541,7 +541,7 @@ void GameLoader::IdentifyGamesInZipArchive(
|
||||||
/*
|
/*
|
||||||
* If the these two games have a different number of files in the zip
|
* If the these two games have a different number of files in the zip
|
||||||
* archive, but one consists only of the overlapping files, we can safely
|
* archive, but one consists only of the overlapping files, we can safely
|
||||||
* conclude that these files represent only the game with the larger
|
* conclude that these files represent only the game with the larger
|
||||||
* number of files present. Otherwise, if only the overlapping files are
|
* number of files present. Otherwise, if only the overlapping files are
|
||||||
* present for both, we have a genuine ambiguity and hence do nothing.
|
* present for both, we have a genuine ambiguity and hence do nothing.
|
||||||
*/
|
*/
|
||||||
|
@ -553,7 +553,7 @@ void GameLoader::IdentifyGamesInZipArchive(
|
||||||
{
|
{
|
||||||
files_found_by_game.erase(game_name);
|
files_found_by_game.erase(game_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the missing files for each game we found in the zip archive, then use
|
// Find the missing files for each game we found in the zip archive, then use
|
||||||
// this to determine whether the complete game exists
|
// this to determine whether the complete game exists
|
||||||
auto compare = [](const File::ptr_t &a, const File::ptr_t &b) { return a->filename < b->filename; };
|
auto compare = [](const File::ptr_t &a, const File::ptr_t &b) { return a->filename < b->filename; };
|
||||||
|
@ -592,12 +592,12 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_
|
||||||
std::set<std::string> complete_games;
|
std::set<std::string> complete_games;
|
||||||
std::map<std::string, std::set<File::ptr_t>> files_missing_by_game;
|
std::map<std::string, std::set<File::ptr_t>> files_missing_by_game;
|
||||||
IdentifyGamesInZipArchive(&complete_games, &files_missing_by_game, zip, m_regions_by_game);
|
IdentifyGamesInZipArchive(&complete_games, &files_missing_by_game, zip, m_regions_by_game);
|
||||||
|
|
||||||
// Find complete, merged games
|
// Find complete, merged games
|
||||||
std::set<std::string> complete_merged_games;
|
std::set<std::string> complete_merged_games;
|
||||||
std::map<std::string, std::set<File::ptr_t>> files_missing_by_merged_game;
|
std::map<std::string, std::set<File::ptr_t>> files_missing_by_merged_game;
|
||||||
IdentifyGamesInZipArchive(&complete_merged_games, &files_missing_by_merged_game, zip, m_regions_by_merged_game);
|
IdentifyGamesInZipArchive(&complete_merged_games, &files_missing_by_merged_game, zip, m_regions_by_merged_game);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find incomplete child games by sorting child games out from the unmerged
|
* Find incomplete child games by sorting child games out from the unmerged
|
||||||
* games results and pruning out complete merged games. Don't care about
|
* games results and pruning out complete merged games. Don't care about
|
||||||
|
@ -623,7 +623,7 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_
|
||||||
{
|
{
|
||||||
incomplete_child_games.erase(game_name);
|
incomplete_child_games.erase(game_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete merged games take highest precedence
|
// Complete merged games take highest precedence
|
||||||
for (auto &game_name: complete_merged_games)
|
for (auto &game_name: complete_merged_games)
|
||||||
{
|
{
|
||||||
|
@ -635,17 +635,17 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_
|
||||||
// complete merged games from missing file list.
|
// complete merged games from missing file list.
|
||||||
files_missing_by_game.erase(parent);
|
files_missing_by_game.erase(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any remaining incomplete games from the unmerged set are legitimate errors
|
// Any remaining incomplete games from the unmerged set are legitimate errors
|
||||||
for (auto &v: files_missing_by_game)
|
for (auto &v: files_missing_by_game)
|
||||||
{
|
{
|
||||||
for (auto &file: v.second)
|
for (auto &file: v.second)
|
||||||
{
|
{
|
||||||
ErrorLog("'%s' (CRC32 0x%08x) not found in '%s' for game '%s'.", file->filename.c_str(), file->crc32, zipfilename.c_str(), v.first.c_str());
|
ErrorLog("'%s' (CRC32 0x%08x) not found in '%s' for game '%s'.", file->filename.c_str(), file->crc32, zipfilename.c_str(), v.first.c_str());
|
||||||
}
|
}
|
||||||
ErrorLog("Ignoring game '%s' in '%s' because it is missing files.", v.first.c_str(), zipfilename.c_str());
|
ErrorLog("Ignoring game '%s' in '%s' because it is missing files.", v.first.c_str(), zipfilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose game: complete merged game > incomplete child game > complete
|
// Choose game: complete merged game > incomplete child game > complete
|
||||||
// unmerged game
|
// unmerged game
|
||||||
if (!complete_merged_games.empty())
|
if (!complete_merged_games.empty())
|
||||||
|
@ -663,7 +663,7 @@ void GameLoader::ChooseGameInZipArchive(std::string *chosen_game, bool *missing_
|
||||||
ErrorLog("No complete Model 3 games found in '%s'.", zipfilename.c_str());
|
ErrorLog("No complete Model 3 games found in '%s'.", zipfilename.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print out which game we chose from valid candidates in the zip file
|
// Print out which game we chose from valid candidates in the zip file
|
||||||
std::set<std::string> candidates(complete_games);
|
std::set<std::string> candidates(complete_games);
|
||||||
candidates.insert(complete_merged_games.begin(), complete_merged_games.end());
|
candidates.insert(complete_merged_games.begin(), complete_merged_games.end());
|
||||||
|
@ -775,7 +775,7 @@ bool GameLoader::LoadROMs(ROMSet *rom_set, const std::string &game_name, const Z
|
||||||
error |= LoadRegion(&rom, region, zip);
|
error |= LoadRegion(&rom, region, zip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the patches and do some more error checking here
|
// Attach the patches and do some more error checking here
|
||||||
auto &patches_by_region = m_patches_by_game.find(game_name)->second;
|
auto &patches_by_region = m_patches_by_game.find(game_name)->second;
|
||||||
for (auto &v: patches_by_region)
|
for (auto &v: patches_by_region)
|
||||||
|
@ -802,7 +802,7 @@ std::string StripFilename(const std::string &filepath)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If none found, there is directory component here
|
// If none found, there is directory component here
|
||||||
if (last_slash == std::string::npos)
|
if (last_slash == std::string::npos)
|
||||||
return "";
|
return "";
|
||||||
|
@ -814,12 +814,12 @@ std::string StripFilename(const std::string &filepath)
|
||||||
bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename) const
|
bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilename) const
|
||||||
{
|
{
|
||||||
*game = Game();
|
*game = Game();
|
||||||
|
|
||||||
// Read the zip contents
|
// Read the zip contents
|
||||||
ZipArchive zip;
|
ZipArchive zip;
|
||||||
if (LoadZipArchive(&zip, zipfilename))
|
if (LoadZipArchive(&zip, zipfilename))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Pick the game to load (there could be multiple ROM sets in a zip file)
|
// Pick the game to load (there could be multiple ROM sets in a zip file)
|
||||||
std::string chosen_game;
|
std::string chosen_game;
|
||||||
bool missing_parent_roms = false;
|
bool missing_parent_roms = false;
|
||||||
|
@ -829,7 +829,7 @@ bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilenam
|
||||||
|
|
||||||
// Return game information to caller
|
// Return game information to caller
|
||||||
*game = m_game_info_by_game.find(chosen_game)->second;
|
*game = m_game_info_by_game.find(chosen_game)->second;
|
||||||
|
|
||||||
// Bring in additional parent ROM set if needed
|
// Bring in additional parent ROM set if needed
|
||||||
if (missing_parent_roms)
|
if (missing_parent_roms)
|
||||||
{
|
{
|
||||||
|
@ -841,7 +841,7 @@ bool GameLoader::Load(Game *game, ROMSet *rom_set, const std::string &zipfilenam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load
|
// Load
|
||||||
bool error = LoadROMs(rom_set, game->name, zip);
|
bool error = LoadROMs(rom_set, game->name, zip);
|
||||||
if (error)
|
if (error)
|
||||||
*game = Game();
|
*game = Game();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "SDL_net.h"
|
#include "SDLIncludes.h"
|
||||||
|
|
||||||
class TCPReceive
|
class TCPReceive
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define _TCPSEND_H_
|
#define _TCPSEND_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "SDL_net.h"
|
#include "SDLIncludes.h"
|
||||||
|
|
||||||
class TCPSend
|
class TCPSend
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
** This file is part of Supermodel.
|
** This file is part of Supermodel.
|
||||||
**
|
**
|
||||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
** Supermodel 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
|
** the terms of the GNU General Public License as published by the Free
|
||||||
** Software Foundation, either version 3 of the License, or (at your option)
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
** any later version.
|
** any later version.
|
||||||
**
|
**
|
||||||
|
@ -18,22 +18,15 @@
|
||||||
** You should have received a copy of the GNU General Public License along
|
** You should have received a copy of the GNU General Public License along
|
||||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Audio.cpp
|
* Audio.cpp
|
||||||
*
|
*
|
||||||
* SDL audio playback. Implements the OSD audio interface.
|
* SDL audio playback. Implements the OSD audio interface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
|
#include "SDLIncludes.h"
|
||||||
#ifdef SUPERMODEL_OSX
|
|
||||||
#include <SDL/SDL.h>
|
|
||||||
#include <SDL/SDL_audio.h>
|
|
||||||
#else
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <SDL_audio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -45,7 +38,7 @@
|
||||||
|
|
||||||
#define BYTES_PER_SAMPLE (NUM_CHANNELS * sizeof(INT16))
|
#define BYTES_PER_SAMPLE (NUM_CHANNELS * sizeof(INT16))
|
||||||
#define SAMPLES_PER_FRAME (SAMPLE_RATE / SUPERMODEL_FPS)
|
#define SAMPLES_PER_FRAME (SAMPLE_RATE / SUPERMODEL_FPS)
|
||||||
#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE)
|
#define BYTES_PER_FRAME (SAMPLES_PER_FRAME * BYTES_PER_SAMPLE)
|
||||||
|
|
||||||
#define MAX_LATENCY 100
|
#define MAX_LATENCY 100
|
||||||
|
|
||||||
|
@ -87,9 +80,9 @@ void SetAudioEnabled(bool newEnabled)
|
||||||
|
|
||||||
static void PlayCallback(void *data, Uint8 *stream, int len)
|
static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
{
|
{
|
||||||
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
// len, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
// len, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
||||||
|
|
||||||
// Get current write position and adjust it if write has wrapped but play position has not
|
// Get current write position and adjust it if write has wrapped but play position has not
|
||||||
UINT32 adjWritePos = writePos;
|
UINT32 adjWritePos = writePos;
|
||||||
if (writeWrapped)
|
if (writeWrapped)
|
||||||
|
@ -102,7 +95,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
|
|
||||||
//printf("Audio buffer under-run #%u in PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
//printf("Audio buffer under-run #%u in PlayCallback(%d) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
|
||||||
// underRuns, len, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
// underRuns, len, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
|
||||||
|
|
||||||
// See what action to take on under-run
|
// See what action to take on under-run
|
||||||
if (underRunLoop)
|
if (underRunLoop)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +106,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
if (playPos >= audioBufferSize)
|
if (playPos >= audioBufferSize)
|
||||||
// If so, wrap it around to beginning again (but keep write wrapped flag as before)
|
// If so, wrap it around to beginning again (but keep write wrapped flag as before)
|
||||||
playPos -= audioBufferSize;
|
playPos -= audioBufferSize;
|
||||||
else
|
else
|
||||||
// Otherwise, set write wrapped flag as will now appear as if write has wrapped but play position has not
|
// Otherwise, set write wrapped flag as will now appear as if write has wrapped but play position has not
|
||||||
writeWrapped = true;
|
writeWrapped = true;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +117,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INT8* src1;
|
INT8* src1;
|
||||||
INT8* src2;
|
INT8* src2;
|
||||||
UINT32 len1;
|
UINT32 len1;
|
||||||
|
@ -153,7 +146,7 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
{
|
{
|
||||||
// If so, copy play region into audio output stream
|
// If so, copy play region into audio output stream
|
||||||
memcpy(stream, src1, len1);
|
memcpy(stream, src1, len1);
|
||||||
|
|
||||||
// Also, if not looping on under-runs then blank region out
|
// Also, if not looping on under-runs then blank region out
|
||||||
if (!underRunLoop)
|
if (!underRunLoop)
|
||||||
memset(src1, 0, len1);
|
memset(src1, 0, len1);
|
||||||
|
@ -193,10 +186,10 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
|
||||||
static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, void *dest, bool flipStereo)
|
static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, void *dest, bool flipStereo)
|
||||||
{
|
{
|
||||||
INT16 *p = (INT16*)dest;
|
INT16 *p = (INT16*)dest;
|
||||||
|
|
||||||
#if (NUM_CHANNELS == 1)
|
#if (NUM_CHANNELS == 1)
|
||||||
for (unsigned i = 0; i < numSamples; i++)
|
for (unsigned i = 0; i < numSamples; i++)
|
||||||
*p++ = leftBuffer[i] + rightBuffer[i]; // TODO: these should probably be clipped!
|
*p++ = leftBuffer[i] + rightBuffer[i]; // TODO: these should probably be clipped!
|
||||||
#else
|
#else
|
||||||
if (flipStereo) // swap left and right channels
|
if (flipStereo) // swap left and right channels
|
||||||
{
|
{
|
||||||
|
@ -242,7 +235,7 @@ bool OpenAudio()
|
||||||
fmt.format = AUDIO_S16SYS;
|
fmt.format = AUDIO_S16SYS;
|
||||||
fmt.samples = playSamples;
|
fmt.samples = playSamples;
|
||||||
fmt.callback = PlayCallback;
|
fmt.callback = PlayCallback;
|
||||||
|
|
||||||
// Force SDL to use the format we requested; it will convert if necessary
|
// Force SDL to use the format we requested; it will convert if necessary
|
||||||
if (SDL_OpenAudio(&fmt, nullptr) < 0)
|
if (SDL_OpenAudio(&fmt, nullptr) < 0)
|
||||||
return ErrorLog("Unable to open 44.1KHz 2-channel audio with SDL: %s\n", SDL_GetError());
|
return ErrorLog("Unable to open 44.1KHz 2-channel audio with SDL: %s\n", SDL_GetError());
|
||||||
|
@ -255,10 +248,10 @@ bool OpenAudio()
|
||||||
if (audioBuffer == NULL)
|
if (audioBuffer == NULL)
|
||||||
{
|
{
|
||||||
float audioBufMB = (float)audioBufferSize / (float)0x100000;
|
float audioBufMB = (float)audioBufferSize / (float)0x100000;
|
||||||
return ErrorLog("Insufficient memory for audio latency buffer (need %1.1f MB).", audioBufMB);
|
return ErrorLog("Insufficient memory for audio latency buffer (need %1.1f MB).", audioBufMB);
|
||||||
}
|
}
|
||||||
memset(audioBuffer, 0, sizeof(INT8) * audioBufferSize);
|
memset(audioBuffer, 0, sizeof(INT8) * audioBufferSize);
|
||||||
|
|
||||||
// Set initial play position to be beginning of buffer and initial write position to be half-way into buffer
|
// Set initial play position to be beginning of buffer and initial write position to be half-way into buffer
|
||||||
playPos = 0;
|
playPos = 0;
|
||||||
writePos = std::min<int>(audioBufferSize - BYTES_PER_FRAME, (BYTES_PER_FRAME + audioBufferSize) / 2);
|
writePos = std::min<int>(audioBufferSize - BYTES_PER_FRAME, (BYTES_PER_FRAME + audioBufferSize) / 2);
|
||||||
|
@ -289,16 +282,16 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
// Mix together left and right channels into single chunk of data
|
// Mix together left and right channels into single chunk of data
|
||||||
INT16 mixBuffer[NUM_CHANNELS * SAMPLES_PER_FRAME];
|
INT16 mixBuffer[NUM_CHANNELS * SAMPLES_PER_FRAME];
|
||||||
MixChannels(numSamples, leftBuffer, rightBuffer, mixBuffer, flipStereo);
|
MixChannels(numSamples, leftBuffer, rightBuffer, mixBuffer, flipStereo);
|
||||||
|
|
||||||
// Lock SDL audio callback so that it doesn't interfere with following code
|
// Lock SDL audio callback so that it doesn't interfere with following code
|
||||||
SDL_LockAudio();
|
SDL_LockAudio();
|
||||||
|
|
||||||
// Calculate number of bytes for current sound chunk
|
// Calculate number of bytes for current sound chunk
|
||||||
UINT32 numBytes = numSamples * BYTES_PER_SAMPLE;
|
UINT32 numBytes = numSamples * BYTES_PER_SAMPLE;
|
||||||
|
|
||||||
// Get end of current play region (writing must occur past this point)
|
// Get end of current play region (writing must occur past this point)
|
||||||
UINT32 playEndPos = playPos + BYTES_PER_FRAME;
|
UINT32 playEndPos = playPos + BYTES_PER_FRAME;
|
||||||
|
|
||||||
// Undo any wrap-around of the write position that may have occured to create following ordering: playPos < playEndPos < writePos
|
// Undo any wrap-around of the write position that may have occured to create following ordering: playPos < playEndPos < writePos
|
||||||
if (playEndPos > writePos && writeWrapped)
|
if (playEndPos > writePos && writeWrapped)
|
||||||
writePos += audioBufferSize;
|
writePos += audioBufferSize;
|
||||||
|
@ -310,18 +303,18 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
|
|
||||||
//printf("Audio buffer under-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n",
|
//printf("Audio buffer under-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n",
|
||||||
// underRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes);
|
// underRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes);
|
||||||
|
|
||||||
// See what action to take on under-run
|
// See what action to take on under-run
|
||||||
if (underRunLoop)
|
if (underRunLoop)
|
||||||
{
|
{
|
||||||
// If loop, then move play position back to beginning of data in buffer
|
// If loop, then move play position back to beginning of data in buffer
|
||||||
playPos = writePos + numBytes + BYTES_PER_FRAME;
|
playPos = writePos + numBytes + BYTES_PER_FRAME;
|
||||||
|
|
||||||
// Check if play position has moved past end of buffer
|
// Check if play position has moved past end of buffer
|
||||||
if (playPos >= audioBufferSize)
|
if (playPos >= audioBufferSize)
|
||||||
// If so, wrap it around to beginning again (but keep write wrapped flag as before)
|
// If so, wrap it around to beginning again (but keep write wrapped flag as before)
|
||||||
playPos -= audioBufferSize;
|
playPos -= audioBufferSize;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise, set write wrapped flag as will now appear as if write has wrapped but play position has not
|
// Otherwise, set write wrapped flag as will now appear as if write has wrapped but play position has not
|
||||||
writeWrapped = true;
|
writeWrapped = true;
|
||||||
|
@ -341,7 +334,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
|
|
||||||
// Check if write position has caught up with play region and now overlaps it (ie buffer over-run)
|
// Check if write position has caught up with play region and now overlaps it (ie buffer over-run)
|
||||||
bool overRun = writePos + numBytes > playPos + audioBufferSize;
|
bool overRun = writePos + numBytes > playPos + audioBufferSize;
|
||||||
|
|
||||||
bool bufferFull = writePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
|
bool bufferFull = writePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
|
||||||
|
|
||||||
// Move write position back to within buffer
|
// Move write position back to within buffer
|
||||||
|
@ -355,7 +348,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer, boo
|
||||||
|
|
||||||
//printf("Audio buffer over-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n",
|
//printf("Audio buffer over-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n",
|
||||||
// overRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes);
|
// overRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes);
|
||||||
|
|
||||||
bufferFull = true;
|
bufferFull = true;
|
||||||
|
|
||||||
// Discard current chunk of data
|
// Discard current chunk of data
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/**
|
/**
|
||||||
** Supermodel
|
** Supermodel
|
||||||
** A Sega Model 3 Arcade Emulator.
|
** A Sega Model 3 Arcade Emulator.
|
||||||
** Copyright 2011-2019 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
** Copyright 2011-2020 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
** Harry Tuttle, and Spindizzi
|
** Harry Tuttle, and Spindizzi
|
||||||
**
|
**
|
||||||
** This file is part of Supermodel.
|
** This file is part of Supermodel.
|
||||||
**
|
**
|
||||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
** Supermodel 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
|
** the terms of the GNU General Public License as published by the Free
|
||||||
** Software Foundation, either version 3 of the License, or (at your option)
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
** any later version.
|
** any later version.
|
||||||
**
|
**
|
||||||
|
@ -19,10 +19,10 @@
|
||||||
** You should have received a copy of the GNU General Public License along
|
** You should have received a copy of the GNU General Public License along
|
||||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main.cpp
|
* Main.cpp
|
||||||
*
|
*
|
||||||
* Main program driver for the SDL port.
|
* Main program driver for the SDL port.
|
||||||
*
|
*
|
||||||
* To Do Before Next Release
|
* To Do Before Next Release
|
||||||
|
@ -33,11 +33,11 @@
|
||||||
* - Standardize variable naming (recently introduced vars_like_this should be
|
* - Standardize variable naming (recently introduced vars_like_this should be
|
||||||
* converted back to varsLikeThis).
|
* converted back to varsLikeThis).
|
||||||
* - Update save state file revision (strings > 1024 chars are now supported).
|
* - Update save state file revision (strings > 1024 chars are now supported).
|
||||||
* - Fix BlockFile.cpp to use fstream!
|
* - Fix BlockFile.cpp to use fstream!
|
||||||
* - Check to make sure save states use explicitly-sized types for 32/64-bit
|
* - Check to make sure save states use explicitly-sized types for 32/64-bit
|
||||||
* compatibility (i.e., size_t, int, etc. not allowed).
|
* compatibility (i.e., size_t, int, etc. not allowed).
|
||||||
* - Make sure quitting while paused works.
|
* - Make sure quitting while paused works.
|
||||||
* - Add UI keys for balance setting?
|
* - Add UI keys for balance setting?
|
||||||
* - 5.1 audio support?
|
* - 5.1 audio support?
|
||||||
*
|
*
|
||||||
* Compile-Time Options
|
* Compile-Time Options
|
||||||
|
@ -57,11 +57,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "Pkgs/glew.h"
|
#include "Pkgs/glew.h"
|
||||||
#ifdef SUPERMODEL_OSX
|
|
||||||
#include <SDL/SDL.h>
|
|
||||||
#else
|
|
||||||
#include <SDL.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
#include "Util/Format.h"
|
#include "Util/Format.h"
|
||||||
|
@ -73,6 +68,7 @@
|
||||||
#include "DirectInputSystem.h"
|
#include "DirectInputSystem.h"
|
||||||
#include "WinOutputs.h"
|
#include "WinOutputs.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "SDLIncludes.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -112,7 +108,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
SDL_GetWindowSize(s_window, &actualWidth, &actualHeight);
|
SDL_GetWindowSize(s_window, &actualWidth, &actualHeight);
|
||||||
*totalXResPtr = actualWidth;
|
*totalXResPtr = actualWidth;
|
||||||
*totalYResPtr = actualHeight;
|
*totalYResPtr = actualHeight;
|
||||||
|
|
||||||
// If required, fix the aspect ratio of the resolution that the user passed to match Model 3 ratio
|
// If required, fix the aspect ratio of the resolution that the user passed to match Model 3 ratio
|
||||||
float xRes = float(*xResPtr);
|
float xRes = float(*xResPtr);
|
||||||
float yRes = float(*yResPtr);
|
float yRes = float(*yResPtr);
|
||||||
|
@ -124,17 +120,17 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
if (xRes < (yRes*model3Ratio))
|
if (xRes < (yRes*model3Ratio))
|
||||||
yRes = xRes/model3Ratio;
|
yRes = xRes/model3Ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center the visible area
|
// Center the visible area
|
||||||
*xOffsetPtr = (*xResPtr - (unsigned) xRes)/2;
|
*xOffsetPtr = (*xResPtr - (unsigned) xRes)/2;
|
||||||
*yOffsetPtr = (*yResPtr - (unsigned) yRes)/2;
|
*yOffsetPtr = (*yResPtr - (unsigned) yRes)/2;
|
||||||
|
|
||||||
// If the desired resolution is smaller than what we got, re-center again
|
// If the desired resolution is smaller than what we got, re-center again
|
||||||
if (int(*xResPtr) < actualWidth)
|
if (int(*xResPtr) < actualWidth)
|
||||||
*xOffsetPtr += (actualWidth - *xResPtr)/2;
|
*xOffsetPtr += (actualWidth - *xResPtr)/2;
|
||||||
if (int(*yResPtr) < actualHeight)
|
if (int(*yResPtr) < actualHeight)
|
||||||
*yOffsetPtr += (actualHeight - *yResPtr)/2;
|
*yOffsetPtr += (actualHeight - *yResPtr)/2;
|
||||||
|
|
||||||
// OpenGL initialization
|
// OpenGL initialization
|
||||||
glViewport(0,0,*xResPtr,*yResPtr);
|
glViewport(0,0,*xResPtr,*yResPtr);
|
||||||
glClearColor(0.0,0.0,0.0,0.0);
|
glClearColor(0.0,0.0,0.0,0.0);
|
||||||
|
@ -142,14 +138,14 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
// Clear both buffers to ensure a black border
|
// Clear both buffers to ensure a black border
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||||
SDL_GL_SwapWindow(s_window);
|
SDL_GL_SwapWindow(s_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write back resolution parameters
|
// Write back resolution parameters
|
||||||
*xResPtr = (unsigned) xRes;
|
*xResPtr = (unsigned) xRes;
|
||||||
*yResPtr = (unsigned) yRes;
|
*yResPtr = (unsigned) yRes;
|
||||||
|
@ -157,7 +153,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
UINT32 correction = (UINT32)(((yRes / 384.f) * 2) + 0.5f);
|
UINT32 correction = (UINT32)(((yRes / 384.f) * 2) + 0.5f);
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
// Scissor box (to clip visible area)
|
// Scissor box (to clip visible area)
|
||||||
if (s_runtime_config["WideScreen"].ValueAsDefault<bool>(false))
|
if (s_runtime_config["WideScreen"].ValueAsDefault<bool>(false))
|
||||||
{
|
{
|
||||||
|
@ -175,7 +171,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
*
|
*
|
||||||
* Creates an OpenGL display surface of the requested size. xOffset and yOffset
|
* Creates an OpenGL display surface of the requested size. xOffset and yOffset
|
||||||
* are used to return a display surface offset (for OpenGL viewport commands)
|
* are used to return a display surface offset (for OpenGL viewport commands)
|
||||||
* because the actual drawing area may need to be adjusted to preserve the
|
* because the actual drawing area may need to be adjusted to preserve the
|
||||||
* Model 3 aspect ratio. The new resolution will be passed back as well -- both
|
* Model 3 aspect ratio. The new resolution will be passed back as well -- both
|
||||||
* the adjusted viewable area resolution and the total resolution.
|
* the adjusted viewable area resolution and the total resolution.
|
||||||
*
|
*
|
||||||
|
@ -185,7 +181,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
|
||||||
static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen)
|
static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen)
|
||||||
{
|
{
|
||||||
GLenum err;
|
GLenum err;
|
||||||
|
|
||||||
// Call only once per program session (this is because of issues with
|
// Call only once per program session (this is because of issues with
|
||||||
// DirectInput when the window is destroyed and a new one created). Use
|
// DirectInput when the window is destroyed and a new one created). Use
|
||||||
// ResizeGLScreen() to change resolutions instead.
|
// ResizeGLScreen() to change resolutions instead.
|
||||||
|
@ -197,7 +193,7 @@ static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigne
|
||||||
// Initialize video subsystem
|
// Initialize video subsystem
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
return ErrorLog("Unable to initialize SDL video subsystem: %s\n", SDL_GetError());
|
return ErrorLog("Unable to initialize SDL video subsystem: %s\n", SDL_GetError());
|
||||||
|
|
||||||
// Important GL attributes
|
// Important GL attributes
|
||||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
|
||||||
|
@ -205,7 +201,7 @@ static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigne
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,8);
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
|
||||||
|
|
||||||
// Set video mode
|
// Set video mode
|
||||||
s_window = SDL_CreateWindow(caption.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *xResPtr, *yResPtr, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | (fullScreen ? SDL_WINDOW_FULLSCREEN : 0));
|
s_window = SDL_CreateWindow(caption.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *xResPtr, *yResPtr, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | (fullScreen ? SDL_WINDOW_FULLSCREEN : 0));
|
||||||
if (nullptr == s_window)
|
if (nullptr == s_window)
|
||||||
|
@ -213,12 +209,12 @@ static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigne
|
||||||
ErrorLog("Unable to create an OpenGL display: %s\n", SDL_GetError());
|
ErrorLog("Unable to create an OpenGL display: %s\n", SDL_GetError());
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focusWindow)
|
if (focusWindow)
|
||||||
{
|
{
|
||||||
SDL_RaiseWindow(s_window);
|
SDL_RaiseWindow(s_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create OpenGL context
|
// Create OpenGL context
|
||||||
SDL_GLContext context = SDL_GL_CreateContext(s_window);
|
SDL_GLContext context = SDL_GL_CreateContext(s_window);
|
||||||
if (nullptr == context)
|
if (nullptr == context)
|
||||||
|
@ -229,10 +225,10 @@ static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigne
|
||||||
|
|
||||||
// Set vsync
|
// Set vsync
|
||||||
SDL_GL_SetSwapInterval(s_runtime_config["VSync"].ValueAsDefault<bool>(false) ? 1 : 0);
|
SDL_GL_SetSwapInterval(s_runtime_config["VSync"].ValueAsDefault<bool>(false) ? 1 : 0);
|
||||||
|
|
||||||
// Set the context as the current window context
|
// Set the context as the current window context
|
||||||
SDL_GL_MakeCurrent(s_window, context);
|
SDL_GL_MakeCurrent(s_window, context);
|
||||||
|
|
||||||
// Initialize GLEW, allowing us to use features beyond OpenGL 1.2
|
// Initialize GLEW, allowing us to use features beyond OpenGL 1.2
|
||||||
err = glewInit();
|
err = glewInit();
|
||||||
if (GLEW_OK != err)
|
if (GLEW_OK != err)
|
||||||
|
@ -240,7 +236,7 @@ static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigne
|
||||||
ErrorLog("OpenGL initialization failed: %s\n", glewGetErrorString(err));
|
ErrorLog("OpenGL initialization failed: %s\n", glewGetErrorString(err));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetGLGeometry(xOffsetPtr, yOffsetPtr, xResPtr, yResPtr, totalXResPtr, totalYResPtr, keepAspectRatio);
|
return SetGLGeometry(xOffsetPtr, yOffsetPtr, xResPtr, yResPtr, totalXResPtr, totalYResPtr, keepAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +257,7 @@ static bool ResizeGLScreen(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned
|
||||||
ErrorLog("Unable to enter %s mode: %s\n", fullScreen ? "fullscreen" : "windowed", SDL_GetError());
|
ErrorLog("Unable to enter %s mode: %s\n", fullScreen ? "fullscreen" : "windowed", SDL_GetError());
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SetGLGeometry(xOffsetPtr, yOffsetPtr, xResPtr, yResPtr, totalXResPtr, totalYResPtr, keepAspectRatio);
|
return SetGLGeometry(xOffsetPtr, yOffsetPtr, xResPtr, yResPtr, totalXResPtr, totalYResPtr, keepAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +269,7 @@ static bool ResizeGLScreen(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned
|
||||||
*/
|
*/
|
||||||
static void PrintGLInfo(bool createScreen, bool infoLog, bool printExtensions)
|
static void PrintGLInfo(bool createScreen, bool infoLog, bool printExtensions)
|
||||||
{
|
{
|
||||||
unsigned xOffset, yOffset, xRes=496, yRes=384, totalXRes, totalYRes;
|
unsigned xOffset, yOffset, xRes=496, yRes=384, totalXRes, totalYRes;
|
||||||
if (createScreen)
|
if (createScreen)
|
||||||
{
|
{
|
||||||
if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...", false, &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
|
if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...", false, &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
|
||||||
|
@ -282,7 +278,7 @@ static void PrintGLInfo(bool createScreen, bool infoLog, bool printExtensions)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint value;
|
GLint value;
|
||||||
if (infoLog) InfoLog("OpenGL information:");
|
if (infoLog) InfoLog("OpenGL information:");
|
||||||
else puts("OpenGL information:\n");
|
else puts("OpenGL information:\n");
|
||||||
|
@ -355,7 +351,7 @@ static void PrintBAT(unsigned regu, unsigned regl)
|
||||||
uint32_t ea_base = bepi << (31 - 14);
|
uint32_t ea_base = bepi << (31 - 14);
|
||||||
uint32_t ea_limit = ea_base + size - 1;
|
uint32_t ea_limit = ea_base + size - 1;
|
||||||
uint32_t pa_base = brpn << (31 - 14);
|
uint32_t pa_base = brpn << (31 - 14);
|
||||||
uint32_t pa_limit = pa_base + size - 1;
|
uint32_t pa_limit = pa_base + size - 1;
|
||||||
printf("%08X-%08X -> %08X-%08X ", ea_base, ea_limit, pa_base, pa_limit);
|
printf("%08X-%08X -> %08X-%08X ", ea_base, ea_limit, pa_base, pa_limit);
|
||||||
printf("%c%c%c%c ", (wimg&8)?'W':'-', (wimg&4)?'I':'-', (wimg&2)?'M':'-', (wimg&1)?'G':'-');
|
printf("%c%c%c%c ", (wimg&8)?'W':'-', (wimg&4)?'I':'-', (wimg&2)?'M':'-', (wimg&1)?'G':'-');
|
||||||
printf("PP=");
|
printf("PP=");
|
||||||
|
@ -431,7 +427,7 @@ static void DumpPPCRegisters(IBus *bus)
|
||||||
#include "Model3/Model3GraphicsState.h"
|
#include "Model3/Model3GraphicsState.h"
|
||||||
#include "Util/BMPFile.h"
|
#include "Util/BMPFile.h"
|
||||||
#include "OSD/SDL/PolyAnalysis.h"
|
#include "OSD/SDL/PolyAnalysis.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
static void SaveFrameBuffer(const std::string &file)
|
static void SaveFrameBuffer(const std::string &file)
|
||||||
{
|
{
|
||||||
|
@ -441,7 +437,7 @@ static void SaveFrameBuffer(const std::string &file)
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string s_gfxStatePath;
|
static std::string s_gfxStatePath;
|
||||||
|
|
||||||
static std::string GetFileBaseName(const std::string &file)
|
static std::string GetFileBaseName(const std::string &file)
|
||||||
{
|
{
|
||||||
std::string base = file;
|
std::string base = file;
|
||||||
|
@ -466,7 +462,7 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
||||||
0xffffff60,
|
0xffffff60,
|
||||||
0xff0300ff // contour, luminous, etc.
|
0xff0300ff // contour, luminous, etc.
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<uint32_t> unknownCullingNodeBits
|
const std::vector<uint32_t> unknownCullingNodeBits
|
||||||
{
|
{
|
||||||
0xffffffff,
|
0xffffffff,
|
||||||
|
@ -502,7 +498,7 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx = 0; idx < 10; idx++)
|
for (int idx = 0; idx < 10; idx++)
|
||||||
{
|
{
|
||||||
for (int bit = 0; bit < 32; bit++)
|
for (int bit = 0; bit < 32; bit++)
|
||||||
|
@ -523,13 +519,13 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
||||||
|
|
||||||
// Generate the HTML GUI
|
// Generate the HTML GUI
|
||||||
std::string file = Util::Format() << "Analysis/_" << GetFileBaseName(s_gfxStatePath) << ".html";
|
std::string file = Util::Format() << "Analysis/_" << GetFileBaseName(s_gfxStatePath) << ".html";
|
||||||
std::ofstream fs(file);
|
std::ofstream fs(file);
|
||||||
if (!fs.good())
|
if (!fs.good())
|
||||||
ErrorLog("Unable to open '%s' for writing.", file.c_str());
|
ErrorLog("Unable to open '%s' for writing.", file.c_str());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string contents = s_polyAnalysisHTMLPrologue;
|
std::string contents = s_polyAnalysisHTMLPrologue;
|
||||||
contents += " var g_file_base_name = '" + GetFileBaseName(s_gfxStatePath) + "';\n";
|
contents += " var g_file_base_name = '" + GetFileBaseName(s_gfxStatePath) + "';\n";
|
||||||
contents += " var g_unknown_poly_bits = [" + std::string(Util::Format(",").Join(unknownPolyBits)) + "];\n";
|
contents += " var g_unknown_poly_bits = [" + std::string(Util::Format(",").Join(unknownPolyBits)) + "];\n";
|
||||||
contents += " var g_unknown_culling_bits = [" + std::string(Util::Format(",").Join(unknownCullingNodeBits)) + "];\n";
|
contents += " var g_unknown_culling_bits = [" + std::string(Util::Format(",").Join(unknownCullingNodeBits)) + "];\n";
|
||||||
contents += s_polyAnalysisHTMLEpilogue;
|
contents += s_polyAnalysisHTMLEpilogue;
|
||||||
|
@ -543,15 +539,15 @@ static void TestPolygonHeaderBits(IEmulator *Emu)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Save States and NVRAM
|
Save States and NVRAM
|
||||||
|
|
||||||
Save states and NVRAM use the same basic format. When anything changes that
|
Save states and NVRAM use the same basic format. When anything changes that
|
||||||
breaks compatibility with previous versions of Supermodel, the save state
|
breaks compatibility with previous versions of Supermodel, the save state
|
||||||
and NVRAM version numbers must be incremented as needed.
|
and NVRAM version numbers must be incremented as needed.
|
||||||
|
|
||||||
Header block name: "Supermodel Save State" or "Supermodel NVRAM State"
|
Header block name: "Supermodel Save State" or "Supermodel NVRAM State"
|
||||||
Data: Save state file version (4-byte integer), ROM set ID (up to 9 bytes,
|
Data: Save state file version (4-byte integer), ROM set ID (up to 9 bytes,
|
||||||
including terminating \0).
|
including terminating \0).
|
||||||
|
|
||||||
Different subsystems output their own blocks.
|
Different subsystems output their own blocks.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -562,19 +558,19 @@ static unsigned s_saveSlot = 0; // save state slot #
|
||||||
static void SaveState(IEmulator *Model3)
|
static void SaveState(IEmulator *Model3)
|
||||||
{
|
{
|
||||||
CBlockFile SaveState;
|
CBlockFile SaveState;
|
||||||
|
|
||||||
std::string file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
|
std::string file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
|
||||||
if (OKAY != SaveState.Create(file_path, "Supermodel Save State", "Supermodel Version " SUPERMODEL_VERSION))
|
if (OKAY != SaveState.Create(file_path, "Supermodel Save State", "Supermodel Version " SUPERMODEL_VERSION))
|
||||||
{
|
{
|
||||||
ErrorLog("Unable to save state to '%s'.", file_path.c_str());
|
ErrorLog("Unable to save state to '%s'.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write file format version and ROM set ID to header block
|
// Write file format version and ROM set ID to header block
|
||||||
int32_t fileVersion = STATE_FILE_VERSION;
|
int32_t fileVersion = STATE_FILE_VERSION;
|
||||||
SaveState.Write(&fileVersion, sizeof(fileVersion));
|
SaveState.Write(&fileVersion, sizeof(fileVersion));
|
||||||
SaveState.Write(Model3->GetGame().name);
|
SaveState.Write(Model3->GetGame().name);
|
||||||
|
|
||||||
// Save state
|
// Save state
|
||||||
Model3->SaveState(&SaveState);
|
Model3->SaveState(&SaveState);
|
||||||
SaveState.Close();
|
SaveState.Close();
|
||||||
|
@ -585,24 +581,24 @@ static void SaveState(IEmulator *Model3)
|
||||||
static void LoadState(IEmulator *Model3, std::string file_path = std::string())
|
static void LoadState(IEmulator *Model3, std::string file_path = std::string())
|
||||||
{
|
{
|
||||||
CBlockFile SaveState;
|
CBlockFile SaveState;
|
||||||
|
|
||||||
// Generate file path
|
// Generate file path
|
||||||
if (file_path.empty())
|
if (file_path.empty())
|
||||||
file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
|
file_path = Util::Format() << "Saves/" << Model3->GetGame().name << ".st" << s_saveSlot;
|
||||||
|
|
||||||
// Open and check to make sure format is correct
|
// Open and check to make sure format is correct
|
||||||
if (OKAY != SaveState.Load(file_path))
|
if (OKAY != SaveState.Load(file_path))
|
||||||
{
|
{
|
||||||
ErrorLog("Unable to load state from '%s'.", file_path.c_str());
|
ErrorLog("Unable to load state from '%s'.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OKAY != SaveState.FindBlock("Supermodel Save State"))
|
if (OKAY != SaveState.FindBlock("Supermodel Save State"))
|
||||||
{
|
{
|
||||||
ErrorLog("'%s' does not appear to be a valid save state file.", file_path.c_str());
|
ErrorLog("'%s' does not appear to be a valid save state file.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t fileVersion;
|
int32_t fileVersion;
|
||||||
SaveState.Read(&fileVersion, sizeof(fileVersion));
|
SaveState.Read(&fileVersion, sizeof(fileVersion));
|
||||||
if (fileVersion != STATE_FILE_VERSION)
|
if (fileVersion != STATE_FILE_VERSION)
|
||||||
|
@ -610,7 +606,7 @@ static void LoadState(IEmulator *Model3, std::string file_path = std::string())
|
||||||
ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
|
ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load
|
// Load
|
||||||
Model3->LoadState(&SaveState);
|
Model3->LoadState(&SaveState);
|
||||||
SaveState.Close();
|
SaveState.Close();
|
||||||
|
@ -621,19 +617,19 @@ static void LoadState(IEmulator *Model3, std::string file_path = std::string())
|
||||||
static void SaveNVRAM(IEmulator *Model3)
|
static void SaveNVRAM(IEmulator *Model3)
|
||||||
{
|
{
|
||||||
CBlockFile NVRAM;
|
CBlockFile NVRAM;
|
||||||
|
|
||||||
std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
|
std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
|
||||||
if (OKAY != NVRAM.Create(file_path, "Supermodel NVRAM State", "Supermodel Version " SUPERMODEL_VERSION))
|
if (OKAY != NVRAM.Create(file_path, "Supermodel NVRAM State", "Supermodel Version " SUPERMODEL_VERSION))
|
||||||
{
|
{
|
||||||
ErrorLog("Unable to save NVRAM to '%s'. Make sure directory exists!", file_path.c_str());
|
ErrorLog("Unable to save NVRAM to '%s'. Make sure directory exists!", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write file format version and ROM set ID to header block
|
// Write file format version and ROM set ID to header block
|
||||||
int32_t fileVersion = NVRAM_FILE_VERSION;
|
int32_t fileVersion = NVRAM_FILE_VERSION;
|
||||||
NVRAM.Write(&fileVersion, sizeof(fileVersion));
|
NVRAM.Write(&fileVersion, sizeof(fileVersion));
|
||||||
NVRAM.Write(Model3->GetGame().name);
|
NVRAM.Write(Model3->GetGame().name);
|
||||||
|
|
||||||
// Save NVRAM
|
// Save NVRAM
|
||||||
Model3->SaveNVRAM(&NVRAM);
|
Model3->SaveNVRAM(&NVRAM);
|
||||||
NVRAM.Close();
|
NVRAM.Close();
|
||||||
|
@ -643,23 +639,23 @@ static void SaveNVRAM(IEmulator *Model3)
|
||||||
static void LoadNVRAM(IEmulator *Model3)
|
static void LoadNVRAM(IEmulator *Model3)
|
||||||
{
|
{
|
||||||
CBlockFile NVRAM;
|
CBlockFile NVRAM;
|
||||||
|
|
||||||
// Generate file path
|
// Generate file path
|
||||||
std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
|
std::string file_path = Util::Format() << "NVRAM/" << Model3->GetGame().name << ".nv";
|
||||||
|
|
||||||
// Open and check to make sure format is correct
|
// Open and check to make sure format is correct
|
||||||
if (OKAY != NVRAM.Load(file_path))
|
if (OKAY != NVRAM.Load(file_path))
|
||||||
{
|
{
|
||||||
//ErrorLog("Unable to restore NVRAM from '%s'.", filePath);
|
//ErrorLog("Unable to restore NVRAM from '%s'.", filePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OKAY != NVRAM.FindBlock("Supermodel NVRAM State"))
|
if (OKAY != NVRAM.FindBlock("Supermodel NVRAM State"))
|
||||||
{
|
{
|
||||||
ErrorLog("'%s' does not appear to be a valid NVRAM file.", file_path.c_str());
|
ErrorLog("'%s' does not appear to be a valid NVRAM file.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t fileVersion;
|
int32_t fileVersion;
|
||||||
NVRAM.Read(&fileVersion, sizeof(fileVersion));
|
NVRAM.Read(&fileVersion, sizeof(fileVersion));
|
||||||
if (fileVersion != NVRAM_FILE_VERSION)
|
if (fileVersion != NVRAM_FILE_VERSION)
|
||||||
|
@ -667,7 +663,7 @@ static void LoadNVRAM(IEmulator *Model3)
|
||||||
ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
|
ErrorLog("'%s' is incompatible with this version of Supermodel.", file_path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load
|
// Load
|
||||||
Model3->LoadNVRAM(&NVRAM);
|
Model3->LoadNVRAM(&NVRAM);
|
||||||
NVRAM.Close();
|
NVRAM.Close();
|
||||||
|
@ -677,7 +673,7 @@ static void LoadNVRAM(IEmulator *Model3)
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
UI Rendering
|
UI Rendering
|
||||||
|
|
||||||
Currently, only does crosshairs for light gun games.
|
Currently, only does crosshairs for light gun games.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -692,11 +688,11 @@ static void DrawCrosshair(float x, float y, float r, float g, float b)
|
||||||
float base = 0.01f, height = 0.02f; // geometric parameters of each triangle
|
float base = 0.01f, height = 0.02f; // geometric parameters of each triangle
|
||||||
float dist = 0.004f; // distance of triangle tip from center
|
float dist = 0.004f; // distance of triangle tip from center
|
||||||
float a = (float)xRes/(float)yRes; // aspect ratio (to square the crosshair)
|
float a = (float)xRes/(float)yRes; // aspect ratio (to square the crosshair)
|
||||||
|
|
||||||
glColor3f(r, g, b);
|
glColor3f(r, g, b);
|
||||||
glVertex2f(x, y+dist); // bottom triangle
|
glVertex2f(x, y+dist); // bottom triangle
|
||||||
glVertex2f(x+base/2.0f, y+(dist+height)*a);
|
glVertex2f(x+base/2.0f, y+(dist+height)*a);
|
||||||
glVertex2f(x-base/2.0f, y+(dist+height)*a);
|
glVertex2f(x-base/2.0f, y+(dist+height)*a);
|
||||||
glVertex2f(x, y-dist); // top triangle
|
glVertex2f(x, y-dist); // top triangle
|
||||||
glVertex2f(x-base/2.0f, y-(dist+height)*a);
|
glVertex2f(x-base/2.0f, y-(dist+height)*a);
|
||||||
glVertex2f(x+base/2.0f, y-(dist+height)*a);
|
glVertex2f(x+base/2.0f, y-(dist+height)*a);
|
||||||
|
@ -746,7 +742,7 @@ static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned c
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glDisable(GL_TEXTURE_2D); // no texture mapping
|
glDisable(GL_TEXTURE_2D); // no texture mapping
|
||||||
glDisable(GL_BLEND); // no blending
|
glDisable(GL_BLEND); // no blending
|
||||||
glDisable(GL_DEPTH_TEST); // no Z-buffering needed
|
glDisable(GL_DEPTH_TEST); // no Z-buffering needed
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
// Convert gun coordinates to viewspace coordinates
|
// Convert gun coordinates to viewspace coordinates
|
||||||
|
@ -776,7 +772,7 @@ static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned c
|
||||||
GunToViewCoords(&x[1], &y[1]);
|
GunToViewCoords(&x[1], &y[1]);
|
||||||
offscreenTrigger[1] = (Inputs->trigger[1]->offscreenValue) > 0;
|
offscreenTrigger[1] = (Inputs->trigger[1]->offscreenValue) > 0;
|
||||||
}
|
}
|
||||||
// Draw visible crosshairs
|
// Draw visible crosshairs
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1
|
if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1
|
||||||
DrawCrosshair(x[0], y[0], 1.0f, 0.0f, 0.0f);
|
DrawCrosshair(x[0], y[0], 1.0f, 0.0f, 0.0f);
|
||||||
|
@ -787,7 +783,7 @@ static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned c
|
||||||
//PrintGLError(glGetError());
|
//PrintGLError(glGetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
Video Callbacks
|
Video Callbacks
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -830,7 +826,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
CLogger *oldLogger = 0;
|
CLogger *oldLogger = 0;
|
||||||
#else
|
#else
|
||||||
int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs)
|
int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *Inputs, COutputs *Outputs)
|
||||||
{
|
{
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
std::string initialState = s_runtime_config["InitStateFile"].ValueAs<std::string>();
|
std::string initialState = s_runtime_config["InitStateFile"].ValueAs<std::string>();
|
||||||
unsigned prevFPSTicks;
|
unsigned prevFPSTicks;
|
||||||
|
@ -846,10 +842,10 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
if (Model3->LoadGame(game, *rom_set))
|
if (Model3->LoadGame(game, *rom_set))
|
||||||
return 1;
|
return 1;
|
||||||
*rom_set = ROMSet(); // free up this memory we won't need anymore
|
*rom_set = ROMSet(); // free up this memory we won't need anymore
|
||||||
|
|
||||||
// Load NVRAM
|
// Load NVRAM
|
||||||
LoadNVRAM(Model3);
|
LoadNVRAM(Model3);
|
||||||
|
|
||||||
// Set the video mode
|
// Set the video mode
|
||||||
char baseTitleStr[128];
|
char baseTitleStr[128];
|
||||||
char titleStr[128];
|
char titleStr[128];
|
||||||
|
@ -864,9 +860,9 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
if (OKAY != ResizeGLScreen(&xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, !stretch, fullscreen))
|
if (OKAY != ResizeGLScreen(&xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, !stretch, fullscreen))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Info log GL information
|
// Info log GL information
|
||||||
PrintGLInfo(false, true, false);
|
PrintGLInfo(false, true, false);
|
||||||
|
|
||||||
// Initialize audio system
|
// Initialize audio system
|
||||||
if (OKAY != OpenAudio())
|
if (OKAY != OpenAudio())
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -887,7 +883,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
// Attach the outputs to the emulator
|
// Attach the outputs to the emulator
|
||||||
if (Outputs != NULL)
|
if (Outputs != NULL)
|
||||||
Model3->AttachOutputs(Outputs);
|
Model3->AttachOutputs(Outputs);
|
||||||
|
|
||||||
// Initialize the renderers
|
// Initialize the renderers
|
||||||
CRender2D *Render2D = new CRender2D(s_runtime_config);
|
CRender2D *Render2D = new CRender2D(s_runtime_config);
|
||||||
IRender3D *Render3D = s_runtime_config["New3DEngine"].ValueAs<bool>() ? ((IRender3D *) new New3D::CNew3D(s_runtime_config, Model3->GetGame().name)) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config));
|
IRender3D *Render3D = s_runtime_config["New3DEngine"].ValueAs<bool>() ? ((IRender3D *) new New3D::CNew3D(s_runtime_config, Model3->GetGame().name)) : ((IRender3D *) new Legacy3D::CLegacy3D(s_runtime_config));
|
||||||
|
@ -899,11 +895,11 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
|
|
||||||
// Reset emulator
|
// Reset emulator
|
||||||
Model3->Reset();
|
Model3->Reset();
|
||||||
|
|
||||||
// Load initial save state if requested
|
// Load initial save state if requested
|
||||||
if (initialState.length() > 0)
|
if (initialState.length() > 0)
|
||||||
LoadState(Model3, initialState);
|
LoadState(Model3, initialState);
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// If debugger was supplied, set it as logger and attach it to system
|
// If debugger was supplied, set it as logger and attach it to system
|
||||||
oldLogger = GetLogger();
|
oldLogger = GetLogger();
|
||||||
|
@ -936,11 +932,11 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
Model3->RenderFrame();
|
Model3->RenderFrame();
|
||||||
else
|
else
|
||||||
Model3->RunFrame();
|
Model3->RunFrame();
|
||||||
|
|
||||||
// Poll the inputs
|
// Poll the inputs
|
||||||
if (!Inputs->Poll(&game, xOffset, yOffset, xRes, yRes))
|
if (!Inputs->Poll(&game, xOffset, yOffset, xRes, yRes))
|
||||||
quit = true;
|
quit = true;
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
bool processUI = true;
|
bool processUI = true;
|
||||||
if (Debugger != NULL)
|
if (Debugger != NULL)
|
||||||
|
@ -953,7 +949,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
quit = true;
|
quit = true;
|
||||||
processUI = false;
|
processUI = false;
|
||||||
}
|
}
|
||||||
else if (Debugger->CheckPause())
|
else if (Debugger->CheckPause())
|
||||||
{
|
{
|
||||||
paused = true;
|
paused = true;
|
||||||
processUI = false;
|
processUI = false;
|
||||||
|
@ -967,7 +963,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
if (Inputs->uiExit->Pressed())
|
if (Inputs->uiExit->Pressed())
|
||||||
{
|
{
|
||||||
// Quit emulator
|
// Quit emulator
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
else if (Inputs->uiReset->Pressed())
|
else if (Inputs->uiReset->Pressed())
|
||||||
{
|
{
|
||||||
|
@ -979,7 +975,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
|
|
||||||
// Reset emulator
|
// Reset emulator
|
||||||
Model3->Reset();
|
Model3->Reset();
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// If debugger was supplied, reset it too
|
// If debugger was supplied, reset it too
|
||||||
if (Debugger != NULL)
|
if (Debugger != NULL)
|
||||||
|
@ -1012,7 +1008,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
SetAudioEnabled(true);
|
SetAudioEnabled(true);
|
||||||
SDL_SetWindowTitle(s_window, baseTitleStr);
|
SDL_SetWindowTitle(s_window, baseTitleStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send paused value as output
|
// Send paused value as output
|
||||||
if (Outputs != NULL)
|
if (Outputs != NULL)
|
||||||
Outputs->SetValue(OutputPause, paused);
|
Outputs->SetValue(OutputPause, paused);
|
||||||
|
@ -1027,7 +1023,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
delete Render3D;
|
delete Render3D;
|
||||||
Render2D = NULL;
|
Render2D = NULL;
|
||||||
Render3D = NULL;
|
Render3D = NULL;
|
||||||
|
|
||||||
// Resize screen
|
// Resize screen
|
||||||
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
|
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
|
||||||
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
|
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
|
||||||
|
@ -1044,7 +1040,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
|
if (OKAY != Render3D->Init(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes))
|
||||||
goto QuitError;
|
goto QuitError;
|
||||||
Model3->AttachRenderers(Render2D,Render3D);
|
Model3->AttachRenderers(Render2D,Render3D);
|
||||||
|
|
||||||
Inputs->GetInputSystem()->SetMouseVisibility(!s_runtime_config["FullScreen"].ValueAs<bool>());
|
Inputs->GetInputSystem()->SetMouseVisibility(!s_runtime_config["FullScreen"].ValueAs<bool>());
|
||||||
}
|
}
|
||||||
else if (Inputs->uiSaveState->Pressed())
|
else if (Inputs->uiSaveState->Pressed())
|
||||||
|
@ -1081,7 +1077,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
|
|
||||||
// Load game state
|
// Load game state
|
||||||
LoadState(Model3);
|
LoadState(Model3);
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// If debugger was supplied, reset it after loading state
|
// If debugger was supplied, reset it after loading state
|
||||||
if (Debugger != NULL)
|
if (Debugger != NULL)
|
||||||
|
@ -1122,7 +1118,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
puts(" (muted)");
|
puts(" (muted)");
|
||||||
else
|
else
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
puts("This game does not have an MPEG music board.");
|
puts("This game does not have an MPEG music board.");
|
||||||
}
|
}
|
||||||
|
@ -1191,8 +1187,8 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
|
||||||
|
|
||||||
// Frame rate and limiting
|
// Frame rate and limiting
|
||||||
unsigned currentFPSTicks = SDL_GetTicks();
|
unsigned currentFPSTicks = SDL_GetTicks();
|
||||||
if (s_runtime_config["ShowFrameRate"].ValueAs<bool>())
|
if (s_runtime_config["ShowFrameRate"].ValueAs<bool>())
|
||||||
|
@ -1206,7 +1202,7 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
fpsFramesElapsed = 0; // reset frame count
|
fpsFramesElapsed = 0; // reset frame count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paused || s_runtime_config["Throttle"].ValueAs<bool>())
|
if (paused || s_runtime_config["Throttle"].ValueAs<bool>())
|
||||||
{
|
{
|
||||||
UINT32 endTime = SDL_GetTicks();
|
UINT32 endTime = SDL_GetTicks();
|
||||||
|
@ -1227,8 +1223,8 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all threads are paused before shutting down
|
// Make sure all threads are paused before shutting down
|
||||||
Model3->PauseThreads();
|
Model3->PauseThreads();
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// If debugger was supplied, detach it from system and restore old logger
|
// If debugger was supplied, detach it from system and restore old logger
|
||||||
if (Debugger != NULL)
|
if (Debugger != NULL)
|
||||||
|
@ -1237,10 +1233,10 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
|
||||||
SetLogger(oldLogger);
|
SetLogger(oldLogger);
|
||||||
}
|
}
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
|
||||||
// Save NVRAM
|
// Save NVRAM
|
||||||
SaveNVRAM(Model3);
|
SaveNVRAM(Model3);
|
||||||
|
|
||||||
// Close audio
|
// Close audio
|
||||||
CloseAudio();
|
CloseAudio();
|
||||||
|
|
||||||
|
@ -1273,9 +1269,9 @@ static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Uti
|
||||||
"; Supermodel Configuration File\n"
|
"; Supermodel Configuration File\n"
|
||||||
";\n"
|
";\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
Inputs->LoadFromConfig(*runtimeConfig);
|
Inputs->LoadFromConfig(*runtimeConfig);
|
||||||
|
|
||||||
// If the user wants to configure the inputs, do that now
|
// If the user wants to configure the inputs, do that now
|
||||||
if (configure)
|
if (configure)
|
||||||
{
|
{
|
||||||
|
@ -1294,14 +1290,14 @@ static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Uti
|
||||||
{
|
{
|
||||||
fileConfigRoot = &fileConfig->Add(game.name);
|
fileConfigRoot = &fileConfig->Add(game.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the inputs
|
// Configure the inputs
|
||||||
if (Inputs->ConfigureInputs(game, xOffset, yOffset, xRes, yRes))
|
if (Inputs->ConfigureInputs(game, xOffset, yOffset, xRes, yRes))
|
||||||
{
|
{
|
||||||
// Write input configuration and input system settings to config file
|
// Write input configuration and input system settings to config file
|
||||||
Inputs->StoreToConfig(fileConfigRoot);
|
Inputs->StoreToConfig(fileConfigRoot);
|
||||||
Util::Config::WriteINIFile(s_configFilePath, *fileConfig, configFileComment);
|
Util::Config::WriteINIFile(s_configFilePath, *fileConfig, configFileComment);
|
||||||
|
|
||||||
// Also save to runtime configuration in case we proceed and play
|
// Also save to runtime configuration in case we proceed and play
|
||||||
Inputs->StoreToConfig(runtimeConfig);
|
Inputs->StoreToConfig(runtimeConfig);
|
||||||
}
|
}
|
||||||
|
@ -1309,7 +1305,7 @@ static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Uti
|
||||||
puts("Configuration aborted...");
|
puts("Configuration aborted...");
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return OKAY;
|
return OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1379,7 +1375,7 @@ static Util::Config::Node DefaultConfig()
|
||||||
#ifdef SUPERMODEL_WIN32
|
#ifdef SUPERMODEL_WIN32
|
||||||
config.Set("ForceFeedback", false);
|
config.Set("ForceFeedback", false);
|
||||||
#endif
|
#endif
|
||||||
// Platform-specific/UI
|
// Platform-specific/UI
|
||||||
config.Set("New3DEngine", true);
|
config.Set("New3DEngine", true);
|
||||||
config.Set("QuadRendering", false);
|
config.Set("QuadRendering", false);
|
||||||
config.Set("XResolution", "496");
|
config.Set("XResolution", "496");
|
||||||
|
@ -1418,7 +1414,7 @@ static Util::Config::Node DefaultConfig()
|
||||||
static void Title(void)
|
static void Title(void)
|
||||||
{
|
{
|
||||||
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
|
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
|
||||||
puts("Copyright 2011-2019 by Bart Trzynadlowski, Nik Henson, Ian Curtis,");
|
puts("Copyright 2011-2020 by Bart Trzynadlowski, Nik Henson, Ian Curtis,");
|
||||||
puts(" Harry Tuttle, and Spindizzi\n");
|
puts(" Harry Tuttle, and Spindizzi\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1573,7 +1569,7 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
|
||||||
{ "-no-force-feedback", { "ForceFeedback", false } },
|
{ "-no-force-feedback", { "ForceFeedback", false } },
|
||||||
{ "-force-feedback", { "ForceFeedback", true } },
|
{ "-force-feedback", { "ForceFeedback", true } },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
@ -1697,7 +1693,7 @@ int main(int argc, char **argv)
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
InfoLog(" argv[%d] = %s", i, argv[i]);
|
InfoLog(" argv[%d] = %s", i, argv[i]);
|
||||||
InfoLog("");
|
InfoLog("");
|
||||||
|
|
||||||
// Load config and parse command line
|
// Load config and parse command line
|
||||||
auto cmd_line = ParseCommandLine(argc, argv);
|
auto cmd_line = ParseCommandLine(argc, argv);
|
||||||
if (cmd_line.print_help)
|
if (cmd_line.print_help)
|
||||||
|
@ -1718,7 +1714,7 @@ int main(int argc, char **argv)
|
||||||
bool rom_specified = !cmd_line.rom_files.empty();
|
bool rom_specified = !cmd_line.rom_files.empty();
|
||||||
if (!rom_specified && !print_games && !cmd_line.config_inputs && !cmd_line.print_inputs)
|
if (!rom_specified && !print_games && !cmd_line.config_inputs && !cmd_line.print_inputs)
|
||||||
{
|
{
|
||||||
ErrorLog("No ROM file specified.");
|
ErrorLog("No ROM file specified.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1760,7 +1756,7 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin initializing various subsystems...
|
// Begin initializing various subsystems...
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
IEmulator *Model3 = nullptr;
|
IEmulator *Model3 = nullptr;
|
||||||
CInputSystem *InputSystem = nullptr;
|
CInputSystem *InputSystem = nullptr;
|
||||||
|
@ -1769,7 +1765,7 @@ int main(int argc, char **argv)
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
Debugger::CSupermodelDebugger *Debugger = NULL;
|
Debugger::CSupermodelDebugger *Debugger = NULL;
|
||||||
#endif // SUPERMODEL_DEBUGGER
|
#endif // SUPERMODEL_DEBUGGER
|
||||||
|
|
||||||
// Create a window
|
// Create a window
|
||||||
xRes = 496;
|
xRes = 496;
|
||||||
yRes = 384;
|
yRes = 384;
|
||||||
|
@ -1778,7 +1774,7 @@ int main(int argc, char **argv)
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Model 3 emulator
|
// Create Model 3 emulator
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Model3 = s_gfxStatePath.empty() ? static_cast<IEmulator *>(new CModel3(s_runtime_config)) : static_cast<IEmulator *>(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath));
|
Model3 = s_gfxStatePath.empty() ? static_cast<IEmulator *>(new CModel3(s_runtime_config)) : static_cast<IEmulator *>(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath));
|
||||||
|
@ -1812,7 +1808,7 @@ int main(int argc, char **argv)
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: fileConfig is passed so that the global section is used for input settings
|
// NOTE: fileConfig is passed so that the global section is used for input settings
|
||||||
// and because this function may write out a new config file, which must preserve
|
// and because this function may write out a new config file, which must preserve
|
||||||
// all sections. We don't want to pollute the output with built-in defaults.
|
// all sections. We don't want to pollute the output with built-in defaults.
|
||||||
|
@ -1827,11 +1823,11 @@ int main(int argc, char **argv)
|
||||||
Inputs->PrintInputs(NULL);
|
Inputs->PrintInputs(NULL);
|
||||||
InputSystem->PrintSettings();
|
InputSystem->PrintSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rom_specified)
|
if (!rom_specified)
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
// Create outputs
|
// Create outputs
|
||||||
#ifdef SUPERMODEL_WIN32
|
#ifdef SUPERMODEL_WIN32
|
||||||
{
|
{
|
||||||
std::string outputs = s_runtime_config["Outputs"].ValueAs<std::string>();
|
std::string outputs = s_runtime_config["Outputs"].ValueAs<std::string>();
|
||||||
|
@ -1855,7 +1851,7 @@ int main(int argc, char **argv)
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DEBUGGER
|
#ifdef SUPERMODEL_DEBUGGER
|
||||||
// Create Supermodel debugger unless debugging is disabled
|
// Create Supermodel debugger unless debugging is disabled
|
||||||
if (!cmd_line.disable_debugger)
|
if (!cmd_line.disable_debugger)
|
||||||
|
@ -1884,11 +1880,11 @@ Exit:
|
||||||
delete Outputs;
|
delete Outputs;
|
||||||
DestroyGLScreen();
|
DestroyGLScreen();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
if (exitCode)
|
if (exitCode)
|
||||||
InfoLog("Program terminated due to an error.");
|
InfoLog("Program terminated due to an error.");
|
||||||
else
|
else
|
||||||
InfoLog("Program terminated normally.");
|
InfoLog("Program terminated normally.");
|
||||||
|
|
||||||
return exitCode;
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
48
Src/OSD/SDL/SDLIncludes.h
Normal file
48
Src/OSD/SDL/SDLIncludes.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
** Supermodel
|
||||||
|
** A Sega Model 3 Arcade Emulator.
|
||||||
|
** Copyright 2011-2019 Bart Trzynadlowski, Nik Henson, Ian Curtis,
|
||||||
|
** Harry Tuttle, and Spindizzi
|
||||||
|
**
|
||||||
|
** This file is part of Supermodel.
|
||||||
|
**
|
||||||
|
** Supermodel 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 3 of the License, or (at your option)
|
||||||
|
** any later version.
|
||||||
|
**
|
||||||
|
** Supermodel 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 Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDLIncludes.h
|
||||||
|
*
|
||||||
|
* Header file for SDL library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INCLUDED_SDLINCLUDES_H
|
||||||
|
#define INCLUDED_SDLINCLUDES_H
|
||||||
|
|
||||||
|
#ifdef SUPERMODEL_OSX
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_audio.h>
|
||||||
|
#else
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <SDL_audio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NET_BOARD
|
||||||
|
#ifdef SUPERMODEL_OSX
|
||||||
|
#include <SDL2_net/SDL_net.h>
|
||||||
|
#else
|
||||||
|
#include <SDL_net.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // INCLUDED_SDLINCLUDES_H
|
|
@ -29,8 +29,8 @@
|
||||||
* - Implement multiple keyboard and mouse support.
|
* - Implement multiple keyboard and mouse support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SDLInputSystem.h"
|
|
||||||
#include "Supermodel.h"
|
#include "Supermodel.h"
|
||||||
|
#include "SDLInputSystem.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -387,7 +387,7 @@ bool CSDLInputSystem::Poll()
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_QUIT:
|
||||||
return false;
|
return false;
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
if (e.button.y > 0)
|
if (e.button.y > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
** This file is part of Supermodel.
|
** This file is part of Supermodel.
|
||||||
**
|
**
|
||||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
** Supermodel 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
|
** the terms of the GNU General Public License as published by the Free
|
||||||
** Software Foundation, either version 3 of the License, or (at your option)
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
** any later version.
|
** any later version.
|
||||||
**
|
**
|
||||||
|
@ -18,10 +18,10 @@
|
||||||
** You should have received a copy of the GNU General Public License along
|
** You should have received a copy of the GNU General Public License along
|
||||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SDLInputSystem.h
|
* SDLInputSystem.h
|
||||||
*
|
*
|
||||||
* Header file for SDL input system.
|
* Header file for SDL input system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -31,12 +31,7 @@
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include "Inputs/InputSource.h"
|
#include "Inputs/InputSource.h"
|
||||||
#include "Inputs/InputSystem.h"
|
#include "Inputs/InputSystem.h"
|
||||||
|
#include "SDLIncludes.h"
|
||||||
#ifdef SUPERMODEL_OSX
|
|
||||||
#include <SDL/SDL.h>
|
|
||||||
#else
|
|
||||||
#include <SDL.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -74,7 +69,7 @@ private:
|
||||||
short m_mouseWheelDir;
|
short m_mouseWheelDir;
|
||||||
Uint8 m_mouseButtons;
|
Uint8 m_mouseButtons;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Opens all attached joysticks.
|
* Opens all attached joysticks.
|
||||||
*/
|
*/
|
||||||
void OpenJoysticks();
|
void OpenJoysticks();
|
||||||
|
@ -97,7 +92,7 @@ protected:
|
||||||
bool IsKeyPressed(int kbdNum, int keyIndex);
|
bool IsKeyPressed(int kbdNum, int keyIndex);
|
||||||
|
|
||||||
int GetMouseAxisValue(int mseNum, int axisNum);
|
int GetMouseAxisValue(int mseNum, int axisNum);
|
||||||
|
|
||||||
int GetMouseWheelDir(int mseNum);
|
int GetMouseWheelDir(int mseNum);
|
||||||
|
|
||||||
bool IsMouseButPressed(int mseNum, int butNum);
|
bool IsMouseButPressed(int mseNum, int butNum);
|
||||||
|
@ -118,10 +113,10 @@ public:
|
||||||
|
|
||||||
~CSDLInputSystem();
|
~CSDLInputSystem();
|
||||||
|
|
||||||
int GetNumKeyboards();
|
int GetNumKeyboards();
|
||||||
|
|
||||||
int GetNumMice();
|
int GetNumMice();
|
||||||
|
|
||||||
int GetNumJoysticks();
|
int GetNumJoysticks();
|
||||||
|
|
||||||
const KeyDetails *GetKeyDetails(int kbdNum);
|
const KeyDetails *GetKeyDetails(int kbdNum);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
** This file is part of Supermodel.
|
** This file is part of Supermodel.
|
||||||
**
|
**
|
||||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
** Supermodel 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
|
** the terms of the GNU General Public License as published by the Free
|
||||||
** Software Foundation, either version 3 of the License, or (at your option)
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
** any later version.
|
** any later version.
|
||||||
**
|
**
|
||||||
|
@ -18,22 +18,15 @@
|
||||||
** You should have received a copy of the GNU General Public License along
|
** You should have received a copy of the GNU General Public License along
|
||||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread.cpp
|
* Thread.cpp
|
||||||
*
|
*
|
||||||
* SDL-based implementation of threading primitives.
|
* SDL-based implementation of threading primitives.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Supermodel.h"
|
|
||||||
|
|
||||||
#ifdef SUPERMODEL_OSX
|
#include "Supermodel.h"
|
||||||
#include <SDL/SDL.h>
|
#include "SDLIncludes.h"
|
||||||
#include <SDL/SDL_thread.h>
|
|
||||||
#else
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <SDL_thread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void CThread::Sleep(UINT32 ms)
|
void CThread::Sleep(UINT32 ms)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +78,7 @@ const char *CThread::GetLastError()
|
||||||
CThread::CThread(const std::string &name, void *impl)
|
CThread::CThread(const std::string &name, void *impl)
|
||||||
: m_name(name),
|
: m_name(name),
|
||||||
m_impl(impl)
|
m_impl(impl)
|
||||||
|
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
@ -95,7 +88,7 @@ CThread::~CThread()
|
||||||
// User should have called Wait() before thread object is destroyed
|
// User should have called Wait() before thread object is destroyed
|
||||||
if (nullptr != m_impl)
|
if (nullptr != m_impl)
|
||||||
{
|
{
|
||||||
ErrorLog("Runaway thread error. A thread was not properly halted: %s\n", GetName());
|
ErrorLog("Runaway thread error. A thread was not properly halted: %s\n", GetName().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
131
Src/Pkgs/crypt.h
Normal file
131
Src/Pkgs/crypt.h
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
/* 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 z_crc_t* 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 z_crc_t* 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 z_crc_t* 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(const char* passwd, /* password string */
|
||||||
|
unsigned char* buf, /* where to write header */
|
||||||
|
int bufSize,
|
||||||
|
unsigned long* pkeys,
|
||||||
|
const z_crc_t* 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++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
|
||||||
|
buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -10,10 +10,22 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if (defined(_WIN32))
|
#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__APPLE__) || defined(IOAPI_NO_64)
|
||||||
|
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
|
||||||
|
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
|
||||||
|
#define FTELLO_FUNC(stream) ftello(stream)
|
||||||
|
#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
|
||||||
|
#else
|
||||||
|
#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
|
||||||
|
#define FTELLO_FUNC(stream) ftello64(stream)
|
||||||
|
#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "ioapi.h"
|
#include "ioapi.h"
|
||||||
|
|
||||||
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
|
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
|
||||||
|
@ -47,7 +59,7 @@ ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
|
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
|
||||||
if ((tell_uLong) == ((uLong)-1))
|
if ((tell_uLong) == MAXU32)
|
||||||
return (ZPOS64_T)-1;
|
return (ZPOS64_T)-1;
|
||||||
else
|
else
|
||||||
return tell_uLong;
|
return tell_uLong;
|
||||||
|
@ -112,7 +124,7 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename,
|
||||||
mode_fopen = "wb";
|
mode_fopen = "wb";
|
||||||
|
|
||||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||||
file = fopen64((const char*)filename, mode_fopen);
|
file = FOPEN_FUNC((const char*)filename, mode_fopen);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +154,7 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
|
||||||
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
|
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
|
||||||
{
|
{
|
||||||
ZPOS64_T ret;
|
ZPOS64_T ret;
|
||||||
ret = ftello64((FILE *)stream);
|
ret = FTELLO_FUNC((FILE *)stream);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +200,7 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
|
if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef _ZLIBIOAPI64_H
|
#ifndef _ZLIBIOAPI64_H
|
||||||
#define _ZLIBIOAPI64_H
|
#define _ZLIBIOAPI64_H
|
||||||
|
|
||||||
#if (!defined(_WIN32)) && (!defined(WIN32))
|
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
|
||||||
|
|
||||||
// Linux needs this to support file operation on files larger then 4+GB
|
// Linux needs this to support file operation on files larger then 4+GB
|
||||||
// But might need better if/def to select just the platforms that needs them.
|
// But might need better if/def to select just the platforms that needs them.
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
#ifndef _FILE_OFFSET_BIT
|
#ifndef _FILE_OFFSET_BIT
|
||||||
#define _FILE_OFFSET_BIT 64
|
#define _FILE_OFFSET_BIT 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -49,6 +50,11 @@
|
||||||
#define ftello64 ftell
|
#define ftello64 ftell
|
||||||
#define fseeko64 fseek
|
#define fseeko64 fseek
|
||||||
#else
|
#else
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#define fopen64 fopen
|
||||||
|
#define ftello64 ftello
|
||||||
|
#define fseeko64 fseeko
|
||||||
|
#endif
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define fopen64 fopen
|
#define fopen64 fopen
|
||||||
#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
|
#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
|
||||||
|
@ -85,6 +91,8 @@ typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
|
||||||
typedef uint64_t ZPOS64_T;
|
typedef uint64_t ZPOS64_T;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* Maximum unsigned 32-bit value used as placeholder for zip64 */
|
||||||
|
#define MAXU32 0xffffffff
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef unsigned __int64 ZPOS64_T;
|
typedef unsigned __int64 ZPOS64_T;
|
||||||
|
|
|
@ -188,7 +188,7 @@ typedef struct
|
||||||
|
|
||||||
# ifndef NOUNCRYPT
|
# ifndef NOUNCRYPT
|
||||||
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
|
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
|
||||||
const unsigned long* pcrc_32_tab;
|
const z_crc_t* pcrc_32_tab;
|
||||||
# endif
|
# endif
|
||||||
} unz64_s;
|
} unz64_s;
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ typedef struct
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
|
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
|
||||||
for end of file.
|
for end of file.
|
||||||
IN assertion: the stream s has been sucessfully opened for reading.
|
IN assertion: the stream s has been successfully opened for reading.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -801,9 +801,9 @@ extern unzFile ZEXPORT unzOpen64 (const void *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Close a ZipFile opened with unzipOpen.
|
Close a ZipFile opened with unzOpen.
|
||||||
If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
|
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
these files MUST be closed with unzCloseCurrentFile before call unzClose.
|
||||||
return UNZ_OK if there is no problem. */
|
return UNZ_OK if there is no problem. */
|
||||||
extern int ZEXPORT unzClose (unzFile file)
|
extern int ZEXPORT unzClose (unzFile file)
|
||||||
{
|
{
|
||||||
|
@ -1040,26 +1040,26 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||||
{
|
{
|
||||||
uLong uL;
|
uLong uL;
|
||||||
|
|
||||||
if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
|
if(file_info.uncompressed_size == MAXU32)
|
||||||
{
|
{
|
||||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
|
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
|
||||||
err=UNZ_ERRNO;
|
err=UNZ_ERRNO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
|
if(file_info.compressed_size == MAXU32)
|
||||||
{
|
{
|
||||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
|
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
|
||||||
err=UNZ_ERRNO;
|
err=UNZ_ERRNO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
|
if(file_info_internal.offset_curfile == MAXU32)
|
||||||
{
|
{
|
||||||
/* Relative Header offset */
|
/* Relative Header offset */
|
||||||
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
|
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
|
||||||
err=UNZ_ERRNO;
|
err=UNZ_ERRNO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_info.disk_num_start == (unsigned long)-1)
|
if(file_info.disk_num_start == MAXU32)
|
||||||
{
|
{
|
||||||
/* Disk Start Number */
|
/* Disk Start Number */
|
||||||
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||||
|
@ -1145,7 +1145,7 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
|
||||||
szFileName,fileNameBufferSize,
|
szFileName,fileNameBufferSize,
|
||||||
extraField,extraFieldBufferSize,
|
extraField,extraFieldBufferSize,
|
||||||
szComment,commentBufferSize);
|
szComment,commentBufferSize);
|
||||||
if (err==UNZ_OK)
|
if ((err==UNZ_OK) && (pfile_info != NULL))
|
||||||
{
|
{
|
||||||
pfile_info->version = file_info64.version;
|
pfile_info->version = file_info64.version;
|
||||||
pfile_info->version_needed = file_info64.version_needed;
|
pfile_info->version_needed = file_info64.version_needed;
|
||||||
|
@ -1223,7 +1223,7 @@ extern int ZEXPORT unzGoToNextFile (unzFile file)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try locate the file szFileName in the zipfile.
|
Try locate the file szFileName in the zipfile.
|
||||||
For the iCaseSensitivity signification, see unzipStringFileNameCompare
|
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||||
|
|
||||||
return value :
|
return value :
|
||||||
UNZ_OK if the file is found. It becomes the current file.
|
UNZ_OK if the file is found. It becomes the current file.
|
||||||
|
@ -1696,7 +1696,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
|
||||||
return UNZ_PARAMERROR;
|
return UNZ_PARAMERROR;
|
||||||
|
|
||||||
|
|
||||||
if ((pfile_in_zip_read_info->read_buffer == NULL))
|
if (pfile_in_zip_read_info->read_buffer == NULL)
|
||||||
return UNZ_END_OF_LIST_OF_FILE;
|
return UNZ_END_OF_LIST_OF_FILE;
|
||||||
if (len==0)
|
if (len==0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1998,7 +1998,7 @@ extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Close the file in zip opened with unzipOpenCurrentFile
|
Close the file in zip opened with unzOpenCurrentFile
|
||||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||||
*/
|
*/
|
||||||
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
extern int ZEXPORT unzCloseCurrentFile (unzFile file)
|
||||||
|
|
|
@ -197,9 +197,9 @@ extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
|
||||||
|
|
||||||
extern int ZEXPORT unzClose OF((unzFile file));
|
extern int ZEXPORT unzClose OF((unzFile file));
|
||||||
/*
|
/*
|
||||||
Close a ZipFile opened with unzipOpen.
|
Close a ZipFile opened with unzOpen.
|
||||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
these files MUST be closed with unzCloseCurrentFile before call unzClose.
|
||||||
return UNZ_OK if there is no problem. */
|
return UNZ_OK if there is no problem. */
|
||||||
|
|
||||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||||
|
|
Loading…
Reference in a new issue