Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e9cde361e | |||
| ee3ffeeacc | |||
| 8a1427db5c | |||
| 10724c5437 | |||
| 88b1044105 |
@@ -67,6 +67,11 @@
|
||||
87709EE3294D2B0D0084AEE0 /* lcdcompzapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 87709EE2294D2B0D0084AEE0 /* lcdcompzapper.cpp */; };
|
||||
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
|
||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
||||
8F28FD5029FD3E7D008FC4A9 /* 354.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F28FD4D29FD3E7D008FC4A9 /* 354.cpp */; };
|
||||
8F28FD5129FD3E7D008FC4A9 /* coolgirl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F28FD4E29FD3E7D008FC4A9 /* coolgirl.cpp */; };
|
||||
8F28FD5229FD3E7D008FC4A9 /* inx007t.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F28FD4F29FD3E7D008FC4A9 /* inx007t.cpp */; };
|
||||
8F28FD5529FD3EA4008FC4A9 /* debugsymboltable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F28FD5329FD3EA4008FC4A9 /* debugsymboltable.cpp */; };
|
||||
8F28FD5829FD3EB8008FC4A9 /* mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8F28FD5629FD3EB8008FC4A9 /* mutex.cpp */; };
|
||||
945942D014E4F2DC0015D2AA /* FCEUX.icns in Resources */ = {isa = PBXBuildFile; fileRef = 945942CF14E4F2DC0015D2AA /* FCEUX.icns */; };
|
||||
949BBA741A9EF079007B49CC /* 01-222.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949BB7521A9EED55007B49CC /* 01-222.cpp */; };
|
||||
949BBA751A9EF079007B49CC /* 09-034a.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949BB7531A9EED55007B49CC /* 09-034a.cpp */; };
|
||||
@@ -334,6 +339,13 @@
|
||||
87709EE2294D2B0D0084AEE0 /* lcdcompzapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lcdcompzapper.cpp; sourceTree = "<group>"; };
|
||||
8D5B49B6048680CD000E48DA /* FCEU.oecoreplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FCEU.oecoreplugin; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8F28FD4D29FD3E7D008FC4A9 /* 354.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 354.cpp; sourceTree = "<group>"; };
|
||||
8F28FD4E29FD3E7D008FC4A9 /* coolgirl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coolgirl.cpp; sourceTree = "<group>"; };
|
||||
8F28FD4F29FD3E7D008FC4A9 /* inx007t.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = inx007t.cpp; sourceTree = "<group>"; };
|
||||
8F28FD5329FD3EA4008FC4A9 /* debugsymboltable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugsymboltable.cpp; sourceTree = "<group>"; };
|
||||
8F28FD5429FD3EA4008FC4A9 /* debugsymboltable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugsymboltable.h; sourceTree = "<group>"; };
|
||||
8F28FD5629FD3EB8008FC4A9 /* mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mutex.cpp; sourceTree = "<group>"; };
|
||||
8F28FD5729FD3EB8008FC4A9 /* mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mutex.h; sourceTree = "<group>"; };
|
||||
945942CE14E4EF180015D2AA /* OENESSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OENESSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/NES/OENESSystemResponderClient.h; sourceTree = "<group>"; };
|
||||
945942CF14E4F2DC0015D2AA /* FCEUX.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = FCEUX.icns; sourceTree = "<group>"; };
|
||||
949BB74E1A9EED55007B49CC /* asm.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = asm.cpp; sourceTree = "<group>"; };
|
||||
@@ -776,6 +788,8 @@
|
||||
949BB7F01A9EED56007B49CC /* config.cpp */,
|
||||
949BB7F21A9EED56007B49CC /* debug.cpp */,
|
||||
949BB7F31A9EED56007B49CC /* debug.h */,
|
||||
8F28FD5329FD3EA4008FC4A9 /* debugsymboltable.cpp */,
|
||||
8F28FD5429FD3EA4008FC4A9 /* debugsymboltable.h */,
|
||||
949BB7F41A9EED56007B49CC /* drawing.cpp */,
|
||||
949BB7F51A9EED56007B49CC /* drawing.h */,
|
||||
949BB7F61A9EED56007B49CC /* driver.h */,
|
||||
@@ -893,6 +907,7 @@
|
||||
949BB77D1A9EED56007B49CC /* 32.cpp */,
|
||||
949BB77E1A9EED56007B49CC /* 33.cpp */,
|
||||
949BB77F1A9EED56007B49CC /* 34.cpp */,
|
||||
8F28FD4D29FD3E7D008FC4A9 /* 354.cpp */,
|
||||
949BB7801A9EED56007B49CC /* 36.cpp */,
|
||||
949BB7811A9EED56007B49CC /* 3d-block.cpp */,
|
||||
949BB7821A9EED56007B49CC /* 40.cpp */,
|
||||
@@ -944,6 +959,7 @@
|
||||
87709ED8294D24F10084AEE0 /* cheapocabra.cpp */,
|
||||
949BB7AC1A9EED56007B49CC /* cityfighter.cpp */,
|
||||
870D6EA71D4C1F93001E8FC6 /* coolboy.cpp */,
|
||||
8F28FD4E29FD3E7D008FC4A9 /* coolgirl.cpp */,
|
||||
949BB7AD1A9EED56007B49CC /* dance2000.cpp */,
|
||||
949BB7AE1A9EED56007B49CC /* datalatch.cpp */,
|
||||
949BB7AF1A9EED56007B49CC /* dream.cpp */,
|
||||
@@ -965,6 +981,7 @@
|
||||
87709EDC294D252B0084AEE0 /* hp10xx_hp20xx.cpp */,
|
||||
870D6EB11D4C20B3001E8FC6 /* hp898f.cpp */,
|
||||
870D6EB21D4C20B3001E8FC6 /* inlnsf.cpp */,
|
||||
8F28FD4F29FD3E7D008FC4A9 /* inx007t.cpp */,
|
||||
949BB7BA1A9EED56007B49CC /* karaoke.cpp */,
|
||||
949BB7BB1A9EED56007B49CC /* kof97.cpp */,
|
||||
870D6EB51D4C20F8001E8FC6 /* ks7010.cpp */,
|
||||
@@ -1166,6 +1183,8 @@
|
||||
949BBA271A9EED5B007B49CC /* md5.h */,
|
||||
949BBA281A9EED5B007B49CC /* memory.cpp */,
|
||||
949BBA291A9EED5B007B49CC /* memory.h */,
|
||||
8F28FD5629FD3EB8008FC4A9 /* mutex.cpp */,
|
||||
8F28FD5729FD3EB8008FC4A9 /* mutex.h */,
|
||||
949BBA2B1A9EED5B007B49CC /* unzip.cpp */,
|
||||
949BBA2C1A9EED5B007B49CC /* unzip.h */,
|
||||
949BBA2D1A9EED5B007B49CC /* valuearray.h */,
|
||||
@@ -1270,6 +1289,7 @@
|
||||
files = (
|
||||
82EC40A30FD9EC5A0017FC19 /* FCEUGameCore.mm in Sources */,
|
||||
949BBB381A9EFF4A007B49CC /* asm.cpp in Sources */,
|
||||
8F28FD5129FD3E7D008FC4A9 /* coolgirl.cpp in Sources */,
|
||||
949BBB391A9EFF4A007B49CC /* cart.cpp in Sources */,
|
||||
870D6EA81D4C1F93001E8FC6 /* coolboy.cpp in Sources */,
|
||||
949BBB3A1A9EFF4A007B49CC /* cheat.cpp in Sources */,
|
||||
@@ -1296,6 +1316,7 @@
|
||||
949BBB501A9EFF4B007B49CC /* video.cpp in Sources */,
|
||||
949BBB511A9EFF4B007B49CC /* vsuni.cpp in Sources */,
|
||||
949BBB521A9EFF4B007B49CC /* wave.cpp in Sources */,
|
||||
8F28FD5829FD3EB8008FC4A9 /* mutex.cpp in Sources */,
|
||||
949BBB531A9EFF4B007B49CC /* x6502.cpp in Sources */,
|
||||
949BBA741A9EF079007B49CC /* 01-222.cpp in Sources */,
|
||||
949BBA751A9EF079007B49CC /* 09-034a.cpp in Sources */,
|
||||
@@ -1336,6 +1357,7 @@
|
||||
949BBA961A9EF079007B49CC /* 230.cpp in Sources */,
|
||||
949BBA971A9EF079007B49CC /* 232.cpp in Sources */,
|
||||
949BBA981A9EF079007B49CC /* 234.cpp in Sources */,
|
||||
8F28FD5029FD3E7D008FC4A9 /* 354.cpp in Sources */,
|
||||
949BBA991A9EF079007B49CC /* 235.cpp in Sources */,
|
||||
949BBA9A1A9EF079007B49CC /* 244.cpp in Sources */,
|
||||
949BBA9B1A9EF079007B49CC /* 246.cpp in Sources */,
|
||||
@@ -1401,6 +1423,7 @@
|
||||
949BBAD01A9EF07A007B49CC /* datalatch.cpp in Sources */,
|
||||
949BBAD11A9EF07A007B49CC /* dream.cpp in Sources */,
|
||||
949BBAD21A9EF07A007B49CC /* edu2000.cpp in Sources */,
|
||||
8F28FD5529FD3EA4008FC4A9 /* debugsymboltable.cpp in Sources */,
|
||||
949BBAD31A9EF07A007B49CC /* emu2413.c in Sources */,
|
||||
949BBAD51A9EF07A007B49CC /* famicombox.cpp in Sources */,
|
||||
949BBAD61A9EF07A007B49CC /* ffe.cpp in Sources */,
|
||||
@@ -1448,6 +1471,7 @@
|
||||
870D6EC21D4C2BF4001E8FC6 /* snesmouse.cpp in Sources */,
|
||||
949BBAFB1A9EF07A007B49CC /* sl1632.cpp in Sources */,
|
||||
949BBAFC1A9EF07A007B49CC /* subor.cpp in Sources */,
|
||||
8F28FD5229FD3E7D008FC4A9 /* inx007t.cpp in Sources */,
|
||||
949BBAFD1A9EF07A007B49CC /* super24.cpp in Sources */,
|
||||
870D6EAF1D4C1FE7001E8FC6 /* et-4320.cpp in Sources */,
|
||||
949BBAFE1A9EF07A007B49CC /* supervision.cpp in Sources */,
|
||||
@@ -1576,6 +1600,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
@@ -1611,6 +1636,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
|
||||
+3
-1
@@ -233,7 +233,7 @@ static __weak FCEUGameCore *_current;
|
||||
for (int i = 0; i < _soundSize; i++)
|
||||
_soundBuffer[i] = (_soundBuffer[i] << 16) | (_soundBuffer[i] & 0xffff);
|
||||
|
||||
[[self ringBufferAtIndex:0] write:_soundBuffer maxLength:_soundSize << 2];
|
||||
[[self audioBufferAtIndex:0] write:_soundBuffer maxLength:_soundSize << 2];
|
||||
}
|
||||
|
||||
- (void)resetEmulation
|
||||
@@ -795,6 +795,7 @@ const char *GetKeyboard(void) {return "";}
|
||||
bool turbo = false;
|
||||
bool swapDuty = 0; // some Famicom and NES clones had duty cycle bits swapped
|
||||
int dendy = 0;
|
||||
int eoptions = 0;
|
||||
int closeFinishedMovie = 0;
|
||||
int KillFCEUXonFrame = 0;
|
||||
int FCEUD_ShowStatusIcon(void) {return 0;}
|
||||
@@ -824,6 +825,7 @@ EMUFILE_FILE *FCEUD_UTF8_fstream(const char *fn, const char *m)
|
||||
}
|
||||
void FCEUD_NetplayText(uint8 *text) {};
|
||||
void FCEUD_NetworkClose(void) {}
|
||||
void FCEUD_FlushTrace(void) {}
|
||||
void FCEUD_VideoChanged (void) {}
|
||||
bool FCEUD_ShouldDrawInputAids() {return false;}
|
||||
bool FCEUD_PauseAfterPlayback() {return false;}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.6.3</string>
|
||||
<string>2.6.5</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>OEGameCoreController</string>
|
||||
<key>OEGameCoreClass</key>
|
||||
|
||||
+25
-4
@@ -5,6 +5,10 @@ set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
if (${PUBLIC_RELEASE})
|
||||
add_definitions( -DPUBLIC_RELEASE=1 )
|
||||
endif()
|
||||
|
||||
if ( ${QT6} )
|
||||
message( STATUS "GUI Frontend: Qt6")
|
||||
set( Qt Qt6 )
|
||||
@@ -28,6 +32,7 @@ else()
|
||||
include_directories( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Help_INCLUDE_DIRS} )
|
||||
endif()
|
||||
|
||||
|
||||
if(WIN32)
|
||||
find_package(OpenGL REQUIRED)
|
||||
#find_package(Qt5 COMPONENTS Widgets OpenGL REQUIRED)
|
||||
@@ -36,6 +41,8 @@ if(WIN32)
|
||||
add_definitions( -DMSVC -D_CRT_SECURE_NO_WARNINGS )
|
||||
add_definitions( -D__SDL__ -D__QT_DRIVER__ -DQT_DEPRECATED_WARNINGS )
|
||||
add_definitions( -DFCEUDEF_DEBUGGER )
|
||||
add_definitions( /wd4267 /wd4244 )
|
||||
#add_definitions( /wd4018 ) # Integer comparison sign mismatch warnings
|
||||
include_directories( ${SDL_INSTALL_PREFIX}/SDL2/include )
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/drivers/win/zlib )
|
||||
set( OPENGL_LDFLAGS OpenGL::GL )
|
||||
@@ -71,7 +78,8 @@ else(WIN32)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
add_definitions( -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs -fPIC )
|
||||
add_definitions( -Wall -Wno-write-strings -Wno-parentheses -Wno-unused-local-typedefs -fPIC )
|
||||
#add_definitions( -Wno-sign-compare ) # Integer comparison sign mismatch warnings
|
||||
add_definitions( -DFCEUDEF_DEBUGGER )
|
||||
|
||||
#if ( ${QT6} )
|
||||
@@ -85,6 +93,15 @@ else(WIN32)
|
||||
#endif()
|
||||
add_definitions( -D__QT_DRIVER__ -DQT_DEPRECATED_WARNINGS )
|
||||
|
||||
if ( ${ASAN_ENABLE} )
|
||||
add_definitions( -fsanitize=address -fsanitize=bounds-strict )
|
||||
add_definitions( -fsanitize=undefined -fno-sanitize=vptr )
|
||||
set( ASAN_LDFLAGS -lasan -lubsan)
|
||||
message( STATUS "Address Sanitizer Enabled" )
|
||||
else()
|
||||
message( STATUS "Address Sanitizer Disabled" )
|
||||
endif()
|
||||
|
||||
# Check for libminizip
|
||||
pkg_check_modules( MINIZIP REQUIRED minizip)
|
||||
|
||||
@@ -261,6 +278,7 @@ set(SRC_CORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/conddebug.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/debug.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/debugsymboltable.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drawing.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fceu.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fds.cpp
|
||||
@@ -332,6 +350,7 @@ set(SRC_CORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/32.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/33.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/34.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/354.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/36.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/3d-block.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/40.cpp
|
||||
@@ -382,6 +401,7 @@ set(SRC_CORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/cheapocabra.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/cityfighter.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/coolboy.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/coolgirl.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/dance2000.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/datalatch.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/dream.cpp
|
||||
@@ -453,6 +473,7 @@ set(SRC_CORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc7.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/vrc7p.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/yoko.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/boards/inx007t.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/input/arkanoid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/input/bworld.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/input/cursor.cpp
|
||||
@@ -481,13 +502,13 @@ set(SRC_CORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/guid.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/md5.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/memory.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utils/mutex.cpp
|
||||
)
|
||||
|
||||
|
||||
set(SRC_DRIVERS_COMMON
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/args.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/cheat.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/config.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/configSys.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/hq2x.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drivers/common/hq3x.cpp
|
||||
@@ -578,7 +599,7 @@ set(SOURCES ${SRC_CORE} ${SRC_DRIVERS_COMMON} ${SRC_DRIVERS_SDL})
|
||||
# the FCEUX_BUILD_TIMESTAMP preprocessor definition.
|
||||
# Note: with CMake >= 3.8.0, this will respect SOURCE_DATE_EPOCH. For more info,
|
||||
# see <https://reproducible-builds.org/docs/source-date-epoch/>.
|
||||
string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y")
|
||||
string(TIMESTAMP BUILD_TS "%H:%M:%S %b %d %Y" UTC)
|
||||
add_definitions( -DFCEUX_BUILD_TIMESTAMP=\"${BUILD_TS}\" )
|
||||
|
||||
if (WIN32)
|
||||
@@ -613,7 +634,7 @@ add_executable( ${APP_NAME} ${SOURCES} ../resources.qrc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/fceux_git_info.cpp)
|
||||
endif()
|
||||
|
||||
target_link_libraries( ${APP_NAME}
|
||||
target_link_libraries( ${APP_NAME} ${ASAN_LDFLAGS}
|
||||
${${Qt}Widgets_LIBRARIES}
|
||||
${${Qt}Help_LIBRARIES}
|
||||
${${Qt}OpenGL_LIBRARIES}
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ static void M121CW(uint32 A, uint8 V) {
|
||||
if (PRGsize[0] == CHRsize[0]) { // A9713 multigame extension hack!
|
||||
setchr1(A, V | ((EXPREGS[3] & 0x80) << 1));
|
||||
} else {
|
||||
if ((A & 0x1000) == ((MMC3_cmd & 0x80) << 5))
|
||||
if ((A & 0x1000) == static_cast<uint32>((MMC3_cmd & 0x80) << 5))
|
||||
setchr1(A, V | 0x100);
|
||||
else
|
||||
setchr1(A, V);
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
#include "mmc3.h"
|
||||
|
||||
static void M187CW(uint32 A, uint8 V) {
|
||||
if ((A & 0x1000) == ((MMC3_cmd & 0x80) << 5))
|
||||
if ((A & 0x1000) == static_cast<uint32>((MMC3_cmd & 0x80) << 5))
|
||||
setchr1(A, V | 0x100);
|
||||
else
|
||||
setchr1(A, V);
|
||||
|
||||
+42
-34
@@ -1,30 +1,40 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2011 CaH4e3
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2011 CaH4e3
|
||||
* Copyright (C) 2019 Libretro Team
|
||||
* Copyright (C) 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* PCB-018 board, discrete multigame cart 110-in-1
|
||||
*
|
||||
* Mapper 225
|
||||
* Mapper 255
|
||||
*
|
||||
*/
|
||||
|
||||
/* 2020-2-20 - merge mapper 255, re-implement extra RAM */
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 prot[4], prg, mode, chr, mirr;
|
||||
static uint8 extraRAM[4], prg, mode, chr, mirr;
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ prot, 4, "PROT" },
|
||||
{ extraRAM, 4, "PROT" },
|
||||
{ &prg, 1, "PRG" },
|
||||
{ &chr, 1, "CHR" },
|
||||
{ &mode, 1, "MODE" },
|
||||
@@ -36,14 +46,15 @@ static void Sync(void) {
|
||||
if (mode) {
|
||||
setprg16(0x8000, prg);
|
||||
setprg16(0xC000, prg);
|
||||
} else
|
||||
}
|
||||
else
|
||||
setprg32(0x8000, prg >> 1);
|
||||
setchr8(chr);
|
||||
setmirror(mirr ^ 1);
|
||||
}
|
||||
|
||||
static DECLFW(M225Write) {
|
||||
uint32 bank = (A >> 14) & 1;
|
||||
uint8 bank = (A >> 14) & 1;
|
||||
mirr = (A >> 13) & 1;
|
||||
mode = (A >> 12) & 1;
|
||||
chr = (A & 0x3f) | (bank << 6);
|
||||
@@ -52,35 +63,28 @@ static DECLFW(M225Write) {
|
||||
}
|
||||
|
||||
static DECLFW(M225LoWrite) {
|
||||
if (A & 0x800) {
|
||||
prot[A & 0x03] = V;
|
||||
}
|
||||
/* e.g. 115-in-1 [p1][!] CRC32 0xb39d30b4 */
|
||||
if (A & 0x800) extraRAM[A & 3] = V & 0x0F;
|
||||
}
|
||||
|
||||
static DECLFR(M225LoRead) {
|
||||
if (A & 0x800) {
|
||||
return prot[A & 3] & 0x0F;
|
||||
}
|
||||
if (A & 0x800) return extraRAM[A & 3];
|
||||
return X.DB;
|
||||
}
|
||||
|
||||
static void M225Power(void) {
|
||||
prg = 0;
|
||||
chr = 0;
|
||||
mode = 0;
|
||||
mirr = 0;
|
||||
Sync();
|
||||
SetReadHandler(0x5000, 0x5FFF, M225LoRead);
|
||||
SetWriteHandler(0x5000, 0x5FFF, M225LoWrite);
|
||||
SetReadHandler(0x5000, 0x5fff, M225LoRead);
|
||||
SetWriteHandler(0x5000, 0x5fff, M225LoWrite);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M225Write);
|
||||
}
|
||||
|
||||
static void M225Reset(void) {
|
||||
prg = 0;
|
||||
chr = 0;
|
||||
mode = 0;
|
||||
mirr = 0;
|
||||
Sync();
|
||||
}
|
||||
|
||||
@@ -94,3 +98,7 @@ void Mapper225_Init(CartInfo *info) {
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
}
|
||||
|
||||
void Mapper255_Init(CartInfo *info) {
|
||||
Mapper225_Init(info);
|
||||
}
|
||||
+58
-11
@@ -19,36 +19,79 @@
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "ines.h"
|
||||
|
||||
static uint16 cmdreg = 0;
|
||||
static uint8 openbus = 0;
|
||||
|
||||
// For carts with extra 128K prg rom (Contra)
|
||||
static uint8 unrom = 0;
|
||||
static uint8 unromData = 0;
|
||||
|
||||
static uint32 PRGROMSize = 0;
|
||||
|
||||
static uint16 cmdreg;
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ &cmdreg, 2, "CREG" },
|
||||
{ &openbus, 1, "OB" },
|
||||
{ &unrom, 1, "UROM" },
|
||||
{ &unromData, 1, "UDTA" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Sync(void) {
|
||||
if (cmdreg & 0x400)
|
||||
setmirror(MI_0);
|
||||
else
|
||||
setmirror(((cmdreg >> 13) & 1) ^ 1);
|
||||
if (cmdreg & 0x800) {
|
||||
setprg16(0x8000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1));
|
||||
setprg16(0xC000, ((cmdreg & 0x300) >> 3) | ((cmdreg & 0x1F) << 1) | ((cmdreg >> 12) & 1));
|
||||
} else
|
||||
setprg32(0x8000, ((cmdreg & 0x300) >> 4) | (cmdreg & 0x1F));
|
||||
if (unrom) {
|
||||
int PRGPageCount = PRGROMSize / (16 * 1024);
|
||||
setprg16(0x8000, PRGPageCount & 0xC0 | (unromData & 7));
|
||||
setprg16(0xC000, PRGPageCount & 0xC0 | 7);
|
||||
setmirror(MI_V);
|
||||
} else {
|
||||
uint8 bank = ((cmdreg & 0x300) >> 3) | (cmdreg & 0x1F);
|
||||
if (bank >= (PRGROMSize / (32 * 1024))) {
|
||||
openbus = 1;
|
||||
} else {
|
||||
if (cmdreg & 0x400)
|
||||
setmirror(MI_0);
|
||||
else
|
||||
setmirror(((cmdreg >> 13) & 1) ^ 1);
|
||||
if (cmdreg & 0x800) {
|
||||
setprg16(0x8000, (bank << 1) | ((cmdreg >> 12) & 1));
|
||||
setprg16(0xC000, (bank << 1) | ((cmdreg >> 12) & 1));
|
||||
} else
|
||||
setprg32(0x8000, bank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFR(M235Read) {
|
||||
if (openbus) {
|
||||
openbus = 0;
|
||||
return X.DB;
|
||||
}
|
||||
return CartBR(A);
|
||||
}
|
||||
|
||||
static DECLFW(M235Write) {
|
||||
cmdreg = A;
|
||||
unromData = V;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M235Reset(void) {
|
||||
cmdreg = 0;
|
||||
unromData = 0;
|
||||
if (PRGROMSize & 0x20000)
|
||||
unrom = (unrom + 1) & 1;
|
||||
Sync();
|
||||
}
|
||||
|
||||
static void M235Power(void) {
|
||||
setchr8(0);
|
||||
SetWriteHandler(0x8000, 0xFFFF, M235Write);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetReadHandler(0x8000, 0xFFFF, M235Read);
|
||||
cmdreg = 0;
|
||||
unromData = 0;
|
||||
unrom = 0;
|
||||
Sync();
|
||||
}
|
||||
|
||||
@@ -57,7 +100,11 @@ static void M235Restore(int version) {
|
||||
}
|
||||
|
||||
void Mapper235_Init(CartInfo *info) {
|
||||
info->Reset = M235Reset;
|
||||
info->Power = M235Power;
|
||||
GameStateRestore = M235Restore;
|
||||
AddExState(&StateRegs, ~0, 0, 0);
|
||||
|
||||
// needs raw, non-pow2 PRGROM size for comparison
|
||||
PRGROMSize = head.ROM_size * 16384;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2022
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint16 latchAddr;
|
||||
static uint8 latchData;
|
||||
static uint8 submapper;
|
||||
|
||||
static SFORMAT StateRegs[] =
|
||||
{
|
||||
{ &latchAddr, 2, "ADDR" },
|
||||
{ &latchData, 1, "DATA" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void Mapper354_Sync(void)
|
||||
{
|
||||
int prg = latchData & 0x3F | latchAddr << 2 & 0x40 | latchAddr >> 5 & 0x80;
|
||||
switch (latchAddr & 7)
|
||||
{
|
||||
case 0: case 4:
|
||||
setprg32(0x8000, prg >> 1);
|
||||
break;
|
||||
case 1:
|
||||
setprg16(0x8000, prg);
|
||||
setprg16(0xC000, prg | 7);
|
||||
break;
|
||||
case 2: case 6:
|
||||
setprg8(0x8000, prg << 1 | latchData >> 7);
|
||||
setprg8(0xA000, prg << 1 | latchData >> 7);
|
||||
setprg8(0xC000, prg << 1 | latchData >> 7);
|
||||
setprg8(0xE000, prg << 1 | latchData >> 7);
|
||||
break;
|
||||
case 3: case 7:
|
||||
setprg16(0x8000, prg);
|
||||
setprg16(0xC000, prg);
|
||||
break;
|
||||
case 5:
|
||||
setprg8(0x6000, prg << 1 | latchData >> 7);
|
||||
setprg32(0x8000, prg >> 1 | 3);
|
||||
break;
|
||||
}
|
||||
setchr8(0);
|
||||
setmirror(latchData & 0x40 ? MI_H : MI_V);
|
||||
}
|
||||
|
||||
static DECLFW(Mapper354_WriteLatch)
|
||||
{
|
||||
latchData = V;
|
||||
latchAddr = A & 0xFFFF;
|
||||
Mapper354_Sync();
|
||||
}
|
||||
|
||||
static void Mapper354_Reset(void)
|
||||
{
|
||||
latchAddr = latchData = 0;
|
||||
Mapper354_Sync();
|
||||
}
|
||||
|
||||
static void Mapper354_Power(void)
|
||||
{
|
||||
latchAddr = latchData = 0;
|
||||
SetReadHandler(0x6000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(submapper == 1 ? 0xE000 : 0xF000, 0xFFFF, Mapper354_WriteLatch);
|
||||
Mapper354_Sync();
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
Mapper354_Sync();
|
||||
}
|
||||
|
||||
void Mapper354_Init(CartInfo *info)
|
||||
{
|
||||
submapper = info->submapper;
|
||||
info->Power = Mapper354_Power;
|
||||
info->Reset = Mapper354_Reset;
|
||||
GameStateRestore = StateRestore;
|
||||
AddExState(StateRegs, ~0, 0, 0);
|
||||
}
|
||||
@@ -122,7 +122,7 @@ static void UNL43272Sync(void) {
|
||||
if ((latche & 0x81) == 0x81) {
|
||||
setprg32(0x8000, (latche & 0x38) >> 3);
|
||||
} else
|
||||
FCEU_printf("unrecognized command %04!\n", latche);
|
||||
FCEU_printf("unrecognized command %04x!\n", latche);
|
||||
setchr8(0);
|
||||
setmirror(0);
|
||||
}
|
||||
|
||||
+347
-75
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* COOLBOY cartridges use registers at address $6xxx
|
||||
* MINDKIDS cartridges use a solder pad labelled "5/6K" to select between $5000 and $6000
|
||||
*
|
||||
*
|
||||
* $xxx0
|
||||
* 7 bit 0
|
||||
* ---- ----
|
||||
@@ -29,12 +29,11 @@
|
||||
* |||| ||||
|
||||
* |||| |+++-- PRG offset (PRG A19, A18, A17)
|
||||
* |||| +----- Alternate CHR A17
|
||||
* ||++------- PRG offset (PRG A24, A23)
|
||||
* ||++------- PRG offset (PRG A24, A23), CHR offset (CHR A19, A18)
|
||||
* |+--------- PRG mask (PRG A17 from 0: MMC3; 1: offset)
|
||||
* +---------- CHR mask (CHR A17 from 0: MMC3; 1: alternate)
|
||||
*
|
||||
* $xxx1
|
||||
*
|
||||
* 7 bit 0
|
||||
* ---- ----
|
||||
* GHIJ KKLx
|
||||
@@ -55,15 +54,16 @@
|
||||
* $xxx3
|
||||
* 7 bit 0
|
||||
* ---- ----
|
||||
* NPxP QQRx
|
||||
* || | |||
|
||||
* || | +++--- PRG offset for GNROM mode (PRG A16, A15, A14)
|
||||
* || +------- 1: GNROM mode; 0: MMC3 mode
|
||||
* || | (1: PRG A16...13 from QQ, L, R, CPU A14, A13 + CHR A16...10 from MMMM, PPU A12...10;
|
||||
* || | 0: PRG A16...13 from MMC3 + CHR A16...A10 from MMC3 )
|
||||
* NPZP QQRx
|
||||
* |||| |||
|
||||
* |||| +++--- PRG offset for GNROM mode (PRG A16, A15, A14)
|
||||
* |||+------- 1: GNROM mode; 0: MMC3 mode
|
||||
* |||| (1: PRG A16...13 from QQ, L, R, CPU A14, A13 + CHR A16...10 from MMMM, PPU A12...10;
|
||||
* |||| 0: PRG A16...13 from MMC3 + CHR A16...A10 from MMC3 )
|
||||
* ||+-------- 1: Also enable PRG RAM in $5000-$5FFF
|
||||
* |+-+------- Banking mode
|
||||
* |+--------- "Weird MMC3 mode"
|
||||
* +---------- Lockout (prevent further writes to these four registers, only works in MMC3 mode)
|
||||
* +---------- Lockout (prevent further writes to all registers but the one at $xxx2, only works in MMC3 mode)
|
||||
*
|
||||
* Also some new cartridges from MINDKIDS have /WE and /OE pins connected to mapper,
|
||||
* which allows you to rewrite flash memory without soldering.
|
||||
@@ -75,25 +75,90 @@
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "mmc3.h"
|
||||
#include "../ines.h"
|
||||
|
||||
static void COOLBOYCW(uint32 A, uint8 V) {
|
||||
uint32 mask = 0xFF ^ (EXPREGS[0] & 0x80);
|
||||
if (EXPREGS[3] & 0x10) {
|
||||
if (EXPREGS[3] & 0x40) { // Weird mode
|
||||
const int ROM_CHIP = 0x00;
|
||||
const int CFI_CHIP = 0x11;
|
||||
const int FLASH_CHIP = 0x12;
|
||||
|
||||
const uint32 FLASH_SECTOR_SIZE = 128 * 1024;
|
||||
|
||||
extern uint8* WRAM;
|
||||
static uint8* CFI = NULL;
|
||||
static uint8* Flash = NULL;
|
||||
|
||||
static uint8 flash_save = 0;
|
||||
static uint8 flash_state = 0;
|
||||
static uint16 flash_buffer_a[10];
|
||||
static uint8 flash_buffer_v[10];
|
||||
static uint8 cfi_mode = 0;
|
||||
|
||||
static uint16 regs_base = 0;
|
||||
static uint8 flag23 = 0;
|
||||
static uint8 flag45 = 0;
|
||||
static uint8 flag67 = 0;
|
||||
static uint8 flag89 = 0;
|
||||
|
||||
// Macronix 256-mbit memory CFI data
|
||||
const uint8 cfi_data[] =
|
||||
{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x51, 0x52, 0x59, 0x02, 0x00, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x27, 0x36, 0x00, 0x00, 0x03,
|
||||
0x06, 0x09, 0x13, 0x03, 0x05, 0x03, 0x02, 0x19,
|
||||
0x02, 0x00, 0x06, 0x00, 0x01, 0xFF, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
|
||||
0x50, 0x52, 0x49, 0x31, 0x33, 0x14, 0x02, 0x01,
|
||||
0x00, 0x08, 0x00, 0x00, 0x02, 0x95, 0xA5, 0x05,
|
||||
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
static void AA6023CW(uint32 A, uint8 V) {
|
||||
if (flag89) {
|
||||
/*
|
||||
$xxx0
|
||||
7 bit 0
|
||||
---- ----
|
||||
AB.C DEEE
|
||||
|| | ||||
|
||||
|| | |+++-- PRG offset (PRG A19, A18, A17)
|
||||
|| | +----- Alternate CHR A17
|
||||
|| +------- 1=Write-protect CHR-RAM
|
||||
|+--------- PRG mask (PRG A17 from 0: MMC3; 1: offset)
|
||||
+---------- CHR mask (CHR A17 from 0: MMC3; 1: alternate)
|
||||
*/
|
||||
if (EXPREGS[0] & 0b00010000)
|
||||
SetupCartCHRMapping(0, VROM, CHRsize[0], 0); // write-protect CHR-RAM
|
||||
else
|
||||
SetupCartCHRMapping(0, VROM, CHRsize[0], 1); // allow CHR writes
|
||||
}
|
||||
|
||||
uint32 mask = 0xFF ^ (EXPREGS[0] & 0b10000000);
|
||||
if (EXPREGS[3] & 0b00010000) {
|
||||
if (EXPREGS[3] & 0b01000000) { // Weird mode
|
||||
int cbase = (MMC3_cmd & 0x80) << 5;
|
||||
switch (cbase ^ A) { // Don't even try do understand
|
||||
case 0x0400:
|
||||
case 0x0C00: V &= 0x7F; break;
|
||||
}
|
||||
}
|
||||
// Highest bit goes from MMC3 registers when EXPREGS[3]&0x80==0 or from EXPREGS[0]&0x08 otherwise
|
||||
// Highest bit goes from MMC3 registers when EXPREGS[0]&0x80==0 or from EXPREGS[0]&0x08 otherwise
|
||||
setchr1(A,
|
||||
(V & 0x80 & mask) | ((((EXPREGS[0] & 0x08) << 4) & ~mask)) // 7th bit
|
||||
(V & 0x80 & mask) | ((((EXPREGS[0] & 0b00001000) << 4) & ~mask)) // 7th bit
|
||||
| ((EXPREGS[2] & 0x0F) << 3) // 6-3 bits
|
||||
| ((A >> 10) & 7) // 2-0 bits
|
||||
| ((EXPREGS[0] & 0b00110000) << 4) // There are some ROMs with 1 MiB CHR-ROM
|
||||
);
|
||||
} else {
|
||||
if (EXPREGS[3] & 0x40) { // Weird mode, again
|
||||
}
|
||||
else {
|
||||
if (EXPREGS[3] & 0b01000000) { // Weird mode, again
|
||||
int cbase = (MMC3_cmd & 0x80) << 5;
|
||||
switch (cbase ^ A) { // Don't even try do understand
|
||||
case 0x0000: V = DRegBuf[0]; break;
|
||||
@@ -103,18 +168,81 @@ static void COOLBOYCW(uint32 A, uint8 V) {
|
||||
}
|
||||
}
|
||||
// Simple MMC3 mode
|
||||
// Highest bit goes from MMC3 registers when EXPREGS[3]&0x80==0 or from EXPREGS[0]&0x08 otherwise
|
||||
setchr1(A, (V & mask) | (((EXPREGS[0] & 0x08) << 4) & ~mask));
|
||||
// Highest bit goes from MMC3 registers when EXPREGS[0]&0x80==0 or from EXPREGS[0]&0x08 otherwise
|
||||
setchr1(A,
|
||||
(V & mask)
|
||||
| (((EXPREGS[0] & 0x08) << 4) & ~mask)
|
||||
| ((EXPREGS[0] & 0b00110000) << 4)); // There are some ROMs with 1 MiB CHR-ROM
|
||||
}
|
||||
}
|
||||
|
||||
static void COOLBOYPW(uint32 A, uint8 V) {
|
||||
uint32 mask = ((0x3F | (EXPREGS[1] & 0x40) | ((EXPREGS[1] & 0x20) << 2)) ^ ((EXPREGS[0] & 0x40) >> 2)) ^ ((EXPREGS[1] & 0x80) >> 2);
|
||||
uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2);
|
||||
static void AA6023PW(uint32 A, uint8 V) {
|
||||
uint8 CREGS[] = {EXPREGS[0], EXPREGS[1], EXPREGS[2], EXPREGS[3]};
|
||||
// Submappers has scrambled bits
|
||||
if (flag23) {
|
||||
/*
|
||||
$xxx1
|
||||
7 bit 0
|
||||
---- ----
|
||||
GHIL JKKx
|
||||
|||| |||
|
||||
|||| +++--- PRG offset (in order: PRG A20, A21, A22)
|
||||
|||+------- GNROM mode bank PRG size (0: 32 KiB bank, PRG A14=CPU A14; 1: 16 KiB bank, PRG A14=offset A14)
|
||||
||+-------- PRG mask (PRG A20 from 0: offset; 1: MMC3)
|
||||
|+--------- PRG mask (PRG A19 from 0: offset; 1: MMC3)
|
||||
+---------- PRG mask (PRG A18 from 0: MMC3; 1: offset)
|
||||
*/
|
||||
CREGS[1] = (CREGS[1] & 0b11100101)
|
||||
| ((CREGS[1] & 0b00001000) << 1) // PRG A20
|
||||
| ((CREGS[1] & 0b00000010) << 2) // PRG A22
|
||||
| ((((CREGS[1] ^ 0b00010000) & 0b00010000) >> 3)); // GNROM mode bank PRG size
|
||||
}
|
||||
if (flag45) {
|
||||
/*
|
||||
$xxx0
|
||||
7 bit 0
|
||||
---- ----
|
||||
ABCC DEEE
|
||||
|||| ||||
|
||||
|||| |+++-- PRG offset (PRG A19, A18, A17)
|
||||
|||| +----- Alternate CHR A17
|
||||
||++------- PRG offset (PRG A21, A20)
|
||||
|+--------- PRG mask (PRG A17 from 0: MMC3; 1: offset)
|
||||
+---------- CHR mask (CHR A17 from 0: MMC3; 1: alternate)
|
||||
$xxx1
|
||||
7 bit 0
|
||||
---- ----
|
||||
GHIx xxLx
|
||||
||| |
|
||||
||| +--- GNROM mode bank PRG size (1: 32 KiB bank, PRG A14=CPU A14; 0: 16 KiB bank, PRG A14=offset A14)
|
||||
||+-------- PRG mask (PRG A20 from 0: offset; 1: MMC3)
|
||||
|+--------- PRG mask (PRG A19 from 0: offset; 1: MMC3)
|
||||
+---------- PRG mask (PRG A18 from 0: MMC3; 1: offset)
|
||||
*/
|
||||
CREGS[1] = (CREGS[1] & 0b11100011)
|
||||
| ((CREGS[0] & 0b00100000) >> 3) // PRG A21
|
||||
| (CREGS[0] & 0b00010000); // PRG A20
|
||||
CREGS[0] &= 0b11001111;
|
||||
}
|
||||
|
||||
uint32 mask = ((0b00111111 | (CREGS[1] & 0b01000000) | ((CREGS[1] & 0b00100000) << 2)) ^ ((CREGS[0] & 0b01000000) >> 2)) ^ ((CREGS[1] & 0b10000000) >> 2);
|
||||
uint32 base = ((CREGS[0] & 0b00000111) >> 0) | ((CREGS[1] & 0b00010000) >> 1) | ((CREGS[1] & 0b00001100) << 2) | ((CREGS[0] & 0b00110000) << 2);
|
||||
|
||||
if (flash_save && cfi_mode) {
|
||||
setprg32r(CFI_CHIP, 0x8000, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
int chip = !flash_save ? ROM_CHIP : FLASH_CHIP;
|
||||
// There are ROMs with multiple PRG ROM chips
|
||||
int chip_offset = 0;
|
||||
if (flag67 && EXPREGS[0] & 0b00001000) {
|
||||
chip_offset += ROM_size;
|
||||
}
|
||||
|
||||
// Very weird mode
|
||||
// Last banks are first in this mode, ignored when MMC3_cmd&0x40
|
||||
if ((EXPREGS[3] & 0x40) && (V >= 0xFE) && !((MMC3_cmd & 0x40) != 0)) {
|
||||
if ((CREGS[3] & 0b01000000) && (V >= 0xFE) && !((MMC3_cmd & 0x40) != 0)) {
|
||||
switch (A & 0xE000) {
|
||||
case 0xC000:
|
||||
case 0xE000:
|
||||
@@ -123,91 +251,235 @@ static void COOLBOYPW(uint32 A, uint8 V) {
|
||||
}
|
||||
}
|
||||
|
||||
// Regular MMC3 mode, internal ROM size can be up to 2048kb!
|
||||
if (!(EXPREGS[3] & 0x10))
|
||||
setprg8(A, (((base << 4) & ~mask)) | (V & mask));
|
||||
else { // NROM mode
|
||||
if (!(CREGS[3] & 0x10)) {
|
||||
// Regular MMC3 mode but can be extended to 2MiB
|
||||
setprg8r(chip, A, ((((base << 4) & ~mask)) | (V & mask)) + chip_offset);
|
||||
}
|
||||
else {
|
||||
// NROM mode
|
||||
mask &= 0xF0;
|
||||
uint8 emask;
|
||||
if ((((EXPREGS[1] & 2) != 0))) // 32kb mode
|
||||
emask = (EXPREGS[3] & 0x0C) | ((A & 0x4000) >> 13);
|
||||
if (CREGS[1] & 0b00000010) // 32kb mode
|
||||
emask = (CREGS[3] & 0b00001100) | ((A & 0x4000) >> 13);
|
||||
else // 16kb mode
|
||||
emask = EXPREGS[3] & 0x0E;
|
||||
setprg8(A, ((base << 4) & ~mask) // 7-4 bits are from base (see below)
|
||||
| (V & mask) // ... or from MM3 internal regs, depends on mask
|
||||
| emask // 3-1 (or 3-2 when (EXPREGS[3]&0x0C is set) from EXPREGS[3]
|
||||
| ((A & 0x2000) >> 13)); // 0th just as is
|
||||
emask = CREGS[3] & 0b00001110;
|
||||
setprg8r(chip, A, (
|
||||
((base << 4) & ~mask) // 7-4 bits are from base
|
||||
| (V & mask) // ... or from MM3 internal regs, depends on mask
|
||||
| emask // 3-1 (or 3-2 when (EXPREGS[3]&0x0C is set) from EXPREGS[3]
|
||||
| ((A & 0x2000) >> 13) // 0th just as is
|
||||
) + chip_offset); // For multi-chip ROMs
|
||||
}
|
||||
}
|
||||
|
||||
static DECLFW(COOLBOYWrite) {
|
||||
if(A001B & 0x80)
|
||||
CartBW(A,V);
|
||||
static DECLFW(AA6023WramWrite) {
|
||||
if (A001B & 0x80)
|
||||
CartBW(A, V);
|
||||
}
|
||||
|
||||
static DECLFW(AA6023Write) {
|
||||
if (A >= 0x6000) {
|
||||
AA6023WramWrite(A, V);
|
||||
}
|
||||
|
||||
// Deny any further writes when 7th bit is 1 AND 4th is 0
|
||||
if ((EXPREGS[3] & 0x90) != 0x80) {
|
||||
EXPREGS[A & 3] = V;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
|
||||
static void COOLBOYReset(void) {
|
||||
static DECLFW(AA6023FlashWrite) {
|
||||
if (A < 0xC000)
|
||||
MMC3_CMDWrite(A, V);
|
||||
else
|
||||
MMC3_IRQWrite(A, V);
|
||||
|
||||
if (!flash_save) return;
|
||||
if (flash_state < sizeof(flash_buffer_a) / sizeof(flash_buffer_a[0])) {
|
||||
flash_buffer_a[flash_state] = A & 0xFFF;
|
||||
flash_buffer_v[flash_state] = V;
|
||||
flash_state++;
|
||||
|
||||
// enter CFI mode
|
||||
if ((flash_state == 1) &&
|
||||
(flash_buffer_a[0] == 0x0AAA) && (flash_buffer_v[0] == 0x98)) {
|
||||
cfi_mode = 1;
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// erase sector
|
||||
if ((flash_state == 6) &&
|
||||
(flash_buffer_a[0] == 0x0AAA) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x0555) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x0AAA) && (flash_buffer_v[2] == 0x80) &&
|
||||
(flash_buffer_a[3] == 0x0AAA) && (flash_buffer_v[3] == 0xAA) &&
|
||||
(flash_buffer_a[4] == 0x0555) && (flash_buffer_v[4] == 0x55) &&
|
||||
(flash_buffer_v[5] == 0x30)) {
|
||||
int offset = &Page[A >> 11][A] - Flash;
|
||||
int sector = offset / FLASH_SECTOR_SIZE;
|
||||
for (uint32 i = sector * FLASH_SECTOR_SIZE; i < (sector + 1) * FLASH_SECTOR_SIZE; i++)
|
||||
Flash[i % PRGsize[ROM_CHIP]] = 0xFF;
|
||||
FCEU_printf("Flash sector #%d is erased (0x%08x - 0x%08x).\n", sector, offset, offset + FLASH_SECTOR_SIZE);
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// erase chip, lol
|
||||
if ((flash_state == 6) &&
|
||||
(flash_buffer_a[0] == 0x0AAA) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x0555) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x0AAA) && (flash_buffer_v[2] == 0x80) &&
|
||||
(flash_buffer_a[3] == 0x0AAA) && (flash_buffer_v[3] == 0xAA) &&
|
||||
(flash_buffer_a[4] == 0x0555) && (flash_buffer_v[4] == 0x55) &&
|
||||
(flash_buffer_v[5] == 0x10)) {
|
||||
memset(Flash, 0xFF, PRGsize[ROM_CHIP]);
|
||||
FCEU_printf("Flash chip erased.\n");
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// write byte
|
||||
if ((flash_state == 4) &&
|
||||
(flash_buffer_a[0] == 0x0AAA) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x0555) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x0AAA) && (flash_buffer_v[2] == 0xA0)) {
|
||||
int offset = &Page[A >> 11][A] - Flash;
|
||||
if (CartBR(A) != 0xFF) {
|
||||
FCEU_PrintError("Error: can't write to 0x%08x, flash sector is not erased.\n", offset);
|
||||
}
|
||||
else {
|
||||
CartBW(A, V);
|
||||
}
|
||||
flash_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// not a command
|
||||
if (((A & 0xFFF) != 0x0AAA) && ((A & 0xFFF) != 0x0555)) {
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// reset
|
||||
if (V == 0xF0) {
|
||||
flash_state = 0;
|
||||
cfi_mode = 0;
|
||||
}
|
||||
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
}
|
||||
|
||||
static void AA6023Reset(void) {
|
||||
MMC3RegReset();
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
|
||||
flash_state = 0;
|
||||
cfi_mode = 0;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
}
|
||||
|
||||
static void COOLBOYPower(void) {
|
||||
static void AA6023Power(void) {
|
||||
GenMMC3Power();
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
SetWriteHandler(0x5000, 0x5fff, CartBW); // some games access random unmapped areas and crashes because of KT-008 PCB hack in MMC3 source lol
|
||||
SetWriteHandler(0x6000, 0x6fff, COOLBOYWrite);
|
||||
if (regs_base != 0x5000)
|
||||
SetWriteHandler(0x5000, 0x5fff, CartBW); // some games access random unmapped areas and crashes because of KT-008 PCB hack in MMC3 source lol
|
||||
SetWriteHandler(0x6000, 0x7fff, AA6023WramWrite);
|
||||
SetWriteHandler(regs_base, regs_base + 0x0fff, AA6023Write);
|
||||
SetWriteHandler(0x8000, 0xFFFF, AA6023FlashWrite);
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
}
|
||||
|
||||
static void MINDKIDSPower(void) {
|
||||
GenMMC3Power();
|
||||
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
|
||||
static void AA6023Restore(int version) {
|
||||
FixMMC3PRG(MMC3_cmd);
|
||||
FixMMC3CHR(MMC3_cmd);
|
||||
SetWriteHandler(0x5000, 0x5fff, COOLBOYWrite);
|
||||
}
|
||||
|
||||
static void AA6023Close(void) {
|
||||
if (WRAM)
|
||||
FCEU_gfree(WRAM);
|
||||
if (Flash)
|
||||
FCEU_gfree(Flash);
|
||||
if (CFI)
|
||||
FCEU_gfree(CFI);
|
||||
WRAM = Flash = CFI = NULL;
|
||||
}
|
||||
|
||||
void CommonInit(CartInfo* info, int submapper)
|
||||
{
|
||||
GenMMC3_Init(info, 2048, info->vram_size / 1024, !info->ines2 ? 8 : (info->wram_size + info->battery_wram_size) / 1024, info->battery);
|
||||
pwrap = AA6023PW;
|
||||
cwrap = AA6023CW;
|
||||
|
||||
switch (submapper)
|
||||
{
|
||||
case 2:
|
||||
regs_base = 0x7000;
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
case 6:
|
||||
case 8:
|
||||
regs_base = 0x6000;
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
case 9:
|
||||
regs_base = 0x5000;
|
||||
break;
|
||||
default:
|
||||
FCEU_PrintError("Submapper #%d is not supported", submapper);
|
||||
}
|
||||
flag23 = (submapper == 2) || (submapper == 3);
|
||||
flag45 = (submapper == 4) || (submapper == 5);
|
||||
flag67 = (submapper == 6) || (submapper == 7);
|
||||
flag89 = (submapper == 8) || (submapper == 9);
|
||||
info->Power = AA6023Power;
|
||||
info->Reset = AA6023Reset;
|
||||
info->Close = AA6023Close;
|
||||
GameStateRestore = AA6023Restore;
|
||||
|
||||
flash_save = info->battery;
|
||||
|
||||
if (flash_save) {
|
||||
CFI = (uint8*)FCEU_gmalloc(sizeof(cfi_data) * 2);
|
||||
for (size_t i = 0; i < sizeof(cfi_data); i++) {
|
||||
CFI[i * 2] = CFI[i * 2 + 1] = cfi_data[i];
|
||||
}
|
||||
SetupCartPRGMapping(CFI_CHIP, CFI, sizeof(cfi_data) * 2, 0);
|
||||
Flash = (uint8*)FCEU_gmalloc(PRGsize[ROM_CHIP]);
|
||||
for (unsigned int i = 0; i < PRGsize[ROM_CHIP]; i++) {
|
||||
Flash[i] = PRGptr[ROM_CHIP][i % PRGsize[ROM_CHIP]];
|
||||
}
|
||||
SetupCartPRGMapping(FLASH_CHIP, Flash, PRGsize[ROM_CHIP], 1);
|
||||
info->SaveGame[1] = Flash;
|
||||
info->SaveGameLen[1] = PRGsize[ROM_CHIP];
|
||||
}
|
||||
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
if (flash_save)
|
||||
{
|
||||
AddExState(&flash_state, sizeof(flash_state), 0, "FLST");
|
||||
AddExState(flash_buffer_a, sizeof(flash_buffer_a), 0, "FLBA");
|
||||
AddExState(flash_buffer_v, sizeof(flash_buffer_v), 0, "FLBV");
|
||||
AddExState(&cfi_mode, sizeof(cfi_mode), 0, "CFIM");
|
||||
AddExState(Flash, PRGsize[ROM_CHIP], 0, "FLAS");
|
||||
}
|
||||
}
|
||||
|
||||
// Registers at $6xxx
|
||||
void COOLBOY_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 2048, 256, 8, 1);
|
||||
pwrap = COOLBOYPW;
|
||||
cwrap = COOLBOYCW;
|
||||
info->Power = COOLBOYPower;
|
||||
info->Reset = COOLBOYReset;
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
void COOLBOY_Init(CartInfo* info) {
|
||||
CommonInit(info, 0);
|
||||
}
|
||||
|
||||
// Registers at $5xxx
|
||||
void MINDKIDS_Init(CartInfo *info) {
|
||||
GenMMC3_Init(info, 2048, 256, 8, 1);
|
||||
pwrap = COOLBOYPW;
|
||||
cwrap = COOLBOYCW;
|
||||
info->Power = MINDKIDSPower;
|
||||
info->Reset = COOLBOYReset;
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
void MINDKIDS_Init(CartInfo* info) {
|
||||
CommonInit(info, 1);
|
||||
}
|
||||
|
||||
// For NES 2.0 loader
|
||||
void SMD132_SMD133_Init(CartInfo *info) {
|
||||
switch (info->submapper)
|
||||
{
|
||||
case 0:
|
||||
COOLBOY_Init(info);
|
||||
break;
|
||||
case 1:
|
||||
MINDKIDS_Init(info);
|
||||
break;
|
||||
default:
|
||||
FCEU_PrintError("Unknown submapper: #%d.", info->submapper);
|
||||
break;
|
||||
}
|
||||
void AA6023_Init(CartInfo* info) {
|
||||
CommonInit(info, info->submapper);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -474,6 +474,39 @@ void Mapper203_Init(CartInfo *info) {
|
||||
Latch_Init(info, M203Sync, 0, 0x8000, 0xFFFF, 0, 0);
|
||||
}
|
||||
|
||||
//------------------ Map 218 ---------------------------
|
||||
|
||||
static void Mapper218_Power()
|
||||
{
|
||||
//doesn't really matter
|
||||
SetReadHandler(0x6000, 0xFFFF, &CartBROB);
|
||||
}
|
||||
|
||||
void Mapper218_Init(CartInfo *info)
|
||||
{
|
||||
info->Power = &Mapper218_Power;
|
||||
|
||||
//fixed PRG mapping
|
||||
setprg32(0x8000, 0);
|
||||
|
||||
//this mapper is supposed to interpret the iNES header bits specially
|
||||
static const uint8 mirrorings[] = {MI_V,MI_H,MI_0,MI_1};
|
||||
SetupCartMirroring(mirrorings[info->mirrorAs2Bits],1,nullptr);
|
||||
|
||||
//cryptic logic to effect the CHR RAM mappings by mapping 1k blocks to NTARAM according to how the pins are wired
|
||||
//this could be done by bit logic, but this is self-documenting
|
||||
static const uint8 mapping[] = {
|
||||
0,1,0,1,0,1,0,1, //mirrorAs2Bits==0
|
||||
0,0,1,1,0,0,1,1, //mirrorAs2Bits==1
|
||||
0,0,0,0,1,1,1,1, //mirrorAs2Bits==2
|
||||
0,0,0,0,0,0,0,0 //mirrorAs2Bits==3
|
||||
};
|
||||
for(int i=0;i<8;i++)
|
||||
VPageR[i] = &NTARAM[mapping[info->mirrorAs2Bits*8+i]];
|
||||
|
||||
PPUCHRRAM = 0xFF;
|
||||
}
|
||||
|
||||
//------------------ Map 240 ---------------------------
|
||||
|
||||
static void M240Sync(void) {
|
||||
|
||||
@@ -34,11 +34,13 @@ static uint8 *WRAM = NULL;
|
||||
static int kanji_pos, kanji_page, r40C0;
|
||||
static int IRQa, IRQCount;
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static DECLFW(MBWRAM) {
|
||||
if (!(DRegs[3] & 0x10))
|
||||
Page[A >> 11][A] = V;
|
||||
}
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static DECLFR(MAWRAM) {
|
||||
if (DRegs[3] & 0x10)
|
||||
return X.DB;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2022 Cluster
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* NES 2.0 Mapper 470 denotes the INX_007T_V01 multicart circuit board,
|
||||
* used for the Retro-Bit re-release of Battletoads and Double Dragon.
|
||||
* It is basically AOROM with an additional outer bank register at $5000-$5FFF
|
||||
* whose data selects the 256 KiB outer bank.
|
||||
*
|
||||
* $5000-$5FFF
|
||||
* 7 bit 0
|
||||
* ---- ----
|
||||
* xxxx xxOO
|
||||
* ||
|
||||
* ++- Select outer 256 KB PRG ROM bank for CPU $8000-$FFFF
|
||||
*
|
||||
* $8000-$FFFF
|
||||
* 7 bit 0
|
||||
* ---- ----
|
||||
* xxxM xPPP
|
||||
* | |||
|
||||
* | +++- Select inner 32 KB PRG ROM bank for CPU $8000-$FFFF
|
||||
* +------ Select 1 KB VRAM page for all 4 nametables
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 latch_out, latch_in;
|
||||
|
||||
static void INX_007T_Sync() {
|
||||
setprg32(0x8000, (latch_in & 0b111) | (latch_out << 3));
|
||||
setmirror(MI_0 + ((latch_in >> 4) & 1));
|
||||
setchr8(0);
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
INX_007T_Sync();
|
||||
}
|
||||
|
||||
static DECLFW(INX_007T_WriteLow)
|
||||
{
|
||||
latch_out = V;
|
||||
INX_007T_Sync();
|
||||
}
|
||||
|
||||
static DECLFW(INX_007T_WriteHi)
|
||||
{
|
||||
latch_in = V;
|
||||
INX_007T_Sync();
|
||||
}
|
||||
|
||||
static void INX_007T_Power(void) {
|
||||
latch_in = latch_out = 0;
|
||||
INX_007T_Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
SetWriteHandler(0x5000,0x5FFF, INX_007T_WriteLow);
|
||||
SetWriteHandler(0x8000, 0xFFFF, INX_007T_WriteHi);
|
||||
}
|
||||
|
||||
static void INX_007T_Reset(void) {
|
||||
latch_in = latch_out = 0;
|
||||
INX_007T_Sync();
|
||||
}
|
||||
|
||||
void INX_007T_Init(CartInfo *info) {
|
||||
info->Power = INX_007T_Power;
|
||||
info->Reset = INX_007T_Reset;
|
||||
GameStateRestore = StateRestore;
|
||||
SetupCartMirroring(MI_0, 0, NULL);
|
||||
AddExState(&latch_out, 1, 0, "LATO");
|
||||
AddExState(&latch_in, 1, 0, "LATI");
|
||||
}
|
||||
@@ -1376,6 +1376,7 @@ static DECLFW(M406IRQWrite) {
|
||||
MMC3_IRQWrite((A & 0xFFFE) | ((A & 2) >> 1), V);
|
||||
}
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static DECLFW(M406Write) {
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -307,8 +307,7 @@ cartdata MMC5CartList[] =
|
||||
|
||||
#define MMC5_NOCARTS (sizeof(MMC5CartList) / sizeof(MMC5CartList[0]))
|
||||
int DetectMMC5WRAMSize(uint32 crc32) {
|
||||
int x;
|
||||
for (x = 0; x < MMC5_NOCARTS; x++) {
|
||||
for (size_t x = 0; x < MMC5_NOCARTS; x++) {
|
||||
if (crc32 == MMC5CartList[x].crc32) {
|
||||
if(MMC5CartList[x].size > 1)
|
||||
FCEU_printf(" >8KB external WRAM present. Use UNIF if you hack the ROM image.\n");
|
||||
|
||||
+131
-193
@@ -1,7 +1,7 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2014 CaitSith2
|
||||
* Copyright (C) 2014 CaitSith2, 2022 Cluster
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Roms still using NES 1.0 format should be loaded as 32K CHR RAM.
|
||||
* Roms still using NES 1.0 format should be loaded as 8K CHR RAM.
|
||||
* Roms defined under NES 2.0 should use the VRAM size field, defining 7, 8 or 9, based on how much VRAM should be present.
|
||||
* UNIF doesn't have this problem, because unique board names can define this information.
|
||||
* The UNIF names are UNROM-512-8K, UNROM-512-16K and UNROM-512-32K
|
||||
@@ -28,6 +28,7 @@
|
||||
* Known games to use this board are:
|
||||
* Battle Kid 2: Mountain of Torment (512K PRG, 8K CHR RAM, Horizontal Mirroring, Flash disabled)
|
||||
* Study Hall (128K PRG (in 512K flash chip), 8K CHR RAM, Horizontal Mirroring, Flash enabled)
|
||||
* Nix: The Paradox Relic (512 PRG, 8K CHR RAM, Vertical Mirroring, Flash enabled)
|
||||
* Although Xmas 2013 uses a different board, where LEDs can be controlled (with writes to the $8000-BFFF space),
|
||||
* it otherwise functions identically.
|
||||
*/
|
||||
@@ -35,211 +36,147 @@
|
||||
#include "mapinc.h"
|
||||
#include "../ines.h"
|
||||
|
||||
static uint8 latche, latcheinit, bus_conflict, chrram_mask, software_id=false;
|
||||
const int ROM_CHIP = 0x00;
|
||||
const int CFI_CHIP = 0x10;
|
||||
const int FLASH_CHIP = 0x11;
|
||||
|
||||
const int FLASH_SECTOR_SIZE = 4 * 1024;
|
||||
|
||||
static uint8 flash_save, flash_state, flash_id_mode, latche, bus_conflict;
|
||||
static uint16 latcha;
|
||||
static uint8 *flashdata;
|
||||
static uint32 *flash_write_count;
|
||||
static uint8 *FlashPage[32];
|
||||
//static uint32 *FlashWriteCountPage[32];
|
||||
//static uint8 flashloaded = false;
|
||||
static uint8 *flash_data;
|
||||
static uint16 flash_buffer_a[10];
|
||||
static uint8 flash_buffer_v[10];
|
||||
static uint8 flash_id[2];
|
||||
|
||||
static uint8 flash_save=0, flash_state=0, flash_mode=0, flash_bank;
|
||||
static void (*WLSync)(void);
|
||||
static void (*WHSync)(void);
|
||||
|
||||
static INLINE void setfpageptr(int s, uint32 A, uint8 *p) {
|
||||
uint32 AB = A >> 11;
|
||||
int x;
|
||||
|
||||
if (p)
|
||||
for (x = (s >> 1) - 1; x >= 0; x--) {
|
||||
FlashPage[AB + x] = p - A;
|
||||
}
|
||||
static void UNROM512_Sync() {
|
||||
int chip;
|
||||
if (flash_save)
|
||||
chip = !flash_id_mode ? FLASH_CHIP : CFI_CHIP;
|
||||
else
|
||||
for (x = (s >> 1) - 1; x >= 0; x--) {
|
||||
FlashPage[AB + x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void setfprg16(uint32 A, uint32 V) {
|
||||
if (PRGsize[0] >= 16384) {
|
||||
V &= PRGmask16[0];
|
||||
setfpageptr(16, A, flashdata ? (&flashdata[V << 14]) : 0);
|
||||
} else {
|
||||
uint32 VA = V << 3;
|
||||
int x;
|
||||
|
||||
for (x = 0; x < 8; x++)
|
||||
setfpageptr(2, A + (x << 11), flashdata ? (&flashdata[((VA + x) & PRGmask2[0]) << 11]) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void inc_flash_write_count(uint8 bank, uint32 A)
|
||||
{
|
||||
flash_write_count[(bank*4) + ((A&0x3000)>>12)]++;
|
||||
if(!flash_write_count[(bank*4) + ((A&0x3000)>>12)])
|
||||
flash_write_count[(bank*4) + ((A&0x3000)>>12)]++;
|
||||
}
|
||||
|
||||
uint32 GetFlashWriteCount(uint8 bank, uint32 A)
|
||||
{
|
||||
return flash_write_count[(bank*4) + ((A&0x3000)>>12)];
|
||||
chip = ROM_CHIP;
|
||||
setprg16r(chip, 0x8000, latche & 0b11111);
|
||||
setprg16r(chip, 0xc000, ~0);
|
||||
setchr8((latche >> 5) & 0b11);
|
||||
setmirror(MI_0 + ((latche >> 7) & 1));
|
||||
}
|
||||
|
||||
static void StateRestore(int version) {
|
||||
WHSync();
|
||||
UNROM512_Sync();
|
||||
}
|
||||
|
||||
static DECLFW(UNROM512LLatchWrite)
|
||||
static DECLFW(UNROM512FlashWrite)
|
||||
{
|
||||
latche = V;
|
||||
latcha = A;
|
||||
WLSync();
|
||||
if (flash_state < sizeof(flash_buffer_a) / sizeof(flash_buffer_a[0])) {
|
||||
flash_buffer_a[flash_state] = (A & 0x3FFF) | ((latche & 1) << 14);
|
||||
flash_buffer_v[flash_state] = V;
|
||||
flash_state++;
|
||||
|
||||
// enter flash ID mode
|
||||
if ((flash_state == 2) &&
|
||||
(flash_buffer_a[0] == 0x5555) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x2AAA) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[1] == 0x5555) && (flash_buffer_v[1] == 0x90)) {
|
||||
flash_id_mode = 0;
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// erase sector
|
||||
if ((flash_state == 6) &&
|
||||
(flash_buffer_a[0] == 0x5555) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x2AAA) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x5555) && (flash_buffer_v[2] == 0x80) &&
|
||||
(flash_buffer_a[3] == 0x5555) && (flash_buffer_v[3] == 0xAA) &&
|
||||
(flash_buffer_a[4] == 0x2AAA) && (flash_buffer_v[4] == 0x55) &&
|
||||
(flash_buffer_v[5] == 0x30)) {
|
||||
int offset = &Page[A >> 11][A] - flash_data;
|
||||
int sector = offset / FLASH_SECTOR_SIZE;
|
||||
for (int i = sector * FLASH_SECTOR_SIZE; i < (sector + 1) * FLASH_SECTOR_SIZE; i++)
|
||||
flash_data[i % PRGsize[ROM_CHIP]] = 0xFF;
|
||||
FCEU_printf("Flash sector #%d is erased (0x%08x - 0x%08x).\n", sector, offset, offset + FLASH_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
// erase chip
|
||||
if ((flash_state == 6) &&
|
||||
(flash_buffer_a[0] == 0x5555) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x2AAA) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x5555) && (flash_buffer_v[2] == 0x80) &&
|
||||
(flash_buffer_a[3] == 0x5555) && (flash_buffer_v[3] == 0xAA) &&
|
||||
(flash_buffer_a[4] == 0x2AAA) && (flash_buffer_v[4] == 0x55) &&
|
||||
(flash_buffer_a[4] == 0x5555) && (flash_buffer_v[4] == 0x10)) {
|
||||
memset(flash_data, 0xFF, PRGsize[ROM_CHIP]);
|
||||
FCEU_printf("Flash chip erased.\n");
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// write byte
|
||||
if ((flash_state == 4) &&
|
||||
(flash_buffer_a[0] == 0x5555) && (flash_buffer_v[0] == 0xAA) &&
|
||||
(flash_buffer_a[1] == 0x2AAA) && (flash_buffer_v[1] == 0x55) &&
|
||||
(flash_buffer_a[2] == 0x5555) && (flash_buffer_v[2] == 0xA0)) {
|
||||
int offset = &Page[A >> 11][A] - flash_data;
|
||||
if (CartBR(A) != 0xFF) {
|
||||
FCEU_PrintError("Error: can't write to 0x%08x, flash sector is not erased.\n", offset);
|
||||
}
|
||||
else {
|
||||
CartBW(A, V);
|
||||
}
|
||||
flash_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// not a command
|
||||
if (((A & 0xFFF) != 0x0AAA) && ((A & 0xFFF) != 0x0555)) {
|
||||
flash_state = 0;
|
||||
}
|
||||
|
||||
// reset
|
||||
if (V == 0xF0) {
|
||||
flash_state = 0;
|
||||
flash_id_mode = 0;
|
||||
}
|
||||
|
||||
UNROM512_Sync();
|
||||
}
|
||||
|
||||
static DECLFW(UNROM512HLatchWrite)
|
||||
{
|
||||
if (bus_conflict)
|
||||
latche = (V == CartBR(A)) ? V : 0;
|
||||
latche = V & CartBR(A);
|
||||
else
|
||||
latche = V;
|
||||
latcha = A;
|
||||
WHSync();
|
||||
}
|
||||
|
||||
static DECLFR(UNROM512LatchRead)
|
||||
{
|
||||
uint8 flash_id[3]={0xB5,0xB6,0xB7};
|
||||
if(software_id)
|
||||
{
|
||||
if(A&1)
|
||||
return flash_id[ROM_size>>4];
|
||||
else
|
||||
return 0xBF;
|
||||
}
|
||||
if(flash_save)
|
||||
{
|
||||
if(A < 0xC000)
|
||||
{
|
||||
if(GetFlashWriteCount(flash_bank,A))
|
||||
return FlashPage[A >> 11][A];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetFlashWriteCount(ROM_size-1,A))
|
||||
return FlashPage[A >> 11][A];
|
||||
}
|
||||
}
|
||||
return Page[A >> 11][A];
|
||||
UNROM512_Sync();
|
||||
}
|
||||
|
||||
static void UNROM512LatchPower(void) {
|
||||
latche = latcheinit;
|
||||
WHSync();
|
||||
SetReadHandler(0x8000, 0xFFFF, UNROM512LatchRead);
|
||||
latche = 0;
|
||||
UNROM512_Sync();
|
||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||
if(!flash_save)
|
||||
SetWriteHandler(0x8000, 0xFFFF, UNROM512HLatchWrite);
|
||||
else
|
||||
{
|
||||
SetWriteHandler(0x8000,0xBFFF,UNROM512LLatchWrite);
|
||||
SetWriteHandler(0x8000,0xBFFF,UNROM512FlashWrite);
|
||||
SetWriteHandler(0xC000,0xFFFF,UNROM512HLatchWrite);
|
||||
}
|
||||
}
|
||||
|
||||
static void UNROM512LatchClose(void) {
|
||||
if(flash_write_count)
|
||||
FCEU_gfree(flash_write_count);
|
||||
if(flashdata)
|
||||
FCEU_gfree(flashdata);
|
||||
flash_write_count = NULL;
|
||||
flashdata = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void UNROM512LSync() {
|
||||
int erase_a[5]={0x9555,0xAAAA,0x9555,0x9555,0xAAAA};
|
||||
int erase_d[5]={0xAA,0x55,0x80,0xAA,0x55};
|
||||
int erase_b[5]={1,0,1,1,0};
|
||||
|
||||
if(flash_mode==0)
|
||||
{
|
||||
if((latcha == erase_a[flash_state]) && (latche == erase_d[flash_state]) && (flash_bank == erase_b[flash_state]))
|
||||
{
|
||||
flash_state++;
|
||||
if(flash_state == 5)
|
||||
{
|
||||
flash_mode=1;
|
||||
}
|
||||
}
|
||||
else if ((flash_state==2)&&(latcha==0x9555)&&(latche==0xA0)&&(flash_bank==1))
|
||||
{
|
||||
flash_state++;
|
||||
flash_mode=2;
|
||||
}
|
||||
else if ((flash_state==2)&&(latcha==0x9555)&&(latche==0x90)&&(flash_bank==1))
|
||||
{
|
||||
flash_state=0;
|
||||
software_id=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(latche==0xF0)
|
||||
software_id=false;
|
||||
flash_state=0;
|
||||
}
|
||||
}
|
||||
else if(flash_mode==1) //Chip Erase or Sector Erase
|
||||
{
|
||||
if(latche==0x30)
|
||||
{
|
||||
inc_flash_write_count(flash_bank,latcha);
|
||||
memset(&FlashPage[(latcha & 0xF000) >> 11][latcha & 0xF000],0xFF,0x1000);
|
||||
}
|
||||
else if (latche==0x10)
|
||||
{
|
||||
for(uint32 i=0;i<(ROM_size*4);i++)
|
||||
inc_flash_write_count(i>>2,i<<12);
|
||||
memset(flashdata,0xFF,ROM_size*0x4000); //Erasing the rom chip as instructed. Crash rate calulated to be 99.9% :)
|
||||
}
|
||||
flash_state=0;
|
||||
flash_mode=0;
|
||||
}
|
||||
else if(flash_mode==2) //Byte Program
|
||||
{
|
||||
if(!GetFlashWriteCount(flash_bank,latcha))
|
||||
{
|
||||
inc_flash_write_count(flash_bank,latcha);
|
||||
memcpy(&FlashPage[(latcha & 0xF000) >> 11][latcha & 0xF000],&Page[(latcha & 0xF000)>>11][latcha & 0xF000],0x1000);
|
||||
}
|
||||
FlashPage[latcha>>11][latcha]&=latche;
|
||||
flash_state=0;
|
||||
flash_mode=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void UNROM512HSync()
|
||||
{
|
||||
flash_bank=latche&(ROM_size-1);
|
||||
|
||||
setprg16(0x8000, flash_bank);
|
||||
setprg16(0xc000, ~0);
|
||||
setfprg16(0x8000, flash_bank);
|
||||
setfprg16(0xC000, ~0);
|
||||
setchr8r(0, (latche & chrram_mask) >> 5);
|
||||
setmirror(MI_0+(latche>>7));
|
||||
if(flash_data)
|
||||
FCEU_gfree(flash_data);
|
||||
flash_data = NULL;
|
||||
}
|
||||
|
||||
void UNROM512_Init(CartInfo *info) {
|
||||
flash_state=0;
|
||||
flash_bank=0;
|
||||
flash_save=info->battery;
|
||||
info->Power = UNROM512LatchPower;
|
||||
info->Close = UNROM512LatchClose;
|
||||
GameStateRestore = StateRestore;
|
||||
|
||||
if(info->vram_size == 8192)
|
||||
chrram_mask = 0;
|
||||
else if (info->vram_size == 16384)
|
||||
chrram_mask = 0x20;
|
||||
else
|
||||
chrram_mask = 0x60;
|
||||
flash_state = 0;
|
||||
flash_id_mode = 0;
|
||||
flash_save = info->battery;
|
||||
bus_conflict = !info->battery; // Is it required by any game?
|
||||
|
||||
int mirror = (head.ROM_type & 1) | ((head.ROM_type & 8) >> 2);
|
||||
switch (mirror)
|
||||
@@ -258,28 +195,29 @@ void UNROM512_Init(CartInfo *info) {
|
||||
break;
|
||||
}
|
||||
|
||||
bus_conflict = !info->battery;
|
||||
latcheinit = 0;
|
||||
WLSync = UNROM512LSync;
|
||||
WHSync = UNROM512HSync;
|
||||
info->Power = UNROM512LatchPower;
|
||||
info->Close = UNROM512LatchClose;
|
||||
GameStateRestore = StateRestore;
|
||||
if(flash_save)
|
||||
{
|
||||
flashdata = (uint8*)FCEU_gmalloc(ROM_size*0x4000);
|
||||
flash_write_count = (uint32*)FCEU_gmalloc(ROM_size*4*sizeof(uint32));
|
||||
info->SaveGame[0] = (uint8*)flash_write_count;
|
||||
info->SaveGame[1] = flashdata;
|
||||
info->SaveGameLen[0] = ROM_size*4*sizeof(uint32);
|
||||
info->SaveGameLen[1] = ROM_size*0x4000;
|
||||
AddExState(flash_write_count,ROM_size*4*sizeof(uint32),0,"FLASH_WRITE_COUNT");
|
||||
AddExState(flashdata,ROM_size*0x4000,0,"FLASH_DATA");
|
||||
AddExState(&flash_state,1,0,"FLASH_STATE");
|
||||
AddExState(&flash_mode,1,0,"FLASH_MODE");
|
||||
AddExState(&flash_bank,1,0,"FLASH_BANK");
|
||||
AddExState(&latcha,2,0,"LATA");
|
||||
// Allocate memory for flash
|
||||
flash_data = (uint8*)FCEU_gmalloc(PRGsize[ROM_CHIP]);
|
||||
// Copy ROM to flash data
|
||||
for (unsigned int i = 0; i < PRGsize[ROM_CHIP]; i++) {
|
||||
flash_data[i] = PRGptr[ROM_CHIP][i % PRGsize[ROM_CHIP]];
|
||||
}
|
||||
SetupCartPRGMapping(FLASH_CHIP, flash_data, PRGsize[ROM_CHIP], 1);
|
||||
info->SaveGame[0] = flash_data;
|
||||
info->SaveGameLen[0] = PRGsize[ROM_CHIP];
|
||||
|
||||
flash_id[0] = 0xBF;
|
||||
flash_id[1] = 0xB5 + (ROM_size >> 4);
|
||||
SetupCartPRGMapping(CFI_CHIP, flash_id, sizeof(flash_id), 0);
|
||||
|
||||
AddExState(flash_data, PRGsize[ROM_CHIP], 0, "FLSH");
|
||||
AddExState(&flash_state, 1, 0, "FLST");
|
||||
AddExState(&flash_id_mode, 1, 0, "FLMD");
|
||||
AddExState(flash_buffer_a, sizeof(flash_buffer_a), 0, "FLBA");
|
||||
AddExState(flash_buffer_v, sizeof(flash_buffer_v), 0, "FLBV");
|
||||
}
|
||||
AddExState(&latcha, 2, 0, "LATA");
|
||||
AddExState(&latche, 1, 0, "LATC");
|
||||
AddExState(&bus_conflict, 1, 0, "BUSC");
|
||||
}
|
||||
|
||||
+19
-6
@@ -23,7 +23,7 @@
|
||||
static bool isPirate;
|
||||
static uint8 is22, reg1mask, reg2mask;
|
||||
static uint16 IRQCount;
|
||||
static uint8 IRQLatch, IRQa;
|
||||
static uint8 IRQLatch, IRQa, IRQMode;
|
||||
static uint8 prgreg[2], chrreg[8];
|
||||
static uint16 chrhi[8];
|
||||
static uint8 regcmd, irqcmd, mirr, big_bank;
|
||||
@@ -45,6 +45,7 @@ static SFORMAT StateRegs[] =
|
||||
{ &IRQCount, 2, "IRQC" },
|
||||
{ &IRQLatch, 1, "IRQL" },
|
||||
{ &IRQa, 1, "IRQA" },
|
||||
{ &IRQMode, 1, "IRQM" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -115,7 +116,7 @@ static DECLFW(VRC24Write) {
|
||||
case 0x9003: regcmd = V; Sync(); break;
|
||||
case 0xF000: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0xF0; IRQLatch |= V & 0xF; break;
|
||||
case 0xF001: X6502_IRQEnd(FCEU_IQEXT); IRQLatch &= 0x0F; IRQLatch |= V << 4; break;
|
||||
case 0xF002: X6502_IRQEnd(FCEU_IQEXT); acount = 0; IRQCount = IRQLatch; IRQa = V & 2; irqcmd = V & 1; break;
|
||||
case 0xF002: X6502_IRQEnd(FCEU_IQEXT); acount = 0; IRQCount = IRQLatch; IRQMode = V & 4; IRQa = V & 2; irqcmd = V & 1; break;
|
||||
case 0xF003: X6502_IRQEnd(FCEU_IQEXT); IRQa = irqcmd; break;
|
||||
}
|
||||
}
|
||||
@@ -136,16 +137,28 @@ static void VRC24Power(void) {
|
||||
void VRC24IRQHook(int a) {
|
||||
#define LCYCS 341
|
||||
if (IRQa) {
|
||||
acount += a * 3;
|
||||
if (acount >= LCYCS) {
|
||||
while (acount >= LCYCS) {
|
||||
acount -= LCYCS;
|
||||
if (IRQMode) {
|
||||
acount += a;
|
||||
while (acount > 0) {
|
||||
acount--;
|
||||
IRQCount++;
|
||||
if (IRQCount & 0x100) {
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
IRQCount = IRQLatch;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
acount += a * 3;
|
||||
if (acount >= LCYCS) {
|
||||
while (acount >= LCYCS) {
|
||||
acount -= LCYCS;
|
||||
IRQCount++;
|
||||
if (IRQCount & 0x100) {
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
IRQCount = IRQLatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-8
@@ -25,7 +25,7 @@
|
||||
|
||||
static uint8 is26;
|
||||
static uint8 prg[2], chr[8], mirr;
|
||||
static uint8 IRQLatch, IRQa, IRQd;
|
||||
static uint8 IRQLatch, IRQa, IRQd, IRQMode;
|
||||
static int32 IRQCount, CycleCount;
|
||||
static uint8 *WRAM = NULL;
|
||||
static uint32 WRAMSIZE;
|
||||
@@ -40,6 +40,7 @@ static SFORMAT StateRegs[] =
|
||||
{ &IRQLatch, 1, "IRQL" },
|
||||
{ &IRQCount, 4, "IRQC" },
|
||||
{ &CycleCount, 4, "CYCC" },
|
||||
{ &IRQMode, 1, "IRQM" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -109,6 +110,7 @@ static DECLFW(VRC6Write) {
|
||||
case 0xE003: chr[7] = V; Sync(); break;
|
||||
case 0xF000: IRQLatch = V; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||
case 0xF001:
|
||||
IRQMode = V & 4;
|
||||
IRQa = V & 2;
|
||||
IRQd = V & 1;
|
||||
if (V & 2)
|
||||
@@ -132,13 +134,25 @@ static void VRC6Power(void) {
|
||||
|
||||
static void VRC6IRQHook(int a) {
|
||||
if (IRQa) {
|
||||
CycleCount += a * 3;
|
||||
while(CycleCount >= 341) {
|
||||
CycleCount -= 341;
|
||||
IRQCount++;
|
||||
if (IRQCount == 0x100) {
|
||||
IRQCount = IRQLatch;
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
if (IRQMode) {
|
||||
CycleCount += a;
|
||||
while (CycleCount > 0) {
|
||||
CycleCount--;
|
||||
IRQCount++;
|
||||
if (IRQCount & 0x100) {
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
IRQCount = IRQLatch;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CycleCount += a * 3;
|
||||
while(CycleCount >= 341) {
|
||||
CycleCount -= 341;
|
||||
IRQCount++;
|
||||
if (IRQCount == 0x100) {
|
||||
IRQCount = IRQLatch;
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-8
@@ -21,7 +21,7 @@
|
||||
#include "mapinc.h"
|
||||
|
||||
static uint8 vrc7idx, preg[3], creg[8], mirr;
|
||||
static uint8 IRQLatch, IRQa, IRQd;
|
||||
static uint8 IRQLatch, IRQa, IRQd, IRQMode;
|
||||
static int32 IRQCount, CycleCount;
|
||||
static uint8 *WRAM = NULL;
|
||||
static uint32 WRAMSIZE;
|
||||
@@ -44,6 +44,7 @@ static SFORMAT StateRegs[] =
|
||||
{ &IRQCount, 4, "IRQC" },
|
||||
{ &CycleCount, 4, "CYCC" },
|
||||
{ (void**)VRC7Sound_saveptr, sizeof(*VRC7Sound) | FCEUSTATE_INDIRECT, "VRC7" },
|
||||
{ &IRQMode, 1, "IRQM" },
|
||||
{0}
|
||||
};
|
||||
|
||||
@@ -134,6 +135,7 @@ static DECLFW(VRC7Write) {
|
||||
case 0xE000: mirr = V & 3; Sync(); break;
|
||||
case 0xE010: IRQLatch = V; X6502_IRQEnd(FCEU_IQEXT); break;
|
||||
case 0xF000:
|
||||
IRQMode = V & 4;
|
||||
IRQa = V & 2;
|
||||
IRQd = V & 1;
|
||||
if (V & 2)
|
||||
@@ -165,13 +167,25 @@ static void VRC7Close(void)
|
||||
|
||||
static void VRC7IRQHook(int a) {
|
||||
if (IRQa) {
|
||||
CycleCount += a * 3;
|
||||
while(CycleCount >= 341) {
|
||||
CycleCount -= 341;
|
||||
IRQCount++;
|
||||
if (IRQCount == 0x100) {
|
||||
IRQCount = IRQLatch;
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
if (IRQMode) {
|
||||
CycleCount += a;
|
||||
while (CycleCount > 0) {
|
||||
CycleCount--;
|
||||
IRQCount++;
|
||||
if (IRQCount & 0x100) {
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
IRQCount = IRQLatch;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CycleCount += a * 3;
|
||||
while(CycleCount >= 341) {
|
||||
CycleCount -= 341;
|
||||
IRQCount++;
|
||||
if (IRQCount == 0x100) {
|
||||
IRQCount = IRQLatch;
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -562,10 +562,18 @@ void FCEU_LoadGameSave(CartInfo *LocalHWInfo) {
|
||||
|
||||
std::string soot = FCEU_MakeFName(FCEUMKF_SAV, 0, "sav");
|
||||
sp = FCEUD_UTF8fopen(soot, "rb");
|
||||
if (sp != NULL) {
|
||||
if (sp != NULL)
|
||||
{
|
||||
for (int x = 0; x < 4; x++)
|
||||
{
|
||||
if (LocalHWInfo->SaveGame[x])
|
||||
fread(LocalHWInfo->SaveGame[x], 1, LocalHWInfo->SaveGameLen[x], sp);
|
||||
{
|
||||
if ( fread(LocalHWInfo->SaveGame[x], 1, LocalHWInfo->SaveGameLen[x], sp) != static_cast<size_t>(LocalHWInfo->SaveGameLen[x]) )
|
||||
{
|
||||
FCEU_printf("Warning save game data read came up short!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ typedef struct {
|
||||
// to help support games like "Karnov"
|
||||
// that are not really MMC3 but are
|
||||
// set to mapper 4.
|
||||
int mirrorAs2Bits;
|
||||
int battery; // Presence of an actual battery.
|
||||
int ines2;
|
||||
int submapper; // Submappers as defined by NES 2.0
|
||||
|
||||
+19
-41
@@ -59,7 +59,7 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
|
||||
}
|
||||
|
||||
|
||||
CHEATF_SUBFAST SubCheats[256] = { 0 };
|
||||
CHEATF_SUBFAST SubCheats[256];
|
||||
uint32 numsubcheats = 0;
|
||||
int globalCheatDisabled = 0;
|
||||
int disableAutoLSCheats = 0;
|
||||
@@ -152,28 +152,23 @@ int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size) {
|
||||
return count;
|
||||
}
|
||||
|
||||
static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type);
|
||||
static void AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type);
|
||||
static void CheatMemErr(void)
|
||||
{
|
||||
FCEUD_PrintError("Error allocating memory for cheat data.");
|
||||
}
|
||||
|
||||
static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type)
|
||||
static void AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare, int status, int type)
|
||||
{
|
||||
struct CHEATF *temp;
|
||||
if(!(temp = (struct CHEATF *)FCEU_dmalloc(sizeof(struct CHEATF))))
|
||||
{
|
||||
CheatMemErr();
|
||||
return(0);
|
||||
}
|
||||
CHEATF *temp = new CHEATF();
|
||||
|
||||
temp->name = strcpy((char*) FCEU_dmalloc(strlen(name) + 1), name);
|
||||
temp->name = name;
|
||||
temp->addr = addr;
|
||||
temp->val = val;
|
||||
temp->status = status;
|
||||
temp->compare = compare;
|
||||
temp->type = type;
|
||||
temp->next = 0;
|
||||
temp->next = nullptr;
|
||||
|
||||
if(cheats)
|
||||
{
|
||||
@@ -182,8 +177,6 @@ static int AddCheatEntry(const char *name, uint32 addr, uint8 val, int compare,
|
||||
}
|
||||
else
|
||||
cheats = cheatsl = temp;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* The "override_existing" parameter is used only in cheat dialog import.
|
||||
@@ -306,14 +299,13 @@ void FCEU_SaveGameCheats(FILE* fp, int release)
|
||||
fputc(':', fp);
|
||||
|
||||
if (next->compare >= 0)
|
||||
fprintf(fp, "%04x:%02x:%02x:%s\n", next->addr, next->val, next->compare, next->name);
|
||||
fprintf(fp, "%04x:%02x:%02x:%s\n", next->addr, next->val, next->compare, next->name.c_str());
|
||||
else
|
||||
fprintf(fp, "%04x:%02x:%s\n", next->addr, next->val, next->name);
|
||||
fprintf(fp, "%04x:%02x:%s\n", next->addr, next->val, next->name.c_str());
|
||||
|
||||
if (release) free(next->name);
|
||||
struct CHEATF *t = next;
|
||||
next = next->next;
|
||||
if (release) free(t);
|
||||
if (release) delete t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,8 +325,7 @@ void FCEU_FlushGameCheats(FILE *override, int nosave)
|
||||
{
|
||||
struct CHEATF *last=next;
|
||||
next=next->next;
|
||||
free(last->name);
|
||||
free(last);
|
||||
delete last;
|
||||
if(!next) break;
|
||||
}
|
||||
cheats=cheatsl=0;
|
||||
@@ -379,9 +370,7 @@ void FCEU_FlushGameCheats(FILE *override, int nosave)
|
||||
|
||||
int FCEUI_AddCheat(const char *name, uint32 addr, uint8 val, int compare, int type)
|
||||
{
|
||||
|
||||
if(!AddCheatEntry(name, addr, val, compare, 1, type))
|
||||
return 0;
|
||||
AddCheatEntry(name, addr, val, compare, 1, type);
|
||||
savecheats = 1;
|
||||
RebuildSubCheats();
|
||||
|
||||
@@ -415,8 +404,7 @@ int FCEUI_DelCheat(uint32 which)
|
||||
else
|
||||
cheats=cheatsl=0; // No (more) cheats.
|
||||
}
|
||||
free(cur->name); // Now that all references to this cheat are removed,
|
||||
free(cur); // free the memory.
|
||||
delete cur; // free the memory.
|
||||
break;
|
||||
} // *END REMOVE THIS CHEAT*
|
||||
|
||||
@@ -451,18 +439,18 @@ void FCEU_ApplyPeriodicCheats(void)
|
||||
}
|
||||
|
||||
|
||||
void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data)
|
||||
void FCEUI_ListCheats(int (*callb)(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data)
|
||||
{
|
||||
struct CHEATF *next=cheats;
|
||||
|
||||
while(next)
|
||||
{
|
||||
if(!callb(next->name,next->addr,next->val,next->compare,next->status,next->type,data)) break;
|
||||
if(!callb(next->name.c_str(),next->addr,next->val,next->compare,next->status,next->type,data)) break;
|
||||
next=next->next;
|
||||
}
|
||||
}
|
||||
|
||||
int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type)
|
||||
int FCEUI_GetCheat(uint32 which, std::string *name, uint32 *a, uint8 *v, int *compare, int *s, int *type)
|
||||
{
|
||||
struct CHEATF *next=cheats;
|
||||
uint32 x=0;
|
||||
@@ -600,7 +588,7 @@ int FCEUI_DecodePAR(const char *str, int *a, int *v, int *c, int *type)
|
||||
/* name can be NULL if the name isn't going to be changed. */
|
||||
/* same goes for a, v, and s(except the values of each one must be <0) */
|
||||
|
||||
int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int c, int s, int type)
|
||||
int FCEUI_SetCheat(uint32 which, const std::string *name, int32 a, int32 v, int c, int s, int type)
|
||||
{
|
||||
struct CHEATF *next = cheats;
|
||||
uint32 x = 0;
|
||||
@@ -610,13 +598,7 @@ int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int c, int
|
||||
if(x == which)
|
||||
{
|
||||
if(name)
|
||||
{
|
||||
char *t;
|
||||
if((t = (char *)realloc(next->name, strlen(name) + 1)))
|
||||
strcpy(next->name = t, name);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
next->name = *name;
|
||||
if(a >= 0)
|
||||
next->addr = a;
|
||||
if(v >= 0)
|
||||
@@ -662,7 +644,7 @@ int FCEUI_ToggleCheat(uint32 which)
|
||||
|
||||
int FCEUI_GlobalToggleCheat(int global_enabled)
|
||||
{
|
||||
int _numsubcheats = numsubcheats;
|
||||
unsigned int _numsubcheats = numsubcheats;
|
||||
globalCheatDisabled = !global_enabled;
|
||||
RebuildSubCheats();
|
||||
return _numsubcheats != numsubcheats;
|
||||
@@ -911,11 +893,7 @@ int FCEU_DeleteAllCheats(void)
|
||||
while (cur)
|
||||
{
|
||||
next = cur->next;
|
||||
if ( cur->name )
|
||||
{
|
||||
free(cur->name);
|
||||
}
|
||||
free(cur);
|
||||
delete cur;
|
||||
cur = next;
|
||||
}
|
||||
cheats = cheatsl = 0;
|
||||
|
||||
+9
-3
@@ -33,16 +33,22 @@ extern int disableAutoLSCheats;
|
||||
int FCEU_DisableAllCheats(void);
|
||||
int FCEU_DeleteAllCheats(void);
|
||||
|
||||
typedef struct {
|
||||
struct CHEATF_SUBFAST
|
||||
{
|
||||
uint16 addr;
|
||||
uint8 val;
|
||||
int compare;
|
||||
readfunc PrevRead;
|
||||
} CHEATF_SUBFAST;
|
||||
|
||||
CHEATF_SUBFAST(void)
|
||||
{
|
||||
addr = 0; val = 0; compare = 0; PrevRead = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
struct CHEATF {
|
||||
struct CHEATF *next;
|
||||
char *name;
|
||||
std::string name;
|
||||
uint16 addr;
|
||||
uint8 val;
|
||||
int compare; /* -1 for no compare. */
|
||||
|
||||
+15
-10
@@ -11,25 +11,27 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
static char *aboutString = 0;
|
||||
static std::string aboutString;
|
||||
|
||||
#ifndef FCEUX_BUILD_TIMESTAMP
|
||||
#define FCEUX_BUILD_TIMESTAMP __TIME__ " " __DATE__
|
||||
#endif
|
||||
|
||||
//#pragma message( "Compiling using C++ Std: " __FCEU_STRINGIZE(__cplusplus) )
|
||||
|
||||
// returns a string suitable for use in an aboutbox
|
||||
const char *FCEUI_GetAboutString(void)
|
||||
{
|
||||
const char *aboutTemplate =
|
||||
FCEU_NAME_AND_VERSION "\n\n"
|
||||
"Administrators:\n"
|
||||
"zeromus, mjbudd77, feos\n"
|
||||
"zeromus, feos\n"
|
||||
"\n"
|
||||
"Current Contributors:\n"
|
||||
"CaH4e3, rainwarrior, owomomo, punkrockguy318\n"
|
||||
"CaH4e3, rainwarrior, owomomo, punkrockguy318, Cluster\n"
|
||||
"\n"
|
||||
"Past Contributors:\n"
|
||||
"xhainingx, gocha, AnS\n"
|
||||
"xhainingx, gocha, AnS, mjbudd77\n"
|
||||
"\n"
|
||||
"FCEUX 2.0:\n"
|
||||
"mz, nitsujrehtona, SP, Ugly Joe,\n"
|
||||
@@ -55,14 +57,17 @@ const char *FCEUI_GetAboutString(void)
|
||||
"\n"
|
||||
FCEUX_BUILD_TIMESTAMP "\n";
|
||||
|
||||
if (aboutString) return aboutString;
|
||||
if (aboutString.size() > 0) return aboutString.c_str();
|
||||
|
||||
const char *compilerString = FCEUD_GetCompilerString();
|
||||
|
||||
//allocate the string and concatenate the template with the compiler string
|
||||
if (!(aboutString = (char*)FCEU_dmalloc(strlen(aboutTemplate) + strlen(compilerString) + 1)))
|
||||
return NULL;
|
||||
char cppVersion[128];
|
||||
|
||||
sprintf(aboutString,"%s%s",aboutTemplate,compilerString);
|
||||
return aboutString;
|
||||
snprintf( cppVersion, sizeof(cppVersion), "\nCompiled using C++ Language Standard: %li\n", __cplusplus);
|
||||
|
||||
aboutString.assign( aboutTemplate );
|
||||
aboutString.append( compilerString );
|
||||
aboutString.append( cppVersion );
|
||||
|
||||
return aboutString.c_str();
|
||||
}
|
||||
|
||||
+14
-5
@@ -6,6 +6,7 @@
|
||||
#include "cart.h"
|
||||
#include "ines.h"
|
||||
#include "debug.h"
|
||||
#include "debugsymboltable.h"
|
||||
#include "driver.h"
|
||||
#include "ppu.h"
|
||||
|
||||
@@ -41,6 +42,13 @@ int offsetStringToInt(unsigned int type, const char* offsetBuffer)
|
||||
}
|
||||
else // BT_C
|
||||
{
|
||||
auto sym = debugSymbolTable.getSymbolAtAnyBank(offsetBuffer);
|
||||
|
||||
if (sym)
|
||||
{
|
||||
return sym->offset() & 0xFFFF;
|
||||
}
|
||||
|
||||
int type = GIT_CART;
|
||||
|
||||
if (GameInfo)
|
||||
@@ -642,7 +650,8 @@ uint16 StackNextIgnorePC = 0xFFFF;
|
||||
|
||||
///fires a breakpoint
|
||||
static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||
int i, j, romAddrPC;
|
||||
int i, romAddrPC;
|
||||
unsigned int j;
|
||||
uint8 brk_type;
|
||||
uint8 stackop=0;
|
||||
uint8 stackopstartaddr=0,stackopendaddr=0;
|
||||
@@ -783,7 +792,7 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||
{
|
||||
if (watchpoint[i].flags & BT_R)
|
||||
{
|
||||
if ( (watchpoint[i].flags & WP_X) && (watchpoint[i].address == romAddrPC) )
|
||||
if ( (watchpoint[i].flags & WP_X) && (watchpoint[i].address == static_cast<unsigned int>(romAddrPC)) )
|
||||
{
|
||||
BREAKHIT(i);
|
||||
}
|
||||
@@ -814,7 +823,7 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||
// TXS and TSX only deal with the pointer.
|
||||
if (watchpoint[i].flags & stackop)
|
||||
{
|
||||
for (j = (stackopstartaddr|0x0100); j <= (stackopendaddr|0x0100); j++)
|
||||
for (j = (stackopstartaddr|0x0100); j <= (static_cast<unsigned int>(stackopendaddr)|0x0100); j++)
|
||||
{
|
||||
if (watchpoint[i].endaddress)
|
||||
{
|
||||
@@ -840,7 +849,7 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||
// Pushes to stack
|
||||
if (watchpoint[i].flags & WP_W)
|
||||
{
|
||||
for (j = (X.S|0x0100); j < (StackAddrBackup|0x0100); j++)
|
||||
for (j = (X.S|0x0100); j < (static_cast<unsigned int>(StackAddrBackup)|0x0100); j++)
|
||||
{
|
||||
if (watchpoint[i].endaddress)
|
||||
{
|
||||
@@ -858,7 +867,7 @@ static void breakpoint(uint8 *opcode, uint16 A, int size) {
|
||||
// Pulls from stack
|
||||
if (watchpoint[i].flags & WP_R)
|
||||
{
|
||||
for (j = (StackAddrBackup|0x0100); j < (X.S|0x0100); j++)
|
||||
for (j = (StackAddrBackup|0x0100); j < (static_cast<unsigned int>(X.S)|0x0100); j++)
|
||||
{
|
||||
if (watchpoint[i].endaddress)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,911 @@
|
||||
/// \file
|
||||
/// \brief Implements debug symbol table (from .nl files)
|
||||
|
||||
#include "debugsymboltable.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
#include "fceu.h"
|
||||
#include "cart.h"
|
||||
|
||||
#ifdef __QT_DRIVER__
|
||||
#include "Qt/ConsoleUtilities.h"
|
||||
#else
|
||||
extern char LoadedRomFName[4096];
|
||||
static inline const char* getRomFile() { return LoadedRomFName; }
|
||||
#endif
|
||||
|
||||
extern FCEUGI *GameInfo;
|
||||
|
||||
debugSymbolTable_t debugSymbolTable;
|
||||
|
||||
static char dbgSymTblErrMsg[256] = {0};
|
||||
static bool dbgSymAllowDuplicateNames = true;
|
||||
//--------------------------------------------------------------
|
||||
// debugSymbol_t
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbol_t::updateName( const char *name, int arrayIndex )
|
||||
{
|
||||
std::string newName;
|
||||
|
||||
newName.assign( name );
|
||||
|
||||
while ( newName.size() > 0 )
|
||||
{
|
||||
if ( isspace( newName.back() ) )
|
||||
{
|
||||
newName.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arrayIndex >= 0)
|
||||
{
|
||||
char stmp[32];
|
||||
|
||||
sprintf( stmp, "[%i]", arrayIndex );
|
||||
|
||||
newName.append(stmp);
|
||||
}
|
||||
|
||||
if (page)
|
||||
{
|
||||
debugSymbol_t *dupSym = debugSymbolTable.getSymbol( page->pageNum(), newName );
|
||||
|
||||
if (!dbgSymAllowDuplicateNames && dupSym != nullptr && dupSym != this)
|
||||
{
|
||||
snprintf( dbgSymTblErrMsg, sizeof(dbgSymTblErrMsg), "Error: debug symbol '%s' already exists in %s page.\n", newName.c_str(), page->pageName() );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_name = newName;
|
||||
|
||||
debugSymbolTable.updateSymbol(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
void debugSymbol_t::trimTrailingSpaces(void)
|
||||
{
|
||||
while ( _name.size() > 0 )
|
||||
{
|
||||
if ( isspace( _name.back() ) )
|
||||
{
|
||||
_name.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ( _comment.size() > 0 )
|
||||
{
|
||||
if ( isspace( _comment.back() ) )
|
||||
{
|
||||
_comment.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
// debugSymbolPage_t
|
||||
//--------------------------------------------------------------
|
||||
debugSymbolPage_t::debugSymbolPage_t(int page)
|
||||
{
|
||||
_pageNum = page;
|
||||
|
||||
_pageName[0] = 0;
|
||||
|
||||
if (page == -2)
|
||||
{
|
||||
strcpy( _pageName, "REG");
|
||||
}
|
||||
else if (page == -1)
|
||||
{
|
||||
strcpy( _pageName, "RAM");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( _pageName, sizeof(_pageName), "%X", page);
|
||||
_pageName[sizeof(_pageName)-1] = 0;
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbolPage_t::~debugSymbolPage_t(void)
|
||||
{
|
||||
for (auto it=symMap.begin(); it!=symMap.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolPage_t::addSymbol( debugSymbol_t*sym )
|
||||
{
|
||||
// Check if symbol already is loaded by that name or offset
|
||||
if ( symMap.count( sym->offset() ) )
|
||||
{
|
||||
snprintf( dbgSymTblErrMsg, sizeof(dbgSymTblErrMsg), "Error: symbol offset 0x%04X already has an entry on %s page\n", sym->offset(), _pageName );
|
||||
return -1;
|
||||
}
|
||||
if ( !dbgSymAllowDuplicateNames && (sym->name().size() > 0) && symNameMap.count( sym->name() ) )
|
||||
{
|
||||
snprintf( dbgSymTblErrMsg, sizeof(dbgSymTblErrMsg), "Error: symbol name '%s' already exists on %s page\n", sym->name().c_str(), _pageName );
|
||||
return -1;
|
||||
}
|
||||
|
||||
symMap[ sym->offset() ] = sym;
|
||||
|
||||
sym->page = this;
|
||||
|
||||
// Comment only lines don't need to have a name.
|
||||
if (sym->name().size() > 0)
|
||||
{
|
||||
symNameMap[ sym->name() ] = sym;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *debugSymbolPage_t::getSymbolAtOffset( int ofs )
|
||||
{
|
||||
auto it = symMap.find( ofs );
|
||||
return it != symMap.end() ? it->second : nullptr;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *debugSymbolPage_t::getSymbol( const std::string &name )
|
||||
{
|
||||
auto it = symNameMap.find( name );
|
||||
return it != symNameMap.end() ? it->second : nullptr;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolPage_t::deleteSymbolAtOffset( int ofs )
|
||||
{
|
||||
auto it = symMap.find( ofs );
|
||||
|
||||
if ( it != symMap.end() )
|
||||
{
|
||||
auto sym = it->second;
|
||||
|
||||
if ( sym->name().size() > 0 )
|
||||
{
|
||||
auto itName = symNameMap.find( sym->name() );
|
||||
|
||||
if ( (itName != symNameMap.end()) && (itName->second == sym) )
|
||||
{
|
||||
symNameMap.erase(itName);
|
||||
}
|
||||
}
|
||||
symMap.erase(it);
|
||||
delete sym;
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolPage_t::updateSymbol(debugSymbol_t *sym)
|
||||
{
|
||||
auto itName = symNameMap.begin();
|
||||
|
||||
while (itName != symNameMap.end())
|
||||
{
|
||||
if (itName->second == sym)
|
||||
{
|
||||
if (sym->name().size() == 0 || sym->name().compare( itName->first ) )
|
||||
{
|
||||
//printf("Changing Name: %s %s\n", itName->first.c_str(), sym->name().c_str() );
|
||||
itName = symNameMap.erase(itName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
itName++;
|
||||
}
|
||||
}
|
||||
if (sym->name().size() > 0)
|
||||
{
|
||||
symNameMap[ sym->name() ] = sym;
|
||||
}
|
||||
|
||||
// Sanity Check
|
||||
auto it = symMap.find( sym->offset() );
|
||||
|
||||
if ( it == symMap.end() )
|
||||
{ // This shouldn't happen
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolPage_t::save(void)
|
||||
{
|
||||
FILE *fp;
|
||||
debugSymbol_t *sym;
|
||||
std::map <int, debugSymbol_t*>::iterator it;
|
||||
const char *romFile;
|
||||
std::string filename;
|
||||
char stmp[512];
|
||||
int i,j;
|
||||
|
||||
if ( symMap.size() == 0 )
|
||||
{
|
||||
//printf("Skipping Empty Debug Page Save\n");
|
||||
return 0;
|
||||
}
|
||||
if ( _pageNum == -2 )
|
||||
{
|
||||
//printf("Skipping Register Debug Page Save\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
romFile = getRomFile();
|
||||
|
||||
if ( romFile == nullptr )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
i=0;
|
||||
while ( romFile[i] != 0 )
|
||||
{
|
||||
|
||||
if ( romFile[i] == '|' )
|
||||
{
|
||||
filename.push_back('.');
|
||||
}
|
||||
else
|
||||
{
|
||||
filename.push_back(romFile[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if ( _pageNum < 0 )
|
||||
{
|
||||
filename.append(".ram.nl" );
|
||||
}
|
||||
else
|
||||
{
|
||||
char suffix[32];
|
||||
|
||||
sprintf( suffix, ".%X.nl", _pageNum );
|
||||
|
||||
filename.append( suffix );
|
||||
}
|
||||
|
||||
fp = ::fopen( filename.c_str(), "w" );
|
||||
|
||||
if ( fp == nullptr )
|
||||
{
|
||||
FCEU_printf("Error: Could not open file '%s' for writing\n", filename.c_str() );
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (it=symMap.begin(); it!=symMap.end(); it++)
|
||||
{
|
||||
const char *c;
|
||||
|
||||
sym = it->second;
|
||||
|
||||
i=0; j=0; c = sym->_comment.c_str();
|
||||
|
||||
while ( c[i] != 0 )
|
||||
{
|
||||
if ( c[i] == '\n' )
|
||||
{
|
||||
i++; break;
|
||||
}
|
||||
else
|
||||
{
|
||||
stmp[j] = c[i]; j++; i++;
|
||||
}
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
fprintf( fp, "$%04X#%s#%s\n", sym->offset(), sym->name().c_str(), stmp );
|
||||
|
||||
j=0;
|
||||
while ( c[i] != 0 )
|
||||
{
|
||||
if ( c[i] == '\n' )
|
||||
{
|
||||
i++; stmp[j] = 0;
|
||||
|
||||
if ( j > 0 )
|
||||
{
|
||||
fprintf( fp, "\\%s\n", stmp );
|
||||
}
|
||||
j=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stmp[j] = c[i]; j++; i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
void debugSymbolPage_t::print(void)
|
||||
{
|
||||
FILE *fp;
|
||||
debugSymbol_t *sym;
|
||||
std::map <int, debugSymbol_t*>::iterator it;
|
||||
|
||||
fp = stdout;
|
||||
|
||||
fprintf( fp, "Page: %X \n", _pageNum );
|
||||
|
||||
for (it=symMap.begin(); it!=symMap.end(); it++)
|
||||
{
|
||||
sym = it->second;
|
||||
|
||||
fprintf( fp, " Sym: $%04X '%s' \n", sym->ofs, sym->name().c_str() );
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
// debugSymbolTable_t
|
||||
//--------------------------------------------------------------
|
||||
debugSymbolTable_t::debugSymbolTable_t(void)
|
||||
{
|
||||
cs = new FCEU::mutex();
|
||||
|
||||
dbgSymTblErrMsg[0] = 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbolTable_t::~debugSymbolTable_t(void)
|
||||
{
|
||||
this->clear();
|
||||
|
||||
if (cs)
|
||||
{
|
||||
delete cs;
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
void debugSymbolTable_t::clear(void)
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||
|
||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
pageMap.clear();
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
static int generateNLFilenameForBank(int bank, std::string &NLfilename)
|
||||
{
|
||||
int i;
|
||||
const char *romFile;
|
||||
|
||||
romFile = getRomFile();
|
||||
|
||||
if ( romFile == nullptr )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
i=0;
|
||||
while ( romFile[i] != 0 )
|
||||
{
|
||||
|
||||
if ( romFile[i] == '|' )
|
||||
{
|
||||
NLfilename.push_back('.');
|
||||
}
|
||||
else
|
||||
{
|
||||
NLfilename.push_back(romFile[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (bank < 0)
|
||||
{
|
||||
// The NL file for the RAM addresses has the name nesrom.nes.ram.nl
|
||||
NLfilename.append(".ram.nl");
|
||||
}
|
||||
else
|
||||
{
|
||||
char stmp[64];
|
||||
#ifdef DW3_NL_0F_1F_HACK
|
||||
if(bank == 0x0F)
|
||||
bank = 0x1F;
|
||||
#endif
|
||||
sprintf( stmp, ".%X.nl", bank);
|
||||
NLfilename.append( stmp );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int generateNLFilenameForAddress(int address, std::string &NLfilename)
|
||||
{
|
||||
int bank;
|
||||
|
||||
if (address < 0x8000)
|
||||
{
|
||||
bank = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bank = getBank(address);
|
||||
#ifdef DW3_NL_0F_1F_HACK
|
||||
if(bank == 0x0F)
|
||||
bank = 0x1F;
|
||||
#endif
|
||||
}
|
||||
return generateNLFilenameForBank( bank, NLfilename );
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::loadFileNL( int bank )
|
||||
{
|
||||
FILE *fp;
|
||||
int i, j, ofs, lineNum = 0, literal = 0, array = 0;
|
||||
std::string fileName;
|
||||
char stmp[512], line[512];
|
||||
debugSymbolPage_t *page = nullptr;
|
||||
debugSymbol_t *sym = nullptr;
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
//printf("Looking to Load Debug Bank: $%X \n", bank );
|
||||
|
||||
if ( generateNLFilenameForBank( bank, fileName ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
//printf("Loading NL File: %s\n", fileName.c_str() );
|
||||
|
||||
fp = ::fopen( fileName.c_str(), "r" );
|
||||
|
||||
if ( fp == nullptr )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
page = new debugSymbolPage_t(bank);
|
||||
|
||||
pageMap[ page->pageNum() ] = page;
|
||||
|
||||
while ( fgets( line, sizeof(line), fp ) != 0 )
|
||||
{
|
||||
i=0; lineNum++;
|
||||
//printf("%4i:%s", lineNum, line );
|
||||
|
||||
if ( line[i] == '\\' )
|
||||
{
|
||||
// Line is a comment continuation line.
|
||||
i++;
|
||||
|
||||
j=0;
|
||||
stmp[j] = '\n'; j++;
|
||||
|
||||
while ( line[i] != 0 )
|
||||
{
|
||||
stmp[j] = line[i]; j++; i++;
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
j--;
|
||||
while ( j >= 0 )
|
||||
{
|
||||
if ( isspace( stmp[j] ) )
|
||||
{
|
||||
stmp[j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
j--;
|
||||
}
|
||||
if ( sym != nullptr )
|
||||
{
|
||||
sym->_comment.append( stmp );
|
||||
}
|
||||
}
|
||||
else if ( line[i] == '$' )
|
||||
{
|
||||
// Line is a new debug offset
|
||||
array = 0;
|
||||
|
||||
j=0; i++;
|
||||
if ( !isxdigit( line[i] ) )
|
||||
{
|
||||
FCEU_printf("Error: Invalid Offset on Line %i of File %s\n", lineNum, fileName.c_str() );
|
||||
}
|
||||
while ( isxdigit( line[i] ) )
|
||||
{
|
||||
stmp[j] = line[i]; i++; j++;
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
ofs = strtol( stmp, nullptr, 16 );
|
||||
|
||||
if ( line[i] == '/' )
|
||||
{
|
||||
j=0; i++;
|
||||
while ( isxdigit( line[i] ) )
|
||||
{
|
||||
stmp[j] = line[i]; i++; j++;
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
array = strtol( stmp, nullptr, 16 );
|
||||
}
|
||||
|
||||
if ( line[i] != '#' )
|
||||
{
|
||||
FCEU_printf("Error: Missing field delimiter following offset $%X on Line %i of File %s\n", ofs, lineNum, fileName.c_str() );
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
|
||||
while ( isspace(line[i]) ) i++;
|
||||
|
||||
j = 0;
|
||||
while ( line[i] != 0 )
|
||||
{
|
||||
if ( line[i] == '\\' )
|
||||
{
|
||||
if ( literal )
|
||||
{
|
||||
switch ( line[i] )
|
||||
{
|
||||
case 'r':
|
||||
stmp[j] = '\r';
|
||||
break;
|
||||
case 'n':
|
||||
stmp[j] = '\n';
|
||||
break;
|
||||
case 't':
|
||||
stmp[j] = '\t';
|
||||
break;
|
||||
default:
|
||||
stmp[j] = line[i];
|
||||
break;
|
||||
}
|
||||
j++; i++;
|
||||
literal = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
literal = !literal;
|
||||
}
|
||||
}
|
||||
else if ( line[i] == '#' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
stmp[j] = line[i]; j++; i++;
|
||||
}
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
j--;
|
||||
while ( j >= 0 )
|
||||
{
|
||||
if ( isspace( stmp[j] ) )
|
||||
{
|
||||
stmp[j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
j--;
|
||||
}
|
||||
|
||||
if ( line[i] != '#' )
|
||||
{
|
||||
FCEU_printf("Error: Missing field delimiter following name '%s' on Line %i of File %s\n", stmp, lineNum, fileName.c_str() );
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
|
||||
sym = new debugSymbol_t( ofs, stmp );
|
||||
|
||||
if ( sym == nullptr )
|
||||
{
|
||||
FCEU_printf("Error: Failed to allocate memory for offset $%04X Name '%s' on Line %i of File %s\n", ofs, stmp, lineNum, fileName.c_str() );
|
||||
continue;
|
||||
}
|
||||
sym->ofs = ofs;
|
||||
sym->_name.assign( stmp );
|
||||
|
||||
while ( isspace( line[i] ) ) i++;
|
||||
|
||||
j=0;
|
||||
while ( line[i] != 0 )
|
||||
{
|
||||
stmp[j] = line[i]; j++; i++;
|
||||
}
|
||||
stmp[j] = 0;
|
||||
|
||||
j--;
|
||||
while ( j >= 0 )
|
||||
{
|
||||
if ( isspace( stmp[j] ) )
|
||||
{
|
||||
stmp[j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
j--;
|
||||
}
|
||||
|
||||
sym->_comment.assign( stmp );
|
||||
|
||||
if ( array > 0 )
|
||||
{
|
||||
debugSymbol_t *arraySym = nullptr;
|
||||
|
||||
for (j=0; j<array; j++)
|
||||
{
|
||||
arraySym = new debugSymbol_t();
|
||||
|
||||
if ( arraySym )
|
||||
{
|
||||
arraySym->ofs = sym->ofs + j;
|
||||
|
||||
sprintf( stmp, "[%i]", j );
|
||||
arraySym->_name.assign( sym->name() );
|
||||
arraySym->_name.append( stmp );
|
||||
arraySym->_comment.assign( sym->comment() );
|
||||
|
||||
if ( page->addSymbol( arraySym ) )
|
||||
{
|
||||
FCEU_printf("Error: Failed to add symbol for offset $%04X Name '%s' on Line %i of File %s\n", ofs, arraySym->name().c_str(), lineNum, fileName.c_str() );
|
||||
FCEU_printf("%s\n", errorMessage() );
|
||||
delete arraySym; arraySym = nullptr; // Failed to add symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
delete sym; sym = nullptr; // Delete temporary symbol
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( page->addSymbol( sym ) )
|
||||
{
|
||||
FCEU_printf("Error: Failed to add symbol for offset $%04X Name '%s' on Line %i of File %s\n", ofs, sym->name().c_str(), lineNum, fileName.c_str() );
|
||||
FCEU_printf("%s\n", errorMessage() );
|
||||
delete sym; sym = nullptr; // Failed to add symbol
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::loadRegisterMap(void)
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
debugSymbolPage_t *page;
|
||||
|
||||
page = new debugSymbolPage_t(-2);
|
||||
|
||||
page->addSymbol( new debugSymbol_t( 0x2000, "PPU_CTRL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2001, "PPU_MASK" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2002, "PPU_STATUS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2003, "PPU_OAM_ADDR" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2004, "PPU_OAM_DATA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2005, "PPU_SCROLL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2006, "PPU_ADDRESS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x2007, "PPU_DATA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4000, "SQ1_VOL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4001, "SQ1_SWEEP" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4002, "SQ1_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4003, "SQ1_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4004, "SQ2_VOL" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4005, "SQ2_SWEEP" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4006, "SQ2_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4007, "SQ2_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4008, "TRI_LINEAR" ) );
|
||||
// page->addSymbol( new debugSymbol_t( 0x4009, "UNUSED" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400A, "TRI_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400B, "TRI_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400C, "NOISE_VOL" ) );
|
||||
// page->addSymbol( new debugSymbol_t( 0x400D, "UNUSED" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400E, "NOISE_LO" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x400F, "NOISE_HI" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4010, "DMC_FREQ" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4011, "DMC_RAW" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4012, "DMC_START" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4013, "DMC_LEN" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4014, "OAM_DMA" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4015, "APU_STATUS" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4016, "JOY1" ) );
|
||||
page->addSymbol( new debugSymbol_t( 0x4017, "JOY2_FRAME" ) );
|
||||
|
||||
pageMap[ page->pageNum() ] = page;
|
||||
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::loadGameSymbols(void)
|
||||
{
|
||||
int nPages, pageSize, romSize = 0x10000;
|
||||
|
||||
this->save();
|
||||
this->clear();
|
||||
|
||||
if ( GameInfo != nullptr )
|
||||
{
|
||||
romSize = 16 + CHRsize[0] + PRGsize[0];
|
||||
}
|
||||
|
||||
loadFileNL( -1 );
|
||||
|
||||
loadRegisterMap();
|
||||
|
||||
pageSize = (1<<debuggerPageSize);
|
||||
|
||||
//nPages = 1<<(15-debuggerPageSize);
|
||||
nPages = romSize / pageSize;
|
||||
|
||||
//printf("RomSize: %i NumPages: %i \n", romSize, nPages );
|
||||
|
||||
for(int i=0;i<nPages;i++)
|
||||
{
|
||||
//printf("Loading Page Offset: $%06X\n", pageSize*i );
|
||||
|
||||
loadFileNL( i );
|
||||
}
|
||||
|
||||
//print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int debugSymbolTable_t::addSymbolAtBankOffset(int bank, int ofs, const char *name, const char *comment)
|
||||
{
|
||||
int result = -1;
|
||||
debugSymbol_t *sym = new debugSymbol_t(ofs, name, comment);
|
||||
|
||||
result = addSymbolAtBankOffset(bank, ofs, sym);
|
||||
|
||||
if (result)
|
||||
{ // Symbol add failed
|
||||
delete sym;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::addSymbolAtBankOffset( int bank, int ofs, debugSymbol_t *sym )
|
||||
{
|
||||
int result = -1;
|
||||
debugSymbolPage_t *page;
|
||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
it = pageMap.find( bank );
|
||||
|
||||
if ( it == pageMap.end() )
|
||||
{
|
||||
page = new debugSymbolPage_t(bank);
|
||||
pageMap[ bank ] = page;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = it->second;
|
||||
}
|
||||
result = page->addSymbol( sym );
|
||||
|
||||
return result;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::deleteSymbolAtBankOffset( int bank, int ofs )
|
||||
{
|
||||
debugSymbolPage_t *page;
|
||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
it = pageMap.find( bank );
|
||||
|
||||
if ( it == pageMap.end() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
page = it->second;
|
||||
}
|
||||
|
||||
return page->deleteSymbolAtOffset( ofs );
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
int debugSymbolTable_t::updateSymbol(debugSymbol_t *sym)
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
if (sym->page == nullptr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return sym->page->updateSymbol(sym);
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *debugSymbolTable_t::getSymbolAtBankOffset( int bank, int ofs )
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
auto it = pageMap.find( bank );
|
||||
|
||||
return it != pageMap.end() ? it->second->getSymbolAtOffset( ofs ) : nullptr;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *debugSymbolTable_t::getSymbol( int bank, const std::string &name )
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
auto it = pageMap.find( bank );
|
||||
|
||||
return it != pageMap.end() ? it->second->getSymbol( name ) : nullptr;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
debugSymbol_t *debugSymbolTable_t::getSymbolAtAnyBank( const std::string &name )
|
||||
{
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
for (auto &page : pageMap)
|
||||
{
|
||||
auto sym = getSymbol( page.first, name );
|
||||
|
||||
if ( sym )
|
||||
{
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
void debugSymbolTable_t::save(void)
|
||||
{
|
||||
debugSymbolPage_t *page;
|
||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||
{
|
||||
page = it->second;
|
||||
|
||||
page->save();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
void debugSymbolTable_t::print(void)
|
||||
{
|
||||
debugSymbolPage_t *page;
|
||||
std::map <int, debugSymbolPage_t*>::iterator it;
|
||||
FCEU::autoScopedLock alock(cs);
|
||||
|
||||
for (it=pageMap.begin(); it!=pageMap.end(); it++)
|
||||
{
|
||||
page = it->second;
|
||||
|
||||
page->print();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
const char *debugSymbolTable_t::errorMessage(void)
|
||||
{
|
||||
return dbgSymTblErrMsg;
|
||||
}
|
||||
//--------------------------------------------------------------
|
||||
@@ -0,0 +1,166 @@
|
||||
#ifndef _DEBUGSYMBOLTABLE_H_
|
||||
#define _DEBUGSYMBOLTABLE_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "utils/mutex.h"
|
||||
|
||||
class debugSymbolPage_t;
|
||||
class debugSymbolTable_t;
|
||||
|
||||
class debugSymbol_t
|
||||
{
|
||||
public:
|
||||
debugSymbol_t(void)
|
||||
{
|
||||
ofs = 0;
|
||||
page = nullptr;
|
||||
};
|
||||
|
||||
debugSymbol_t( int ofs, const char *name = nullptr, const char *comment = nullptr )
|
||||
{
|
||||
this->ofs = ofs;
|
||||
|
||||
if (name)
|
||||
{
|
||||
this->_name.assign(name);
|
||||
}
|
||||
if ( comment )
|
||||
{
|
||||
this->_comment.assign( comment );
|
||||
}
|
||||
page = nullptr;
|
||||
}
|
||||
|
||||
const std::string &name(void)
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
const std::string &comment(void)
|
||||
{
|
||||
return _comment;
|
||||
}
|
||||
|
||||
void commentAssign( std::string str )
|
||||
{
|
||||
_comment.assign(str);
|
||||
return;
|
||||
}
|
||||
|
||||
void commentAssign( const char *str )
|
||||
{
|
||||
_comment.assign(str);
|
||||
return;
|
||||
}
|
||||
|
||||
int offset(void)
|
||||
{
|
||||
return ofs;
|
||||
}
|
||||
|
||||
void setOffset( int o )
|
||||
{
|
||||
if (o != ofs)
|
||||
{
|
||||
ofs = o;
|
||||
}
|
||||
}
|
||||
|
||||
int updateName( const char *name, int arrayIndex = -1 );
|
||||
|
||||
void trimTrailingSpaces(void);
|
||||
|
||||
private:
|
||||
|
||||
int ofs;
|
||||
std::string _name;
|
||||
std::string _comment;
|
||||
debugSymbolPage_t *page;
|
||||
|
||||
friend class debugSymbolPage_t;
|
||||
friend class debugSymbolTable_t;
|
||||
};
|
||||
|
||||
class debugSymbolPage_t
|
||||
{
|
||||
public:
|
||||
debugSymbolPage_t(int page);
|
||||
~debugSymbolPage_t(void);
|
||||
|
||||
int save(void);
|
||||
void print(void);
|
||||
int size(void){ return symMap.size(); }
|
||||
|
||||
int addSymbol( debugSymbol_t *sym );
|
||||
|
||||
int deleteSymbolAtOffset( int ofs );
|
||||
|
||||
int updateSymbol( debugSymbol_t *sym );
|
||||
|
||||
debugSymbol_t *getSymbolAtOffset( int ofs );
|
||||
|
||||
debugSymbol_t *getSymbol( const std::string &name );
|
||||
|
||||
int pageNum(void)
|
||||
{
|
||||
return _pageNum;
|
||||
}
|
||||
|
||||
const char *pageName(void)
|
||||
{
|
||||
return _pageName;
|
||||
}
|
||||
|
||||
private:
|
||||
int _pageNum;
|
||||
char _pageName[8];
|
||||
std::map <int, debugSymbol_t*> symMap;
|
||||
std::map <std::string, debugSymbol_t*> symNameMap;
|
||||
|
||||
friend class debugSymbolTable_t;
|
||||
};
|
||||
|
||||
class debugSymbolTable_t
|
||||
{
|
||||
|
||||
public:
|
||||
debugSymbolTable_t(void);
|
||||
~debugSymbolTable_t(void);
|
||||
|
||||
int loadFileNL( int addr );
|
||||
int loadGameSymbols(void);
|
||||
int numPages(void){ return pageMap.size(); }
|
||||
|
||||
void save(void);
|
||||
void clear(void);
|
||||
void print(void);
|
||||
|
||||
debugSymbol_t *getSymbolAtBankOffset( int bank, int ofs );
|
||||
|
||||
debugSymbol_t *getSymbol( int bank, const std::string& name);
|
||||
|
||||
debugSymbol_t *getSymbolAtAnyBank( const std::string& name);
|
||||
|
||||
int addSymbolAtBankOffset( int bank, int ofs, debugSymbol_t *sym );
|
||||
|
||||
int addSymbolAtBankOffset(int bank, int ofs, const char* name, const char* comment = nullptr);
|
||||
|
||||
int deleteSymbolAtBankOffset( int bank, int ofs );
|
||||
|
||||
int updateSymbol( debugSymbol_t *sym );
|
||||
|
||||
const char *errorMessage(void);
|
||||
|
||||
private:
|
||||
std::map <int, debugSymbolPage_t*> pageMap;
|
||||
FCEU::mutex *cs;
|
||||
|
||||
int loadRegisterMap(void);
|
||||
|
||||
};
|
||||
|
||||
extern debugSymbolTable_t debugSymbolTable;
|
||||
|
||||
#endif
|
||||
+10
-5
@@ -23,7 +23,7 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname);
|
||||
const char *FCEUD_GetCompilerString();
|
||||
|
||||
//This makes me feel dirty for some reason.
|
||||
void FCEU_printf(const char *format, ...);
|
||||
void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
|
||||
#define FCEUI_printf FCEU_printf
|
||||
|
||||
//Video interface
|
||||
@@ -192,7 +192,7 @@ void TaseditorManualFunction(void);
|
||||
int32 FCEUI_GetDesiredFPS(void);
|
||||
void FCEUI_SaveSnapshot(void);
|
||||
void FCEUI_SaveSnapshotAs(void);
|
||||
void FCEU_DispMessage(const char *format, int disppos, ...);
|
||||
void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 3 );
|
||||
#define FCEUI_DispMessage FCEU_DispMessage
|
||||
|
||||
int FCEUI_DecodePAR(const char *code, int *a, int *v, int *c, int *type);
|
||||
@@ -207,10 +207,10 @@ void FCEUI_CheatSearchGetRange(uint32 first, uint32 last, int (*callb)(uint32 a,
|
||||
void FCEUI_CheatSearchGet(int (*callb)(uint32 a, uint8 last, uint8 current, void *data), void *data);
|
||||
void FCEUI_CheatSearchBegin(void);
|
||||
void FCEUI_CheatSearchEnd(int type, uint8 v1, uint8 v2);
|
||||
void FCEUI_ListCheats(int (*callb)(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data);
|
||||
void FCEUI_ListCheats(int (*callb)(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data), void *data);
|
||||
|
||||
int FCEUI_GetCheat(uint32 which, char **name, uint32 *a, uint8 *v, int *compare, int *s, int *type);
|
||||
int FCEUI_SetCheat(uint32 which, const char *name, int32 a, int32 v, int compare,int s, int type);
|
||||
int FCEUI_GetCheat(uint32 which, std::string *name, uint32 *a, uint8 *v, int *compare, int *s, int *type);
|
||||
int FCEUI_SetCheat(uint32 which, const std::string *name, int32 a, int32 v, int compare,int s, int type);
|
||||
|
||||
void FCEUI_CheatSearchShowExcluded(void);
|
||||
void FCEUI_CheatSearchSetCurrentAsOriginal(void);
|
||||
@@ -254,6 +254,8 @@ void FCEUI_VSUniToggleDIP(int w);
|
||||
uint8 FCEUI_VSUniGetDIPs(void);
|
||||
void FCEUI_VSUniSetDIP(int w, int state);
|
||||
void FCEUI_VSUniCoin(void);
|
||||
void FCEUI_VSUniCoin2(void);
|
||||
void FCEUI_VSUniService(void);
|
||||
|
||||
void FCEUI_FDSInsert(void); //mbg merge 7/17/06 changed to void fn(void) to make it an EMUCMDFN
|
||||
//int FCEUI_FDSEject(void);
|
||||
@@ -330,6 +332,9 @@ void FCEUD_DebugBreakpoint(int bp_num);
|
||||
///the driver should log the current instruction, if it wants (we should move the code in the win driver that does this to the shared area)
|
||||
void FCEUD_TraceInstruction(uint8 *opcode, int size);
|
||||
|
||||
///the driver should flush its trace log
|
||||
void FCEUD_FlushTrace();
|
||||
|
||||
///the driver might should update its NTView (only used if debugging support is compiled in)
|
||||
void FCEUD_UpdateNTView(int scanline, bool drawall);
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@
|
||||
static void GetString(char *s, int max)
|
||||
{
|
||||
int x;
|
||||
fgets(s,max,stdin);
|
||||
if ( fgets(s,max,stdin) == nullptr )
|
||||
{
|
||||
s[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for(x=0;x<max;x++)
|
||||
if(s[x]=='\n')
|
||||
@@ -41,7 +45,10 @@ static uint32 GetH16(unsigned int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
if(buf[0]=='$')
|
||||
@@ -56,7 +63,10 @@ static uint8 Get8(unsigned int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
sscanf(buf,"%u",&def);
|
||||
@@ -67,7 +77,10 @@ static int GetI(int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
sscanf(buf,"%d",&def);
|
||||
@@ -78,7 +91,10 @@ static int GetYN(int def)
|
||||
{
|
||||
char buf[32];
|
||||
printf("(Y/N)[%s]: ",def?"Y":"N");
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if(buf[0]=='y' || buf[0]=='Y')
|
||||
return(1);
|
||||
if(buf[0]=='n' || buf[0]=='N')
|
||||
@@ -114,7 +130,10 @@ int ListChoice(int hmm)
|
||||
|
||||
tryagain:
|
||||
printf(" <'Enter' to continue, (S)top, or enter a number.> ");
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(buf[0]=='s' || buf[0]=='S') return(-1);
|
||||
if(buf[0]=='\n') return(0);
|
||||
if(!sscanf(buf,"%d",&num))
|
||||
@@ -128,7 +147,10 @@ int ListChoice(int hmm)
|
||||
|
||||
tryagain2:
|
||||
printf(" <'Enter' to make no selection or enter a number.> ");
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if(buf[0]=='\n') return(0);
|
||||
if(!sscanf(buf,"%d",&num))
|
||||
return(0);
|
||||
@@ -199,7 +221,8 @@ static void ToggleCheat(int num)
|
||||
|
||||
static void ModifyCheat(int num)
|
||||
{
|
||||
char *name;
|
||||
std::string name;
|
||||
std::string *pName;
|
||||
char buf[256];
|
||||
uint32 A;
|
||||
uint8 V;
|
||||
@@ -211,7 +234,7 @@ static void ModifyCheat(int num)
|
||||
|
||||
FCEUI_GetCheat(num, &name, &A, &V, &compare, &s, &type);
|
||||
|
||||
printf("Name [%s]: ",name);
|
||||
printf("Name [%s]: ",name.c_str());
|
||||
GetString(buf,256);
|
||||
|
||||
/* This obviously doesn't allow for cheats with no names. Bah. Who wants
|
||||
@@ -219,9 +242,9 @@ static void ModifyCheat(int num)
|
||||
*/
|
||||
|
||||
if(buf[0])
|
||||
name=buf; // Change name when FCEUI_SetCheat() is called.
|
||||
pName=&name; // Change name when FCEUI_SetCheat() is called.
|
||||
else
|
||||
name=0; // Don't change name when FCEUI_SetCheat() is called.
|
||||
pName=nullptr; // Don't change name when FCEUI_SetCheat() is called.
|
||||
|
||||
printf("Address [$%04x]: ",(unsigned int)A);
|
||||
A=GetH16(A);
|
||||
@@ -240,7 +263,7 @@ static void ModifyCheat(int num)
|
||||
if(t=='Y' || t=='y') s=1;
|
||||
else if(t=='N' || t=='n') s=0;
|
||||
|
||||
FCEUI_SetCheat(num,name,A,V,compare,s,type);
|
||||
FCEUI_SetCheat(num,pName,A,V,compare,s,type);
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +343,7 @@ static void AddCheat(void)
|
||||
}
|
||||
|
||||
static int lid;
|
||||
static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data)
|
||||
static int clistcallb(const char *name, uint32 a, uint8 v, int compare, int s, int type, void *data)
|
||||
{
|
||||
char tmp[512];
|
||||
int ret;
|
||||
@@ -348,7 +371,10 @@ static void ListCheats(void)
|
||||
{
|
||||
char tmp[32];
|
||||
printf(" <(T)oggle status, (M)odify, or (D)elete this cheat.> ");
|
||||
fgets(tmp,ARRAY_SIZE(tmp),stdin);
|
||||
if ( fgets(tmp,ARRAY_SIZE(tmp),stdin) == nullptr )
|
||||
{
|
||||
tmp[0] = 0;
|
||||
}
|
||||
switch(tolower(tmp[0]))
|
||||
{
|
||||
case 't':ToggleCheat(which);
|
||||
@@ -405,7 +431,10 @@ static int ShowShortList(const char *moe[], int n, int def)
|
||||
clo:
|
||||
|
||||
printf("\nSelection [%d]> ",def+1);
|
||||
fgets(tmp,ARRAY_SIZE(tmp),stdin);
|
||||
if ( fgets(tmp,ARRAY_SIZE(tmp),stdin) == nullptr )
|
||||
{
|
||||
return def;
|
||||
}
|
||||
if(tmp[0]=='\n')
|
||||
return def;
|
||||
c=tolower(tmp[0]);
|
||||
@@ -504,7 +533,10 @@ static void DoMenu(MENU *men)
|
||||
|
||||
recommand:
|
||||
printf("Command> ");
|
||||
fgets(buf,ARRAY_SIZE(buf),stdin);
|
||||
if ( fgets(buf,ARRAY_SIZE(buf),stdin) == nullptr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
c=tolower(buf[0]);
|
||||
if(c=='\n')
|
||||
goto recommand;
|
||||
|
||||
@@ -145,6 +145,11 @@ static void GetValueR(FILE *fp, char *str, void *v, int c)
|
||||
{
|
||||
if(!c) // String, allocate some memory.
|
||||
{
|
||||
// Windows enforces a 32767 character limit for text boxes by default
|
||||
// If a string exceeds this length, it's probably a corrupt file
|
||||
if (s > 32768)
|
||||
goto gogl;
|
||||
|
||||
if(!(*(char **)v=(char*)malloc(s)))
|
||||
goto gogl;
|
||||
|
||||
@@ -208,7 +213,7 @@ void SaveParse(const CFGSTRUCT *cfgst, FILE *fp)
|
||||
if(*(char **)cfgst[x].ptr)
|
||||
{
|
||||
// Only save it if there IS a string.
|
||||
unsigned int len = strlen(*(char **)cfgst[x].ptr);
|
||||
size_t len = strlen(*(char **)cfgst[x].ptr);
|
||||
SetValueR(fp,cfgst[x].name,*(char **)cfgst[x].ptr, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ Config::_load()
|
||||
int
|
||||
Config::_loadFile(const char* fname)
|
||||
{
|
||||
signed int pos, eqPos;
|
||||
size_t pos=0, eqPos=0;
|
||||
std::fstream config;
|
||||
std::map<std::string, int>::iterator int_i;
|
||||
std::map<std::string, double>::iterator dbl_i;
|
||||
@@ -656,7 +656,7 @@ Config::_loadFile(const char* fname)
|
||||
configFile = fname;
|
||||
}
|
||||
std::string line, name, value;
|
||||
char buf[1024];
|
||||
char buf[4096];
|
||||
|
||||
// set the exception handling to catch i/o errors
|
||||
config.exceptions(std::fstream::badbit);
|
||||
@@ -671,7 +671,7 @@ Config::_loadFile(const char* fname)
|
||||
|
||||
while(!config.eof()) {
|
||||
// read a line
|
||||
config.getline(buf, 1024);
|
||||
config.getline(buf, sizeof(buf));
|
||||
line = buf;
|
||||
|
||||
// check line validity
|
||||
@@ -723,7 +723,7 @@ Config::save()
|
||||
std::map<std::string, double>::iterator dbl_i;
|
||||
std::map<std::string, std::string>::iterator str_i;
|
||||
std::string configFile = _dir + "/" + cfgFile;
|
||||
char buf[1024];
|
||||
char buf[4096];
|
||||
|
||||
// set the exception handling to catch i/o errors
|
||||
config.exceptions(std::ios::failbit | std::ios::badbit);
|
||||
@@ -741,19 +741,19 @@ Config::save()
|
||||
// write each configuration setting
|
||||
for(int_i = _intOptMap.begin(); int_i != _intOptMap.end(); int_i++)
|
||||
{
|
||||
snprintf(buf, 1024, "%s = %d\n",
|
||||
snprintf(buf, sizeof(buf), "%s = %d\n",
|
||||
int_i->first.c_str(), int_i->second);
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
for(dbl_i = _dblOptMap.begin(); dbl_i != _dblOptMap.end(); dbl_i++)
|
||||
{
|
||||
snprintf(buf, 1024, "%s = %f\n",
|
||||
snprintf(buf, sizeof(buf), "%s = %f\n",
|
||||
dbl_i->first.c_str(), dbl_i->second);
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
for(str_i = _strOptMap.begin(); str_i != _strOptMap.end(); str_i++)
|
||||
{
|
||||
snprintf(buf, 1024, "%s = %s\n",
|
||||
snprintf(buf, sizeof(buf), "%s = %s\n",
|
||||
str_i->first.c_str(), str_i->second.c_str());
|
||||
config.write(buf, strlen(buf));
|
||||
}
|
||||
|
||||
@@ -238,18 +238,18 @@ void KillBlitToHigh(void)
|
||||
{
|
||||
if(palettetranslate)
|
||||
{
|
||||
free(palettetranslate);
|
||||
FCEU_free(palettetranslate);
|
||||
palettetranslate=NULL;
|
||||
}
|
||||
|
||||
if(specbuf8bpp)
|
||||
{
|
||||
free(specbuf8bpp);
|
||||
FCEU_free(specbuf8bpp);
|
||||
specbuf8bpp = NULL;
|
||||
}
|
||||
if(specbuf32bpp)
|
||||
{
|
||||
free(specbuf32bpp);
|
||||
FCEU_free(specbuf32bpp);
|
||||
specbuf32bpp = NULL;
|
||||
}
|
||||
if(specbuf)
|
||||
@@ -259,11 +259,11 @@ void KillBlitToHigh(void)
|
||||
hq3x_Kill();
|
||||
else
|
||||
hq2x_Kill();
|
||||
free(specbuf);
|
||||
FCEU_free(specbuf);
|
||||
specbuf=NULL;
|
||||
}
|
||||
if (nes_ntsc) {
|
||||
free(nes_ntsc);
|
||||
FCEU_free(nes_ntsc);
|
||||
nes_ntsc = NULL;
|
||||
}
|
||||
if (ntscblit) {
|
||||
@@ -466,7 +466,7 @@ void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, in
|
||||
/* Todo: Make sure 24bpp code works right with big-endian cpus */
|
||||
|
||||
//takes a pointer to XBuf and applies fully modern deemph palettizing
|
||||
template<int SCALE> static u32 _ModernDeemphColorMap(u8* src, u8* srcbuf)
|
||||
template<int SCALE> static u32 _ModernDeemphColorMap(const u8* src, const u8* srcbuf)
|
||||
{
|
||||
u8 pixel = *src;
|
||||
|
||||
@@ -492,7 +492,7 @@ template<int SCALE> static u32 _ModernDeemphColorMap(u8* src, u8* srcbuf)
|
||||
return color;
|
||||
}
|
||||
|
||||
u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale)
|
||||
u32 ModernDeemphColorMap(const u8* src, const u8* srcbuf, int scale)
|
||||
{
|
||||
if(scale == 1) return _ModernDeemphColorMap<1>(src,srcbuf);
|
||||
else if(scale == 2) return _ModernDeemphColorMap<2>(src,srcbuf);
|
||||
@@ -503,14 +503,14 @@ u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale)
|
||||
else if(scale == 7) return _ModernDeemphColorMap<7>(src,srcbuf);
|
||||
else if(scale == 8) return _ModernDeemphColorMap<8>(src,srcbuf);
|
||||
else if(scale == 9) return _ModernDeemphColorMap<9>(src,srcbuf);
|
||||
else { abort(); return 0; }
|
||||
else { FCEU_abort("unhandled ModernDeemphColorMap scale"); return 0; }
|
||||
}
|
||||
|
||||
typedef u32 (*ModernDeemphColorMapFuncPtr)( u8*, u8* );
|
||||
typedef u32 (*ModernDeemphColorMapFuncPtr)( const u8*, const u8* );
|
||||
|
||||
static ModernDeemphColorMapFuncPtr getModernDeemphColorMapFunc(int scale)
|
||||
{
|
||||
ModernDeemphColorMapFuncPtr ptr = NULL;
|
||||
ModernDeemphColorMapFuncPtr ptr;
|
||||
|
||||
if(scale == 1) ptr = &_ModernDeemphColorMap<1>;
|
||||
else if(scale == 2) ptr = &_ModernDeemphColorMap<2>;
|
||||
@@ -521,7 +521,7 @@ static ModernDeemphColorMapFuncPtr getModernDeemphColorMapFunc(int scale)
|
||||
else if(scale == 7) ptr = &_ModernDeemphColorMap<7>;
|
||||
else if(scale == 8) ptr = &_ModernDeemphColorMap<8>;
|
||||
else if(scale == 9) ptr = &_ModernDeemphColorMap<9>;
|
||||
else { abort(); ptr = NULL; }
|
||||
else { FCEU_abort("unhandled ModernDeemphColorMap scale"); ptr = nullptr; }
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -29,4 +29,4 @@ void Blit32to16(uint32 *src, uint16 *dest, int xr, int yr, int dpitch,
|
||||
int shiftr[3], int shiftl[3]);
|
||||
|
||||
|
||||
u32 ModernDeemphColorMap(u8* src, u8* srcbuf, int scale);
|
||||
u32 ModernDeemphColorMap(const u8* src, const u8* srcbuf, int scale);
|
||||
|
||||
+9
-5
@@ -23,21 +23,22 @@ THE SOFTWARE.
|
||||
#include "emufile.h"
|
||||
#include "utils/xstring.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
bool EMUFILE::readAllBytes(std::vector<u8>* dstbuf, const std::string& fname)
|
||||
{
|
||||
EMUFILE_FILE file(fname.c_str(),"rb");
|
||||
if(file.fail()) return false;
|
||||
int size = file.size();
|
||||
size_t size = file.size();
|
||||
dstbuf->resize(size);
|
||||
file.fread(&dstbuf->at(0),size);
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t EMUFILE_MEMORY::_fread(const void *ptr, size_t bytes){
|
||||
u32 remain = len-pos;
|
||||
u32 todo = std::min<u32>(remain,(u32)bytes);
|
||||
size_t remain = len-pos;
|
||||
size_t todo = std::min<size_t>(remain,bytes);
|
||||
if(len==0)
|
||||
{
|
||||
failbit = true;
|
||||
@@ -78,13 +79,16 @@ void EMUFILE_FILE::open(const char* fname, const char* mode)
|
||||
}
|
||||
|
||||
|
||||
void EMUFILE_FILE::truncate(s32 length)
|
||||
void EMUFILE_FILE::truncate(size_t length)
|
||||
{
|
||||
::fflush(fp);
|
||||
#ifdef _MSC_VER
|
||||
_chsize(_fileno(fp),length);
|
||||
#else
|
||||
ftruncate(fileno(fp),length);
|
||||
if ( ftruncate(fileno(fp),length) != 0 )
|
||||
{
|
||||
printf("Warning: EMUFILE_FILE::truncate failed\n");
|
||||
}
|
||||
#endif
|
||||
// this is probably wrong if mode is "wb"
|
||||
fclose(fp);
|
||||
|
||||
+31
-30
@@ -59,7 +59,7 @@ public:
|
||||
bool fail(bool unset=false) { bool ret = failbit; if(unset) unfail(); return ret; }
|
||||
void unfail() { failbit=false; }
|
||||
|
||||
bool eof() { return size()==ftell(); }
|
||||
bool eof() { return size() == static_cast<size_t>(ftell()); }
|
||||
|
||||
size_t fread(const void *ptr, size_t bytes){
|
||||
return _fread(ptr,bytes);
|
||||
@@ -109,13 +109,13 @@ public:
|
||||
double readdouble();
|
||||
size_t readdouble(double* val);
|
||||
|
||||
virtual int fseek(int offset, int origin) = 0;
|
||||
virtual int fseek(long int offset, int origin) = 0;
|
||||
|
||||
virtual int ftell() = 0;
|
||||
virtual int size() = 0;
|
||||
virtual long int ftell() = 0;
|
||||
virtual size_t size() = 0;
|
||||
virtual void fflush() = 0;
|
||||
|
||||
virtual void truncate(s32 length) = 0;
|
||||
virtual void truncate(size_t length) = 0;
|
||||
};
|
||||
|
||||
//todo - handle read-only specially?
|
||||
@@ -123,9 +123,10 @@ class EMUFILE_MEMORY : public EMUFILE {
|
||||
protected:
|
||||
std::vector<u8> *vec;
|
||||
bool ownvec;
|
||||
s32 pos, len;
|
||||
long int pos;
|
||||
size_t len;
|
||||
|
||||
void reserve(u32 amt) {
|
||||
void reserve(size_t amt) {
|
||||
if(vec->size() < amt)
|
||||
vec->resize(amt);
|
||||
}
|
||||
@@ -133,12 +134,12 @@ protected:
|
||||
public:
|
||||
|
||||
EMUFILE_MEMORY(std::vector<u8> *underlying) : vec(underlying), ownvec(false), pos(0), len((s32)underlying->size()) { }
|
||||
EMUFILE_MEMORY(u32 preallocate) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(0) {
|
||||
EMUFILE_MEMORY(size_t preallocate) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(0) {
|
||||
vec->resize(preallocate);
|
||||
len = preallocate;
|
||||
}
|
||||
EMUFILE_MEMORY() : vec(new std::vector<u8>()), ownvec(true), pos(0), len(0) { vec->reserve(1024); }
|
||||
EMUFILE_MEMORY(void* buf, s32 size) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(size) {
|
||||
EMUFILE_MEMORY(void* buf, size_t size) : vec(new std::vector<u8>()), ownvec(true), pos(0), len(size) {
|
||||
vec->resize(size);
|
||||
if(size != 0)
|
||||
memcpy(&vec->front(),buf,size);
|
||||
@@ -150,11 +151,11 @@ public:
|
||||
|
||||
virtual EMUFILE* memwrap();
|
||||
|
||||
virtual void truncate(s32 length)
|
||||
virtual void truncate(size_t length)
|
||||
{
|
||||
vec->resize(length);
|
||||
len = length;
|
||||
if(pos>length) pos=length;
|
||||
if (static_cast<size_t>(pos) > length) pos=static_cast<long int>(length);
|
||||
}
|
||||
|
||||
u8* buf() {
|
||||
@@ -192,7 +193,7 @@ public:
|
||||
//if(_fread(&temp,1) != 1)
|
||||
// return EOF;
|
||||
//else return temp;
|
||||
u32 remain = len-pos;
|
||||
size_t remain = len-pos;
|
||||
if(remain<1) {
|
||||
failbit = true;
|
||||
return -1;
|
||||
@@ -216,13 +217,13 @@ public:
|
||||
//they handle the return values correctly
|
||||
|
||||
virtual void fwrite(const void *ptr, size_t bytes){
|
||||
reserve(pos+(s32)bytes);
|
||||
reserve(pos+bytes);
|
||||
memcpy(buf()+pos,ptr,bytes);
|
||||
pos += (s32)bytes;
|
||||
len = std::max<int>(pos,len);
|
||||
pos += static_cast<long>(bytes);
|
||||
len = std::max<size_t>(pos,len);
|
||||
}
|
||||
|
||||
virtual int fseek(int offset, int origin){
|
||||
virtual int fseek(long int offset, int origin){
|
||||
//work differently for read-only...?
|
||||
switch(origin) {
|
||||
case SEEK_SET:
|
||||
@@ -232,7 +233,7 @@ public:
|
||||
pos += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
pos = size()+offset;
|
||||
pos = (long int)(size()+offset);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@@ -241,24 +242,24 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int ftell() {
|
||||
virtual long int ftell() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
virtual void fflush() {}
|
||||
|
||||
void set_len(s32 length)
|
||||
void set_len(size_t length)
|
||||
{
|
||||
len = length;
|
||||
if(pos > length)
|
||||
pos = length;
|
||||
if (static_cast<size_t>(pos) > length)
|
||||
pos = static_cast<long>(length);
|
||||
}
|
||||
void trim()
|
||||
{
|
||||
vec->resize(len);
|
||||
}
|
||||
|
||||
virtual int size() { return (int)len; }
|
||||
virtual size_t size() { return len; }
|
||||
};
|
||||
|
||||
class EMUFILE_FILE : public EMUFILE {
|
||||
@@ -288,7 +289,7 @@ public:
|
||||
|
||||
bool is_open() { return fp != NULL; }
|
||||
|
||||
virtual void truncate(s32 length);
|
||||
virtual void truncate(size_t length);
|
||||
|
||||
virtual int fprintf(const char *format, ...) {
|
||||
va_list argptr;
|
||||
@@ -321,20 +322,20 @@ public:
|
||||
failbit = true;
|
||||
}
|
||||
|
||||
virtual int fseek(int offset, int origin) {
|
||||
virtual int fseek(long int offset, int origin) {
|
||||
return ::fseek(fp, offset, origin);
|
||||
}
|
||||
|
||||
virtual int ftell() {
|
||||
return (u32)::ftell(fp);
|
||||
virtual long int ftell() {
|
||||
return ::ftell(fp);
|
||||
}
|
||||
|
||||
virtual int size() {
|
||||
int oldpos = ftell();
|
||||
virtual size_t size() {
|
||||
long int oldpos = ftell();
|
||||
fseek(0,SEEK_END);
|
||||
int len = ftell();
|
||||
long int len = ftell();
|
||||
fseek(oldpos,SEEK_SET);
|
||||
return len;
|
||||
return static_cast<size_t>(len);
|
||||
}
|
||||
|
||||
virtual void fflush() {
|
||||
|
||||
+33
-23
@@ -181,7 +181,6 @@ static void FCEU_CloseGame(void)
|
||||
}
|
||||
|
||||
#ifdef __WIN_DRIVER__
|
||||
extern char LoadedRomFName[2048];
|
||||
if (storePreferences(mass_replace(LoadedRomFName, "|", ".").c_str()))
|
||||
FCEUD_PrintError("Couldn't store debugging data");
|
||||
CDLoggerROMClosed();
|
||||
@@ -226,10 +225,10 @@ static void FCEU_CloseGame(void)
|
||||
currFrameCounter = 0;
|
||||
|
||||
//Reset flags for Undo/Redo/Auto Savestating //adelikat: TODO: maybe this stuff would be cleaner as a struct or class
|
||||
lastSavestateMade[0] = 0;
|
||||
lastSavestateMade.clear();
|
||||
undoSS = false;
|
||||
redoSS = false;
|
||||
lastLoadstateMade[0] = 0;
|
||||
lastLoadstateMade.clear();
|
||||
undoLS = false;
|
||||
redoLS = false;
|
||||
AutoSS = false;
|
||||
@@ -421,7 +420,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
|
||||
//----------
|
||||
//attempt to open the files
|
||||
FCEUFILE *fp;
|
||||
char fullname[2048]; // this name contains both archive name and ROM file name
|
||||
std::string fullname; // this name contains both archive name and ROM file name
|
||||
int lastpal = PAL;
|
||||
int lastdendy = dendy;
|
||||
|
||||
@@ -431,7 +430,7 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
|
||||
// currently there's only one situation:
|
||||
// the user clicked cancel form the open from archive dialog
|
||||
int userCancel = 0;
|
||||
fp = FCEU_fopen(name, 0, "rb", 0, -1, romextensions, &userCancel);
|
||||
fp = FCEU_fopen(name, LoadedRomFNamePatchToUse[0] ? LoadedRomFNamePatchToUse : nullptr, "rb", 0, -1, romextensions, &userCancel);
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
@@ -443,16 +442,19 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
|
||||
}
|
||||
else if (fp->archiveFilename != "")
|
||||
{
|
||||
strcpy(fullname, fp->archiveFilename.c_str());
|
||||
strcat(fullname, "|");
|
||||
strcat(fullname, fp->filename.c_str());
|
||||
} else
|
||||
strcpy(fullname, name);
|
||||
fullname.assign(fp->archiveFilename.c_str());
|
||||
fullname.append("|");
|
||||
fullname.append(fp->filename.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fullname.assign(name);
|
||||
}
|
||||
|
||||
// reset loaded game BEFORE it's loading.
|
||||
ResetGameLoaded();
|
||||
//file opened ok. start loading.
|
||||
FCEU_printf("Loading %s...\n\n", fullname);
|
||||
FCEU_printf("Loading %s...\n\n", fullname.c_str());
|
||||
GetFileBase(fp->filename.c_str());
|
||||
//reset parameters so they're cleared just in case a format's loader doesn't know to do the clearing
|
||||
MasterRomInfoParams = TMasterRomInfoParams();
|
||||
@@ -484,16 +486,16 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
|
||||
bool FCEUXLoad(const char *name, FCEUFILE * fp);
|
||||
|
||||
int load_result;
|
||||
load_result = iNESLoad(fullname, fp, OverwriteVidMode);
|
||||
load_result = iNESLoad(fullname.c_str(), fp, OverwriteVidMode);
|
||||
if (load_result == LOADER_INVALID_FORMAT)
|
||||
{
|
||||
load_result = NSFLoad(fullname, fp);
|
||||
load_result = NSFLoad(fullname.c_str(), fp);
|
||||
if (load_result == LOADER_INVALID_FORMAT)
|
||||
{
|
||||
load_result = UNIFLoad(fullname, fp);
|
||||
load_result = UNIFLoad(fullname.c_str(), fp);
|
||||
if (load_result == LOADER_INVALID_FORMAT)
|
||||
{
|
||||
load_result = FDSLoad(fullname, fp);
|
||||
load_result = FDSLoad(fullname.c_str(), fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -502,7 +504,6 @@ FCEUGI *FCEUI_LoadGameVirtual(const char *name, int OverwriteVidMode, bool silen
|
||||
|
||||
#ifdef __WIN_DRIVER__
|
||||
// ################################## Start of SP CODE ###########################
|
||||
extern char LoadedRomFName[2048];
|
||||
extern int loadDebugDataFailed;
|
||||
|
||||
if ((loadDebugDataFailed = loadPreferences(mass_replace(LoadedRomFName, "|", ".").c_str())))
|
||||
@@ -725,7 +726,8 @@ extern unsigned int frameAdvHoldTimer;
|
||||
///Skip may be passed in, if FRAMESKIP is #defined, to cause this to emulate more than one frame
|
||||
void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int skip) {
|
||||
//skip initiates frame skip if 1, or frame skip and sound skip if 2
|
||||
int r, ssize;
|
||||
FCEU_MAYBE_UNUSED int r;
|
||||
int ssize;
|
||||
|
||||
JustFrameAdvanced = false;
|
||||
|
||||
@@ -742,7 +744,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
||||
{
|
||||
EmulationPaused = EMULATIONPAUSED_FA;
|
||||
}
|
||||
if (frameAdvance_Delay_count < frameAdvanceDelayScaled)
|
||||
if ( static_cast<unsigned int>(frameAdvance_Delay_count) < frameAdvanceDelayScaled)
|
||||
{
|
||||
frameAdvance_Delay_count++;
|
||||
}
|
||||
@@ -808,6 +810,9 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
||||
|
||||
if (skip != 2) ssize = FlushEmulateSound(); //If skip = 2 we are skipping sound processing
|
||||
|
||||
//flush tracer once a frame, since we're likely to end up back at a user interaction loop after this with emulation paused
|
||||
FCEUD_FlushTrace();
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
CallRegisteredLuaFunctions(LUACALL_AFTEREMULATION);
|
||||
#endif
|
||||
@@ -887,7 +892,8 @@ void ResetNES(void) {
|
||||
extern uint8 *XBackBuf;
|
||||
memset(XBackBuf, 0, 256 * 256);
|
||||
|
||||
FCEU_DispMessage("Reset", 0);
|
||||
// OpenEmu
|
||||
//FCEU_DispMessage("Reset", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1061,7 +1067,7 @@ void FCEU_ResetVidSys(void) {
|
||||
|
||||
FCEUS FSettings;
|
||||
|
||||
void FCEU_printf(const char *format, ...)
|
||||
void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...)
|
||||
{
|
||||
char temp[2048];
|
||||
|
||||
@@ -1081,7 +1087,7 @@ void FCEU_printf(const char *format, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void FCEU_PrintError(const char *format, ...)
|
||||
void FCEU_PrintError( __FCEU_PRINTF_FORMAT const char *format, ...)
|
||||
{
|
||||
char temp[2048];
|
||||
|
||||
@@ -1228,12 +1234,16 @@ void FCEUI_ClearEmulationFrameStepped()
|
||||
//ideally maybe we shouldnt be using this, but i need it for quick merging
|
||||
void FCEUI_SetEmulationPaused(int val) {
|
||||
EmulationPaused = val;
|
||||
if(EmulationPaused)
|
||||
FCEUD_FlushTrace();
|
||||
}
|
||||
|
||||
void FCEUI_ToggleEmulationPause(void)
|
||||
{
|
||||
EmulationPaused = (EmulationPaused & EMULATIONPAUSED_PAUSED) ^ EMULATIONPAUSED_PAUSED;
|
||||
DebuggerWasUpdated = false;
|
||||
if(EmulationPaused)
|
||||
FCEUD_FlushTrace();
|
||||
}
|
||||
|
||||
void FCEUI_FrameAdvanceEnd(void) {
|
||||
@@ -1241,8 +1251,8 @@ void FCEUI_FrameAdvanceEnd(void) {
|
||||
}
|
||||
|
||||
void FCEUI_FrameAdvance(void) {
|
||||
frameAdvanceRequested = true;
|
||||
frameAdvance_Delay_count = 0;
|
||||
frameAdvanceRequested = true;
|
||||
}
|
||||
|
||||
static int AutosaveCounter = 0;
|
||||
@@ -1259,7 +1269,7 @@ void UpdateAutosave(void) {
|
||||
FCEUSS_Save(f, false);
|
||||
AutoSS = true; //Flag that an auto-savestate was made
|
||||
free(f);
|
||||
f = NULL;
|
||||
f = NULL;
|
||||
AutosaveStatus[AutosaveIndex] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -139,10 +139,10 @@ extern FCEUS FSettings;
|
||||
|
||||
bool CheckFileExists(const char* filename); //Receives a filename (fullpath) and checks to see if that file exists
|
||||
|
||||
void FCEU_PrintError(const char *format, ...);
|
||||
void FCEU_printf(const char *format, ...);
|
||||
void FCEU_DispMessage(const char *format, int disppos, ...);
|
||||
void FCEU_DispMessageOnMovie(const char *format, ...);
|
||||
void FCEU_PrintError( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
|
||||
void FCEU_printf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
|
||||
void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 3 );
|
||||
void FCEU_DispMessageOnMovie( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 1, 2 );
|
||||
void FCEU_TogglePPU();
|
||||
|
||||
void SetNESDeemph_OldHacky(uint8 d, int force);
|
||||
|
||||
+28
-10
@@ -29,6 +29,7 @@
|
||||
#include "state.h"
|
||||
#include "file.h"
|
||||
#include "cart.h"
|
||||
#include "ines.h"
|
||||
#include "netplay.h"
|
||||
#include "driver.h"
|
||||
#include "movie.h"
|
||||
@@ -223,14 +224,23 @@ void FCEU_FDSSelect(void)
|
||||
FCEU_DispMessage("Disk %d Side %c Selected", 0, SelectDisk >> 1, (SelectDisk & 1) ? 'B' : 'A');
|
||||
}
|
||||
|
||||
#define IRQ_Repeat (IRQa & 0x01)
|
||||
#define IRQ_Enabled (IRQa & 0x02)
|
||||
#define IRQ_Repeat 0x01
|
||||
#define IRQ_Enabled 0x02
|
||||
|
||||
static void FDSFix(int a) {
|
||||
if ((IRQa & IRQ_Enabled) && IRQCount) {
|
||||
if (IRQa & IRQ_Enabled) {
|
||||
IRQCount -= a;
|
||||
if (IRQCount <= 0) {
|
||||
IRQCount = IRQLatch;
|
||||
/* Puff Puff Golf notes:
|
||||
Game freezes while music playing ingame after inserting Disk Side B.
|
||||
IRQ is usually fired at scanline 169 and 183 for music to work.
|
||||
|
||||
At some point after inserting disk B, an IRQ is fired at scanline 174 which
|
||||
will just freeze game while music plays.
|
||||
|
||||
If you ignore triggering IRQ altogether, game plays but no music
|
||||
*/
|
||||
X6502_IRQBegin(FCEU_IQEXT);
|
||||
if (!(IRQa & IRQ_Repeat)) {
|
||||
IRQa &= ~IRQ_Enabled;
|
||||
@@ -574,21 +584,30 @@ void FDSSoundReset(void) {
|
||||
static DECLFW(FDSWrite) {
|
||||
switch (A) {
|
||||
case 0x4020:
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
IRQLatch &= 0xFF00;
|
||||
IRQLatch |= V;
|
||||
break;
|
||||
case 0x4021:
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
IRQLatch &= 0xFF;
|
||||
IRQLatch |= V << 8;
|
||||
break;
|
||||
case 0x4022:
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
IRQCount = IRQLatch;
|
||||
IRQa = V & 3;
|
||||
if (FDSRegs[3] & 1) {
|
||||
IRQa = V & 0x03;
|
||||
if (IRQa & IRQ_Enabled) {
|
||||
IRQCount = IRQLatch;
|
||||
} else {
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x4023:
|
||||
if (!(V & 0x01)) {
|
||||
IRQa &= ~IRQ_Enabled;
|
||||
X6502_IRQEnd(FCEU_IQEXT);
|
||||
X6502_IRQEnd(FCEU_IQEXT2);
|
||||
}
|
||||
break;
|
||||
case 0x4023: break;
|
||||
case 0x4024:
|
||||
if (mapperFDS_diskinsert && ~mapperFDS_control & 0x04) {
|
||||
|
||||
@@ -834,7 +853,6 @@ int FDSLoad(const char *name, FCEUFILE *fp) {
|
||||
free(fn);
|
||||
}
|
||||
|
||||
extern char LoadedRomFName[2048];
|
||||
strcpy(LoadedRomFName, name); //For the debugger list
|
||||
|
||||
GameInfo->type = GIT_FDS;
|
||||
|
||||
+17
-26
@@ -69,7 +69,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
|
||||
|
||||
if(!ips) return;
|
||||
|
||||
char* buf = (char*)FCEU_dmalloc(fp->size);
|
||||
char* buf = (char*)FCEU_malloc(fp->size);
|
||||
memcpy(buf,fp->EnsureMemorystream()->buf(),fp->size);
|
||||
|
||||
|
||||
@@ -108,13 +108,7 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
|
||||
if((offset+size)>(uint32)fp->size)
|
||||
{
|
||||
// Probably a little slow.
|
||||
char *newbuf=(char *)realloc(buf,offset+size);
|
||||
if(!newbuf)
|
||||
{
|
||||
free(buf); buf=NULL;
|
||||
FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count);
|
||||
goto end;
|
||||
}
|
||||
char *newbuf=(char *)FCEU_realloc(buf,offset+size);
|
||||
buf=newbuf;
|
||||
memset(buf+fp->size,0,offset+size-fp->size);
|
||||
fp->size=offset+size;
|
||||
@@ -133,17 +127,15 @@ void ApplyIPS(FILE *ips, FCEUFILE* fp)
|
||||
if((offset+size)>(uint32)fp->size)
|
||||
{
|
||||
// Probably a little slow.
|
||||
char *newbuf=(char *)realloc(buf,offset+size);
|
||||
if(!newbuf)
|
||||
{
|
||||
free(buf); buf=NULL;
|
||||
FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count);
|
||||
goto end;
|
||||
}
|
||||
char *newbuf=(char *)FCEU_realloc(buf,offset+size);
|
||||
buf=newbuf;
|
||||
memset(buf+fp->size,0,offset+size-fp->size);
|
||||
fp->size=offset+size;
|
||||
}
|
||||
if ( fread(buf+offset,1,size,ips) != static_cast<size_t>(size) )
|
||||
{
|
||||
FCEU_printf(" Warn IPS data read came up short!\n");
|
||||
}
|
||||
fread(buf+offset,1,size,ips);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
@@ -326,9 +318,9 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, const char *mode, cha
|
||||
{
|
||||
uint32 magic;
|
||||
|
||||
magic = fp->fgetc();
|
||||
magic|=fp->fgetc()<<8;
|
||||
magic|=fp->fgetc()<<16;
|
||||
magic = (fp->fgetc() & 0x00ff);
|
||||
magic|= (fp->fgetc() & 0x00ff) << 8;
|
||||
magic|= (fp->fgetc() & 0x00ff) << 16;
|
||||
fp->fseek(0,SEEK_SET);
|
||||
|
||||
if(magic==0x088b1f) {
|
||||
@@ -338,7 +330,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, const char *mode, cha
|
||||
if(gzfile) {
|
||||
delete fp;
|
||||
|
||||
int size;
|
||||
size_t size;
|
||||
for(size=0; gzgetc(gzfile) != EOF; size++) {}
|
||||
EMUFILE_MEMORY* ms = new EMUFILE_MEMORY(size);
|
||||
gzseek(gzfile,0,SEEK_SET);
|
||||
@@ -457,13 +449,12 @@ int FCEU_fisarchive(FCEUFILE *fp)
|
||||
std::string GetMfn() //Retrieves the movie filename from curMovieFilename (for adding to savestate and auto-save files)
|
||||
{
|
||||
std::string movieFilenamePart;
|
||||
extern char curMovieFilename[512];
|
||||
if(*curMovieFilename)
|
||||
{
|
||||
if (!curMovieFilename.empty())
|
||||
{
|
||||
char drv[PATH_MAX], dir[PATH_MAX], name[PATH_MAX], ext[PATH_MAX];
|
||||
splitpath(curMovieFilename,drv,dir,name,ext);
|
||||
splitpath(curMovieFilename.c_str(),drv,dir,name,ext);
|
||||
movieFilenamePart = std::string(".") + name;
|
||||
}
|
||||
}
|
||||
return movieFilenamePart;
|
||||
}
|
||||
|
||||
@@ -495,7 +486,7 @@ void FCEUI_SetDirOverride(int which, char *n)
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if(!(*strp=(char*)FCEU_dmalloc(2048))) //mbg merge 7/17/06 cast to char*
|
||||
if(!(*strp=(char*)FCEU_malloc(2048))) //mbg merge 7/17/06 cast to char*
|
||||
return(0);
|
||||
va_start(ap,fmt);
|
||||
ret=vsnprintf(*strp,2048,fmt,ap);
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ struct FCEUFILE {
|
||||
int archiveIndex;
|
||||
|
||||
//the size of the file
|
||||
int size;
|
||||
size_t size;
|
||||
|
||||
//whether the file is contained in an archive
|
||||
bool isArchive() { return archiveCount > 0; }
|
||||
|
||||
@@ -16,12 +16,34 @@ enum EGIV
|
||||
GIV_USER = 2, //What was set by FCEUI_SetVidSys().
|
||||
};
|
||||
|
||||
enum EGIPPU
|
||||
{
|
||||
GIPPU_USER = 0,
|
||||
GIPPU_RP2C04_0001 = 1,
|
||||
GIPPU_RP2C04_0002 = 2,
|
||||
GIPPU_RP2C04_0003 = 3,
|
||||
GIPPU_RP2C04_0004 = 4,
|
||||
GIPPU_RC2C03B = 5,
|
||||
GIPPU_RC2C05_01 = 6,
|
||||
GIPPU_RC2C05_02 = 7,
|
||||
GIPPU_RC2C05_03 = 8,
|
||||
GIPPU_RC2C05_04 = 9,
|
||||
};
|
||||
|
||||
enum EGIVS
|
||||
{
|
||||
EGIVS_NORMAL = 0,
|
||||
EGIVS_RBI = 1, // RBI Baseball protection
|
||||
EGIVS_TKO = 2, // TKO Boxing protection
|
||||
EGIVS_XEVIOUS = 3, // Super Xevious protection
|
||||
};
|
||||
|
||||
enum ESIS
|
||||
{
|
||||
SIS_NONE = 0,
|
||||
SIS_DATACH = 1,
|
||||
SIS_NWC = 2,
|
||||
SIS_VSUNISYSTEM = 3,
|
||||
SIS_VSUNISYSTEM = 3, // Is it used?
|
||||
SIS_NSF = 4,
|
||||
};
|
||||
|
||||
@@ -44,6 +66,8 @@ enum ESI
|
||||
SI_COUNT = SI_LCDCOMP_ZAPPER
|
||||
};
|
||||
|
||||
|
||||
|
||||
inline const char* ESI_Name(ESI esi)
|
||||
{
|
||||
static const char * const names[] =
|
||||
@@ -137,6 +161,9 @@ struct FCEUGI
|
||||
ESI input[2]; //Desired input for emulated input ports 1 and 2; -1 for unknown desired input.
|
||||
ESIFC inputfc; //Desired Famicom expansion port device. -1 for unknown desired input.
|
||||
ESIS cspecial; //Special cart expansion: DIP switches, barcode reader, etc.
|
||||
EGIPPU vs_ppu; //PPU type for Vs. System
|
||||
EGIVS vs_type; //Vs. System type
|
||||
uint8 vs_cswitch; // Switch first and second controllers for Vs. System
|
||||
|
||||
MD5DATA MD5;
|
||||
|
||||
|
||||
+152
-41
@@ -37,6 +37,7 @@
|
||||
#include "cheat.h"
|
||||
#include "vsuni.h"
|
||||
#include "driver.h"
|
||||
#include "input.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@@ -54,9 +55,11 @@ iNES_HEADER head;
|
||||
static CartInfo iNESCart;
|
||||
|
||||
uint8 Mirroring = 0;
|
||||
uint8 MirroringAs2bits = 0;
|
||||
uint32 ROM_size = 0;
|
||||
uint32 VROM_size = 0;
|
||||
char LoadedRomFName[2048]; //mbg merge 7/17/06 added
|
||||
char LoadedRomFName[4096]; //mbg merge 7/17/06 added
|
||||
char LoadedRomFNamePatchToUse[4096];
|
||||
|
||||
static int CHRRAMSize = -1;
|
||||
static int iNES_Init(int num);
|
||||
@@ -107,11 +110,11 @@ void iNESGI(GI h) { //bbit edited: removed static keyword
|
||||
if (iNESCart.Close)
|
||||
iNESCart.Close();
|
||||
if (ROM) {
|
||||
free(ROM);
|
||||
FCEU_free(ROM);
|
||||
ROM = NULL;
|
||||
}
|
||||
if (VROM) {
|
||||
free(VROM);
|
||||
FCEU_free(VROM);
|
||||
VROM = NULL;
|
||||
}
|
||||
if (trainerpoo) {
|
||||
@@ -141,6 +144,9 @@ struct INPSEL {
|
||||
ESIFC inputfc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Function to set input controllers based on CRC
|
||||
*/
|
||||
static void SetInput(void) {
|
||||
static struct INPSEL moo[] =
|
||||
{
|
||||
@@ -153,9 +159,9 @@ static void SetInput(void) {
|
||||
{0x48ca0ee1, SI_GAMEPAD, SI_GAMEPAD, SIFC_BWORLD }, // Barcode World
|
||||
{0x4318a2f8, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Barker Bill's Trick Shooting
|
||||
{0x6cca1c1f, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, // Dai Undoukai
|
||||
{0x24598791, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Duck Hunt
|
||||
{0x24598791, SI_GAMEPAD, SI_ZAPPER, SIFC_NONE }, // Duck Hunt
|
||||
{0xd5d6eac4, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, // Edu (As)
|
||||
{0xe9a7fe9e, SI_UNSET, SI_MOUSE, SIFC_NONE }, // Educational Computer 2000
|
||||
{0xe9a7fe9e, SI_UNSET, SI_MOUSE, SIFC_SUBORKB }, // Educational Computer 2000
|
||||
{0x8f7b1669, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, // FP BASIC 3.3 by maxzhou88
|
||||
{0xf7606810, SI_UNSET, SI_UNSET, SIFC_FKB }, // Family BASIC 2.0A
|
||||
{0x895037bc, SI_UNSET, SI_UNSET, SIFC_FKB }, // Family BASIC 2.1a
|
||||
@@ -215,6 +221,7 @@ static void SetInput(void) {
|
||||
{0x67b126b9, SI_GAMEPAD, SI_GAMEPAD, SIFC_FAMINETSYS }, // Famicom Network System
|
||||
{0x00000000, SI_UNSET, SI_UNSET, SIFC_UNSET }
|
||||
};
|
||||
|
||||
int x = 0;
|
||||
|
||||
while (moo[x].input1 >= 0 || moo[x].input2 >= 0 || moo[x].inputfc >= 0) {
|
||||
@@ -228,6 +235,64 @@ static void SetInput(void) {
|
||||
}
|
||||
}
|
||||
|
||||
struct INPSEL_NES20 {
|
||||
uint8 expansion_id;
|
||||
ESI input1;
|
||||
ESI input2;
|
||||
ESIFC inputfc;
|
||||
};
|
||||
|
||||
/*
|
||||
* Function to set input controllers based on NES 2.0 header
|
||||
*/
|
||||
extern int eoptions;
|
||||
static void SetInputNes20(uint8 expansion) {
|
||||
static struct INPSEL_NES20 moo[] =
|
||||
{
|
||||
{0x01, SI_GAMEPAD, SI_GAMEPAD, SIFC_UNSET }, // Standard NES/Famicom controllers
|
||||
{0x02, SI_GAMEPAD, SI_GAMEPAD, SIFC_NONE }, // NES Four Score/Satellite with two additional standard controllers
|
||||
{0x03, SI_GAMEPAD, SI_GAMEPAD, SIFC_4PLAYER }, // Famicom Four Players Adapter with two additional standard controllers using the "simple" protocol
|
||||
{0x04, SI_GAMEPAD, SI_GAMEPAD, SIFC_NONE }, // Vs. System (1P via $4016)
|
||||
{0x05, SI_GAMEPAD, SI_GAMEPAD, SIFC_NONE }, // Vs. System (1P via $4017)
|
||||
{0x07, SI_ZAPPER, SI_NONE, SIFC_NONE }, // Vs. Zapper
|
||||
{0x08, SI_UNSET, SI_ZAPPER, SIFC_NONE }, // Zapper ($4017)
|
||||
{0x0A, SI_UNSET, SI_UNSET, SIFC_SHADOW }, // Bandai Hyper Shot Lightgun
|
||||
{0x0B, SI_UNSET, SI_POWERPADA, SIFC_UNSET }, // Power Pad Side A
|
||||
{0x0C, SI_UNSET, SI_POWERPADB, SIFC_UNSET }, // Power Pad Side B
|
||||
{0x0D, SI_UNSET, SI_UNSET, SIFC_FTRAINERA }, // Family Trainer Side A
|
||||
{0x0E, SI_UNSET, SI_UNSET, SIFC_FTRAINERB }, // Family Trainer Side B
|
||||
{0x0F, SI_UNSET, SI_ARKANOID, SIFC_UNSET }, // Arkanoid Vaus Controller (NES)
|
||||
{0x10, SI_UNSET, SI_UNSET, SIFC_ARKANOID }, // Arkanoid Vaus Controller (Famicom)
|
||||
{0x12, SI_UNSET, SI_UNSET, SIFC_HYPERSHOT }, // Konami Hyper Shot Controller
|
||||
{0x15, SI_UNSET, SI_UNSET, SIFC_MAHJONG }, // Jissen Mahjong Controller
|
||||
{0x17, SI_UNSET, SI_UNSET, SIFC_OEKAKIDS }, // Oeka Kids Tablet
|
||||
{0x18, SI_UNSET, SI_UNSET, SIFC_BWORLD }, // Sunsoft Barcode Battler
|
||||
{0x1B, SI_UNSET, SI_UNSET, SIFC_TOPRIDER }, // Top Rider (Inflatable Bicycle)
|
||||
{0x23, SI_UNSET, SI_UNSET, SIFC_FKB }, // Family BASIC Keyboard plus Famicom Data Recorder
|
||||
{0x24, SI_UNSET, SI_UNSET, SIFC_PEC586KB }, // Dongda PEC-586 Keyboard
|
||||
{0x26, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, // Subor Keyboard
|
||||
//{0x27, SI_UNSET, SI_MOUSE, SIFC_SUBORKB }, // Subor Keyboard plus mouse (3x8-bit protocol)
|
||||
{0x28, SI_UNSET, SI_MOUSE, SIFC_SUBORKB }, // Subor Keyboard plus mouse (24-bit protocol)
|
||||
{0x29, SI_UNSET, SI_SNES_MOUSE, SIFC_UNSET }, // SNES Mouse
|
||||
{0, SI_UNSET, SI_UNSET, SIFC_UNSET }
|
||||
};
|
||||
|
||||
int x = 0;
|
||||
|
||||
if (expansion == 0x02)
|
||||
eoptions |= 32768; // dirty hack to enable Four-Score
|
||||
GameInfo->vs_cswitch = expansion == 0x05;
|
||||
|
||||
while (moo[x].expansion_id) {
|
||||
if (moo[x].expansion_id == expansion) {
|
||||
GameInfo->input[0] = moo[x].input1;
|
||||
GameInfo->input[1] = moo[x].input2;
|
||||
GameInfo->inputfc = moo[x].inputfc;
|
||||
break; }
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
#define INESB_INCOMPLETE 1
|
||||
#define INESB_CORRUPT 2
|
||||
#define INESB_HACKED 4
|
||||
@@ -276,7 +341,7 @@ static const TMasterRomInfo sMasterRomInfo[] = {
|
||||
const TMasterRomInfo* MasterRomInfo;
|
||||
TMasterRomInfoParams MasterRomInfoParams;
|
||||
|
||||
static void CheckHInfo(void) {
|
||||
static void CheckHInfo(uint64 partialmd5) {
|
||||
/* ROM images that have the battery-backed bit set in the header that really
|
||||
don't have battery-backed RAM is not that big of a problem, so I'll
|
||||
treat this differently by only listing games that should have battery-backed RAM.
|
||||
@@ -327,14 +392,9 @@ static void CheckHInfo(void) {
|
||||
#include "ines-correct.h"
|
||||
};
|
||||
int32 tofix = 0, x, mask;
|
||||
uint64 partialmd5 = 0;
|
||||
|
||||
for (x = 0; x < 8; x++)
|
||||
partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8);
|
||||
CheckBad(partialmd5);
|
||||
|
||||
MasterRomInfo = NULL;
|
||||
for (int i = 0; i < ARRAY_SIZE(sMasterRomInfo); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(sMasterRomInfo); i++) {
|
||||
const TMasterRomInfo& info = sMasterRomInfo[i];
|
||||
if (info.md5lower != partialmd5)
|
||||
continue;
|
||||
@@ -343,7 +403,7 @@ static void CheckHInfo(void) {
|
||||
if (!info.params) break;
|
||||
|
||||
std::vector<std::string> toks = tokenize_str(info.params, ",");
|
||||
for (int j = 0; j < (int)toks.size(); j++) {
|
||||
for (size_t j = 0; j < toks.size(); j++) {
|
||||
std::vector<std::string> parts = tokenize_str(toks[j], "=");
|
||||
MasterRomInfoParams[parts[0]] = parts[1];
|
||||
}
|
||||
@@ -673,7 +733,7 @@ BMAPPINGLocal bmap[] = {
|
||||
{"", 215, UNL8237_Init},
|
||||
{"", 216, Mapper216_Init},
|
||||
{"", 217, Mapper217_Init}, // Redefined to a new Discrete BMC mapper
|
||||
// {"", 218, Mapper218_Init},
|
||||
{"", 218, Mapper218_Init},
|
||||
{"UNLA9746", 219, UNLA9746_Init},
|
||||
{"Debug Mapper", 220, QTAi_Init},
|
||||
{"UNLN625092", 221, UNLN625092_Init},
|
||||
@@ -710,7 +770,7 @@ BMAPPINGLocal bmap[] = {
|
||||
{"SAN GUO ZHI PIRATE", 252, Mapper252_Init},
|
||||
{"DRAGON BALL PIRATE", 253, Mapper253_Init},
|
||||
{"", 254, Mapper254_Init},
|
||||
// {"", 255, Mapper255_Init}, // No good dumps for this mapper
|
||||
{"", 255, Mapper255_Init}, // dupe of 225
|
||||
|
||||
//-------- Mappers 256-511 is the Supplementary Multilingual Plane ----------
|
||||
//-------- Mappers 512-767 is the Supplementary Ideographic Plane -----------
|
||||
@@ -727,9 +787,12 @@ BMAPPINGLocal bmap[] = {
|
||||
{"F-15 MMC3 Based", 259, BMCF15_Init},
|
||||
{"HP10xx/H20xx Boards", 260, BMCHPxx_Init},
|
||||
{"810544-CA-1", 261, BMC810544CA1_Init},
|
||||
{"SMD132/SMD133", 268, SMD132_SMD133_Init},
|
||||
{"AA6023/AA6023B", 268, AA6023_Init},
|
||||
{"COOLGIRL", 342, COOLGIRL_Init },
|
||||
{"FAM250/81-01-39-C/SCHI-24", 354, Mapper354_Init },
|
||||
|
||||
{"Impact Soft MMC3 Flash Board", 406, Mapper406_Init },
|
||||
{"INX_007T_V01", 470, INX_007T_Init },
|
||||
|
||||
{"KONAMI QTAi Board", 547, QTAi_Init },
|
||||
|
||||
@@ -737,7 +800,10 @@ BMAPPINGLocal bmap[] = {
|
||||
};
|
||||
|
||||
int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
int result;
|
||||
struct md5_context md5;
|
||||
uint64 partialmd5 = 0;
|
||||
const char* mappername = "Not Listed";
|
||||
|
||||
if (FCEU_fread(&head, 1, 16, fp) != 16 || memcmp(&head, "NES\x1A", 4))
|
||||
return LOADER_INVALID_FORMAT;
|
||||
@@ -766,6 +832,9 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
} else
|
||||
Mirroring = (head.ROM_type & 1);
|
||||
|
||||
MirroringAs2bits = head.ROM_type & 1;
|
||||
if (head.ROM_type & 8) MirroringAs2bits |= 2;
|
||||
|
||||
int not_round_size;
|
||||
if (!iNES2) {
|
||||
not_round_size = head.ROM_size;
|
||||
@@ -809,20 +878,64 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL)
|
||||
return 0;
|
||||
ROM = (uint8*)FCEU_malloc(ROM_size << 14);
|
||||
memset(ROM, 0xFF, ROM_size << 14);
|
||||
|
||||
if (VROM_size) {
|
||||
if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) {
|
||||
free(ROM);
|
||||
ROM = NULL;
|
||||
FCEU_PrintError("Unable to allocate memory.");
|
||||
return LOADER_HANDLED_ERROR;
|
||||
}
|
||||
VROM = (uint8*)FCEU_malloc(VROM_size << 13);
|
||||
memset(VROM, 0xFF, VROM_size << 13);
|
||||
}
|
||||
|
||||
// Set Vs. System flag if need
|
||||
if (!iNES2) {
|
||||
GameInfo->type = !(head.ROM_type2 & 1) ? GIT_CART : GIT_VSUNI;
|
||||
}
|
||||
else {
|
||||
switch (!(head.ROM_type2 & 2) ? (head.ROM_type2 & 3) : (head.VS_hardware & 0xF)) {
|
||||
case 0:
|
||||
GameInfo->type = GIT_CART;
|
||||
break;
|
||||
case 1:
|
||||
GameInfo->type = GIT_VSUNI;
|
||||
break;
|
||||
default:
|
||||
FCEU_PrintError("Game type is not supported at all.");
|
||||
goto init_error;
|
||||
}
|
||||
}
|
||||
|
||||
// Set Vs. System PPU type if need
|
||||
if (GameInfo->type == GIT_VSUNI && !(head.ROM_type2 & 2)) {
|
||||
switch (head.VS_hardware & 0xF) {
|
||||
case 0x0: GameInfo->vs_ppu = GIPPU_RC2C03B; break;
|
||||
//case 0x1: GameInfo->vs_ppu = GIPPU_RPC2C03C; break;
|
||||
case 0x2: GameInfo->vs_ppu = GIPPU_RP2C04_0001; break;
|
||||
case 0x3: GameInfo->vs_ppu = GIPPU_RP2C04_0002; break;
|
||||
case 0x4: GameInfo->vs_ppu = GIPPU_RP2C04_0003; break;
|
||||
case 0x5: GameInfo->vs_ppu = GIPPU_RP2C04_0004; break;
|
||||
case 0x6: GameInfo->vs_ppu = GIPPU_RC2C03B; break;
|
||||
//case 0x7: GameInfo->ppu = GIPPU_RPC2C03C; break;
|
||||
case 0x8: GameInfo->vs_ppu = GIPPU_RC2C05_01; break;
|
||||
case 0x9: GameInfo->vs_ppu = GIPPU_RC2C05_02; break;
|
||||
case 0xA: GameInfo->vs_ppu = GIPPU_RC2C05_03; break;
|
||||
case 0xB: GameInfo->vs_ppu = GIPPU_RC2C05_04; break;
|
||||
//case 0xC: GameInfo->ppu = GIPPU_RPC2C05_05; break;
|
||||
default:
|
||||
FCEU_PrintError("Vs. System PPU type is not supported at all.");
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
switch (head.VS_hardware >> 4) {
|
||||
case 0x0: GameInfo->vs_type = EGIVS_NORMAL; break;
|
||||
case 0x1: GameInfo->vs_type = EGIVS_RBI; break;
|
||||
case 0x2: GameInfo->vs_type = EGIVS_TKO; break;
|
||||
case 0x3: GameInfo->vs_type = EGIVS_XEVIOUS; break;
|
||||
default:
|
||||
FCEU_PrintError("Vs. System type is not supported at all.");
|
||||
goto init_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (head.ROM_type & 4) { /* Trainer */
|
||||
trainerpoo = (uint8*)FCEU_gmalloc(512);
|
||||
FCEU_fread(trainerpoo, 512, 1, fp);
|
||||
@@ -838,7 +951,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
if (VROM_size)
|
||||
FCEU_fread(VROM, 0x2000, VROM_size, fp);
|
||||
|
||||
md5_starts(&md5);
|
||||
md5_starts(&md5);
|
||||
md5_update(&md5, ROM, ROM_size << 14);
|
||||
|
||||
iNESGameCRC32 = CalcCRC32(0, ROM, ROM_size << 14);
|
||||
@@ -849,12 +962,14 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
}
|
||||
md5_finish(&md5, iNESCart.MD5);
|
||||
memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5));
|
||||
for (int x = 0; x < 8; x++)
|
||||
partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8);
|
||||
|
||||
iNESCart.CRC32 = iNESGameCRC32;
|
||||
|
||||
FCEU_printf(" PRG ROM: %d x 16KiB = %d KiB\n", round ? ROM_size : not_round_size, (round ? ROM_size : not_round_size) * 16);
|
||||
FCEU_printf(" CHR ROM: %d x 8KiB = %d KiB\n", VROM_size, VROM_size * 8);
|
||||
FCEU_printf(" ROM CRC32: 0x%08lx\n", iNESGameCRC32);
|
||||
FCEU_printf(" ROM CRC32: 0x%08x\n", iNESGameCRC32);
|
||||
{
|
||||
int x;
|
||||
FCEU_printf(" ROM MD5: 0x");
|
||||
@@ -863,9 +978,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
FCEU_printf("\n");
|
||||
}
|
||||
|
||||
const char* mappername = "Not Listed";
|
||||
|
||||
for (int mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) {
|
||||
for (size_t mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) {
|
||||
if (bmap[mappertest].number == MapperNo) {
|
||||
mappername = bmap[mappertest].name;
|
||||
break;
|
||||
@@ -891,17 +1004,12 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
}
|
||||
|
||||
SetInput();
|
||||
CheckHInfo();
|
||||
{
|
||||
int x;
|
||||
uint64 partialmd5 = 0;
|
||||
// Input can be overriden by NES 2.0 header
|
||||
if (iNES2) SetInputNes20(head.expansion);
|
||||
CheckHInfo(partialmd5);
|
||||
FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);
|
||||
CheckBad(partialmd5);
|
||||
|
||||
for (x = 0; x < 8; x++) {
|
||||
partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8);
|
||||
}
|
||||
|
||||
FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);
|
||||
}
|
||||
/* Must remain here because above functions might change value of
|
||||
VROM_size and free(VROM).
|
||||
*/
|
||||
@@ -918,8 +1026,9 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
|
||||
iNESCart.battery = (head.ROM_type & 2) ? 1 : 0;
|
||||
iNESCart.mirror = Mirroring;
|
||||
iNESCart.mirrorAs2Bits = MirroringAs2bits;
|
||||
|
||||
int result = iNES_Init(MapperNo);
|
||||
result = iNES_Init(MapperNo);
|
||||
switch(result)
|
||||
{
|
||||
case 0:
|
||||
@@ -931,6 +1040,8 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
||||
FCEU_PrintError("Unable to allocate CHR-RAM.");
|
||||
break;
|
||||
}
|
||||
|
||||
init_error:
|
||||
if (ROM) free(ROM);
|
||||
if (VROM) free(VROM);
|
||||
if (trainerpoo) free(trainerpoo);
|
||||
@@ -995,7 +1106,7 @@ int iNesSaveAs(const char* name)
|
||||
//caitsith2: done. iNesSave() now gets filename and calls iNesSaveAs with that filename.
|
||||
FILE *fp;
|
||||
|
||||
if (GameInfo->type != GIT_CART) return 0;
|
||||
if ((GameInfo->type != GIT_CART) && (GameInfo->type != GIT_VSUNI)) return 0;
|
||||
if (GameInterface != iNESGI) return 0;
|
||||
|
||||
fp = fopen(name, "wb");
|
||||
|
||||
+23
-13
@@ -25,6 +25,8 @@
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#include "cart.h"
|
||||
|
||||
struct TMasterRomInfo
|
||||
{
|
||||
uint64 md5lower;
|
||||
@@ -43,27 +45,30 @@ extern uint8 *VROM;
|
||||
extern uint32 VROM_size;
|
||||
extern uint32 ROM_size;
|
||||
extern uint8 *ExtraNTARAM;
|
||||
extern uint8 **VPageR;
|
||||
extern int iNesSave(void); //bbit Edited: line added
|
||||
extern int iNesSaveAs(const char* name);
|
||||
extern char LoadedRomFName[2048]; //bbit Edited: line added
|
||||
extern char LoadedRomFName[4096]; //bbit Edited: line added
|
||||
extern char LoadedRomFNamePatchToUse[4096];
|
||||
extern char *iNesShortFName(void);
|
||||
extern const TMasterRomInfo* MasterRomInfo;
|
||||
extern TMasterRomInfoParams MasterRomInfoParams;
|
||||
|
||||
//mbg merge 7/19/06 changed to c++ decl format
|
||||
struct iNES_HEADER {
|
||||
char ID[4]; /*NES^Z*/ // 0-3
|
||||
uint8 ROM_size; // 4
|
||||
uint8 VROM_size; // 5
|
||||
uint8 ROM_type; // 6
|
||||
uint8 ROM_type2; // 7
|
||||
uint8 ROM_type3; // 8
|
||||
uint8 Upper_ROM_VROM_size; // 9
|
||||
uint8 RAM_size; // 10
|
||||
uint8 VRAM_size; // 11
|
||||
uint8 TV_system; // 12
|
||||
uint8 VS_hardware; // 13
|
||||
uint8 reserved[2]; // 14, 15
|
||||
char ID[4]; /*NES^Z*/ // 0-3
|
||||
uint8 ROM_size; // 4
|
||||
uint8 VROM_size; // 5
|
||||
uint8 ROM_type; // 6
|
||||
uint8 ROM_type2; // 7
|
||||
uint8 ROM_type3; // 8
|
||||
uint8 Upper_ROM_VROM_size; // 9
|
||||
uint8 RAM_size; // 10
|
||||
uint8 VRAM_size; // 11
|
||||
uint8 TV_system; // 12
|
||||
uint8 VS_hardware; // 13
|
||||
uint8 misc_roms; // 14
|
||||
uint8 expansion; // 15
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
@@ -242,6 +247,7 @@ void Mapper213_Init(CartInfo *);
|
||||
void Mapper214_Init(CartInfo *);
|
||||
void Mapper216_Init(CartInfo *);
|
||||
void Mapper217_Init(CartInfo *);
|
||||
void Mapper218_Init(CartInfo *);
|
||||
void Mapper220_Init(CartInfo *);
|
||||
void Mapper222_Init(CartInfo *);
|
||||
void Mapper225_Init(CartInfo *);
|
||||
@@ -268,8 +274,12 @@ void Mapper250_Init(CartInfo *);
|
||||
void Mapper252_Init(CartInfo *);
|
||||
void Mapper253_Init(CartInfo *);
|
||||
void Mapper254_Init(CartInfo *);
|
||||
void Mapper255_Init(CartInfo *);
|
||||
void Mapper354_Init(CartInfo *);
|
||||
void Mapper406_Init(CartInfo *);
|
||||
|
||||
void INX_007T_Init(CartInfo* info);
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int32 number;
|
||||
|
||||
+60
-22
@@ -106,6 +106,8 @@ uint8 FCEU_GetJoyJoy(void)
|
||||
}
|
||||
|
||||
extern uint8 coinon;
|
||||
extern uint8 coinon2;
|
||||
extern uint8 service;
|
||||
|
||||
//set to true if the fourscore is attached
|
||||
static bool FSAttached = false;
|
||||
@@ -431,8 +433,11 @@ void FCEU_UpdateInput(void)
|
||||
portFC.driver->Update(portFC.ptr,portFC.attrib);
|
||||
}
|
||||
|
||||
if(GameInfo->type==GIT_VSUNI)
|
||||
if(coinon) coinon--;
|
||||
if (GameInfo->type == GIT_VSUNI) {
|
||||
if (coinon) coinon--;
|
||||
if (coinon2) coinon2--;
|
||||
if (service) service--;
|
||||
}
|
||||
|
||||
if(FCEUnetplay)
|
||||
NetplayUpdate(joy);
|
||||
@@ -454,7 +459,11 @@ static DECLFR(VSUNIRead0)
|
||||
|
||||
ret|=(vsdip&3)<<3;
|
||||
if(coinon)
|
||||
ret|=0x4;
|
||||
ret |= 0x20;
|
||||
if (coinon2)
|
||||
ret |= 0x40;
|
||||
if (service)
|
||||
ret |= 0x04;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -668,7 +677,9 @@ void FCEU_DoSimpleCommand(int cmd)
|
||||
{
|
||||
case FCEUNPCMD_FDSINSERT: FCEU_FDSInsert();break;
|
||||
case FCEUNPCMD_FDSSELECT: FCEU_FDSSelect();break;
|
||||
case FCEUNPCMD_VSUNICOIN: FCEU_VSUniCoin(); break;
|
||||
case FCEUNPCMD_VSUNICOIN: FCEU_VSUniCoin(0); break;
|
||||
case FCEUNPCMD_VSUNICOIN2: FCEU_VSUniCoin(1); break;
|
||||
case FCEUNPCMD_VSUNISERVICE: FCEU_VSUniService(); break;
|
||||
case FCEUNPCMD_VSUNIDIP0:
|
||||
case FCEUNPCMD_VSUNIDIP0+1:
|
||||
case FCEUNPCMD_VSUNIDIP0+2:
|
||||
@@ -726,6 +737,22 @@ void FCEUI_VSUniCoin(void)
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_VSUNICOIN);
|
||||
}
|
||||
|
||||
void FCEUI_VSUniCoin2(void)
|
||||
{
|
||||
if (!FCEU_IsValidUI(FCEUI_INSERT_COIN))
|
||||
return;
|
||||
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_VSUNICOIN2);
|
||||
}
|
||||
|
||||
void FCEUI_VSUniService(void)
|
||||
{
|
||||
if (!FCEU_IsValidUI(FCEUI_INSERT_COIN))
|
||||
return;
|
||||
|
||||
FCEU_QSimpleCommand(FCEUNPCMD_VSUNISERVICE);
|
||||
}
|
||||
|
||||
//Resets the frame counter if movie inactive and rom is reset or power-cycle
|
||||
void ResetFrameCounter()
|
||||
{
|
||||
@@ -798,6 +825,7 @@ static void RamSearchOpLTE(void);
|
||||
static void RamSearchOpGTE(void);
|
||||
static void RamSearchOpEQ(void);
|
||||
static void RamSearchOpNE(void);
|
||||
static void ToggleCheats(void);
|
||||
static void DebuggerStepInto(void);
|
||||
static void FA_SkipLag(void);
|
||||
static void OpenRom(void);
|
||||
@@ -900,17 +928,17 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
|
||||
{ EMUCMD_FDS_EJECT_INSERT, EMUCMDTYPE_FDS, FCEUI_FDSInsert, 0, 0, "Eject or Insert FDS Disk", EMUCMDFLAG_TASEDITOR },
|
||||
{ EMUCMD_FDS_SIDE_SELECT, EMUCMDTYPE_FDS, FCEUI_FDSSelect, 0, 0, "Switch FDS Disk Side", EMUCMDFLAG_TASEDITOR },
|
||||
|
||||
{ EMUCMD_VSUNI_COIN, EMUCMDTYPE_VSUNI, FCEUI_VSUniCoin, 0, 0, "Insert Coin", EMUCMDFLAG_TASEDITOR },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_0, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 0", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_1, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 1", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_2, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 2", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_3, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 3", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_4, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 4", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_5, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 5", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_6, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 6", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_7, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 7", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_8, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 8", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_9, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dipswitch 9", 0 },
|
||||
{ EMUCMD_VSUNI_COIN, EMUCMDTYPE_VSUNI, FCEUI_VSUniCoin, 0, 0, "Insert Coin #1", EMUCMDFLAG_TASEDITOR },
|
||||
{ EMUCMD_VSUNI_COIN_2, EMUCMDTYPE_VSUNI, FCEUI_VSUniCoin2, 0, 0, "Insert Coin #2", EMUCMDFLAG_TASEDITOR },
|
||||
{ EMUCMD_VSUNI_SERVICE_BUTTON, EMUCMDTYPE_VSUNI, FCEUI_VSUniService, 0, 0, "Service Button", EMUCMDFLAG_TASEDITOR },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_0, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 0", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_1, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 1", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_2, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 2", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_3, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 3", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_4, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 4", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_5, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 5", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_6, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 6", 0 },
|
||||
{ EMUCMD_VSUNI_TOGGLE_DIP_7, EMUCMDTYPE_VSUNI, CommandToggleDip, 0, 0, "Toggle Dip Switch 7", 0 },
|
||||
|
||||
{ EMUCMD_MISC_AUTOSAVE, EMUCMDTYPE_MISC, FCEUI_RewindToLastAutosave, 0, 0, "Load Last Auto-save", 0},
|
||||
{ EMUCMD_MISC_SHOWSTATES, EMUCMDTYPE_MISC, ViewSlots, 0, 0, "View save slots", 0 },
|
||||
@@ -945,6 +973,7 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
|
||||
{ EMUCMD_TOOL_RAMSEARCHGTE, EMUCMDTYPE_TOOL, RamSearchOpGTE, 0, 0, "Ram Search - Greater Than or Equal", 0},
|
||||
{ EMUCMD_TOOL_RAMSEARCHEQ, EMUCMDTYPE_TOOL, RamSearchOpEQ, 0, 0, "Ram Search - Equal", 0},
|
||||
{ EMUCMD_TOOL_RAMSEARCHNE, EMUCMDTYPE_TOOL, RamSearchOpNE, 0, 0, "Ram Search - Not Equal", 0},
|
||||
{ EMUCMD_TOOL_TOGGLECHEATS, EMUCMDTYPE_TOOL, ToggleCheats, 0, 0, "Toggle Cheats", 0},
|
||||
{ EMUCMD_RERECORD_DISPLAY_TOGGLE, EMUCMDTYPE_MISC, FCEUI_MovieToggleRerecordDisplay,0, 0, "Toggle Rerecord Display", EMUCMDFLAG_TASEDITOR },
|
||||
|
||||
{ EMUCMD_TASEDITOR_REWIND, EMUCMDTYPE_TASEDITOR, TaseditorRewindOn, TaseditorRewindOff, 0, "Frame Rewind", EMUCMDFLAG_TASEDITOR },
|
||||
@@ -960,12 +989,12 @@ struct EMUCMDTABLE FCEUI_CommandTable[]=
|
||||
|
||||
#define NUM_EMU_CMDS (sizeof(FCEUI_CommandTable)/sizeof(FCEUI_CommandTable[0]))
|
||||
|
||||
static int execcmd, i;
|
||||
static int execcmd;
|
||||
|
||||
void FCEUI_HandleEmuCommands(TestCommandState* testfn)
|
||||
{
|
||||
bool taseditor = FCEUMOV_Mode(MOVIEMODE_TASEDITOR);
|
||||
for(i=0; i<NUM_EMU_CMDS; ++i)
|
||||
for(size_t i=0; i<NUM_EMU_CMDS; ++i)
|
||||
{
|
||||
int new_state;
|
||||
int old_state = FCEUI_CommandTable[i].state;
|
||||
@@ -1268,6 +1297,18 @@ static void RamSearchOpNE(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int globalCheatDisabled;
|
||||
extern unsigned int FrozenAddressCount;
|
||||
static void ToggleCheats()
|
||||
{
|
||||
FCEUI_GlobalToggleCheat(globalCheatDisabled);
|
||||
FCEU_DispMessage("%d cheats active", 0, FrozenAddressCount);
|
||||
#ifdef __WIN_DRIVER__
|
||||
UpdateCheatRelatedWindow();
|
||||
UpdateCheatListGroupBoxUI();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DebuggerStepInto()
|
||||
{
|
||||
#ifdef __WIN_DRIVER__
|
||||
@@ -1324,10 +1365,7 @@ static void MovieSubtitleToggle(void)
|
||||
|
||||
static void UndoRedoSavestate(void)
|
||||
{
|
||||
// FIXME this will always evaluate to true, should this be
|
||||
// if (*lastSavestateMade...) to check if it holds a string or just
|
||||
// a '\0'?
|
||||
if (lastSavestateMade && (undoSS || redoSS))
|
||||
if ( !lastSavestateMade.empty() && (undoSS || redoSS))
|
||||
SwapSaveState();
|
||||
}
|
||||
|
||||
@@ -1380,7 +1418,7 @@ static void TaseditorCommand(void)
|
||||
**/
|
||||
EMUCMDTABLE* GetEmuCommandById(int cmd)
|
||||
{
|
||||
for (i = 0; i<NUM_EMU_CMDS; ++i)
|
||||
for (size_t i = 0; i<NUM_EMU_CMDS; ++i)
|
||||
{
|
||||
if (FCEUI_CommandTable[i].cmd == cmd)
|
||||
return &FCEUI_CommandTable[i];
|
||||
|
||||
+4
-2
@@ -197,8 +197,8 @@ enum EMUCMD
|
||||
EMUCMD_VSUNI_TOGGLE_DIP_5,
|
||||
EMUCMD_VSUNI_TOGGLE_DIP_6,
|
||||
EMUCMD_VSUNI_TOGGLE_DIP_7,
|
||||
EMUCMD_VSUNI_TOGGLE_DIP_8,
|
||||
EMUCMD_VSUNI_TOGGLE_DIP_9,
|
||||
EMUCMD_VSUNI_COIN_2,
|
||||
EMUCMD_VSUNI_SERVICE_BUTTON,
|
||||
EMUCMD_MISC_AUTOSAVE,
|
||||
EMUCMD_MISC_SHOWSTATES,
|
||||
EMUCMD_MISC_USE_INPUT_PRESET_1,
|
||||
@@ -259,6 +259,8 @@ enum EMUCMD
|
||||
EMUCMD_MOVIE_RECORD_MODE_OVERWRITE,
|
||||
EMUCMD_MOVIE_RECORD_MODE_INSERT,
|
||||
|
||||
EMUCMD_TOOL_TOGGLECHEATS,
|
||||
|
||||
EMUCMD_MAX
|
||||
};
|
||||
|
||||
|
||||
+189
-31
@@ -24,6 +24,7 @@
|
||||
#include "file.h"
|
||||
#include "video.h"
|
||||
#include "debug.h"
|
||||
#include "debugsymboltable.h"
|
||||
#include "sound.h"
|
||||
#include "drawing.h"
|
||||
#include "state.h"
|
||||
@@ -54,6 +55,9 @@ extern TASEDITOR_LUA taseditor_lua;
|
||||
#ifdef __SDL__
|
||||
|
||||
#ifdef __QT_DRIVER__
|
||||
#include "drivers/Qt/sdl.h"
|
||||
#include "drivers/Qt/main.h"
|
||||
#include "drivers/Qt/input.h"
|
||||
#include "drivers/Qt/fceuWrapper.h"
|
||||
#include "drivers/Qt/TasEditor/selection.h"
|
||||
#include "drivers/Qt/TasEditor/laglog.h"
|
||||
@@ -182,10 +186,13 @@ struct LuaSaveState {
|
||||
persisted = true;
|
||||
FILE* inf = fopen(filename.c_str(),"rb");
|
||||
fseek(inf,0,SEEK_END);
|
||||
int len = ftell(inf);
|
||||
long int len = ftell(inf);
|
||||
fseek(inf,0,SEEK_SET);
|
||||
data = new EMUFILE_MEMORY(len);
|
||||
fread(data->buf(),1,len,inf);
|
||||
if ( fread(data->buf(),1,len,inf) != static_cast<size_t>(len) )
|
||||
{
|
||||
FCEU_printf("Warning: LuaSaveState::ensureLoad failed to load full buffer.\n");
|
||||
}
|
||||
fclose(inf);
|
||||
}
|
||||
};
|
||||
@@ -250,7 +257,7 @@ static const char *guiCallbackTable = "FCEU.GUI";
|
||||
static int frameAdvanceWaiting = FALSE;
|
||||
|
||||
// We save our pause status in the case of a natural death.
|
||||
static int wasPaused = FALSE;
|
||||
//static int wasPaused = FALSE;
|
||||
|
||||
// Transparency strength. 255=opaque, 0=so transparent it's invisible
|
||||
static int transparencyModifier = 255;
|
||||
@@ -656,12 +663,11 @@ static int emu_loadrom(lua_State *L)
|
||||
return 0;
|
||||
#elif defined(__QT_DRIVER__)
|
||||
const char *nameo2 = luaL_checkstring(L,1);
|
||||
char nameo[2048];
|
||||
std::string nameo;
|
||||
|
||||
strncpy(nameo, nameo2, sizeof(nameo));
|
||||
nameo[sizeof(nameo)-1] = 0;
|
||||
nameo.assign( nameo2 );
|
||||
|
||||
LoadGameFromLua( nameo );
|
||||
LoadGameFromLua( nameo.c_str() );
|
||||
|
||||
//lua_cpcall(L, emu_wait_for_rom_load, NULL);
|
||||
//printf("Attempting to Load ROM: '%s'\n", nameo );
|
||||
@@ -743,7 +749,7 @@ static int emu_addgamegenie(lua_State *L) {
|
||||
|
||||
while (FCEUI_GetCheat(i,NULL,&Caddr,&Cval,&Ccompare,NULL,&Ctype)) {
|
||||
|
||||
if ((GGaddr == Caddr) && (GGval == Cval) && (GGcomp == Ccompare) && (Ctype == 1)) {
|
||||
if ((static_cast<uint32>(GGaddr) == Caddr) && (GGval == static_cast<int>(Cval)) && (GGcomp == Ccompare) && (Ctype == 1)) {
|
||||
// Already Added, so consider it a success
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
@@ -773,7 +779,7 @@ static int emu_delgamegenie(lua_State *L) {
|
||||
int GGaddr, GGcomp, GGval;
|
||||
uint32 i=0;
|
||||
|
||||
char * Cname;
|
||||
std::string Cname;
|
||||
uint32 Caddr;
|
||||
uint8 Cval;
|
||||
int Ccompare, Ctype;
|
||||
@@ -786,7 +792,7 @@ static int emu_delgamegenie(lua_State *L) {
|
||||
|
||||
while (FCEUI_GetCheat(i,&Cname,&Caddr,&Cval,&Ccompare,NULL,&Ctype)) {
|
||||
|
||||
if ((!strcmp(msg,Cname)) && (GGaddr == Caddr) && (GGval == Cval) && (GGcomp == Ccompare) && (Ctype == 1)) {
|
||||
if ((Cname == msg) && (static_cast<uint32>(GGaddr) == Caddr) && (GGval == static_cast<int>(Cval)) && (GGcomp == Ccompare) && (Ctype == 1)) {
|
||||
// Delete cheat code
|
||||
if (FCEUI_DelCheat(i)) {
|
||||
lua_pushboolean(L, true);
|
||||
@@ -1302,7 +1308,10 @@ void freadint(unsigned int& value, FILE* file)
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
int r = 0;
|
||||
fread(&r, 1, 1, file);
|
||||
if ( fread(&r, 1, 1, file) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
rv |= r << (i*8);
|
||||
}
|
||||
value = rv;
|
||||
@@ -1346,7 +1355,10 @@ void LuaSaveData::ImportRecords(void* fileV)
|
||||
break;
|
||||
|
||||
cur->data = new unsigned char [cur->size];
|
||||
fread(cur->data, cur->size, 1, file);
|
||||
if ( fread(cur->data, cur->size, 1, file) == 0 )
|
||||
{
|
||||
memset( cur->data, 0, cur->size );
|
||||
}
|
||||
|
||||
Record* next = new Record();
|
||||
memcpy(next, cur, sizeof(Record));
|
||||
@@ -1632,7 +1644,7 @@ static void toCStringConverter(lua_State* L, int i, char*& ptr, int& remaining)
|
||||
if(remaining <= 0)
|
||||
return;
|
||||
|
||||
const char* str = ptr; // for debugging
|
||||
//const char* str = ptr; // for debugging
|
||||
|
||||
// if there is a __tostring metamethod then call it
|
||||
int usedMeta = luaL_callmeta(L, i, "__tostring");
|
||||
@@ -1994,7 +2006,7 @@ static int memory_getregister(lua_State *L)
|
||||
{
|
||||
const char* qualifiedRegisterName = luaL_checkstring(L,1);
|
||||
lua_settop(L,0);
|
||||
for(int cpu = 0; cpu < sizeof(cpuToRegisterMaps)/sizeof(*cpuToRegisterMaps); cpu++)
|
||||
for(size_t cpu = 0; cpu < sizeof(cpuToRegisterMaps)/sizeof(*cpuToRegisterMaps); cpu++)
|
||||
{
|
||||
cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu];
|
||||
int cpuNameLen = strlen(ctrm.cpuName);
|
||||
@@ -2028,7 +2040,7 @@ static int memory_setregister(lua_State *L)
|
||||
const char* qualifiedRegisterName = luaL_checkstring(L,1);
|
||||
unsigned long value = (unsigned long)(luaL_checkinteger(L,2));
|
||||
lua_settop(L,0);
|
||||
for(int cpu = 0; cpu < sizeof(cpuToRegisterMaps)/sizeof(*cpuToRegisterMaps); cpu++)
|
||||
for(size_t cpu = 0; cpu < sizeof(cpuToRegisterMaps)/sizeof(*cpuToRegisterMaps); cpu++)
|
||||
{
|
||||
cpuToRegisterMap ctrm = cpuToRegisterMaps[cpu];
|
||||
int cpuNameLen = strlen(ctrm.cpuName);
|
||||
@@ -2244,7 +2256,7 @@ static void CallRegisteredLuaMemHook_LuaMatch(unsigned int address, int size, un
|
||||
#endif
|
||||
lua_settop(L, 0);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, luaMemHookTypeStrings[hookType]);
|
||||
for(int i = address; i != address+size; i++)
|
||||
for(unsigned int i = address; i != address+size; i++)
|
||||
{
|
||||
lua_rawgeti(L, -1, i);
|
||||
if (lua_isfunction(L, -1))
|
||||
@@ -2448,6 +2460,7 @@ LuaMemHookType MatchHookTypeToCPU(lua_State* L, LuaMemHookType hookType)
|
||||
case LUAMEMHOOK_WRITE: return LUAMEMHOOK_WRITE_SUB;
|
||||
case LUAMEMHOOK_READ: return LUAMEMHOOK_READ_SUB;
|
||||
case LUAMEMHOOK_EXEC: return LUAMEMHOOK_EXEC_SUB;
|
||||
default: return hookType;
|
||||
}
|
||||
}
|
||||
return hookType;
|
||||
@@ -2457,6 +2470,7 @@ static int memory_registerwrite(lua_State *L)
|
||||
{
|
||||
return memory_registerHook(L, MatchHookTypeToCPU(L,LUAMEMHOOK_WRITE), 1);
|
||||
}
|
||||
FCEU_MAYBE_UNUSED
|
||||
static int memory_registerread(lua_State *L)
|
||||
{
|
||||
return memory_registerHook(L, MatchHookTypeToCPU(L,LUAMEMHOOK_READ), 1);
|
||||
@@ -2638,6 +2652,112 @@ static int input_get(lua_State *L) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(__QT_DRIVER__)
|
||||
// Qt/SDL
|
||||
{
|
||||
const uint8_t *keyBuf = QtSDL_getKeyboardState(nullptr);
|
||||
|
||||
if (keyBuf)
|
||||
{
|
||||
char keyName[64];
|
||||
const char *keyOut = nullptr;
|
||||
|
||||
for (int i=0; i<SDL_NUM_SCANCODES; i++)
|
||||
{
|
||||
if (keyBuf[i])
|
||||
{
|
||||
SDL_Keycode k = SDL_GetKeyFromScancode( static_cast<SDL_Scancode>(i) );
|
||||
|
||||
const char* name = SDL_GetKeyName(k);
|
||||
|
||||
//printf("Key:%i '%s'\n", i, name);
|
||||
|
||||
if ( isalpha(name[0]) || isdigit(name[0]) )
|
||||
{ // If name starts with letters or number, copy name without spaces
|
||||
int ii=0, jj=0;
|
||||
while (name[ii] != 0)
|
||||
{
|
||||
if ( isalpha(name[ii]) || isdigit(name[ii]) || (name[ii] == '_') )
|
||||
{
|
||||
keyName[jj] = name[ii]; jj++;
|
||||
}
|
||||
ii++;
|
||||
}
|
||||
keyName[jj] = 0;
|
||||
|
||||
keyOut = keyName;
|
||||
}
|
||||
else
|
||||
{ // Handle special char names
|
||||
switch (name[0])
|
||||
{
|
||||
case '[':
|
||||
keyOut = "LeftBracket";
|
||||
break;
|
||||
case ']':
|
||||
keyOut = "RightBracket";
|
||||
break;
|
||||
case '{':
|
||||
keyOut = "LeftBrace";
|
||||
break;
|
||||
case '}':
|
||||
keyOut = "RightBrace";
|
||||
break;
|
||||
case ',':
|
||||
keyOut = "Comma";
|
||||
break;
|
||||
case '.':
|
||||
keyOut = "Period";
|
||||
break;
|
||||
case '~':
|
||||
keyOut = "Tilde";
|
||||
break;
|
||||
case '`':
|
||||
keyOut = "Backtick";
|
||||
break;
|
||||
case '|':
|
||||
keyOut = "VerticalBar";
|
||||
break;
|
||||
case '/':
|
||||
keyOut = "Slash";
|
||||
break;
|
||||
case '\\':
|
||||
keyOut = "BackSlash";
|
||||
break;
|
||||
case '+':
|
||||
keyOut = "Plus";
|
||||
break;
|
||||
case '=':
|
||||
keyOut = "Equals";
|
||||
break;
|
||||
case '_':
|
||||
keyOut = "Underscore";
|
||||
break;
|
||||
case '-':
|
||||
keyOut = "Minus";
|
||||
break;
|
||||
case ';':
|
||||
keyOut = "SemiColon";
|
||||
break;
|
||||
case ':':
|
||||
keyOut = "Colon";
|
||||
break;
|
||||
case '\'':
|
||||
case '\"':
|
||||
keyOut = "Quote";
|
||||
break;
|
||||
default:
|
||||
keyOut = name;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, -2, keyOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
//SDL TODO: implement this for keyboard!!
|
||||
#endif
|
||||
@@ -3117,11 +3237,10 @@ static int savestate_loadscriptdata(lua_State *L) {
|
||||
{
|
||||
LuaSaveData saveData;
|
||||
|
||||
char luaSaveFilename [512];
|
||||
strncpy(luaSaveFilename, filename, 512);
|
||||
luaSaveFilename[512-(1+7/*strlen(".luasav")*/)] = '\0';
|
||||
strcat(luaSaveFilename, ".luasav");
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename, "rb");
|
||||
std::string luaSaveFilename;
|
||||
luaSaveFilename.assign( filename );
|
||||
luaSaveFilename.append( ".luasav");
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename.c_str(), "rb");
|
||||
if(luaSaveFile)
|
||||
{
|
||||
saveData.ImportRecords(luaSaveFile);
|
||||
@@ -3743,7 +3862,7 @@ static inline bool str2colour(uint32 *colour, lua_State *L, const char *str) {
|
||||
*colour = ((rand()*255/RAND_MAX) << 8) | ((rand()*255/RAND_MAX) << 16) | ((rand()*255/RAND_MAX) << 24) | 0xFF;
|
||||
return true;
|
||||
}
|
||||
for(int i = 0; i < sizeof(s_colorMapping)/sizeof(*s_colorMapping); i++) {
|
||||
for(size_t i = 0; i < sizeof(s_colorMapping)/sizeof(*s_colorMapping); i++) {
|
||||
if(!stricmp(str,s_colorMapping[i].name)) {
|
||||
*colour = s_colorMapping[i].value;
|
||||
return true;
|
||||
@@ -3779,7 +3898,6 @@ static inline uint32 gui_getcolour_wrapped(lua_State *L, int offset, bool hasDef
|
||||
lua_pushnil(L); // first key
|
||||
int keyIndex = lua_gettop(L);
|
||||
int valueIndex = keyIndex + 1;
|
||||
bool first = true;
|
||||
while(lua_next(L, offset))
|
||||
{
|
||||
bool keyIsString = (lua_type(L, keyIndex) == LUA_TSTRING);
|
||||
@@ -3985,6 +4103,7 @@ static int gui_box(lua_State *L) {
|
||||
}
|
||||
|
||||
// (old) gui.box(x1, y1, x2, y2, color)
|
||||
FCEU_MAYBE_UNUSED
|
||||
static int gui_box_old(lua_State *L) {
|
||||
|
||||
int x1,y1,x2,y2;
|
||||
@@ -4314,6 +4433,7 @@ draw_outline:
|
||||
}
|
||||
}
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static int strlinelen(const char* string)
|
||||
{
|
||||
const char* s = string;
|
||||
@@ -4324,6 +4444,7 @@ static int strlinelen(const char* string)
|
||||
return s - string;
|
||||
}
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static void LuaDisplayString (const char *string, int y, int x, uint32 color, uint32 outlineColor)
|
||||
{
|
||||
if(!string)
|
||||
@@ -4491,7 +4612,7 @@ void LuaDrawTextTransWH(const char *str, size_t l, int &x, int y, uint32 color,
|
||||
return;
|
||||
|
||||
size_t len = l;
|
||||
int defaultAlpha = std::max<int>(0, std::min<int>(transparencyModifier, 255));
|
||||
//int defaultAlpha = std::max<int>(0, std::min<int>(transparencyModifier, 255));
|
||||
int diffx;
|
||||
int diffy = std::max<int>(0, std::min<int>(7, LUA_SCREEN_HEIGHT - y));
|
||||
|
||||
@@ -4560,7 +4681,7 @@ void LuaDrawTextTransWH(const char *str, size_t l, int &x, int y, uint32 color,
|
||||
// main HUD.
|
||||
static int gui_text(lua_State *L) {
|
||||
|
||||
extern int font_height;
|
||||
//extern int font_height;
|
||||
const char *msg;
|
||||
int x, y;
|
||||
size_t l;
|
||||
@@ -4957,6 +5078,27 @@ static int debugger_resetinstructionscount(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// debugger.getsymboloffset()
|
||||
static int debugger_getsymboloffset(lua_State *L)
|
||||
{
|
||||
debugSymbol_t *sym = NULL;
|
||||
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
int bank = luaL_checkinteger(L, 2);
|
||||
sym = debugSymbolTable.getSymbol(bank, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
sym = debugSymbolTable.getSymbolAtAnyBank(name);
|
||||
}
|
||||
|
||||
lua_pushinteger(L, sym ? sym->offset() : -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TAS Editor functions library
|
||||
|
||||
// bool taseditor.registerauto()
|
||||
@@ -4978,7 +5120,7 @@ static int taseditor_registermanual(lua_State *L)
|
||||
if (!lua_isnil(L,1))
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
|
||||
const char* caption = NULL;
|
||||
FCEU_MAYBE_UNUSED const char* caption = NULL;
|
||||
if (!lua_isnil(L, 2))
|
||||
caption = lua_tostring(L, 2);
|
||||
|
||||
@@ -5364,10 +5506,10 @@ static int doPopup(lua_State *L, const char* deftype, const char* deficon) {
|
||||
assert(iicon >= 0 && iicon <= 3);
|
||||
if(!(iicon >= 0 && iicon <= 3)) iicon = 0;
|
||||
|
||||
#ifdef __WIN_DRIVER__
|
||||
static const char * const titles [] = {"Notice", "Question", "Warning", "Error"};
|
||||
const char* answer = "ok";
|
||||
|
||||
#ifdef __WIN_DRIVER__
|
||||
static const int etypes [] = {MB_OK, MB_YESNO, MB_YESNOCANCEL, MB_OKCANCEL, MB_ABORTRETRYIGNORE};
|
||||
static const int eicons [] = {MB_ICONINFORMATION, MB_ICONQUESTION, MB_ICONWARNING, MB_ICONERROR};
|
||||
//StopSound(); //mbg merge 7/27/08
|
||||
@@ -5512,13 +5654,20 @@ use_console:
|
||||
// We don't want parameters
|
||||
if (!t[0]) {
|
||||
fprintf(stderr, "[Press Enter]");
|
||||
fgets(buffer, sizeof(buffer), stdin);
|
||||
if ( fgets(buffer, sizeof(buffer), stdin) == nullptr )
|
||||
{
|
||||
FCEU_printf("Error: fgets from stdin failed\n");
|
||||
}
|
||||
// We're done
|
||||
return 0;
|
||||
|
||||
}
|
||||
fprintf(stderr, "(%s): ", t);
|
||||
fgets(buffer, sizeof(buffer), stdin);
|
||||
if ( fgets(buffer, sizeof(buffer), stdin) == nullptr )
|
||||
{
|
||||
FCEU_printf("Error: fgets from stdin failed\n");
|
||||
buffer[0] = 0;
|
||||
}
|
||||
|
||||
// Check if the option is in the list
|
||||
if (strchr(t, tolower(buffer[0]))) {
|
||||
@@ -5571,7 +5720,11 @@ static int doOpenFilePopup(lua_State *L, bool saveFile) {
|
||||
// TODO: more sophisticated interface
|
||||
char filename[PATH_MAX];
|
||||
printf("Enter %s filename: ", saveFile ? "save" : "open");
|
||||
fgets(filename, PATH_MAX, stdin);
|
||||
if ( fgets(filename, PATH_MAX, stdin) == nullptr )
|
||||
{
|
||||
FCEU_printf("Warning: fgets from stdin failed\n");
|
||||
filename[0] = 0;
|
||||
}
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, filename);
|
||||
lua_rawseti(L, -2, 1);
|
||||
@@ -5802,6 +5955,7 @@ static int bitbit(lua_State *L)
|
||||
}
|
||||
|
||||
// The function called periodically to ensure Lua doesn't run amok.
|
||||
FCEU_MAYBE_UNUSED
|
||||
static void FCEU_LuaHookFunction(lua_State *L, lua_Debug *dbg) {
|
||||
|
||||
if (numTries-- == 0) {
|
||||
@@ -6127,6 +6281,7 @@ static const struct luaL_reg debuggerlib[] = {
|
||||
{"getinstructionscount", debugger_getinstructionscount},
|
||||
{"resetcyclescount", debugger_resetcyclescount},
|
||||
{"resetinstructionscount", debugger_resetinstructionscount},
|
||||
{"getsymboloffset", debugger_getsymboloffset},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
@@ -6288,7 +6443,10 @@ int FCEU_LoadLuaCode(const char *filename, const char *arg)
|
||||
|
||||
getfilepath = getfilepath.substr(0,getfilepath.find_last_of("/\\") + 1);
|
||||
|
||||
SetCurrentDir(getfilepath.c_str());
|
||||
if ( SetCurrentDir(getfilepath.c_str()) != 0 )
|
||||
{
|
||||
FCEU_printf("Warning: Failed chdir failed to set current dir to: %s\n", getfilepath.c_str() );
|
||||
}
|
||||
|
||||
//stop any lua we might already have had running
|
||||
FCEU_LuaStop();
|
||||
|
||||
+36
-22
@@ -114,7 +114,7 @@ SFORMAT FCEUMOV_STATEINFO[]={
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
char curMovieFilename[512] = {0};
|
||||
std::string curMovieFilename;
|
||||
MovieData currMovieData;
|
||||
MovieData defaultMovieData;
|
||||
int currRerecordCount; // Keep the global value
|
||||
@@ -409,6 +409,7 @@ MovieData::MovieData()
|
||||
, rerecordCount(0)
|
||||
, binaryFlag(false)
|
||||
, loadFrameCount(-1)
|
||||
, fourscore(false)
|
||||
, microphone(false)
|
||||
, RAMInitOption(0)
|
||||
, RAMInitSeed(0)
|
||||
@@ -692,7 +693,7 @@ bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader)
|
||||
{
|
||||
LoadFM2_binarychunk(movieData, fp, size);
|
||||
return true;
|
||||
} else if (isnewline && movieData.loadFrameCount == movieData.records.size())
|
||||
} else if (isnewline && static_cast<size_t>(movieData.loadFrameCount) == movieData.records.size())
|
||||
// exit prematurely if loaded the specified amound of records
|
||||
return true;
|
||||
switch(state)
|
||||
@@ -806,7 +807,10 @@ static EMUFILE *openRecordingMovie(const char* fname)
|
||||
FCEU_PrintError("Error opening movie output file: %s", fname);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(curMovieFilename, fname);
|
||||
if ( fname != curMovieFilename.c_str() )
|
||||
{
|
||||
curMovieFilename.assign(fname);
|
||||
}
|
||||
|
||||
return osRecordingMovie;
|
||||
}
|
||||
@@ -826,7 +830,7 @@ static void RedumpWholeMovieFile(bool justToggledRecording = false)
|
||||
bool recording = (movieMode == MOVIEMODE_RECORD);
|
||||
assert((NULL != osRecordingMovie) == (recording != justToggledRecording) && "osRecordingMovie should be consistent with movie mode!");
|
||||
|
||||
if (NULL == openRecordingMovie(curMovieFilename))
|
||||
if (NULL == openRecordingMovie(curMovieFilename.c_str()))
|
||||
return;
|
||||
|
||||
currMovieData.dump(osRecordingMovie, false/*currMovieData.binaryFlag*/, recording);
|
||||
@@ -874,7 +878,7 @@ static void OnMovieClosed()
|
||||
{
|
||||
assert(movieMode == MOVIEMODE_INACTIVE);
|
||||
|
||||
curMovieFilename[0] = 0; //No longer a current movie filename
|
||||
curMovieFilename.clear(); //No longer a current movie filename
|
||||
freshMovie = false; //No longer a fresh movie loaded
|
||||
if (bindSavestate) AutoSS = false; //If bind movies to savestates is true, then there is no longer a valid auto-save to load
|
||||
|
||||
@@ -990,7 +994,7 @@ bool MovieData::loadSaveramFrom(std::vector<uint8>* buf)
|
||||
return false;
|
||||
}
|
||||
|
||||
if(currCartInfo->SaveGameLen[i] != len)
|
||||
if(currCartInfo->SaveGameLen[i] != static_cast<unsigned int>(len))
|
||||
{
|
||||
FCEU_PrintError("movie battery load mismatch 3");
|
||||
return false;
|
||||
@@ -1039,7 +1043,7 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
|
||||
|
||||
currMovieData = MovieData();
|
||||
|
||||
strcpy(curMovieFilename, fname);
|
||||
curMovieFilename.assign(fname);
|
||||
FCEUFILE *fp = FCEU_fopen(fname,0,"rb",0);
|
||||
if (!fp) return false;
|
||||
if(fp->isArchive() && !_read_only) {
|
||||
@@ -1220,7 +1224,11 @@ void FCEUMOV_AddInputState()
|
||||
if (mr->command_fds_select())
|
||||
FCEU_FDSSelect();
|
||||
if (mr->command_vs_insertcoin())
|
||||
FCEU_VSUniCoin();
|
||||
FCEU_VSUniCoin(0);
|
||||
if (mr->command_vs_insertcoin2())
|
||||
FCEU_VSUniCoin(1);
|
||||
if (mr->command_vs_service())
|
||||
FCEU_VSUniService();
|
||||
_currCommand = 0;
|
||||
} else
|
||||
#endif
|
||||
@@ -1248,14 +1256,18 @@ void FCEUMOV_AddInputState()
|
||||
if(mr->command_fds_select())
|
||||
FCEU_FDSSelect();
|
||||
if (mr->command_vs_insertcoin())
|
||||
FCEU_VSUniCoin();
|
||||
FCEU_VSUniCoin(0);
|
||||
if (mr->command_vs_insertcoin2())
|
||||
FCEU_VSUniCoin(1);
|
||||
if (mr->command_vs_service())
|
||||
FCEU_VSUniService();
|
||||
|
||||
joyports[0].load(mr);
|
||||
joyports[1].load(mr);
|
||||
}
|
||||
|
||||
//if we are on the last frame, then pause the emulator if the player requested it
|
||||
if (currFrameCounter == currMovieData.records.size()-1)
|
||||
if ( static_cast<size_t>(currFrameCounter) == currMovieData.records.size()-1)
|
||||
{
|
||||
if(FCEUD_PauseAfterPlayback())
|
||||
{
|
||||
@@ -1326,6 +1338,8 @@ void FCEUMOV_AddCommand(int cmd)
|
||||
case FCEUNPCMD_FDSINSERT: cmd = MOVIECMD_FDS_INSERT; break;
|
||||
case FCEUNPCMD_FDSSELECT: cmd = MOVIECMD_FDS_SELECT; break;
|
||||
case FCEUNPCMD_VSUNICOIN: cmd = MOVIECMD_VS_INSERTCOIN; break;
|
||||
case FCEUNPCMD_VSUNICOIN2: cmd = MOVIECMD_VS_INSERTCOIN2; break;
|
||||
case FCEUNPCMD_VSUNISERVICE: cmd = MOVIECMD_VS_SERVICE; break;
|
||||
// all other netplay commands (e.g. FCEUNPCMD_VSUNIDIP0) are not supported by movie recorder for now
|
||||
default: return;
|
||||
}
|
||||
@@ -1434,7 +1448,7 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
|
||||
#endif
|
||||
movie_readonly = true;
|
||||
}
|
||||
if (FCEU_isFileInArchive(curMovieFilename))
|
||||
if (FCEU_isFileInArchive(curMovieFilename.c_str()))
|
||||
{
|
||||
//a little rule: cant load states in read+write mode with a movie from an archive.
|
||||
//so we are going to switch it to readonly mode in that case
|
||||
@@ -1569,10 +1583,10 @@ bool FCEUMOV_ReadState(EMUFILE* is, uint32 size)
|
||||
//TODO: turn frame counter to red to get attention
|
||||
if (!backupSavestates) //If backups are disabled we can just resume normally since we can't restore so stop movie and inform user
|
||||
{
|
||||
FCEU_PrintError("Error: Savestate taken from a frame (%d) after the final frame in the savestated movie (%d) cannot be verified against current movie (%d). This is not permitted.\nUnable to restore backup, movie playback stopped.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
|
||||
FCEU_PrintError("Error: Savestate taken from a frame (%d) after the final frame in the savestated movie (%zi) cannot be verified against current movie (%zi). This is not permitted.\nUnable to restore backup, movie playback stopped.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
|
||||
FCEUI_StopMovie();
|
||||
} else
|
||||
FCEU_PrintError("Savestate taken from a frame (%d) after the final frame in the savestated movie (%d) cannot be verified against current movie (%d). This is not permitted.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
|
||||
FCEU_PrintError("Savestate taken from a frame (%d) after the final frame in the savestated movie (%zi) cannot be verified against current movie (%zi). This is not permitted.", currFrameCounter, tempMovieData.records.size() - 1, currMovieData.records.size() - 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1728,7 +1742,7 @@ void FCEUI_MovieToggleReadOnly()
|
||||
strcpy(message, "Movie is now Read+Write");
|
||||
|
||||
strcat(message, GetMovieModeStr());
|
||||
FCEU_DispMessage(message,0);
|
||||
FCEU_DispMessage("%s",0,message);
|
||||
}
|
||||
|
||||
void FCEUI_MovieToggleRecording()
|
||||
@@ -1772,7 +1786,7 @@ void FCEUI_MovieToggleRecording()
|
||||
|
||||
strcat(message, GetMovieModeStr());
|
||||
|
||||
FCEU_DispMessage(message, 0);
|
||||
FCEU_DispMessage("%s",0,message);
|
||||
}
|
||||
|
||||
void FCEUI_MovieInsertFrame()
|
||||
@@ -1799,7 +1813,7 @@ void FCEUI_MovieInsertFrame()
|
||||
strcat(message, GetMovieModeStr());
|
||||
}
|
||||
|
||||
FCEU_DispMessage(message, 0);
|
||||
FCEU_DispMessage("%s",0,message);
|
||||
}
|
||||
|
||||
void FCEUI_MovieDeleteFrame()
|
||||
@@ -1837,7 +1851,7 @@ void FCEUI_MovieDeleteFrame()
|
||||
strcat(message, GetMovieModeStr());
|
||||
}
|
||||
|
||||
FCEU_DispMessage(message, 0);
|
||||
FCEU_DispMessage("%s",0,message);
|
||||
}
|
||||
|
||||
void FCEUI_MovieTruncate()
|
||||
@@ -1875,7 +1889,7 @@ void FCEUI_MovieTruncate()
|
||||
strcat(message, GetMovieModeStr());
|
||||
}
|
||||
|
||||
FCEU_DispMessage(message, 0);
|
||||
FCEU_DispMessage("%s",0,message);
|
||||
}
|
||||
|
||||
void FCEUI_MovieNextRecordMode()
|
||||
@@ -1945,7 +1959,7 @@ void FCEUI_MoviePlayFromBeginning(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
string FCEUI_GetMovieName(void)
|
||||
std::string FCEUI_GetMovieName(void)
|
||||
{
|
||||
return curMovieFilename;
|
||||
}
|
||||
@@ -2039,9 +2053,9 @@ void FCEUI_CreateMovieFile(std::string fn)
|
||||
void FCEUI_MakeBackupMovie(bool dispMessage)
|
||||
{
|
||||
//This function generates backup movie files
|
||||
string currentFn; //Current movie fillename
|
||||
string backupFn; //Target backup filename
|
||||
string tempFn; //temp used in back filename creation
|
||||
std::string currentFn; //Current movie fillename
|
||||
std::string backupFn; //Target backup filename
|
||||
std::string tempFn; //temp used in back filename creation
|
||||
stringstream stream;
|
||||
int x; //Temp variable for string manip
|
||||
bool exist = false; //Used to test if filename exists
|
||||
|
||||
+7
-3
@@ -81,7 +81,9 @@ enum EMOVIECMD
|
||||
MOVIECMD_POWER = 2,
|
||||
MOVIECMD_FDS_INSERT = 4,
|
||||
MOVIECMD_FDS_SELECT = 8,
|
||||
MOVIECMD_VS_INSERTCOIN = 16
|
||||
MOVIECMD_VS_INSERTCOIN = 16,
|
||||
MOVIECMD_VS_INSERTCOIN2 = 32,
|
||||
MOVIECMD_VS_SERVICE = 64
|
||||
};
|
||||
|
||||
EMOVIEMODE FCEUMOV_Mode();
|
||||
@@ -131,6 +133,8 @@ public:
|
||||
bool command_fds_insert() { return (commands & MOVIECMD_FDS_INSERT) != 0; }
|
||||
bool command_fds_select() { return (commands & MOVIECMD_FDS_SELECT) != 0; }
|
||||
bool command_vs_insertcoin() { return (commands & MOVIECMD_VS_INSERTCOIN) != 0; }
|
||||
bool command_vs_insertcoin2() { return (commands & MOVIECMD_VS_INSERTCOIN2) != 0; }
|
||||
bool command_vs_service() { return (commands & MOVIECMD_VS_SERVICE) != 0; }
|
||||
|
||||
void toggleBit(int joy, int bit)
|
||||
{
|
||||
@@ -210,7 +214,7 @@ public:
|
||||
//whether microphone is enabled
|
||||
bool microphone;
|
||||
|
||||
int getNumRecords() { return (int)records.size(); }
|
||||
int getNumRecords() { return static_cast<int>( records.size() ); }
|
||||
|
||||
int RAMInitOption, RAMInitSeed;
|
||||
|
||||
@@ -272,7 +276,7 @@ private:
|
||||
extern EMOVIEMODE movieMode;
|
||||
extern MovieData currMovieData;
|
||||
extern int currFrameCounter;
|
||||
extern char curMovieFilename[512];
|
||||
extern std::string curMovieFilename;
|
||||
extern bool subtitlesOnAVI;
|
||||
extern bool freshMovie;
|
||||
extern bool movie_readonly;
|
||||
|
||||
+4
-1
@@ -122,7 +122,10 @@ int FCEUNET_SendFile(uint8 cmd, char *fn)
|
||||
FCEUX_fstat(fileno(fp),&sb);
|
||||
len = sb.st_size;
|
||||
buf = (char*)FCEU_dmalloc(len); //mbg merge 7/17/06 added cast
|
||||
fread(buf, 1, len, fp);
|
||||
if ( fread(buf, 1, len, fp) != static_cast<size_t>(len) )
|
||||
{
|
||||
FCEU_printf("Warning: FCEUNET_SendFile failed to load complete file.\n");
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
cbuf = (char*)FCEU_dmalloc(4 + len + len / 1000 + 12); //mbg merge 7/17/06 added cast
|
||||
|
||||
+4
-1
@@ -7,7 +7,10 @@ extern int FCEUnetplay;
|
||||
#define FCEUNPCMD_POWER 0x02
|
||||
|
||||
#define FCEUNPCMD_VSUNICOIN 0x07
|
||||
#define FCEUNPCMD_VSUNIDIP0 0x08
|
||||
#define FCEUNPCMD_VSUNIDIP0 0x08
|
||||
#define FCEUNPCMD_VSUNICOIN2 0x20
|
||||
#define FCEUNPCMD_VSUNISERVICE 0x21
|
||||
|
||||
#define FCEUNPCMD_FDSINSERTx 0x10
|
||||
#define FCEUNPCMD_FDSINSERT 0x18
|
||||
//#define FCEUNPCMD_FDSEJECT 0x19
|
||||
|
||||
+1
-2
@@ -32,6 +32,7 @@
|
||||
#include "file.h"
|
||||
#include "fds.h"
|
||||
#include "cart.h"
|
||||
#include "ines.h"
|
||||
#include "input.h"
|
||||
#include "state.h"
|
||||
#include "driver.h"
|
||||
@@ -123,8 +124,6 @@ static uint16 PlayAddr; //configuration
|
||||
static uint16 InitAddr; //configuration
|
||||
static uint16 LoadAddr; //configuration
|
||||
|
||||
extern char LoadedRomFName[2048];
|
||||
|
||||
NSF_HEADER NSFHeader; //mbg merge 6/29/06 - needs to be global
|
||||
|
||||
void NSFMMC5_Close(void);
|
||||
|
||||
+19
-4
@@ -48,7 +48,7 @@ static uint8 joop[4];
|
||||
static uint8 joopcmd;
|
||||
static uint32 framets = 0;
|
||||
static uint32 frameptr = 0;
|
||||
static uint8* moviedata = NULL;
|
||||
static uint8* moviedata = nullptr;
|
||||
static uint32 moviedatasize = 0;
|
||||
static uint32 firstframeoffset = 0;
|
||||
static uint32 savestate_offset = 0;
|
||||
@@ -626,7 +626,19 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
|
||||
//ResetInputTypes();
|
||||
|
||||
fp->fseek(firstframeoffset,SEEK_SET);
|
||||
moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
||||
uint8 *newMovieData = (uint8*)realloc(moviedata, moviedatasize);
|
||||
if (newMovieData)
|
||||
{
|
||||
moviedata = newMovieData;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moviedata)
|
||||
{
|
||||
free(moviedata); moviedata = nullptr;
|
||||
}
|
||||
return FCM_CONVERTRESULT_REALLOC_FAIL;
|
||||
}
|
||||
fp->fread((char*)moviedata,moviedatasize);
|
||||
|
||||
frameptr = 0;
|
||||
@@ -669,8 +681,11 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
|
||||
md.ports[0] = md.ports[1] = SI_GAMEPAD;
|
||||
}
|
||||
|
||||
free(moviedata);
|
||||
moviedata = 0;
|
||||
if (moviedata)
|
||||
{
|
||||
free(moviedata);
|
||||
moviedata = nullptr;
|
||||
}
|
||||
|
||||
delete fp;
|
||||
return FCM_CONVERTRESULT_SUCCESS;
|
||||
|
||||
@@ -10,6 +10,7 @@ enum EFCM_CONVERTRESULT
|
||||
FCM_CONVERTRESULT_OLDVERSION,
|
||||
FCM_CONVERTRESULT_UNSUPPORTEDVERSION,
|
||||
FCM_CONVERTRESULT_STARTFROMSAVESTATENOTSUPPORTED,
|
||||
FCM_CONVERTRESULT_REALLOC_FAIL,
|
||||
};
|
||||
|
||||
inline const char * EFCM_CONVERTRESULT_message(EFCM_CONVERTRESULT e)
|
||||
|
||||
@@ -87,6 +87,7 @@ pal *palo = NULL;
|
||||
(type) (y + to_rgb [4] * i + to_rgb [5] * q)\
|
||||
)
|
||||
|
||||
FCEU_MAYBE_UNUSED
|
||||
static void ApplyDeemphasisNTSC(int entry, u8& r, u8& g, u8& b)
|
||||
{
|
||||
static float const to_float = 1.0f / 0xFF;
|
||||
@@ -252,6 +253,7 @@ static void ApplyDeemphasisBisqwit(int entry, u8& r, u8& g, u8& b)
|
||||
}
|
||||
|
||||
//classic algorithm
|
||||
FCEU_MAYBE_UNUSED
|
||||
static void ApplyDeemphasisClassic(int entry, u8& r, u8& g, u8& b)
|
||||
{
|
||||
//DEEMPH BITS MAY BE ORDERED WRONG. PLEASE CHECK
|
||||
|
||||
+76
-68
@@ -4,6 +4,9 @@
|
||||
#define EMPTY_PALETTE_64 EMPTY_PALETTE_16 EMPTY_PALETTE_16 EMPTY_PALETTE_16 EMPTY_PALETTE_16
|
||||
#define EMPTY_PALETTE_DEEMPH_X_7 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64 EMPTY_PALETTE_64
|
||||
|
||||
//this assumes the color is already shifted <<2, as it is in these cases
|
||||
#define P64RPC(x) ( ((x)&~3) | (((x)>>6)&3))
|
||||
|
||||
pal rp2c04001[512] = {
|
||||
#include "rp2c04001.h"
|
||||
EMPTY_PALETTE_DEEMPH_X_7
|
||||
@@ -23,12 +26,14 @@ pal rp2c05004[512] = {
|
||||
EMPTY_PALETTE_DEEMPH_X_7
|
||||
};
|
||||
|
||||
#undef P64RPC
|
||||
|
||||
// Fixed palette entries used by the GUI
|
||||
pal palette_unvarying[] = {
|
||||
{ 0x00<<2,0x00<<2,0x00<<2}, // 0 = Black
|
||||
{ 0x3F<<2,0x3F<<2,0x34<<2}, // 1 = White
|
||||
{ 0x00<<2,0x00<<2,0x00<<2}, // 2 = Black
|
||||
{ 0x1d<<2,0x1d<<2,0x24<<2}, // 3 = Greyish
|
||||
{ 0x00,0x00,0x00}, // 0 = Black
|
||||
{ 0xFF,0xFF,0xD3}, // 1 = White
|
||||
{ 0x00,0x00,0x00}, // 2 = Black
|
||||
{ 0x75,0x75,0x92}, // 3 = Greyish
|
||||
{ 190, 0, 0}, // 4 = Reddish
|
||||
{ 51,255, 51}, // 5 = Bright green
|
||||
{ 49, 14,200}, // 6 = Ultramarine Blue
|
||||
@@ -52,73 +57,76 @@ pal palette_unvarying[] = {
|
||||
};
|
||||
|
||||
|
||||
#define P64(x) (((x)<<2)|((x>>4)&3))
|
||||
|
||||
// Default palette
|
||||
pal palette[512] = {
|
||||
{ P64(0x1D), P64(0x1D), P64(0x1D)}, /* Value 0 */
|
||||
{ P64(0x09), P64(0x06), P64(0x23)}, /* Value 1 */
|
||||
{ P64(0x00), P64(0x00), P64(0x2A)}, /* Value 2 */
|
||||
{ P64(0x11), P64(0x00), P64(0x27)}, /* Value 3 */
|
||||
{ P64(0x23), P64(0x00), P64(0x1D)}, /* Value 4 */
|
||||
{ P64(0x2A), P64(0x00), P64(0x04)}, /* Value 5 */
|
||||
{ P64(0x29), P64(0x00), P64(0x00)}, /* Value 6 */
|
||||
{ P64(0x1F), P64(0x02), P64(0x00)}, /* Value 7 */
|
||||
{ P64(0x10), P64(0x0B), P64(0x00)}, /* Value 8 */
|
||||
{ P64(0x00), P64(0x11), P64(0x00)}, /* Value 9 */
|
||||
{ P64(0x00), P64(0x14), P64(0x00)}, /* Value 10 */
|
||||
{ P64(0x00), P64(0x0F), P64(0x05)}, /* Value 11 */
|
||||
{ P64(0x06), P64(0x0F), P64(0x17)}, /* Value 12 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 13 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 14 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 15 */
|
||||
{ P64(0x2F), P64(0x2F), P64(0x2F)}, /* Value 16 */
|
||||
{ P64(0x00), P64(0x1C), P64(0x3B)}, /* Value 17 */
|
||||
{ P64(0x08), P64(0x0E), P64(0x3B)}, /* Value 18 */
|
||||
{ P64(0x20), P64(0x00), P64(0x3C)}, /* Value 19 */
|
||||
{ P64(0x2F), P64(0x00), P64(0x2F)}, /* Value 20 */
|
||||
{ P64(0x39), P64(0x00), P64(0x16)}, /* Value 21 */
|
||||
{ P64(0x36), P64(0x0A), P64(0x00)}, /* Value 22 */
|
||||
{ P64(0x32), P64(0x13), P64(0x03)}, /* Value 23 */
|
||||
{ P64(0x22), P64(0x1C), P64(0x00)}, /* Value 24 */
|
||||
{ P64(0x00), P64(0x25), P64(0x00)}, /* Value 25 */
|
||||
{ P64(0x00), P64(0x2A), P64(0x00)}, /* Value 26 */
|
||||
{ P64(0x00), P64(0x24), P64(0x0E)}, /* Value 27 */
|
||||
{ P64(0x00), P64(0x20), P64(0x22)}, /* Value 28 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 29 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 30 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 31 */
|
||||
{ P64(0x3F), P64(0x3F), P64(0x3F)}, /* Value 32 */
|
||||
{ P64(0x0F), P64(0x2F), P64(0x3F)}, /* Value 33 */
|
||||
{ P64(0x17), P64(0x25), P64(0x3F)}, /* Value 34 */
|
||||
{ P64(0x33), P64(0x22), P64(0x3F)}, /* Value 35 */
|
||||
{ P64(0x3D), P64(0x1E), P64(0x3F)}, /* Value 36 */
|
||||
{ P64(0x3F), P64(0x1D), P64(0x2D)}, /* Value 37 */
|
||||
{ P64(0x3F), P64(0x1D), P64(0x18)}, /* Value 38 */
|
||||
{ P64(0x3F), P64(0x26), P64(0x0E)}, /* Value 39 */
|
||||
{ P64(0x3C), P64(0x2F), P64(0x0F)}, /* Value 40 */
|
||||
{ P64(0x20), P64(0x34), P64(0x04)}, /* Value 41 */
|
||||
{ P64(0x13), P64(0x37), P64(0x12)}, /* Value 42 */
|
||||
{ P64(0x16), P64(0x3E), P64(0x26)}, /* Value 43 */
|
||||
{ P64(0x00), P64(0x3A), P64(0x36)}, /* Value 44 */
|
||||
{ P64(0x1E), P64(0x1E), P64(0x1E)}, /* Value 45 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 46 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 47 */
|
||||
{ P64(0x3F), P64(0x3F), P64(0x3F)}, /* Value 48 */
|
||||
{ P64(0x2A), P64(0x39), P64(0x3F)}, /* Value 49 */
|
||||
{ P64(0x31), P64(0x35), P64(0x3F)}, /* Value 50 */
|
||||
{ P64(0x35), P64(0x32), P64(0x3F)}, /* Value 51 */
|
||||
{ P64(0x3F), P64(0x31), P64(0x3F)}, /* Value 52 */
|
||||
{ P64(0x3F), P64(0x31), P64(0x36)}, /* Value 53 */
|
||||
{ P64(0x3F), P64(0x2F), P64(0x2C)}, /* Value 54 */
|
||||
{ P64(0x3F), P64(0x36), P64(0x2A)}, /* Value 55 */
|
||||
{ P64(0x3F), P64(0x39), P64(0x28)}, /* Value 56 */
|
||||
{ P64(0x38), P64(0x3F), P64(0x28)}, /* Value 57 */
|
||||
{ P64(0x2A), P64(0x3C), P64(0x2F)}, /* Value 58 */
|
||||
{ P64(0x2C), P64(0x3F), P64(0x33)}, /* Value 59 */
|
||||
{ P64(0x27), P64(0x3F), P64(0x3C)}, /* Value 60 */
|
||||
{ P64(0x31), P64(0x31), P64(0x31)}, /* Value 61 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 62 */
|
||||
{ P64(0x00), P64(0x00), P64(0x00)}, /* Value 63 */
|
||||
|
||||
{ 0x1D<<2, 0x1D<<2, 0x1D<<2 }, /* Value 0 */
|
||||
{ 0x09<<2, 0x06<<2, 0x23<<2 }, /* Value 1 */
|
||||
{ 0x00<<2, 0x00<<2, 0x2A<<2 }, /* Value 2 */
|
||||
{ 0x11<<2, 0x00<<2, 0x27<<2 }, /* Value 3 */
|
||||
{ 0x23<<2, 0x00<<2, 0x1D<<2 }, /* Value 4 */
|
||||
{ 0x2A<<2, 0x00<<2, 0x04<<2 }, /* Value 5 */
|
||||
{ 0x29<<2, 0x00<<2, 0x00<<2 }, /* Value 6 */
|
||||
{ 0x1F<<2, 0x02<<2, 0x00<<2 }, /* Value 7 */
|
||||
{ 0x10<<2, 0x0B<<2, 0x00<<2 }, /* Value 8 */
|
||||
{ 0x00<<2, 0x11<<2, 0x00<<2 }, /* Value 9 */
|
||||
{ 0x00<<2, 0x14<<2, 0x00<<2 }, /* Value 10 */
|
||||
{ 0x00<<2, 0x0F<<2, 0x05<<2 }, /* Value 11 */
|
||||
{ 0x06<<2, 0x0F<<2, 0x17<<2 }, /* Value 12 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 13 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 14 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 15 */
|
||||
{ 0x2F<<2, 0x2F<<2, 0x2F<<2 }, /* Value 16 */
|
||||
{ 0x00<<2, 0x1C<<2, 0x3B<<2 }, /* Value 17 */
|
||||
{ 0x08<<2, 0x0E<<2, 0x3B<<2 }, /* Value 18 */
|
||||
{ 0x20<<2, 0x00<<2, 0x3C<<2 }, /* Value 19 */
|
||||
{ 0x2F<<2, 0x00<<2, 0x2F<<2 }, /* Value 20 */
|
||||
{ 0x39<<2, 0x00<<2, 0x16<<2 }, /* Value 21 */
|
||||
{ 0x36<<2, 0x0A<<2, 0x00<<2 }, /* Value 22 */
|
||||
{ 0x32<<2, 0x13<<2, 0x03<<2 }, /* Value 23 */
|
||||
{ 0x22<<2, 0x1C<<2, 0x00<<2 }, /* Value 24 */
|
||||
{ 0x00<<2, 0x25<<2, 0x00<<2 }, /* Value 25 */
|
||||
{ 0x00<<2, 0x2A<<2, 0x00<<2 }, /* Value 26 */
|
||||
{ 0x00<<2, 0x24<<2, 0x0E<<2 }, /* Value 27 */
|
||||
{ 0x00<<2, 0x20<<2, 0x22<<2 }, /* Value 28 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 29 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 30 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 31 */
|
||||
{ 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 32 */
|
||||
{ 0x0F<<2, 0x2F<<2, 0x3F<<2 }, /* Value 33 */
|
||||
{ 0x17<<2, 0x25<<2, 0x3F<<2 }, /* Value 34 */
|
||||
{ 0x33<<2, 0x22<<2, 0x3F<<2 }, /* Value 35 */
|
||||
{ 0x3D<<2, 0x1E<<2, 0x3F<<2 }, /* Value 36 */
|
||||
{ 0x3F<<2, 0x1D<<2, 0x2D<<2 }, /* Value 37 */
|
||||
{ 0x3F<<2, 0x1D<<2, 0x18<<2 }, /* Value 38 */
|
||||
{ 0x3F<<2, 0x26<<2, 0x0E<<2 }, /* Value 39 */
|
||||
{ 0x3C<<2, 0x2F<<2, 0x0F<<2 }, /* Value 40 */
|
||||
{ 0x20<<2, 0x34<<2, 0x04<<2 }, /* Value 41 */
|
||||
{ 0x13<<2, 0x37<<2, 0x12<<2 }, /* Value 42 */
|
||||
{ 0x16<<2, 0x3E<<2, 0x26<<2 }, /* Value 43 */
|
||||
{ 0x00<<2, 0x3A<<2, 0x36<<2 }, /* Value 44 */
|
||||
{ 0x1E<<2, 0x1E<<2, 0x1E<<2 }, /* Value 45 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 46 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 47 */
|
||||
{ 0x3F<<2, 0x3F<<2, 0x3F<<2 }, /* Value 48 */
|
||||
{ 0x2A<<2, 0x39<<2, 0x3F<<2 }, /* Value 49 */
|
||||
{ 0x31<<2, 0x35<<2, 0x3F<<2 }, /* Value 50 */
|
||||
{ 0x35<<2, 0x32<<2, 0x3F<<2 }, /* Value 51 */
|
||||
{ 0x3F<<2, 0x31<<2, 0x3F<<2 }, /* Value 52 */
|
||||
{ 0x3F<<2, 0x31<<2, 0x36<<2 }, /* Value 53 */
|
||||
{ 0x3F<<2, 0x2F<<2, 0x2C<<2 }, /* Value 54 */
|
||||
{ 0x3F<<2, 0x36<<2, 0x2A<<2 }, /* Value 55 */
|
||||
{ 0x3F<<2, 0x39<<2, 0x28<<2 }, /* Value 56 */
|
||||
{ 0x38<<2, 0x3F<<2, 0x28<<2 }, /* Value 57 */
|
||||
{ 0x2A<<2, 0x3C<<2, 0x2F<<2 }, /* Value 58 */
|
||||
{ 0x2C<<2, 0x3F<<2, 0x33<<2 }, /* Value 59 */
|
||||
{ 0x27<<2, 0x3F<<2, 0x3C<<2 }, /* Value 60 */
|
||||
{ 0x31<<2, 0x31<<2, 0x31<<2 }, /* Value 61 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 62 */
|
||||
{ 0x00<<2, 0x00<<2, 0x00<<2 }, /* Value 63 */
|
||||
#undef P64
|
||||
|
||||
//luke's .16+ palette
|
||||
//{0x60, 0x60, 0x60}, /* Value 0 */
|
||||
|
||||
+64
-64
@@ -1,64 +1,64 @@
|
||||
{0xfc, 0xc4, 0xd8},
|
||||
{0x40, 0x88, 0xfc},
|
||||
{0xd8, 0x28, 0x00},
|
||||
{0x5c, 0x94, 0xfc},
|
||||
{0x00, 0x80, 0x88},
|
||||
{0x00, 0x44, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xe4, 0x00, 0x58},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x74, 0x74, 0x74},
|
||||
{0xfc, 0x98, 0x38},
|
||||
{0xa8, 0x00, 0x10},
|
||||
{0x8c, 0x00, 0x74},
|
||||
{0xfc, 0x98, 0x38},
|
||||
{0x40, 0x2c, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x3c, 0xbc, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x80, 0xd0, 0x10},
|
||||
{0x9c, 0xfc, 0xf0},
|
||||
{0xc4, 0xd4, 0xfc},
|
||||
{0xfc, 0xbc, 0xb0},
|
||||
{0x20, 0x38, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x58, 0xf8, 0x98},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0xbc, 0xbc, 0xbc},
|
||||
{0xf4, 0x78, 0xfc},
|
||||
{0x24, 0x18, 0x8c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0xe4, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x4c, 0xdc, 0x48},
|
||||
{0x00, 0xe8, 0xd8},
|
||||
{0x18, 0x3c, 0x5c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x7c, 0x08, 0x00},
|
||||
{0xfc, 0xc4, 0xfc},
|
||||
{0xa4, 0x00, 0x00},
|
||||
{0x80, 0x00, 0xf0},
|
||||
{0x00, 0x00, 0xa8},
|
||||
{0xfc, 0x74, 0x60},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x94, 0x00},
|
||||
{0xbc, 0xbc, 0xbc},
|
||||
{0x00, 0x50, 0x00},
|
||||
{0xe0, 0xfc, 0xa0},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0xc8, 0x4c, 0x0c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x70, 0xec},
|
||||
{0x00, 0x44, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xe0, 0xfc, 0xa0},
|
||||
{0xfc, 0x74, 0xb4},
|
||||
{0x88, 0x70, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xd8)},
|
||||
{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)},
|
||||
{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)},
|
||||
{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)},
|
||||
{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)},
|
||||
{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)},
|
||||
{P64RPC(0x8c), P64RPC(0x00), P64RPC(0x74)},
|
||||
{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)},
|
||||
{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)},
|
||||
{P64RPC(0x9c), P64RPC(0xfc), P64RPC(0xf0)},
|
||||
{P64RPC(0xc4), P64RPC(0xd4), P64RPC(0xfc)},
|
||||
{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)},
|
||||
{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x58), P64RPC(0xf8), P64RPC(0x98)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)},
|
||||
{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)},
|
||||
{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)},
|
||||
{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)},
|
||||
{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xfc)},
|
||||
{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)},
|
||||
{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)},
|
||||
{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)},
|
||||
{P64RPC(0xe0), P64RPC(0xfc), P64RPC(0xa0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xe0), P64RPC(0xfc), P64RPC(0xa0)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)},
|
||||
{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
|
||||
+64
-64
@@ -1,64 +1,64 @@
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0x98, 0x38},
|
||||
{0x88, 0x70, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0xf0, 0xbc},
|
||||
{0xfc, 0x74, 0xb4},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0xe4, 0xfc},
|
||||
{0xd8, 0x28, 0x00},
|
||||
{0x80, 0x00, 0xf0},
|
||||
{0xfc, 0xe4, 0xa0},
|
||||
{0xfc, 0xc4, 0xfc},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x40, 0x88, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x3c, 0x14},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x3c, 0xbc, 0xfc},
|
||||
{0xa4, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x90, 0x38},
|
||||
{0x80, 0xd0, 0x10},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x5c, 0x94, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xf4, 0x78, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x58, 0xf8, 0x98},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x40, 0x2c, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x44, 0x00, 0x9c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xbc, 0xb0},
|
||||
{0xfc, 0x74, 0x60},
|
||||
{0xd4, 0xc8, 0xfc},
|
||||
{0x00, 0x70, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xbc, 0xbc, 0xbc},
|
||||
{0x00, 0x00, 0xa8},
|
||||
{0xbc, 0x00, 0xbc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x74, 0x74, 0x74},
|
||||
{0x00, 0x44, 0x00},
|
||||
{0x20, 0x38, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x4c, 0xdc, 0x48},
|
||||
{0xc8, 0x4c, 0x0c},
|
||||
{0x18, 0x3c, 0x5c},
|
||||
{0x24, 0x18, 0x8c},
|
||||
{0xe4, 0x00, 0x58},
|
||||
{0x00, 0x94, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0xe8, 0xd8},
|
||||
{0x7c, 0x08, 0x00},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0x00, 0x10},
|
||||
{0x00, 0x50, 0x00},
|
||||
{0x74, 0x74, 0x74},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)},
|
||||
{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0xf0), P64RPC(0xbc)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)},
|
||||
{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)},
|
||||
{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)},
|
||||
{P64RPC(0xfc), P64RPC(0xe4), P64RPC(0xa0)},
|
||||
{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xfc)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x3c), P64RPC(0x14)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)},
|
||||
{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x90), P64RPC(0x38)},
|
||||
{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x58), P64RPC(0xf8), P64RPC(0x98)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x44), P64RPC(0x00), P64RPC(0x9c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)},
|
||||
{P64RPC(0xd4), P64RPC(0xc8), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)},
|
||||
{P64RPC(0xbc), P64RPC(0x00), P64RPC(0xbc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)},
|
||||
{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)},
|
||||
{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)},
|
||||
{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)},
|
||||
{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)},
|
||||
{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)},
|
||||
{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)},
|
||||
{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)},
|
||||
{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
|
||||
+64
-64
@@ -1,64 +1,64 @@
|
||||
{0x44, 0x00, 0x9c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x74, 0x74, 0x74},
|
||||
{0x00, 0xa8, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0xa8, 0xe4, 0xfc},
|
||||
{0x00, 0x44, 0x00},
|
||||
{0x24, 0x18, 0x8c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xbc, 0xb0},
|
||||
{0x40, 0x2c, 0x00},
|
||||
{0xe4, 0x00, 0x58},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x5c, 0x94, 0xfc},
|
||||
{0x00, 0x80, 0x88},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x20, 0x38, 0xec},
|
||||
{0x00, 0x94, 0x00},
|
||||
{0x88, 0x70, 0x00},
|
||||
{0xc8, 0x4c, 0x0c},
|
||||
{0x00, 0x90, 0x38},
|
||||
{0x74, 0x74, 0x74},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0xa8},
|
||||
{0xd8, 0x28, 0x00},
|
||||
{0xa4, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xc4, 0xd8},
|
||||
{0x40, 0x88, 0xfc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0x98, 0x38},
|
||||
{0xfc, 0x74, 0x60},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x80, 0xd0, 0x10},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x3c, 0xbc, 0xfc},
|
||||
{0xf4, 0x78, 0xfc},
|
||||
{0x00, 0x70, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0xe8, 0xd8},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x7c, 0x08, 0x00},
|
||||
{0x4c, 0xdc, 0x48},
|
||||
{0xf0, 0xbc, 0x3c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x50, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xc4, 0xd4, 0xfc},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0x80, 0x00, 0xf0},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x18, 0x3c, 0x5c},
|
||||
{P64RPC(0x44), P64RPC(0x00), P64RPC(0x9c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
{P64RPC(0x00), P64RPC(0xa8), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)},
|
||||
{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)},
|
||||
{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)},
|
||||
{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)},
|
||||
{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)},
|
||||
{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)},
|
||||
{P64RPC(0x00), P64RPC(0x90), P64RPC(0x38)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)},
|
||||
{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)},
|
||||
{P64RPC(0xa4), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xc4), P64RPC(0xd8)},
|
||||
{P64RPC(0x40), P64RPC(0x88), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)},
|
||||
{P64RPC(0xf4), P64RPC(0x78), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0xe8), P64RPC(0xd8)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)},
|
||||
{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)},
|
||||
{P64RPC(0xf0), P64RPC(0xbc), P64RPC(0x3c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xc4), P64RPC(0xd4), P64RPC(0xfc)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)},
|
||||
|
||||
+64
-64
@@ -1,64 +1,64 @@
|
||||
{0x88, 0x70, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x80, 0x88},
|
||||
{0xf0, 0xbc, 0x3c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x24, 0x18, 0x8c},
|
||||
{0xc8, 0x4c, 0x0c},
|
||||
{0xbc, 0xbc, 0xbc},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x4c, 0xdc, 0x48},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xbc, 0xb0},
|
||||
{0xfc, 0xd8, 0xa8},
|
||||
{0x00, 0xa8, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0x74, 0xb4},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x20, 0x38, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0x74, 0x60},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x5c, 0x94, 0xfc},
|
||||
{0x00, 0x94, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0xf0, 0xbc},
|
||||
{0x3c, 0xbc, 0xfc},
|
||||
{0xa8, 0x00, 0x10},
|
||||
{0x00, 0x50, 0x00},
|
||||
{0x7c, 0x08, 0x00},
|
||||
{0x00, 0x00, 0xa8},
|
||||
{0x80, 0x00, 0xf0},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x74, 0x74, 0x74},
|
||||
{0xe4, 0x00, 0x58},
|
||||
{0x18, 0x3c, 0x5c},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x70, 0xec},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xe4, 0xa0},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x40, 0x2c, 0x00},
|
||||
{0xd8, 0x28, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x9c, 0xfc, 0xf0},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0x98, 0x38},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xa8, 0xe4, 0xfc},
|
||||
{0x80, 0xd0, 0x10},
|
||||
{0x00, 0x00, 0x00},
|
||||
{0xfc, 0xfc, 0xfc},
|
||||
{0x00, 0x44, 0x00},
|
||||
{P64RPC(0x88), P64RPC(0x70), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x80), P64RPC(0x88)},
|
||||
{P64RPC(0xf0), P64RPC(0xbc), P64RPC(0x3c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x24), P64RPC(0x18), P64RPC(0x8c)},
|
||||
{P64RPC(0xc8), P64RPC(0x4c), P64RPC(0x0c)},
|
||||
{P64RPC(0xbc), P64RPC(0xbc), P64RPC(0xbc)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x4c), P64RPC(0xdc), P64RPC(0x48)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xbc), P64RPC(0xb0)},
|
||||
{P64RPC(0xfc), P64RPC(0xd8), P64RPC(0xa8)},
|
||||
{P64RPC(0x00), P64RPC(0xa8), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0xb4)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x20), P64RPC(0x38), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0x74), P64RPC(0x60)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x5c), P64RPC(0x94), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x94), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0xf0), P64RPC(0xbc)},
|
||||
{P64RPC(0x3c), P64RPC(0xbc), P64RPC(0xfc)},
|
||||
{P64RPC(0xa8), P64RPC(0x00), P64RPC(0x10)},
|
||||
{P64RPC(0x00), P64RPC(0x50), P64RPC(0x00)},
|
||||
{P64RPC(0x7c), P64RPC(0x08), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0xa8)},
|
||||
{P64RPC(0x80), P64RPC(0x00), P64RPC(0xf0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x74), P64RPC(0x74), P64RPC(0x74)},
|
||||
{P64RPC(0xe4), P64RPC(0x00), P64RPC(0x58)},
|
||||
{P64RPC(0x18), P64RPC(0x3c), P64RPC(0x5c)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x70), P64RPC(0xec)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xe4), P64RPC(0xa0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x40), P64RPC(0x2c), P64RPC(0x00)},
|
||||
{P64RPC(0xd8), P64RPC(0x28), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x9c), P64RPC(0xfc), P64RPC(0xf0)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0x98), P64RPC(0x38)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xa8), P64RPC(0xe4), P64RPC(0xfc)},
|
||||
{P64RPC(0x80), P64RPC(0xd0), P64RPC(0x10)},
|
||||
{P64RPC(0x00), P64RPC(0x00), P64RPC(0x00)},
|
||||
{P64RPC(0xfc), P64RPC(0xfc), P64RPC(0xfc)},
|
||||
{P64RPC(0x00), P64RPC(0x44), P64RPC(0x00)},
|
||||
|
||||
+67
-16
@@ -57,6 +57,7 @@
|
||||
|
||||
#define PPU_status (PPU[2])
|
||||
|
||||
#define READPALNOGS(ofs) (PALRAM[(ofs)])
|
||||
#define READPAL(ofs) (PALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF))
|
||||
#define READUPAL(ofs) (UPALRAM[(ofs)] & (GRAYSCALE ? 0x30 : 0xFF))
|
||||
|
||||
@@ -455,13 +456,24 @@ volatile int rendercount, vromreadcount, undefinedvromcount, LogAddress = -1;
|
||||
unsigned char *cdloggervdata = NULL;
|
||||
unsigned int cdloggerVideoDataSize = 0;
|
||||
|
||||
int GetCHRAddress(int A) {
|
||||
if (cdloggerVideoDataSize) {
|
||||
int result = &VPage[A >> 10][A] - CHRptr[0];
|
||||
int GetCHRAddress(int A)
|
||||
{
|
||||
if (cdloggerVideoDataSize)
|
||||
{
|
||||
int result = -1;
|
||||
if ( (A >= 0) && (A < 0x2000) )
|
||||
{
|
||||
result = &VPage[A >> 10][A] - CHRptr[0];
|
||||
}
|
||||
if ((result >= 0) && (result < (int)cdloggerVideoDataSize))
|
||||
{
|
||||
return result;
|
||||
} else
|
||||
if(A < 0x2000) return A;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (A >= 0) && (A < 0x2000) ) return A;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1987,6 +1999,7 @@ void runppu(int x) {
|
||||
struct BGData {
|
||||
struct Record {
|
||||
uint8 nt, pecnt, at, pt[2], qtnt;
|
||||
uint8 ppu1[8];
|
||||
|
||||
INLINE void Read() {
|
||||
NTRefreshAddr = RefreshAddr = ppur.get_ntread();
|
||||
@@ -1998,7 +2011,12 @@ struct BGData {
|
||||
}
|
||||
pecnt = (RefreshAddr & 1) << 3;
|
||||
nt = CALL_PPUREAD(RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
ppu1[0] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[1] = PPU[1];
|
||||
runppu(1);
|
||||
|
||||
|
||||
|
||||
RefreshAddr = ppur.get_atread();
|
||||
at = CALL_PPUREAD(RefreshAddr);
|
||||
@@ -2010,37 +2028,57 @@ struct BGData {
|
||||
at <<= 2;
|
||||
//horizontal scroll clocked at cycle 3 and then
|
||||
//vertical scroll at 251
|
||||
ppu1[2] = PPU[1];
|
||||
runppu(1);
|
||||
if (PPUON) {
|
||||
ppur.increment_hsc();
|
||||
if (ppur.status.cycle == 251)
|
||||
ppur.increment_vs();
|
||||
}
|
||||
ppu1[3] = PPU[1];
|
||||
runppu(1);
|
||||
|
||||
ppur.par = nt;
|
||||
RefreshAddr = ppur.get_ptread();
|
||||
if (PEC586Hack) {
|
||||
pt[0] = CALL_PPUREAD(RefreshAddr | pecnt);
|
||||
runppu(kFetchTime);
|
||||
ppu1[4] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[5] = PPU[1];
|
||||
runppu(1);
|
||||
pt[1] = CALL_PPUREAD(RefreshAddr | pecnt);
|
||||
runppu(kFetchTime);
|
||||
ppu1[6] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[7] = PPU[1];
|
||||
runppu(1);
|
||||
} else if (QTAIHack && (qtnt & 0x40)) {
|
||||
pt[0] = *(CHRptr[0] + RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
ppu1[4] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[5] = PPU[1];
|
||||
runppu(1);
|
||||
RefreshAddr |= 8;
|
||||
pt[1] = *(CHRptr[0] + RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
ppu1[6] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[7] = PPU[1];
|
||||
runppu(1);
|
||||
} else {
|
||||
if (ScreenON)
|
||||
RENDER_LOG(RefreshAddr);
|
||||
pt[0] = CALL_PPUREAD(RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
ppu1[4] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[5] = PPU[1];
|
||||
runppu(1);
|
||||
RefreshAddr |= 8;
|
||||
if (ScreenON)
|
||||
RENDER_LOG(RefreshAddr);
|
||||
pt[1] = CALL_PPUREAD(RefreshAddr);
|
||||
runppu(kFetchTime);
|
||||
ppu1[6] = PPU[1];
|
||||
runppu(1);
|
||||
ppu1[7] = PPU[1];
|
||||
runppu(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2216,7 +2254,7 @@ int FCEUX_PPU_Loop(int skip) {
|
||||
pixel = ((pt[0] >> (7 - bgpx)) & 1) | (((pt[1] >> (7 - bgpx)) & 1) << 1) | bgdata.main[bgtile].at;
|
||||
}
|
||||
if (renderbg)
|
||||
pixelcolor = READPAL(pixel);
|
||||
pixelcolor = READPALNOGS(pixel);
|
||||
|
||||
//look for a sprite to be drawn
|
||||
bool havepixel = false;
|
||||
@@ -2261,12 +2299,25 @@ int FCEUX_PPU_Loop(int skip) {
|
||||
spixel |= (oam[2] & 3) << 2;
|
||||
|
||||
if (rendersprites)
|
||||
pixelcolor = READPAL(0x10 + spixel);
|
||||
pixelcolor = READPALNOGS(0x10 + spixel);
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++ = PaletteAdjustPixel(pixelcolor);
|
||||
*dptr++= PPU[1]>>5; //grab deemph
|
||||
//apply grayscale.. kind of clunky
|
||||
//really we need to read the entire palette instead of just ppu1
|
||||
//this will be needed for special color effects probably (very fine rainbows and whatnot?)
|
||||
//are you allowed to chang the palette mid-line anyway? well you can definitely change the grayscale flag as we know from the FF1 "polygon" effect
|
||||
if(bgdata.main[xt+2].ppu1[xp]&1)
|
||||
pixelcolor &= 0x30;
|
||||
|
||||
//this does deemph stuff inside it.. which is probably wrong...
|
||||
*ptr = PaletteAdjustPixel(pixelcolor);
|
||||
|
||||
ptr++;
|
||||
|
||||
//grab deemph..
|
||||
//I guess this works the same way as the grayscale, ideally?
|
||||
*dptr++ = bgdata.main[xt+2].ppu1[xp]>>5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ uint8 tmpd;
|
||||
#endif
|
||||
|
||||
#ifndef PPUT_MMC5SP
|
||||
uint8 zz;
|
||||
FCEU_MAYBE_UNUSED uint8 zz;
|
||||
#else
|
||||
uint8 xs, ys;
|
||||
xs = X1;
|
||||
|
||||
+3
-2
@@ -534,9 +534,10 @@ static INLINE void DMCDMA(void)
|
||||
PrepDPCM();
|
||||
else
|
||||
{
|
||||
SIRQStat|=0x80;
|
||||
if(DMCFormat&0x80)
|
||||
if(DMCFormat&0x80) {
|
||||
SIRQStat|=0x80;
|
||||
X6502_IRQBegin(FCEU_IQDPCM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+81
-71
@@ -70,11 +70,11 @@ static int StateShow;
|
||||
//tells the save system innards that we're loading the old format
|
||||
bool FCEU_state_loading_old_format = false;
|
||||
|
||||
char lastSavestateMade[2048]; //Stores the filename of the last savestate made (needed for UndoSavestate)
|
||||
std::string lastSavestateMade; //Stores the filename of the last savestate made (needed for UndoSavestate)
|
||||
bool undoSS = false; //This will be true if there is lastSavestateMade, it was made since ROM was loaded, a backup state for lastSavestateMade exists
|
||||
bool redoSS = false; //This will be true if UndoSaveState is run, will turn false when a new savestate is made
|
||||
|
||||
char lastLoadstateMade[2048]; //Stores the filename of the last state loaded (needed for Undo/Redo loadstate)
|
||||
std::string lastLoadstateMade; //Stores the filename of the last state loaded (needed for Undo/Redo loadstate)
|
||||
bool undoLS = false; //This will be true if a backupstate was made and it was made since ROM was loaded
|
||||
bool redoLS = false; //This will be true if a backupstate was loaded, meaning redoLoadState can be run
|
||||
|
||||
@@ -88,7 +88,7 @@ EMUFILE_MEMORY memory_savestate;
|
||||
// temporary buffer for compressed data of a savestate
|
||||
std::vector<uint8> compressed_buf;
|
||||
|
||||
#define SFMDATA_SIZE (64)
|
||||
#define SFMDATA_SIZE (128)
|
||||
static SFORMAT SFMDATA[SFMDATA_SIZE];
|
||||
static int SFEXINDEX;
|
||||
|
||||
@@ -110,7 +110,7 @@ SFORMAT SFCPU[]={
|
||||
{ &X.Y, 1, "Y\0\0"},
|
||||
{ &X.S, 1, "S\0\0"},
|
||||
{ &X.P, 1, "P\0\0"},
|
||||
{ &X.DB, 1, "DB"},
|
||||
{ &X.DB, 1, "DB\0"},
|
||||
{ &RAM, 0x800 | FCEUSTATE_INDIRECT, "RAM", },
|
||||
{ 0 }
|
||||
};
|
||||
@@ -133,7 +133,7 @@ static int SubWrite(EMUFILE* os, SFORMAT *sf)
|
||||
|
||||
while(sf->v)
|
||||
{
|
||||
if(sf->s==~0) //Link to another struct
|
||||
if(sf->s==~0u) //Link to another struct
|
||||
{
|
||||
uint32 tmp;
|
||||
|
||||
@@ -191,7 +191,7 @@ static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc)
|
||||
{
|
||||
while(sf->v)
|
||||
{
|
||||
if(sf->s==~0) // Link to another SFORMAT structure.
|
||||
if(sf->s==~0u) // Link to another SFORMAT structure.
|
||||
{
|
||||
SFORMAT *tmp;
|
||||
if((tmp= CheckS((SFORMAT *)sf->v, tsize, desc) ))
|
||||
@@ -307,13 +307,24 @@ static bool ReadStateChunks(EMUFILE* is, int32 totalsize)
|
||||
// load back buffer
|
||||
{
|
||||
extern uint8 *XBackBuf;
|
||||
if(is->fread((char*)XBackBuf,size) != size)
|
||||
ret = false;
|
||||
//ignore 8 garbage bytes, whose idea was it to write these or even have them there in the first place
|
||||
if(size == 256*256+8)
|
||||
{
|
||||
if(is->fread((char*)XBackBuf,256*256) != 256*256)
|
||||
ret = false;
|
||||
is->fseek(8,SEEK_CUR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is->fread((char*)XBackBuf,size) != size)
|
||||
ret = false;
|
||||
}
|
||||
|
||||
|
||||
//MBG TODO - can this be moved to a better place?
|
||||
//does it even make sense, displaying XBuf when its XBackBuf we just loaded?
|
||||
#ifdef __WIN_DRIVER__
|
||||
else
|
||||
if(ret)
|
||||
{
|
||||
FCEUD_BlitScreen(XBuf);
|
||||
UpdateFCEUWindow();
|
||||
@@ -404,7 +415,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
// save back buffer
|
||||
{
|
||||
extern uint8 *XBackBuf;
|
||||
uint32 size = 256 * 256 + 8;
|
||||
uint32 size = 256 * 256;
|
||||
os->fputc(8);
|
||||
write32le(size, os);
|
||||
os->fwrite((char*)XBackBuf,size);
|
||||
@@ -416,7 +427,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
if(SPostSave) SPostSave();
|
||||
|
||||
//save the length of the file
|
||||
int len = memory_savestate.size();
|
||||
size_t len = memory_savestate.size();
|
||||
|
||||
//sanity check: len and totalsize should be the same
|
||||
if(len != totalsize)
|
||||
@@ -427,7 +438,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
|
||||
int error = Z_OK;
|
||||
uint8* cbuf = (uint8*)memory_savestate.buf();
|
||||
uLongf comprlen = -1;
|
||||
uLongf comprlen = ~0lu;
|
||||
if(compressionLevel != Z_NO_COMPRESSION && (compressSavestates || FCEUMOV_Mode(MOVIEMODE_TASEDITOR)))
|
||||
{
|
||||
// worst case compression: zlib says "0.1% larger than sourceLen plus 12 bytes"
|
||||
@@ -446,7 +457,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
|
||||
//dump it to the destination file
|
||||
outstream->fwrite((char*)header,16);
|
||||
outstream->fwrite((char*)cbuf,comprlen==-1?totalsize:comprlen);
|
||||
outstream->fwrite((char*)cbuf,comprlen==~0lu?totalsize:comprlen);
|
||||
|
||||
return error == Z_OK;
|
||||
}
|
||||
@@ -455,7 +466,7 @@ bool FCEUSS_SaveMS(EMUFILE* outstream, int compressionLevel)
|
||||
void FCEUSS_Save(const char *fname, bool display_message)
|
||||
{
|
||||
EMUFILE* st = 0;
|
||||
char fn[2048];
|
||||
std::string fn;
|
||||
|
||||
if (geniestage==1)
|
||||
{
|
||||
@@ -467,24 +478,24 @@ void FCEUSS_Save(const char *fname, bool display_message)
|
||||
if(fname) //If filename is given use it.
|
||||
{
|
||||
st = FCEUD_UTF8_fstream(fname, "wb");
|
||||
strcpy(fn, fname);
|
||||
fn.assign(fname);
|
||||
}
|
||||
else //Else, generate one
|
||||
{
|
||||
//FCEU_PrintError("daCurrentState=%d",CurrentState);
|
||||
strcpy(fn, FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str());
|
||||
fn = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0);
|
||||
|
||||
//backup existing savestate first
|
||||
if (CheckFileExists(fn) && backupSavestates) //adelikat: If the files exists and we are allowed to make backup savestates
|
||||
if (CheckFileExists(fn.c_str()) && backupSavestates) //adelikat: If the files exists and we are allowed to make backup savestates
|
||||
{
|
||||
CreateBackupSaveState(fn); //Make a backup of previous savestate before overwriting it
|
||||
strcpy(lastSavestateMade,fn); //Remember what the last savestate filename was (for undoing later)
|
||||
CreateBackupSaveState(fn.c_str()); //Make a backup of previous savestate before overwriting it
|
||||
lastSavestateMade.assign(fn); //Remember what the last savestate filename was (for undoing later)
|
||||
undoSS = true; //Backup was created so undo is possible
|
||||
}
|
||||
else
|
||||
undoSS = false; //so backup made so lastSavestateMade does have a backup file, so no undo
|
||||
|
||||
st = FCEUD_UTF8_fstream(fn,"wb");
|
||||
st = FCEUD_UTF8_fstream(fn.c_str(),"wb");
|
||||
}
|
||||
|
||||
if (st == NULL || st->get_fp() == NULL)
|
||||
@@ -500,13 +511,12 @@ void FCEUSS_Save(const char *fname, bool display_message)
|
||||
LuaSaveData saveData;
|
||||
CallRegisteredLuaSaveFunctions(CurrentState, saveData);
|
||||
|
||||
char luaSaveFilename [512];
|
||||
strncpy(luaSaveFilename, fn, 512);
|
||||
luaSaveFilename[512-(1+7/*strlen(".luasav")*/)] = '\0';
|
||||
strcat(luaSaveFilename, ".luasav");
|
||||
std::string luaSaveFilename;
|
||||
luaSaveFilename.assign(fn.c_str());
|
||||
luaSaveFilename.append(".luasav");
|
||||
if(saveData.recordList)
|
||||
{
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename, "wb");
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename.c_str(), "wb");
|
||||
if(luaSaveFile)
|
||||
{
|
||||
saveData.ExportRecords(luaSaveFile);
|
||||
@@ -515,7 +525,7 @@ void FCEUSS_Save(const char *fname, bool display_message)
|
||||
}
|
||||
else
|
||||
{
|
||||
unlink(luaSaveFilename);
|
||||
unlink(luaSaveFilename.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -655,22 +665,22 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int totalsize = FCEU_de32lsb(header + 4);
|
||||
int stateversion = FCEU_de32lsb(header + 8);
|
||||
int comprlen = FCEU_de32lsb(header + 12);
|
||||
size_t totalsize = FCEU_de32lsb(header + 4);
|
||||
int stateversion = FCEU_de32lsb(header + 8);
|
||||
uint32_t comprlen = FCEU_de32lsb(header + 12);
|
||||
|
||||
// reinit memory_savestate
|
||||
// memory_savestate is global variable which already has its vector of bytes, so no need to allocate memory every time we use save/loadstate
|
||||
if ((int)(memory_savestate.get_vec())->size() < totalsize)
|
||||
if ((memory_savestate.get_vec())->size() < totalsize)
|
||||
(memory_savestate.get_vec())->resize(totalsize);
|
||||
memory_savestate.set_len(totalsize);
|
||||
memory_savestate.unfail();
|
||||
memory_savestate.fseek(0, SEEK_SET);
|
||||
|
||||
if(comprlen != -1)
|
||||
if(comprlen != ~0u)
|
||||
{
|
||||
// the savestate is compressed: read from is to compressed_buf, then decompress from compressed_buf to memory_savestate.vec
|
||||
if ((int)compressed_buf.size() < comprlen) compressed_buf.resize(comprlen);
|
||||
if (compressed_buf.size() < comprlen) compressed_buf.resize(comprlen);
|
||||
is->fread(&compressed_buf[0], comprlen);
|
||||
|
||||
uLongf uncomprlen = totalsize;
|
||||
@@ -712,8 +722,8 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
|
||||
|
||||
bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
{
|
||||
EMUFILE* st;
|
||||
char fn[2048];
|
||||
fceuScopedPtr <EMUFILE> st; // fceuScopedPtr will auto delete the allocated EMUFILE at function return.
|
||||
std::string fn;
|
||||
|
||||
//mbg movie - this needs to be overhauled
|
||||
////this fixes read-only toggle problems
|
||||
@@ -731,20 +741,21 @@ bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
if (fname)
|
||||
{
|
||||
st = FCEUD_UTF8_fstream(fname, "rb");
|
||||
strcpy(fn, fname);
|
||||
} else
|
||||
fn.assign(fname);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(fn, FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname).c_str());
|
||||
st=FCEUD_UTF8_fstream(fn,"rb");
|
||||
strcpy(lastLoadstateMade,fn);
|
||||
fn = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname);
|
||||
st=FCEUD_UTF8_fstream(fn.c_str(),"rb");
|
||||
lastLoadstateMade.assign(fn);
|
||||
}
|
||||
|
||||
if (st == NULL || (st->get_fp() == NULL))
|
||||
if (st.get() == NULL || (st.get()->get_fp() == NULL))
|
||||
{
|
||||
if (display_message)
|
||||
{
|
||||
FCEU_DispMessage("State %d load error.", 0, CurrentState);
|
||||
//FCEU_DispMessage("State %d load error. Filename: %s", 0, CurrentState, fn);
|
||||
//FCEU_DispMessage("State %d load error. Filename: %s", 0, CurrentState, fn.c_str());
|
||||
}
|
||||
SaveStateStatus[CurrentState] = 0;
|
||||
return false;
|
||||
@@ -753,38 +764,37 @@ bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
//If in bot mode, don't do a backup when loading.
|
||||
//Otherwise you eat at the hard disk, since so many
|
||||
//states are being loaded.
|
||||
if (FCEUSS_LoadFP(st, backupSavestates ? SSLOADPARAM_BACKUP : SSLOADPARAM_NOBACKUP))
|
||||
if (FCEUSS_LoadFP(st.get(), backupSavestates ? SSLOADPARAM_BACKUP : SSLOADPARAM_NOBACKUP))
|
||||
{
|
||||
if (fname)
|
||||
{
|
||||
char szFilename[260]={0};
|
||||
splitpath(fname, 0, 0, szFilename, 0);
|
||||
if (display_message)
|
||||
if (display_message)
|
||||
{
|
||||
FCEU_DispMessage("State %s loaded.", 0, szFilename);
|
||||
//FCEU_DispMessage("State %s loaded. Filename: %s", 0, szFilename, fn);
|
||||
}
|
||||
} else
|
||||
FCEU_DispMessage("State %s loaded.", 0, szFilename);
|
||||
//FCEU_DispMessage("State %s loaded. Filename: %s", 0, szFilename, fn.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (display_message)
|
||||
if (display_message)
|
||||
{
|
||||
FCEU_DispMessage("State %d loaded.", 0, CurrentState);
|
||||
//FCEU_DispMessage("State %d loaded. Filename: %s", 0, CurrentState, fn);
|
||||
}
|
||||
FCEU_DispMessage("State %d loaded.", 0, CurrentState);
|
||||
//FCEU_DispMessage("State %d loaded. Filename: %s", 0, CurrentState, fn.c_str());
|
||||
}
|
||||
SaveStateStatus[CurrentState] = 1;
|
||||
}
|
||||
delete st;
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
if (!internalSaveLoad)
|
||||
{
|
||||
LuaSaveData saveData;
|
||||
|
||||
char luaSaveFilename [512];
|
||||
strncpy(luaSaveFilename, fn, 512);
|
||||
luaSaveFilename[512-(1+7/*strlen(".luasav")*/)] = '\0';
|
||||
strcat(luaSaveFilename, ".luasav");
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename, "rb");
|
||||
std::string luaSaveFilename;
|
||||
luaSaveFilename.assign(fn.c_str());
|
||||
luaSaveFilename.append(".luasav");
|
||||
FILE* luaSaveFile = fopen(luaSaveFilename.c_str(), "rb");
|
||||
if(luaSaveFile)
|
||||
{
|
||||
saveData.ImportRecords(luaSaveFile);
|
||||
@@ -796,7 +806,7 @@ bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
#endif
|
||||
|
||||
#ifdef __WIN_DRIVER__
|
||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||
Update_RAM_Search(); // Update_RAM_Watch() is also called.
|
||||
#endif
|
||||
|
||||
//Update input display if movie is loaded
|
||||
@@ -806,7 +816,8 @@ bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
cur_input_display = FCEU_GetJoyJoy(); //Input display should show the last buttons pressed (stored in the savestate)
|
||||
|
||||
return true;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!fname)
|
||||
SaveStateStatus[CurrentState] = 1;
|
||||
@@ -816,7 +827,6 @@ bool FCEUSS_Load(const char *fname, bool display_message)
|
||||
FCEU_DispMessage("Error(s) reading state %d!", 0, CurrentState);
|
||||
//FCEU_DispMessage("Error(s) reading state %d! Filename: %s", 0, CurrentState, fn);
|
||||
}
|
||||
delete st;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -848,7 +858,7 @@ void ResetExState(void (*PreSave)(void), void (*PostSave)(void))
|
||||
for(x=0;x<SFEXINDEX;x++)
|
||||
{
|
||||
if(SFMDATA[x].desc)
|
||||
free( (void*)SFMDATA[x].desc);
|
||||
FCEU_free( (void*)SFMDATA[x].desc);
|
||||
}
|
||||
// adelikat, 3/14/09: had to add this to clear out the size parameter. NROM(mapper 0) games were having savestate crashes if loaded after a non NROM game because the size variable was carrying over and causing savestates to save too much data
|
||||
SFMDATA[0].s = 0;
|
||||
@@ -863,7 +873,7 @@ void AddExState(void *v, uint32 s, int type, const char *desc)
|
||||
//do not accept extra state information if a null pointer was provided for v, so list won't terminate early
|
||||
if (v == 0) return;
|
||||
|
||||
if(s==~0)
|
||||
if(s==~0u)
|
||||
{
|
||||
SFORMAT* sf = (SFORMAT*)v;
|
||||
std::map<std::string,bool> names;
|
||||
@@ -1056,13 +1066,13 @@ void SwapSaveState()
|
||||
//Both files must exist
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
if (!lastSavestateMade)
|
||||
if (lastSavestateMade.empty())
|
||||
{
|
||||
FCEUI_DispMessage("Can't Undo",0);
|
||||
FCEUI_printf("Undo savestate was attempted but unsuccessful because there was not a recently used savestate.\n");
|
||||
return; //If there is no last savestate, can't undo
|
||||
}
|
||||
string backup = GenerateBackupSaveStateFn(lastSavestateMade); //Get filename of backup state
|
||||
string backup = GenerateBackupSaveStateFn(lastSavestateMade.c_str()); //Get filename of backup state
|
||||
if (!CheckFileExists(backup.c_str()))
|
||||
{
|
||||
FCEUI_DispMessage("Can't Undo",0);
|
||||
@@ -1076,9 +1086,9 @@ void SwapSaveState()
|
||||
string temp = backup; //Put backup filename in temp
|
||||
temp.append("x"); //Add x
|
||||
|
||||
rename(backup.c_str(),temp.c_str()); //rename backup file to temp file
|
||||
rename(lastSavestateMade,backup.c_str()); //rename current as backup
|
||||
rename(temp.c_str(),lastSavestateMade); //rename backup as current
|
||||
rename(backup.c_str(),temp.c_str()); //rename backup file to temp file
|
||||
rename(lastSavestateMade.c_str(),backup.c_str()); //rename current as backup
|
||||
rename(temp.c_str(),lastSavestateMade.c_str()); //rename backup as current
|
||||
|
||||
undoSS = true; //Just in case, if this was run, then there is definately a last savestate and backup
|
||||
if (redoSS) //This was a redo function, so if run again it will be an undo again
|
||||
@@ -1103,7 +1113,7 @@ string GetBackupFileName()
|
||||
string filename;
|
||||
int x;
|
||||
|
||||
filename = strdup(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0).c_str()); //Generate normal savestate filename
|
||||
filename = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); //Generate normal savestate filename
|
||||
x = filename.find_last_of("."); //Find last dot
|
||||
filename = filename.substr(0,x); //Chop off file extension
|
||||
filename.append(".bak.fc0"); //add .bak
|
||||
@@ -1161,10 +1171,10 @@ void LoadBackup()
|
||||
void RedoLoadState()
|
||||
{
|
||||
if (!redoLS) return;
|
||||
if (lastLoadstateMade && redoLS)
|
||||
if (!lastLoadstateMade.empty() && redoLS)
|
||||
{
|
||||
FCEUSS_Load(lastLoadstateMade);
|
||||
FCEUI_printf("Redoing %s\n",lastLoadstateMade);
|
||||
FCEUSS_Load(lastLoadstateMade.c_str());
|
||||
FCEUI_printf("Redoing %s\n",lastLoadstateMade.c_str());
|
||||
}
|
||||
redoLS = false; //Flag that RedoLoadState can not be run again
|
||||
undoLS = true; //Flag that LoadBackup can be run again
|
||||
|
||||
+3
-2
@@ -17,6 +17,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <string>
|
||||
|
||||
enum ENUM_SSLOADPARAMS
|
||||
{
|
||||
@@ -67,10 +68,10 @@ void LoadBackup(); //Loads the backupsavestate
|
||||
void RedoLoadState(); //reloads a loadstate if backupsavestate was run
|
||||
void SwapSaveState(); //Swaps a savestate with its backup state
|
||||
|
||||
extern char lastSavestateMade[2048]; //Filename of last savestate used
|
||||
extern std::string lastSavestateMade; //Filename of last savestate used
|
||||
extern bool undoSS; //undo savestate flag
|
||||
extern bool redoSS; //redo savestate flag
|
||||
extern char lastLoadstateMade[2048]; //Filename of last state loaded
|
||||
extern std::string lastLoadstateMade; //Filename of last state loaded
|
||||
extern bool undoLS; //undo loadstate flag
|
||||
extern bool redoLS; //redo savestate flag
|
||||
extern bool backupSavestates; //Whether or not to make backups, true by default
|
||||
|
||||
+85
-1
@@ -62,6 +62,8 @@ typedef signed int int32;
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
//#include <typeinfo>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -131,7 +133,7 @@ typedef uint32_t uint32;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) && !defined(__QT_DRIVER__)
|
||||
#if defined(WIN32) && !defined(__QT_DRIVER__) && !defined(__WIN_DRIVER__)
|
||||
#define __WIN_DRIVER__
|
||||
#endif
|
||||
|
||||
@@ -143,6 +145,88 @@ typedef uint8 (*readfunc)(uint32 A);
|
||||
#define CTASSERT(x) typedef char __assert ## y[(x) ? 1 : -1];
|
||||
#endif
|
||||
|
||||
#define __FCEU_STRINGIZE2(x) #x
|
||||
#define __FCEU_STRINGIZE(x) __FCEU_STRINGIZE2(x)
|
||||
|
||||
#define FCEU_CPP_HAS_STD(x) ( defined(__cplusplus) && (__cplusplus >= x) )
|
||||
|
||||
#ifdef __has_cpp_attribute
|
||||
#define FCEU_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||
#else
|
||||
#define FCEU_HAS_CPP_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
|
||||
#define FCEU_UNUSED(x) (void)(x)
|
||||
|
||||
#if FCEU_CPP_HAS_STD(201603L) || FCEU_HAS_CPP_ATTRIBUTE(maybe_unused)
|
||||
#define FCEU_MAYBE_UNUSED [[maybe_unused]]
|
||||
#else
|
||||
#define FCEU_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Microsoft compiler won't catch format issues, but VS IDE can catch on analysis mode
|
||||
#define __FCEU_PRINTF_FORMAT _In_z_ _Printf_format_string_
|
||||
#define __FCEU_PRINTF_ATTRIBUTE( fmt, va )
|
||||
|
||||
#elif defined(__GNUC__) || defined(__clang__) || FCEU_HAS_CPP_ATTRIBUTE(format)
|
||||
// GCC and Clang compilers will perform printf format type checks, useful for catching format errors.
|
||||
#define __FCEU_PRINTF_FORMAT
|
||||
#define __FCEU_PRINTF_ATTRIBUTE( fmt, va ) __attribute__((__format__(__printf__, fmt, va)))
|
||||
|
||||
#else
|
||||
#define __FCEU_PRINTF_FORMAT
|
||||
#define __FCEU_PRINTF_ATTRIBUTE( fmt, va )
|
||||
#endif
|
||||
|
||||
// Scoped pointer ensures that memory pointed to by this object gets cleaned up
|
||||
// and deallocated when this object goes out of scope. Helps prevent memory leaks
|
||||
// on temporary memory allocations in functions with early outs.
|
||||
template <typename T>
|
||||
class fceuScopedPtr
|
||||
{
|
||||
public:
|
||||
fceuScopedPtr( T *ptrIn = nullptr )
|
||||
{
|
||||
//printf("Scoped Pointer Constructor <%s>: %p\n", typeid(T).name(), ptrIn );
|
||||
ptr = ptrIn;
|
||||
}
|
||||
|
||||
~fceuScopedPtr(void)
|
||||
{
|
||||
//printf("Scoped Pointer Destructor <%s>: %p\n", typeid(T).name(), ptr );
|
||||
if (ptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
T* operator= (T *ptrIn)
|
||||
{
|
||||
ptr = ptrIn;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* get(void)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void Delete(void)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T *ptr;
|
||||
|
||||
};
|
||||
|
||||
#include "utils/endian.h"
|
||||
|
||||
#endif
|
||||
|
||||
+2
-1
@@ -140,7 +140,7 @@ static int DoMirroring(FCEUFILE *fp) {
|
||||
return(0);
|
||||
FCEU_printf(" %02x", t);
|
||||
}
|
||||
FCEU_printf("\n Default Name/Attribute Table Mirroring: Horizontal\n", uchead.info);
|
||||
FCEU_printf("\n Default Name/Attribute Table Mirroring: Horizontal\n");
|
||||
mirrortodo = 0;
|
||||
}
|
||||
return(1);
|
||||
@@ -475,6 +475,7 @@ static BMAPPING bmap[] = {
|
||||
{ "FNS", FNS_Init, BMCFLAG_16KCHRR },
|
||||
{ "BS-400R", BS400R_Init, 0 },
|
||||
{ "BS-4040R", BS4040R_Init, 0 },
|
||||
{ "COOLGIRL", COOLGIRL_Init, 0 },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
+2
-1
@@ -162,7 +162,8 @@ void MINDKIDS_Init(CartInfo *info);
|
||||
void FNS_Init(CartInfo *info);
|
||||
void BS400R_Init(CartInfo *info);
|
||||
void BS4040R_Init(CartInfo *info);
|
||||
void SMD132_SMD133_Init(CartInfo *info);
|
||||
void AA6023_Init(CartInfo *info);
|
||||
void COOLGIRL_Init(CartInfo* info);
|
||||
|
||||
extern uint8 *UNIFchrrama; // Meh. So I can stop CHR RAM
|
||||
// bank switcherooing with certain boards...
|
||||
|
||||
+65
-28
@@ -28,53 +28,90 @@
|
||||
#include "../fceu.h"
|
||||
#include "memory.h"
|
||||
|
||||
///allocates the specified number of bytes. exits process if this fails
|
||||
void *FCEU_amalloc(size_t size, size_t alignment)
|
||||
{
|
||||
size = (size + alignment - 1) & ~(alignment-1);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
void *ret = _aligned_malloc(size,alignment);
|
||||
#else
|
||||
void *ret = aligned_alloc(alignment,size);
|
||||
#endif
|
||||
|
||||
if(!ret)
|
||||
FCEU_abort("Error allocating memory!");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FCEU_afree(void* ptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *_FCEU_malloc(uint32 size)
|
||||
{
|
||||
void* ret = malloc(size);
|
||||
|
||||
if(!ret)
|
||||
FCEU_abort("Error allocating memory!");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _FCEU_free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void *FCEU_gmalloc(uint32 size)
|
||||
{
|
||||
|
||||
void *ret;
|
||||
ret=malloc(size);
|
||||
if(!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory! Doing a hard exit.");
|
||||
exit(1);
|
||||
}
|
||||
FCEU_MemoryRand((uint8*)ret,size,true); // initialize according to RAMInitOption, default zero
|
||||
return ret;
|
||||
void *ret = _FCEU_malloc(size);
|
||||
|
||||
// initialize according to RAMInitOption, default zero
|
||||
FCEU_MemoryRand((uint8*)ret,size,true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///allocates the specified number of bytes. returns null if this fails
|
||||
void *FCEU_malloc(uint32 size)
|
||||
{
|
||||
void *ret;
|
||||
ret=malloc(size);
|
||||
if(!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory!");
|
||||
return(0);
|
||||
}
|
||||
memset(ret,0,size); // initialize to 0
|
||||
return ret;
|
||||
void *ret = _FCEU_malloc(size);
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
///frees memory allocated with FCEU_gmalloc
|
||||
void FCEU_gfree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
_FCEU_free(ptr);
|
||||
}
|
||||
|
||||
///frees memory allocated with FCEU_malloc
|
||||
void FCEU_free(void *ptr) // Might do something with this and FCEU_malloc later...
|
||||
void FCEU_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
_FCEU_free(ptr);
|
||||
}
|
||||
|
||||
void *FCEU_dmalloc(uint32 size)
|
||||
{
|
||||
return malloc(size);
|
||||
return FCEU_malloc(size);
|
||||
}
|
||||
|
||||
void FCEU_dfree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
return FCEU_free(ptr);
|
||||
}
|
||||
|
||||
void* FCEU_realloc(void* ptr, size_t size)
|
||||
{
|
||||
return realloc(ptr,size);
|
||||
}
|
||||
|
||||
void FCEU_abort(const char* message)
|
||||
{
|
||||
if(message) FCEU_PrintError("%s", message);
|
||||
abort();
|
||||
}
|
||||
|
||||
+28
-7
@@ -24,13 +24,34 @@
|
||||
|
||||
#define FCEU_dwmemset(d,c,n) {int _x; for(_x=n-4;_x>=0;_x-=4) *(uint32 *)&(d)[_x]=c;}
|
||||
|
||||
void *FCEU_malloc(uint32 size); // initialized to 0
|
||||
void *FCEU_gmalloc(uint32 size); // used by boards for WRAM etc, initialized to 0 (default) or other via RAMInitOption
|
||||
void FCEU_gfree(void *ptr);
|
||||
void FCEU_free(void *ptr);
|
||||
void FCEU_memmove(void *d, void *s, uint32 l);
|
||||
//returns a buffer initialized to 0
|
||||
void *FCEU_malloc(uint32 size);
|
||||
|
||||
// wrapper for debugging when its needed, otherwise act like
|
||||
// normal malloc/free
|
||||
//returns a buffer, with jumbled initial contents
|
||||
//used by boards for WRAM etc, initialized to 0 (default) or other via RAMInitOption
|
||||
void *FCEU_gmalloc(uint32 size);
|
||||
|
||||
//free memory allocated with FCEU_gmalloc
|
||||
void FCEU_gfree(void *ptr);
|
||||
|
||||
//returns an aligned buffer, initialized to 0
|
||||
//the alignment will default to the largest thing you could ever sensibly want for massively aligned cache friendly buffers
|
||||
void *FCEU_amalloc(size_t size, size_t alignment = 256);
|
||||
|
||||
//frees memory allocated with FCEU_amalloc
|
||||
void FCEU_afree(void* ptr);
|
||||
|
||||
//free memory allocated with FCEU_malloc
|
||||
void FCEU_free(void *ptr);
|
||||
|
||||
//reallocate memory allocated with FCEU_malloc
|
||||
void* FCEU_realloc(void* ptr, size_t size);
|
||||
|
||||
//don't use these. change them if you find them.
|
||||
void *FCEU_dmalloc(uint32 size);
|
||||
|
||||
//don't use these. change them if you find them.
|
||||
void FCEU_dfree(void *ptr);
|
||||
|
||||
//aborts the process for fatal errors
|
||||
void FCEU_abort(const char* message = nullptr);
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// mutex.cpp
|
||||
#include <cstdio>
|
||||
|
||||
#include "mutex.h"
|
||||
|
||||
namespace FCEU
|
||||
{
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Cross platform mutex
|
||||
// __QT_DRIVER__ multi-threaded application that uses Qt mutex implementation for synchronization
|
||||
// __WIN_DRIVER__ is single thread application so sync methods are unimplemented.
|
||||
//-----------------------------------------------------
|
||||
mutex::mutex(void)
|
||||
{
|
||||
#ifdef __QT_DRIVER__
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
mtx = new QRecursiveMutex();
|
||||
#else
|
||||
mtx = new QMutex( QMutex::Recursive );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
mutex::~mutex(void)
|
||||
{
|
||||
#ifdef __QT_DRIVER__
|
||||
if (mtx)
|
||||
{
|
||||
delete mtx;
|
||||
mtx = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex::lock(void)
|
||||
{
|
||||
#ifdef __QT_DRIVER__
|
||||
mtx->lock();
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex::unlock(void)
|
||||
{
|
||||
#ifdef __QT_DRIVER__
|
||||
mtx->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
// Scoped AutoLock
|
||||
//-----------------------------------------------------
|
||||
autoScopedLock::autoScopedLock( mutex *mtx )
|
||||
{
|
||||
m = mtx;
|
||||
if (m)
|
||||
{
|
||||
m->lock();
|
||||
}
|
||||
}
|
||||
|
||||
autoScopedLock::~autoScopedLock(void)
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
m->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
// mutex.h
|
||||
|
||||
#ifdef __QT_DRIVER__
|
||||
#include <QMutex>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
#include <QRecursiveMutex>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace FCEU
|
||||
{
|
||||
class mutex
|
||||
{
|
||||
public:
|
||||
mutex(void);
|
||||
~mutex(void);
|
||||
|
||||
void lock(void);
|
||||
void unlock(void);
|
||||
|
||||
private:
|
||||
#ifdef __QT_DRIVER__
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
|
||||
QRecursiveMutex *mtx;
|
||||
#else
|
||||
QMutex *mtx;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
class autoScopedLock
|
||||
{
|
||||
public:
|
||||
autoScopedLock( mutex *mtx );
|
||||
~autoScopedLock(void);
|
||||
|
||||
private:
|
||||
mutex *m;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -194,7 +194,7 @@ static const struct Base64Table
|
||||
data[62] = '+'; // 62
|
||||
data[63] = '/'; // 63
|
||||
// create ascii->value mapping (but due to overlap, write it to highbit region)
|
||||
for(a=0; a<64; ++a) data[data[a]^0x80] = a; //
|
||||
for(a=0; a<64; ++a) data[data[a]^0x80] = static_cast<unsigned char>(a); //
|
||||
data[((unsigned char)'=') ^ 0x80] = 0;
|
||||
}
|
||||
unsigned char operator[] (size_t pos) const { return data[pos]; }
|
||||
|
||||
+2
-2
@@ -62,14 +62,14 @@
|
||||
|
||||
#define FCEU_VERSION_MAJOR 2
|
||||
#define FCEU_VERSION_MINOR 6
|
||||
#define FCEU_VERSION_PATCH 3
|
||||
#define FCEU_VERSION_PATCH 5
|
||||
|
||||
#define FCEU_VERSION_NUMERIC ( (FCEU_VERSION_MAJOR*10000) + (FCEU_VERSION_MINOR*100) + (FCEU_VERSION_PATCH) )
|
||||
#define FCEU_VERSION_MAJOR_DECODE(x) ( (x / 10000) )
|
||||
#define FCEU_VERSION_MINOR_DECODE(x) ( (x / 100) % 100 )
|
||||
#define FCEU_VERSION_PATCH_DECODE(x) (x % 100)
|
||||
|
||||
#define FCEU_VERSION_STRING "2.6.3" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER
|
||||
#define FCEU_VERSION_STRING "2.6.5" FCEU_SUBVERSION_STRING FCEU_FEATURE_STRING FCEU_COMPILER
|
||||
#define FCEU_NAME_AND_VERSION FCEU_NAME " " FCEU_VERSION_STRING
|
||||
|
||||
#endif
|
||||
|
||||
+15
-25
@@ -91,19 +91,19 @@ void FCEU_KillVirtualVideo(void)
|
||||
{
|
||||
if ( XBuf )
|
||||
{
|
||||
FCEU_free(XBuf); XBuf = NULL;
|
||||
FCEU_afree(XBuf); XBuf = NULL;
|
||||
}
|
||||
if ( XBackBuf )
|
||||
{
|
||||
FCEU_free(XBackBuf); XBackBuf = NULL;
|
||||
FCEU_afree(XBackBuf); XBackBuf = NULL;
|
||||
}
|
||||
if ( XDBuf )
|
||||
{
|
||||
FCEU_free(XDBuf); XDBuf = NULL;
|
||||
FCEU_afree(XDBuf); XDBuf = NULL;
|
||||
}
|
||||
if ( XDBackBuf )
|
||||
{
|
||||
FCEU_free(XDBackBuf); XDBackBuf = NULL;
|
||||
FCEU_afree(XDBackBuf); XDBackBuf = NULL;
|
||||
}
|
||||
//printf("Video Core Cleanup\n");
|
||||
}
|
||||
@@ -116,32 +116,22 @@ void FCEU_KillVirtualVideo(void)
|
||||
int FCEU_InitVirtualVideo(void)
|
||||
{
|
||||
//Some driver code may allocate XBuf externally.
|
||||
//256 bytes per scanline, * 240 scanline maximum, +16 for alignment,
|
||||
//256 bytes per scanline, * 240 scanline maximum
|
||||
if(XBuf)
|
||||
return 1;
|
||||
|
||||
XBuf = (u8*)FCEU_malloc(256 * 256 + 16);
|
||||
XBackBuf = (u8*)FCEU_malloc(256 * 256 + 16);
|
||||
XDBuf = (u8*)FCEU_malloc(256 * 256 + 16);
|
||||
XDBackBuf = (u8*)FCEU_malloc(256 * 256 + 16);
|
||||
if(!XBuf || !XBackBuf || !XDBuf || !XDBackBuf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
XBuf = (u8*)FCEU_amalloc(256 * 256);
|
||||
XBackBuf = (u8*)FCEU_amalloc(256 * 256);
|
||||
XDBuf = (u8*)FCEU_amalloc(256 * 256);
|
||||
XDBackBuf = (u8*)FCEU_amalloc(256 * 256);
|
||||
|
||||
|
||||
xbsave = XBuf;
|
||||
|
||||
if( sizeof(uint8*) == 4 )
|
||||
{
|
||||
uintptr_t m = (uintptr_t)XBuf;
|
||||
m = ( 8 - m) & 7;
|
||||
XBuf+=m;
|
||||
}
|
||||
|
||||
memset(XBuf,128,256*256);
|
||||
memset(XBackBuf,128,256*256);
|
||||
memset(XBuf,128,256*256);
|
||||
memset(XBackBuf,128,256*256);
|
||||
memset(XDBuf,0,256*256);
|
||||
memset(XDBackBuf,0,256*256);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -400,7 +390,7 @@ void snapAVI()
|
||||
FCEUI_AviVideoUpdate(XBuf);
|
||||
}
|
||||
|
||||
void FCEU_DispMessageOnMovie(const char *format, ...)
|
||||
void FCEU_DispMessageOnMovie( __FCEU_PRINTF_FORMAT const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -419,7 +409,7 @@ void FCEU_DispMessageOnMovie(const char *format, ...)
|
||||
guiMessage.howlong = 0;
|
||||
}
|
||||
|
||||
void FCEU_DispMessage(const char *format, int disppos=0, ...)
|
||||
void FCEU_DispMessage( __FCEU_PRINTF_FORMAT const char *format, int disppos=0, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -432,7 +422,7 @@ void FCEU_DispMessage(const char *format, int disppos=0, ...)
|
||||
vsnprintf(temp,sizeof(temp),format,ap);
|
||||
va_end(ap);
|
||||
strcat(temp, "\n");
|
||||
FCEU_printf(temp);
|
||||
FCEU_printf("%s",temp);
|
||||
|
||||
if ( vidGuiMsgEna )
|
||||
{
|
||||
|
||||
+10
@@ -7,10 +7,20 @@ int SaveSnapshot(char[]);
|
||||
void ResetScreenshotsCounter();
|
||||
uint32 GetScreenPixel(int x, int y, bool usebackup);
|
||||
int GetScreenPixelPalette(int x, int y, bool usebackup);
|
||||
|
||||
//in case we need more flags in the future we can change the size here
|
||||
//bit0 : monochrome bit
|
||||
//bit5 : emph red
|
||||
//bit6 : emph green
|
||||
//bit7 : emph blue
|
||||
typedef uint8 xfbuf_t;
|
||||
|
||||
extern uint8 *XBuf;
|
||||
extern uint8 *XBackBuf;
|
||||
extern uint8 *XDBuf;
|
||||
extern uint8 *XDBackBuf;
|
||||
extern xfbuf_t *XFBuf;
|
||||
|
||||
extern int ClipSidesOffset;
|
||||
|
||||
struct GUIMESSAGE
|
||||
|
||||
+168
-114
@@ -26,35 +26,23 @@
|
||||
#include "vsuni.h"
|
||||
#include "state.h"
|
||||
#include "driver.h"
|
||||
#include "cart.h"
|
||||
#include "ines.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#define IOPTION_GUN 0x1
|
||||
#define IOPTION_SWAPDIRAB 0x2
|
||||
|
||||
#define IOPTION_PREDIP 0x10
|
||||
typedef struct {
|
||||
const char *name;
|
||||
uint64 md5partial;
|
||||
int mapper;
|
||||
int mirroring;
|
||||
int ppu;
|
||||
int ioption;
|
||||
int predip;
|
||||
} VSUNIENTRY;
|
||||
|
||||
VSUNIENTRY *curvs;
|
||||
|
||||
static uint8 DIPS = 0;
|
||||
static int DIPS_howlong = 0;
|
||||
uint8 vsdip = 0;
|
||||
|
||||
void FCEUI_VSUniToggleDIPView(void) {
|
||||
DIPS = !DIPS;
|
||||
}
|
||||
|
||||
void FCEU_VSUniToggleDIP(int w) {
|
||||
if (GameInfo->type != GIT_VSUNI) {
|
||||
FCEU_DispMessage("Not Vs. System; toggle DIP switch.", 0);
|
||||
return;
|
||||
}
|
||||
vsdip ^= 1 << w;
|
||||
DIPS_howlong = 180;
|
||||
FCEU_DispMessage("DIP switch %d is %s.", 0, w, vsdip & (1 << w) ? "on" : "off");
|
||||
}
|
||||
|
||||
void FCEUI_VSUniSetDIP(int w, int state) {
|
||||
@@ -66,20 +54,19 @@ uint8 FCEUI_VSUniGetDIPs(void) {
|
||||
return(vsdip);
|
||||
}
|
||||
|
||||
static uint8 secdata[2][32] =
|
||||
static uint8 secdata_tko[32] =
|
||||
{
|
||||
{
|
||||
0xff, 0xbf, 0xb7, 0x97, 0x97, 0x17, 0x57, 0x4f,
|
||||
0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90, 0x94, 0x14,
|
||||
0x56, 0x4e, 0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90,
|
||||
0xd4, 0x5c, 0x3e, 0x26, 0x87, 0x83, 0x13, 0x00
|
||||
},
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
|
||||
0x00, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}
|
||||
0xff, 0xbf, 0xb7, 0x97, 0x97, 0x17, 0x57, 0x4f,
|
||||
0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90, 0x94, 0x14,
|
||||
0x56, 0x4e, 0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90,
|
||||
0xd4, 0x5c, 0x3e, 0x26, 0x87, 0x83, 0x13, 0x00
|
||||
};
|
||||
static uint8 secdata_rbi[32] =
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
|
||||
0x00, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static uint8 *secptr;
|
||||
@@ -93,24 +80,30 @@ static DECLFR(VSSecRead) {
|
||||
}
|
||||
return(0x00);
|
||||
}
|
||||
uint8 coinon = 0;
|
||||
|
||||
void FCEU_VSUniCoin(void) {
|
||||
coinon = 6;
|
||||
uint8 coinon = 0;
|
||||
uint8 coinon2 = 0;
|
||||
uint8 service = 0;
|
||||
|
||||
void FCEU_VSUniCoin(uint8 slot) {
|
||||
if (GameInfo->type != GIT_VSUNI)
|
||||
FCEU_DispMessage("Not Vs. System; can't insert coin.", 0);
|
||||
else {
|
||||
switch (slot) {
|
||||
case 0:
|
||||
coinon = 6; break;
|
||||
case 1:
|
||||
coinon2 = 6; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int curppu;
|
||||
static int64 curmd5;
|
||||
|
||||
#define RP2C04_001 1
|
||||
#define RP2C04_002 2
|
||||
#define RP2C04_003 3
|
||||
#define RP2C05_004 4
|
||||
#define RCP2C03B 5
|
||||
#define RC2C05_01 6
|
||||
#define RC2C05_02 7
|
||||
#define RC2C05_03 8
|
||||
#define RC2C05_04 9
|
||||
void FCEU_VSUniService() {
|
||||
if (GameInfo->type != GIT_VSUNI)
|
||||
FCEU_DispMessage("Not Vs. System; can't press service button.", 0);
|
||||
else
|
||||
service = 6;
|
||||
}
|
||||
|
||||
static readfunc OldReadPPU;
|
||||
static writefunc OldWritePPU[2];
|
||||
@@ -126,10 +119,10 @@ static DECLFR(A2002_Topgun) {
|
||||
static DECLFR(A2002_MBJ) { // Mighty Bomb Jack
|
||||
return((OldReadPPU(A) & ~0x3F) | 0x3D);
|
||||
}
|
||||
|
||||
static DECLFW(B2000_2001_2C05) {
|
||||
OldWritePPU[(A & 1) ^ 1](A ^ 1, V);
|
||||
}
|
||||
|
||||
static uint8 xevselect = 0;
|
||||
static DECLFR(XevRead) {
|
||||
if (A == 0x54FF) {
|
||||
@@ -146,7 +139,7 @@ static DECLFR(XevRead) {
|
||||
}
|
||||
|
||||
void FCEU_VSUniSwap(uint8 *j0, uint8 *j1) {
|
||||
if (curvs->ioption & IOPTION_SWAPDIRAB) {
|
||||
if (GameInfo->vs_cswitch) {
|
||||
uint16 t = *j0;
|
||||
*j0 = (*j0 & 0xC) | (*j1 & 0xF3);
|
||||
*j1 = (*j1 & 0xC) | (t & 0xF3);
|
||||
@@ -154,28 +147,39 @@ void FCEU_VSUniSwap(uint8 *j0, uint8 *j1) {
|
||||
}
|
||||
|
||||
void FCEU_VSUniPower(void) {
|
||||
coinon = 0;
|
||||
coinon = coinon2 = service = 0;
|
||||
VSindex = 0;
|
||||
|
||||
if (secptr)
|
||||
SetReadHandler(0x5e00, 0x5e01, VSSecRead);
|
||||
|
||||
if (curppu == RC2C05_04) {
|
||||
switch (GameInfo->vs_ppu) {
|
||||
case GIPPU_RP2C04_0001:
|
||||
case GIPPU_RP2C04_0002:
|
||||
case GIPPU_RP2C04_0003:
|
||||
case GIPPU_RP2C04_0004:
|
||||
default_palette_selection = GameInfo->vs_ppu;
|
||||
break;
|
||||
default:
|
||||
// nothing todo
|
||||
break;
|
||||
}
|
||||
if (GameInfo->vs_ppu == GIPPU_RC2C05_04) {
|
||||
OldReadPPU = GetReadHandler(0x2002);
|
||||
SetReadHandler(0x2002, 0x2002, A2002_Topgun);
|
||||
} else if (curppu == RC2C05_03) {
|
||||
} else if (GameInfo->vs_ppu == GIPPU_RC2C05_03) {
|
||||
OldReadPPU = GetReadHandler(0x2002);
|
||||
SetReadHandler(0x2002, 0x2002, A2002_Gumshoe);
|
||||
} else if (curppu == RC2C05_02) {
|
||||
} else if (GameInfo->vs_ppu == GIPPU_RC2C05_02) {
|
||||
OldReadPPU = GetReadHandler(0x2002);
|
||||
SetReadHandler(0x2002, 0x2002, A2002_MBJ);
|
||||
}
|
||||
if (curppu == RC2C05_04 || curppu == RC2C05_01 || curppu == RC2C05_03 || curppu == RC2C05_02) {
|
||||
if (GameInfo->vs_ppu == GIPPU_RC2C05_01 || GameInfo->vs_ppu == GIPPU_RC2C05_02 || GameInfo->vs_ppu == GIPPU_RC2C05_03 || GameInfo->vs_ppu == GIPPU_RC2C05_04) {
|
||||
OldWritePPU[0] = GetWriteHandler(0x2000);
|
||||
OldWritePPU[1] = GetWriteHandler(0x2001);
|
||||
SetWriteHandler(0x2000, 0x2001, B2000_2001_2C05);
|
||||
}
|
||||
if (curmd5 == 0x2d396247cf58f9faLL) { /* Super Xevious */
|
||||
if (GameInfo->vs_type == EGIVS_XEVIOUS) { /* Super Xevious */
|
||||
SetReadHandler(0x5400, 0x57FF, XevRead);
|
||||
}
|
||||
}
|
||||
@@ -252,47 +256,47 @@ RC2C05-04:
|
||||
|
||||
VSUNIENTRY VSUniGames[] =
|
||||
{
|
||||
{ "Baseball", 0x691d4200ea42be45ULL, 99, 2, RP2C04_001, 0 },
|
||||
{ "Battle City", 0x8540949d74c4d0ebULL, 99, 2, RP2C04_001, 0 },
|
||||
{ "Battle City(Bootleg)", 0x8093cbe7137ac031ULL, 99, 2, RP2C04_001, 0 },
|
||||
{ "Baseball", 0x691d4200ea42be45ULL, 99, 2, GIPPU_RP2C04_0001, 0, 0, EGIVS_NORMAL },
|
||||
{ "Battle City", 0x8540949d74c4d0ebULL, 99, 2, GIPPU_RP2C04_0001, 0, 0, EGIVS_NORMAL },
|
||||
{ "Battle City(Bootleg)", 0x8093cbe7137ac031ULL, 99, 2, GIPPU_RP2C04_0001, 0, 0, EGIVS_NORMAL },
|
||||
|
||||
{ "Clu Clu Land", 0x1b8123218f62b1eeULL, 99, 2, RP2C05_004, IOPTION_SWAPDIRAB },
|
||||
{ "Dr Mario", 0xe1af09c477dc0081ULL, 1, 0, RP2C04_003, IOPTION_SWAPDIRAB },
|
||||
{ "Duck Hunt", 0x47735d1e5f1205bbULL, 99, 2, RCP2C03B, IOPTION_GUN },
|
||||
{ "Excitebike", 0x3dcd1401bcafde77ULL, 99, 2, RP2C04_003, 0 },
|
||||
{ "Excitebike (J)", 0x7ea51c9d007375f0ULL, 99, 2, RP2C05_004, 0 },
|
||||
{ "Freedom Force", 0xed96436bd1b5e688ULL, 4, 0, RP2C04_001, IOPTION_GUN }, /* Wrong color in game select screen? */
|
||||
{ "Stroke and Match Golf", 0x612325606e82bc66ULL, 99, 2, RP2C04_002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x01 },
|
||||
{ "Clu Clu Land", 0x1b8123218f62b1eeULL, 99, 2, GIPPU_RP2C04_0004, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Dr Mario", 0xe1af09c477dc0081ULL, 1, 0, GIPPU_RP2C04_0003, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Duck Hunt", 0x47735d1e5f1205bbULL, 99, 2, GIPPU_RC2C03B, VS_OPTION_GUN, 0, EGIVS_NORMAL },
|
||||
{ "Excitebike", 0x3dcd1401bcafde77ULL, 99, 2, GIPPU_RP2C04_0003, 0, 0, EGIVS_NORMAL },
|
||||
{ "Excitebike (J)", 0x7ea51c9d007375f0ULL, 99, 2, GIPPU_RP2C04_0004, 0, 0, EGIVS_NORMAL },
|
||||
{ "Freedom Force", 0xed96436bd1b5e688ULL, 4, 0, GIPPU_RP2C04_0001, VS_OPTION_GUN, 0, EGIVS_NORMAL }, /* Wrong color in game select screen? */
|
||||
{ "Stroke and Match Golf", 0x612325606e82bc66ULL, 99, 2, GIPPU_RP2C04_0002, VS_OPTION_SWAPDIRAB | VS_OPTION_PREDIP, 0x01, EGIVS_NORMAL },
|
||||
|
||||
{ "Goonies", 0xb4032d694e1d2733ULL, 151, 1, RP2C04_003, 0 },
|
||||
{ "Gradius", 0x50687ae63bdad976ULL, 151, 1, RP2C04_001, IOPTION_SWAPDIRAB },
|
||||
{ "Gumshoe", 0x87161f8ee37758d3ULL, 99, 2, RC2C05_03, IOPTION_GUN },
|
||||
{ "Gumshoe", 0xb8500780bf69ce29ULL, 99, 2, RC2C05_03, IOPTION_GUN },
|
||||
{ "Hogan's Alley", 0xd78b7f0bb621fb45ULL, 99, 2, RP2C04_001, IOPTION_GUN },
|
||||
{ "Ice Climber", 0xd21e999513435e2aULL, 99, 2, RP2C05_004, IOPTION_SWAPDIRAB },
|
||||
{ "Ladies Golf", 0x781b24be57ef6785ULL, 99, 2, RP2C04_002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },
|
||||
{ "Goonies", 0xb4032d694e1d2733ULL, 151, 1, GIPPU_RP2C04_0003, 0, 0, EGIVS_NORMAL },
|
||||
{ "Gradius", 0x50687ae63bdad976ULL, 151, 1, GIPPU_RP2C04_0001, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Gumshoe", 0x87161f8ee37758d3ULL, 99, 2, GIPPU_RC2C05_03, VS_OPTION_GUN, 0, EGIVS_NORMAL },
|
||||
{ "Gumshoe", 0xb8500780bf69ce29ULL, 99, 2, GIPPU_RC2C05_03, VS_OPTION_GUN, 0, EGIVS_NORMAL },
|
||||
{ "Hogan's Alley", 0xd78b7f0bb621fb45ULL, 99, 2, GIPPU_RP2C04_0001, VS_OPTION_GUN, 0, EGIVS_NORMAL },
|
||||
{ "Ice Climber", 0xd21e999513435e2aULL, 99, 2, GIPPU_RP2C04_0004, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Ladies Golf", 0x781b24be57ef6785ULL, 99, 2, GIPPU_RP2C04_0002, VS_OPTION_SWAPDIRAB | VS_OPTION_PREDIP, 0x1, EGIVS_NORMAL },
|
||||
|
||||
{ "Mach Rider", 0x015672618af06441ULL, 99, 2, RP2C04_002, 0 },
|
||||
{ "Mach Rider (J)", 0xa625afb399811a8aULL, 99, 2, RP2C04_001, 0 },
|
||||
{ "Mighty Bomb Jack", 0xe6a89f4873fac37bULL, 0, 2, RC2C05_02, 0 },
|
||||
{ "Ninja Jajamaru Kun", 0xb26a2c31474099c0ULL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB },
|
||||
{ "Pinball", 0xc5f49d3de7f2e9b8ULL, 99, 2, RP2C04_001, IOPTION_PREDIP, 0x01 },
|
||||
{ "Pinball (J)", 0x66ab1a3828cc901cULL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x1 },
|
||||
{ "Platoon", 0x160f237351c19f1fULL, 68, 1, RP2C04_001, 0 },
|
||||
{ "RBI Baseball", 0x6a02d345812938afULL, 4, 1, RP2C04_001, IOPTION_SWAPDIRAB },
|
||||
{ "Soccer", 0xd4e7a9058780eda3ULL, 99, 2, RP2C04_003, IOPTION_SWAPDIRAB },
|
||||
{ "Star Luster", 0x8360e134b316d94cULL, 99, 2, RCP2C03B, 0 },
|
||||
{ "Stroke and Match Golf (J)", 0x869bb83e02509747ULL, 99, 2, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },
|
||||
{ "Super Sky Kid", 0x78d04c1dd4ec0101ULL, 4, 1, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x20 },
|
||||
{ "Mach Rider", 0x015672618af06441ULL, 99, 2, GIPPU_RP2C04_0002, 0, 0, EGIVS_NORMAL },
|
||||
{ "Mach Rider (J)", 0xa625afb399811a8aULL, 99, 2, GIPPU_RP2C04_0001, 0, 0, EGIVS_NORMAL },
|
||||
{ "Mighty Bomb Jack", 0xe6a89f4873fac37bULL, 0, 2, GIPPU_RC2C05_02, 0, 0, EGIVS_NORMAL },
|
||||
{ "Ninja Jajamaru Kun", 0xb26a2c31474099c0ULL, 99, 2, GIPPU_RC2C05_01, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Pinball", 0xc5f49d3def2e9b8ULL, 99, 2, GIPPU_RP2C04_0001, VS_OPTION_PREDIP, 0x01, EGIVS_NORMAL },
|
||||
{ "Pinball (J)", 0x66ab1a3828cc901cULL, 99, 2, GIPPU_RC2C03B, VS_OPTION_PREDIP, 0x01, EGIVS_NORMAL },
|
||||
{ "Platoon", 0x160f237351c19f1fULL, 68, 1, GIPPU_RP2C04_0001, 0, 0, EGIVS_NORMAL },
|
||||
{ "RBI Baseball", 0x6a02d345812938afULL, 4, 1, GIPPU_RP2C04_0001, VS_OPTION_SWAPDIRAB, 0, EGIVS_RBI },
|
||||
{ "Soccer", 0xd4e7a9058780eda3ULL, 99, 2, GIPPU_RP2C04_0003, VS_OPTION_SWAPDIRAB, 0, EGIVS_NORMAL },
|
||||
{ "Star Luster", 0x8360e134b316d94cULL, 99, 2, GIPPU_RC2C03B, 0, 0, EGIVS_NORMAL },
|
||||
{ "Stroke and Match Golf (J)", 0x869bb83e02509747ULL, 99, 2, GIPPU_RC2C03B, VS_OPTION_SWAPDIRAB | VS_OPTION_PREDIP, 0x01, EGIVS_NORMAL },
|
||||
{ "Super Sky Kid", 0x78d04c1dd4ec0101ULL, 4, 1, GIPPU_RC2C03B, VS_OPTION_SWAPDIRAB | VS_OPTION_PREDIP, 0x20, EGIVS_NORMAL },
|
||||
|
||||
{ "Super Xevious", 0x2d396247cf58f9faULL, 206, 0, RP2C04_001, 0 },
|
||||
{ "Tetris", 0x531a5e8eea4ce157ULL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x20 },
|
||||
{ "Top Gun", 0xf1dea36e6a7b531dULL, 2, 0, RC2C05_04, 0 },
|
||||
{ "VS Castlevania", 0x92fd6909c81305b9ULL, 2, 1, RP2C04_002, 0 },
|
||||
{ "VS Slalom", 0x4889b5a50a623215ULL, 0, 1, RP2C04_002, 0 },
|
||||
{ "VS Super Mario Bros", 0x39d8cfa788e20b6cULL, 99, 2, RP2C05_004, 0 },
|
||||
{ "VS Super Mario Bros [a1]", 0xfc182e5aefbce14dULL, 99, 2, RP2C05_004, 0 },
|
||||
{ "VS TKO Boxing", 0x6e1ee06171d8ce3aULL, 4, 1, RP2C04_003, IOPTION_PREDIP, 0x00 },
|
||||
{ "Super Xevious", 0x2d396247cf58f9faULL, 206, 0, GIPPU_RP2C04_0001, 0, 0, EGIVS_XEVIOUS },
|
||||
{ "Tetris", 0x531a5e8eea4ce157ULL, 99, 2, GIPPU_RC2C03B, VS_OPTION_PREDIP, 0x20, EGIVS_NORMAL },
|
||||
{ "Top Gun", 0xf1dea36e6a7b531dULL, 2, 0, GIPPU_RC2C05_04, 0, 0, EGIVS_NORMAL },
|
||||
{ "VS Castlevania", 0x92fd6909c81305b9ULL, 2, 1, GIPPU_RP2C04_0002, 0, 0, EGIVS_NORMAL },
|
||||
{ "VS Slalom", 0x4889b5a50a623215ULL, 0, 1, GIPPU_RP2C04_0002, 0, 0, EGIVS_NORMAL },
|
||||
{ "VS Super Mario Bros", 0x39d8cfa788e20b6cULL, 99, 2, GIPPU_RP2C04_0004, 0, 0, EGIVS_NORMAL },
|
||||
{ "VS Super Mario Bros [a1]", 0xfc182e5aefbce14dULL, 99, 2, GIPPU_RP2C04_0004, 0, 0, EGIVS_NORMAL },
|
||||
{ "VS TKO Boxing", 0x6e1ee06171d8ce3aULL, 4, 1, GIPPU_RP2C04_0003, VS_OPTION_PREDIP, 0x00, EGIVS_TKO },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -301,36 +305,84 @@ void FCEU_VSUniCheck(uint64 md5partial, int *MapperNo, uint8 *Mirroring) {
|
||||
|
||||
while (vs->name) {
|
||||
if (md5partial == vs->md5partial) {
|
||||
if (vs->ppu < RCP2C03B) default_palette_selection = vs->ppu;
|
||||
*MapperNo = vs->mapper;
|
||||
*Mirroring = vs->mirroring;
|
||||
GameInfo->type = GIT_VSUNI;
|
||||
GameInfo->cspecial = SIS_VSUNISYSTEM;
|
||||
GameInfo->inputfc = SIFC_NONE;
|
||||
curppu = vs->ppu;
|
||||
curmd5 = md5partial;
|
||||
int32 tofix = 0;
|
||||
if (*MapperNo != vs->mapper) {
|
||||
tofix |= 1;
|
||||
*MapperNo = vs->mapper;
|
||||
}
|
||||
if (*Mirroring != vs->mirroring) {
|
||||
tofix |= 2;
|
||||
*Mirroring = vs->mirroring;
|
||||
}
|
||||
if (GameInfo->type != GIT_VSUNI) {
|
||||
tofix |= 4;
|
||||
GameInfo->type = GIT_VSUNI;
|
||||
}
|
||||
if (GameInfo->vs_type != vs->type) {
|
||||
tofix |= 8;
|
||||
GameInfo->vs_type = vs->type;
|
||||
}
|
||||
if (vs->ppu && (GameInfo->vs_ppu != vs->ppu)) {
|
||||
tofix |= 16;
|
||||
GameInfo->vs_ppu = vs->ppu;
|
||||
}
|
||||
|
||||
secptr = 0;
|
||||
|
||||
switch (GameInfo->vs_type)
|
||||
{
|
||||
static int64 tko = 0x6e1ee06171d8ce3aULL, rbi = 0x6a02d345812938afULL;
|
||||
if (md5partial == tko)
|
||||
secptr = secdata[0];
|
||||
if (md5partial == rbi)
|
||||
secptr = secdata[1];
|
||||
case EGIVS_RBI: secptr = secdata_rbi; break;
|
||||
case EGIVS_TKO: secptr = secdata_tko; break;
|
||||
default: secptr = 0; break;
|
||||
}
|
||||
|
||||
vsdip = 0x0;
|
||||
if (vs->ioption & IOPTION_PREDIP) {
|
||||
if (vs->ioption & VS_OPTION_PREDIP) {
|
||||
vsdip = vs->predip;
|
||||
}
|
||||
if (vs->ioption & IOPTION_GUN) {
|
||||
if ((vs->ioption & VS_OPTION_GUN) && !head.expansion) {
|
||||
tofix |= 32;
|
||||
GameInfo->input[0] = SI_ZAPPER;
|
||||
GameInfo->input[1] = SI_NONE;
|
||||
} else {
|
||||
GameInfo->input[0] = GameInfo->input[1] = SI_GAMEPAD;
|
||||
GameInfo->inputfc = SIFC_NONE;
|
||||
}
|
||||
curvs = vs;
|
||||
else if (!head.expansion) {
|
||||
GameInfo->input[0] = GameInfo->input[1] = SI_GAMEPAD;
|
||||
GameInfo->inputfc = SIFC_NONE;
|
||||
}
|
||||
if ((vs->ioption & VS_OPTION_SWAPDIRAB) && !GameInfo->vs_cswitch) {
|
||||
tofix |= 64;
|
||||
GameInfo->vs_cswitch = 1;
|
||||
}
|
||||
|
||||
if (tofix) {
|
||||
char gigastr[768];
|
||||
strcpy(gigastr, "The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");
|
||||
if (tofix & 4) {
|
||||
sprintf(gigastr + strlen(gigastr), "Game type should be set to Vs. System. ");
|
||||
}
|
||||
if (tofix & 1)
|
||||
sprintf(gigastr + strlen(gigastr), "The mapper number should be set to %d. ", *MapperNo);
|
||||
if (tofix & 2) {
|
||||
const char* mstr[3] = { "Horizontal", "Vertical", "Four-screen" };
|
||||
sprintf(gigastr + strlen(gigastr), "Mirroring should be set to \"%s\". ", mstr[vs->mirroring & 3]);
|
||||
}
|
||||
if (tofix & 8) {
|
||||
const char* mstr[4] = { "Normal", "RBI Baseball protection", "TKO Boxing protection", "Super Xevious protection"};
|
||||
sprintf(gigastr + strlen(gigastr), "Vs. System type should be set to \"%s\". ", mstr[vs->type]);
|
||||
}
|
||||
if (tofix & 16)
|
||||
{
|
||||
const char* mstr[10] = { "Default", "RP2C04-0001", "RP2C04-0002", "RP2C04-0003", "RP2C04-0004", "RC2C03B", "RC2C05-01", "RC2C05-02" , "RC2C05-03" , "RC2C05-04" };
|
||||
sprintf(gigastr + strlen(gigastr), "Vs. System PPU should be set to \"%s\". ", mstr[vs->ppu]);
|
||||
}
|
||||
if (tofix & 32)
|
||||
sprintf(gigastr + strlen(gigastr), "The controller type should be set to zapper. ");
|
||||
if (tofix & 64)
|
||||
sprintf(gigastr + strlen(gigastr), "The controllers should be swapped. ");
|
||||
strcat(gigastr, "\n");
|
||||
FCEU_printf("%s", gigastr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
vs++;
|
||||
@@ -341,7 +393,7 @@ void FCEU_VSUniDraw(uint8 *XBuf) {
|
||||
uint32 *dest;
|
||||
int y, x;
|
||||
|
||||
if (!DIPS) return;
|
||||
if (DIPS_howlong-- <= 0) return;
|
||||
|
||||
dest = (uint32*)(XBuf + 256 * 12 + 164);
|
||||
for (y = 24; y; y--, dest += (256 - 72) >> 2) {
|
||||
@@ -371,6 +423,8 @@ void FCEU_VSUniDraw(uint8 *XBuf) {
|
||||
SFORMAT FCEUVSUNI_STATEINFO[] = {
|
||||
{ &vsdip, 1, "vsdp" },
|
||||
{ &coinon, 1, "vscn" },
|
||||
{ &coinon2, 1, "vsc2" },
|
||||
{ &service, 1, "vssv" },
|
||||
{ &VSindex, 1, "vsin" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
+19
-1
@@ -1,7 +1,25 @@
|
||||
enum IOPTION {
|
||||
VS_OPTION_GUN = 0x1,
|
||||
VS_OPTION_SWAPDIRAB = 0x2,
|
||||
VS_OPTION_PREDIP = 0x10,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
uint64 md5partial;
|
||||
int mapper;
|
||||
int mirroring;
|
||||
EGIPPU ppu;
|
||||
int ioption;
|
||||
int predip;
|
||||
EGIVS type;
|
||||
} VSUNIENTRY;
|
||||
|
||||
void FCEU_VSUniPower(void);
|
||||
void FCEU_VSUniCheck(uint64 md5partial, int *, uint8 *);
|
||||
void FCEU_VSUniDraw(uint8 *XBuf);
|
||||
|
||||
void FCEU_VSUniToggleDIP(int); /* For movies and netplay */
|
||||
void FCEU_VSUniCoin(void);
|
||||
void FCEU_VSUniCoin(uint8 slot);
|
||||
void FCEU_VSUniService();
|
||||
void FCEU_VSUniSwap(uint8 *j0, uint8 *j1);
|
||||
|
||||
+2
-2
@@ -318,8 +318,8 @@ static uint8 ZNTable[256];
|
||||
#define LD_ZP(op) {uint8 A; uint8 x; GetZP(A); x=RdRAM(A); op; break;}
|
||||
#define LD_ZPX(op) {uint8 A; uint8 x; GetZPI(A,_X); x=RdRAM(A); op; break;}
|
||||
#define LD_ZPY(op) {uint8 A; uint8 x; GetZPI(A,_Y); x=RdRAM(A); op; break;}
|
||||
#define LD_AB(op) {unsigned int A; uint8 x; GetAB(A); x=RdMem(A); op; break; }
|
||||
#define LD_ABI(reg,op) {unsigned int A; uint8 x; GetABIRD(A,reg); x=RdMem(A); op; break;}
|
||||
#define LD_AB(op) {unsigned int A; FCEU_MAYBE_UNUSED uint8 x; GetAB(A); x=RdMem(A); op; break; }
|
||||
#define LD_ABI(reg,op) {unsigned int A; FCEU_MAYBE_UNUSED uint8 x; GetABIRD(A,reg); x=RdMem(A); op; break;}
|
||||
#define LD_ABX(op) LD_ABI(_X,op)
|
||||
#define LD_ABY(op) LD_ABI(_Y,op)
|
||||
#define LD_IX(op) {unsigned int A; uint8 x; GetIX(A); x=RdMem(A); op; break;}
|
||||
|
||||
Reference in New Issue
Block a user