Upgrade to 1.8 beta core

git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@23 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
DJRobX 2007-11-07 01:27:54 +00:00
parent 0e1ef89215
commit ee40ad3d5c
301 changed files with 100519 additions and 33545 deletions

View File

@ -51,7 +51,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(SolutionDir)zlib&quot;;&quot;$(SolutionDir)libpng&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)src\win32\dependencies\zlib&quot;;&quot;$(SolutionDir)src\win32\dependencies\libpng&quot;;&quot;$(SolutionDir)src\win32\dependencies\cximage&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;DEV_VERSION;BKPT_SUPPORT;MMX;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;DEV_VERSION;BKPT_SUPPORT;MMX;_CRT_SECURE_NO_WARNINGS"
StringPooling="false" StringPooling="false"
MinimalRebuild="true" MinimalRebuild="true"
@ -83,7 +83,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="nafxcwd.lib LIBCMTD.lib Vfw32.Lib OpenGL32.Lib dinput8.lib dxguid.lib ddraw.lib winmm.lib d3dx9.lib Dsound.lib" AdditionalDependencies="nafxcwd.lib LIBCMTD.lib Vfw32.Lib OpenGL32.Lib dinput8.lib dxguid.lib ddraw.lib dxerr9.lib winmm.lib d3dx9.lib d3d9.lib Dsound.lib"
OutputFile="$(ProjectDir)VisualBoyAdvance.exe" OutputFile="$(ProjectDir)VisualBoyAdvance.exe"
Version="" Version=""
LinkIncremental="2" LinkIncremental="2"
@ -165,7 +165,7 @@
OmitFramePointers="true" OmitFramePointers="true"
EnableFiberSafeOptimizations="false" EnableFiberSafeOptimizations="false"
WholeProgramOptimization="true" WholeProgramOptimization="true"
AdditionalIncludeDirectories="&quot;$(SolutionDir)zlib&quot;;&quot;$(SolutionDir)libpng&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)src\win32\dependencies\zlib&quot;;&quot;$(SolutionDir)src\win32\dependencies\libpng&quot;;&quot;$(SolutionDir)src\win32\dependencies\cximage&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;FINAL_VERSION;MMX;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;FINAL_VERSION;MMX;_CRT_SECURE_NO_WARNINGS"
IgnoreStandardIncludePath="false" IgnoreStandardIncludePath="false"
GeneratePreprocessedFile="0" GeneratePreprocessedFile="0"
@ -216,7 +216,7 @@
Name="VCLinkerTool" Name="VCLinkerTool"
RegisterOutput="false" RegisterOutput="false"
IgnoreImportLibrary="false" IgnoreImportLibrary="false"
AdditionalDependencies="nafxcw.lib LIBCMT.lib Vfw32.Lib OpenGL32.Lib dinput8.lib winmm.lib dxguid.lib ddraw.lib d3dx9.lib Dsound.lib" AdditionalDependencies="nafxcw.lib LIBCMT.lib Vfw32.Lib OpenGL32.Lib dinput8.lib winmm.lib dxguid.lib ddraw.lib d3d9.lib d3dx9.lib Dsound.lib"
ShowProgress="0" ShowProgress="0"
OutputFile="$(ProjectDir)VisualBoyAdvance.exe" OutputFile="$(ProjectDir)VisualBoyAdvance.exe"
Version="" Version=""
@ -308,7 +308,7 @@
EnableIntrinsicFunctions="true" EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
OmitFramePointers="true" OmitFramePointers="true"
AdditionalIncludeDirectories="&quot;$(SolutionDir)zlib&quot;;&quot;$(SolutionDir)libpng&quot;" AdditionalIncludeDirectories="&quot;$(SolutionDir)src\win32\dependencies\zlib&quot;;&quot;$(SolutionDir)src\win32\dependencies\libpng&quot;;&quot;$(SolutionDir)src\win32\dependencies\cximage&quot;"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;FINAL_VERSION;MMX;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;FINAL_VERSION;MMX;_CRT_SECURE_NO_WARNINGS"
IgnoreStandardIncludePath="false" IgnoreStandardIncludePath="false"
GeneratePreprocessedFile="0" GeneratePreprocessedFile="0"
@ -649,14 +649,6 @@
RelativePath=".\src\hq_shared32.cpp" RelativePath=".\src\hq_shared32.cpp"
> >
</File> </File>
<File
RelativePath=".\src\lq3x.cpp"
>
</File>
<File
RelativePath=".\src\lq4x.cpp"
>
</File>
<File <File
RelativePath=".\src\portable.cpp" RelativePath=".\src\portable.cpp"
> >
@ -683,16 +675,40 @@
> >
</File> </File>
<File <File
RelativePath=".\src\getopt.cpp" RelativePath=".\src\getopt.c"
> >
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\src\getopt1.cpp" RelativePath=".\src\getopt1.c"
> >
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\src\memgzio.cpp" RelativePath=".\src\memgzio.c"
> >
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\src\snd_interp.cpp" RelativePath=".\src\snd_interp.cpp"
@ -890,6 +906,10 @@
RelativePath=".\src\win32\FileDlg.cpp" RelativePath=".\src\win32\FileDlg.cpp"
> >
</File> </File>
<File
RelativePath=".\src\win32\GameOverrides.cpp"
>
</File>
<File <File
RelativePath=".\src\win32\GBACheats.cpp" RelativePath=".\src\win32\GBACheats.cpp"
> >
@ -1002,6 +1022,14 @@
RelativePath=".\src\win32\RomInfo.cpp" RelativePath=".\src\win32\RomInfo.cpp"
> >
</File> </File>
<File
RelativePath=".\src\win32\skin.cpp"
>
</File>
<File
RelativePath=".\src\win32\skinButton.cpp"
>
</File>
<File <File
RelativePath=".\src\win32\StringTokenizer.cpp" RelativePath=".\src\win32\StringTokenizer.cpp"
> >
@ -1014,10 +1042,6 @@
RelativePath=".\src\win32\TileView.cpp" RelativePath=".\src\win32\TileView.cpp"
> >
</File> </File>
<File
RelativePath=".\src\win32\UniVideoModeDlg.cpp"
>
</File>
<File <File
RelativePath=".\src\win32\VideoMode.cpp" RelativePath=".\src\win32\VideoMode.cpp"
> >
@ -1106,6 +1130,10 @@
RelativePath=".\src\win32\DirectSound.cpp" RelativePath=".\src\win32\DirectSound.cpp"
> >
</File> </File>
<File
RelativePath=".\src\win32\display.cpp"
>
</File>
<File <File
RelativePath=".\src\win32\GDIDisplay.cpp" RelativePath=".\src\win32\GDIDisplay.cpp"
> >
@ -1155,6 +1183,130 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="Cximage"
>
<File
RelativePath=".\src\win32\dependencies\cximage\tif_xfile.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximabmp.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximadsp.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximaenc.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximaexif.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximage.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximagif.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximahist.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximaico.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximainfo.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximaint.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximaj2k.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximajas.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximajbg.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximajpg.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximalpha.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximalyr.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximamng.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximapal.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximapcx.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximapng.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximasel.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximatga.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximath.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximatif.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximatran.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximawbmp.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximawmf.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\ximawnd.cpp"
>
</File>
<File
RelativePath=".\src\win32\dependencies\cximage\xmemfile.cpp"
>
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="Header" Name="Header"
@ -1624,15 +1776,7 @@
> >
</File> </File>
<File <File
RelativePath=".\res\resource.h" RelativePath=".\src\win32\VBA.rc"
>
</File>
<File
RelativePath=".\res\VBA.ico"
>
</File>
<File
RelativePath=".\res\VBA.rc"
> >
</File> </File>
</Filter> </Filter>

View File

@ -1,6 +1,8 @@
#include "System.h" #include "System.h"
#include "Port.h" #include "Port.h"
extern int RGB_LOW_BITS_MASK;
extern "C" extern "C"
{ {
@ -48,6 +50,7 @@ int Init_2xSaI(u32 BitFormat)
greenMask = 0x7E0; greenMask = 0x7E0;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xF7DEF7DE; qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xF7DEF7DE;
hq2x_init(16); hq2x_init(16);
RGB_LOW_BITS_MASK = 0x0821;
} else if (BitFormat == 555) { } else if (BitFormat == 555) {
colorMask = 0x7BDE7BDE; colorMask = 0x7BDE7BDE;
lowPixelMask = 0x04210421; lowPixelMask = 0x04210421;
@ -57,6 +60,7 @@ int Init_2xSaI(u32 BitFormat)
greenMask = 0x3E0; greenMask = 0x3E0;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0x7BDE7BDE; qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0x7BDE7BDE;
hq2x_init(15); hq2x_init(15);
RGB_LOW_BITS_MASK = 0x0421;
} else { } else {
return 0; return 0;
} }
@ -67,6 +71,7 @@ int Init_2xSaI(u32 BitFormat)
qlowpixelMask = 0x030303; qlowpixelMask = 0x030303;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xfefefe; qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xfefefe;
hq2x_init(32); hq2x_init(32);
RGB_LOW_BITS_MASK = 0x010101;
} else } else
return 0; return 0;

31
src/AutoBuild.h Normal file
View File

@ -0,0 +1,31 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __AUTOBUILD_H__
#define __AUTOBUILD_H__
#ifndef VERSION
#define VERSION "1.8.0"
#endif
//change the FALSE to TRUE for autoincrement of build number
#define INCREMENT_VERSION FALSE
#define FILEVER 1,8,0,600
#define PRODUCTVER 1,8,0,600
#define STRFILEVER "1, 8, 0, 600\0"
#define STRPRODUCTVER "1, 8, 0, 600\0"
#endif //__AUTOBUILD_H__

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -192,6 +192,9 @@
#define GSA_16_BIT_MIF_FALSE 109 #define GSA_16_BIT_MIF_FALSE 109
#define GSA_16_BIT_MIF_LOWER_OR_EQ_U 110 #define GSA_16_BIT_MIF_LOWER_OR_EQ_U 110
#define GSA_16_BIT_MIF_HIGHER_OR_EQ_U 111 #define GSA_16_BIT_MIF_HIGHER_OR_EQ_U 111
#define MASTER_CODE 112
#define CHEATS_16_BIT_WRITE 114
#define CHEATS_32_BIT_WRITE 115
CheatsData cheatsList[100]; CheatsData cheatsList[100];
int cheatsNumber = 0; int cheatsNumber = 0;
@ -205,6 +208,7 @@ u32 cheatsCBATemporaryValue = 0;
u16 cheatsCBATable[256]; u16 cheatsCBATable[256];
bool cheatsCBATableGenerated = false; bool cheatsCBATableGenerated = false;
u16 super = 0; u16 super = 0;
extern u32 mastercode;
u8 cheatsCBACurrentSeed[12] = { u8 cheatsCBACurrentSeed[12] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -317,6 +321,9 @@ u8 v3_deadtable2[256] = {
#define CHEAT_PATCH_ROM_16BIT(a,v) \ #define CHEAT_PATCH_ROM_16BIT(a,v) \
WRITE16LE(((u16 *)&rom[(a) & 0x1ffffff]), v); WRITE16LE(((u16 *)&rom[(a) & 0x1ffffff]), v);
#define CHEAT_PATCH_ROM_32BIT(a,v) \
WRITE32LE(((u32 *)&rom[(a) & 0x1ffffff]), v);
static bool isMultilineWithData(int i) static bool isMultilineWithData(int i)
{ {
// we consider it a multiline code if it has more than one line of data // we consider it a multiline code if it has more than one line of data
@ -434,6 +441,9 @@ static bool isMultilineWithData(int i)
case GSA_16_BIT_MIF_FALSE: case GSA_16_BIT_MIF_FALSE:
case GSA_16_BIT_MIF_LOWER_OR_EQ_U: case GSA_16_BIT_MIF_LOWER_OR_EQ_U:
case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: case GSA_16_BIT_MIF_HIGHER_OR_EQ_U:
case MASTER_CODE:
case CHEATS_16_BIT_WRITE:
case CHEATS_32_BIT_WRITE:
return false; return false;
// the codes below have two lines of data // the codes below have two lines of data
case CBA_SLIDE_CODE: case CBA_SLIDE_CODE:
@ -558,6 +568,10 @@ static int getCodeLength(int num)
case GSA_16_BIT_MIF_FALSE: case GSA_16_BIT_MIF_FALSE:
case GSA_16_BIT_MIF_LOWER_OR_EQ_U: case GSA_16_BIT_MIF_LOWER_OR_EQ_U:
case GSA_16_BIT_MIF_HIGHER_OR_EQ_U: case GSA_16_BIT_MIF_HIGHER_OR_EQ_U:
case MASTER_CODE:
case CHEATS_16_BIT_WRITE:
case CHEATS_32_BIT_WRITE:
case UNKNOWN_CODE:
return 1; return 1;
case CBA_IF_KEYS_PRESSED: case CBA_IF_KEYS_PRESSED:
case CBA_SLIDE_CODE: case CBA_SLIDE_CODE:
@ -571,8 +585,10 @@ static int getCodeLength(int num)
int cheatsCheckKeys(u32 keys, u32 extended) int cheatsCheckKeys(u32 keys, u32 extended)
{ {
bool onoff = true; bool onoff = true;
int ticks = 1; int ticks = 0;
int i; int i;
mastercode = 0;
for (i = 0; i<4; i++) for (i = 0; i<4; i++)
if (rompatch2addr [i] != 0) { if (rompatch2addr [i] != 0) {
CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2oldval [i]); CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2oldval [i]);
@ -616,7 +632,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--; count--;
} }
} }
i++;
break; break;
case GSA_16_BIT_SLIDE: case GSA_16_BIT_SLIDE:
i++; i++;
@ -633,7 +648,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--; count--;
} }
} }
i++;
break; break;
case GSA_32_BIT_SLIDE: case GSA_32_BIT_SLIDE:
i++; i++;
@ -650,7 +664,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--; count--;
} }
} }
i++;
break; break;
case GSA_8_BIT_GS_WRITE2: case GSA_8_BIT_GS_WRITE2:
i++; i++;
@ -676,41 +689,49 @@ int cheatsCheckKeys(u32 keys, u32 extended)
} }
} }
break; break;
case GSA_16_BIT_ROM_PATCH:
if((cheatsList[i].status & 1) == 0) {
if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
cheatsList[i].oldValue = CPUReadHalfWord(cheatsList[i].address);
cheatsList[i].status |= 1;
CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value);
}
}
break;
case GSA_16_BIT_ROM_PATCH2C: case GSA_16_BIT_ROM_PATCH2C:
i++; i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) { if(i < cheatsNumber) {
rompatch2addr [0] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; rompatch2addr [0] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [0] = CPUReadHalfWord(rompatch2addr [0]); rompatch2oldval [0] = CPUReadHalfWord(rompatch2addr [0]);
rompatch2val [0] = cheatsList[i].rawaddress & 0xFFFF; rompatch2val [0] = cheatsList[i].rawaddress & 0xFFFF;
} }
i++;
break; break;
case GSA_16_BIT_ROM_PATCH2D: case GSA_16_BIT_ROM_PATCH2D:
i++; i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) { if(i < cheatsNumber) {
rompatch2addr [1] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; rompatch2addr [1] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [1] = CPUReadHalfWord(rompatch2addr [1]); rompatch2oldval [1] = CPUReadHalfWord(rompatch2addr [1]);
rompatch2val [1] = cheatsList[i].rawaddress & 0xFFFF; rompatch2val [1] = cheatsList[i].rawaddress & 0xFFFF;
} }
i++;
break; break;
case GSA_16_BIT_ROM_PATCH2E: case GSA_16_BIT_ROM_PATCH2E:
i++; i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) { if(i < cheatsNumber) {
rompatch2addr [2] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; rompatch2addr [2] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [2] = CPUReadHalfWord(rompatch2addr [2]); rompatch2oldval [2] = CPUReadHalfWord(rompatch2addr [2]);
rompatch2val [2] = cheatsList[i].rawaddress & 0xFFFF; rompatch2val [2] = cheatsList[i].rawaddress & 0xFFFF;
} }
i++;
break; break;
case GSA_16_BIT_ROM_PATCH2F: case GSA_16_BIT_ROM_PATCH2F:
i++; i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) { if(i < cheatsNumber) {
rompatch2addr [3] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000; rompatch2addr [3] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [3] = CPUReadHalfWord(rompatch2addr [3]); rompatch2oldval [3] = CPUReadHalfWord(rompatch2addr [3]);
rompatch2val [3] = cheatsList[i].rawaddress & 0xFFFF; rompatch2val [3] = cheatsList[i].rawaddress & 0xFFFF;
} }
i++; break;
case MASTER_CODE:
mastercode = cheatsList[i].address;
break; break;
} }
if (onoff) { if (onoff) {
@ -724,15 +745,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
case INT_32_BIT_WRITE: case INT_32_BIT_WRITE:
CPUWriteMemory(cheatsList[i].address, cheatsList[i].value); CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
break; break;
case GSA_16_BIT_ROM_PATCH:
if((cheatsList[i].status & 1) == 0) {
if(CPUReadHalfWord(cheatsList[i].address) != cheatsList[i].value) {
cheatsList[i].oldValue = CPUReadHalfWord(cheatsList[i].address);
cheatsList[i].status |= 1;
CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value);
}
}
break;
case GSA_8_BIT_GS_WRITE: case GSA_8_BIT_GS_WRITE:
if(extended & 4) { if(extended & 4) {
CPUWriteByte(cheatsList[i].address, cheatsList[i].value); CPUWriteByte(cheatsList[i].address, cheatsList[i].value);
@ -1289,6 +1301,20 @@ int cheatsCheckKeys(u32 keys, u32 extended)
i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF; i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF;
} }
break; break;
case CHEATS_16_BIT_WRITE:
if ((cheatsList[i].address>>24)>=0x08) {
CHEAT_PATCH_ROM_16BIT(cheatsList[i].address, cheatsList[i].value);
} else {
CPUWriteHalfWord(cheatsList[i].address, cheatsList[i].value);
}
break;
case CHEATS_32_BIT_WRITE:
if ((cheatsList[i].address>>24)>=0x08) {
CHEAT_PATCH_ROM_32BIT(cheatsList[i].address, cheatsList[i].value);
} else {
CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
}
break;
} }
} }
} }
@ -1330,6 +1356,12 @@ void cheatsAdd(const char *codeStr,
case INT_32_BIT_WRITE: case INT_32_BIT_WRITE:
cheatsList[x].oldValue = CPUReadMemory(address); cheatsList[x].oldValue = CPUReadMemory(address);
break; break;
case CHEATS_16_BIT_WRITE:
cheatsList[x].oldValue = CPUReadHalfWord(address);
break;
case CHEATS_32_BIT_WRITE:
cheatsList[x].oldValue = CPUReadMemory(address);
break;
} }
cheatsNumber++; cheatsNumber++;
} }
@ -1351,6 +1383,19 @@ void cheatsDelete(int number, bool restore)
case INT_32_BIT_WRITE: case INT_32_BIT_WRITE:
CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue); CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue);
break; break;
case CHEATS_16_BIT_WRITE:
if ((cheatsList[x].address>>24)>=0x08) {
CHEAT_PATCH_ROM_16BIT(cheatsList[x].address, cheatsList[x].oldValue);
} else {
CPUWriteHalfWord(cheatsList[x].address, cheatsList[x].oldValue);
}
break;
case CHEATS_32_BIT_WRITE:
if ((cheatsList[x].address>>24)>=0x08) {
CHEAT_PATCH_ROM_32BIT(cheatsList[x].address, cheatsList[x].oldValue);
} else {
CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue);
}
case GSA_16_BIT_ROM_PATCH: case GSA_16_BIT_ROM_PATCH:
if(cheatsList[x].status & 1) { if(cheatsList[x].status & 1) {
cheatsList[x].status &= ~1; cheatsList[x].status &= ~1;
@ -1366,6 +1411,9 @@ void cheatsDelete(int number, bool restore)
cheatsList[x].status &= ~1; cheatsList[x].status &= ~1;
} }
break; break;
case MASTER_CODE:
mastercode=0;
break;
} }
} }
if((x+1) < cheatsNumber) { if((x+1) < cheatsNumber) {
@ -1387,6 +1435,7 @@ void cheatsEnable(int i)
{ {
if(i >= 0 && i < cheatsNumber) { if(i >= 0 && i < cheatsNumber) {
cheatsList[i].enabled = true; cheatsList[i].enabled = true;
mastercode = 0;
} }
} }
@ -1409,6 +1458,9 @@ void cheatsDisable(int i)
cheatsList[i].status &= ~1; cheatsList[i].status &= ~1;
} }
break; break;
case MASTER_CODE:
mastercode=0;
break;
} }
cheatsList[i].enabled = false; cheatsList[i].enabled = false;
} }
@ -1416,7 +1468,7 @@ void cheatsDisable(int i)
bool cheatsVerifyCheatCode(const char *code, const char *desc) bool cheatsVerifyCheatCode(const char *code, const char *desc)
{ {
int len = strlen(code); size_t len = strlen(code);
if(len != 11 && len != 13 && len != 17) { if(len != 11 && len != 13 && len != 17) {
systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s'"), code); systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s'"), code);
return false; return false;
@ -1427,7 +1479,7 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
return false; return false;
} }
int i; size_t i;
for(i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
if(!CHEAT_IS_HEX(code[i])) { if(!CHEAT_IS_HEX(code[i])) {
// wrong cheat // wrong cheat
@ -1454,8 +1506,18 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
sscanf(buffer, "%x", &address); sscanf(buffer, "%x", &address);
switch(address >> 24) { switch(address >> 24) {
case 2: case 0x02:
case 3: case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
break; break;
default: default:
systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS, systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS,
@ -1468,9 +1530,9 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
sscanf(buffer, "%x", &value); sscanf(buffer, "%x", &value);
int type = 0; int type = 0;
if(len == 13) if(len == 13)
type = 1; type = 114;
if(len == 17) if(len == 17)
type = 2; type = 115;
cheatsAdd(code, desc, address, address, value, type, type); cheatsAdd(code, desc, address, address, value, type, type);
return true; return true;
} }
@ -1587,6 +1649,15 @@ void cheatsAddGSACode(const char *code, const char *desc, bool v3)
if(v3) { if(v3) {
int type = ((address >> 25) & 127) | ((address >> 17) & 0x80); int type = ((address >> 25) & 127) | ((address >> 17) & 0x80);
u32 addr = (address & 0x00F00000) << 4 | (address & 0x0003FFFF); u32 addr = (address & 0x00F00000) << 4 | (address & 0x0003FFFF);
u16 mcode = (address>>24 & 0xFF);
if ((mcode & 0xFE) == 0xC4)
{
cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | (0x08000000),
value, 257, MASTER_CODE);
mastercode = (address & 0x1FFFFFF) | (0x08000000);
}
else
switch(type) { switch(type) {
case 0x00: case 0x00:
if(address == 0) { if(address == 0) {
@ -1997,6 +2068,10 @@ void cheatsAddGSACode(const char *code, const char *desc, bool v3)
break; break;
} }
break; break;
case 0x0f:
cheatsAdd(code, desc, address, (address & 0xFFFFFFF), value, 256, MASTER_CODE);
mastercode = (address & 0xFFFFFFF);
break;
default: default:
// unsupported code // unsupported code
cheatsAdd(code, desc, address, address, value, 256, cheatsAdd(code, desc, address, address, value, 256,
@ -2466,6 +2541,10 @@ void cheatsAddCBACode(const char *code, const char *desc)
UNKNOWN_CODE); UNKNOWN_CODE);
} }
break; break;
case 0x01:
cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | 0x08000000, value, 512, MASTER_CODE);
mastercode = (address & 0x1FFFFFF) | 0x08000000;
break;
case 0x02: case 0x02:
cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512, cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
CBA_OR); CBA_OR);
@ -2536,17 +2615,33 @@ void cheatsSaveGame(gzFile file)
utilGzWrite(file, cheatsList, sizeof(cheatsList)); utilGzWrite(file, cheatsList, sizeof(cheatsList));
} }
void cheatsReadGame(gzFile file) void cheatsReadGame(gzFile file, int version)
{ {
cheatsNumber = 0; cheatsNumber = 0;
cheatsNumber = utilReadInt(file); cheatsNumber = utilReadInt(file);
if (version > 8)
utilGzRead(file, cheatsList, sizeof(cheatsList)); utilGzRead(file, cheatsList, sizeof(cheatsList));
bool firstCodeBreaker = true; bool firstCodeBreaker = true;
for(int i = 0; i < cheatsNumber; i++) { for(int i = 0; i < cheatsNumber; i++) {
if (version <9)
{
cheatsList[i].code = utilReadInt(file);
cheatsList[i].size = utilReadInt(file);
cheatsList[i].status = utilReadInt(file);
cheatsList[i].enabled = utilReadInt(file) ? true : false;
utilGzRead(file, &cheatsList[i].address, sizeof(u32));
cheatsList[i].rawaddress = cheatsList[i].address;
utilGzRead(file, &cheatsList[i].value, sizeof(u32));
utilGzRead(file, &cheatsList[i].oldValue, sizeof(u32));
utilGzRead(file, &cheatsList[i].codestring, 20*sizeof(char));
utilGzRead(file, &cheatsList[i].desc, 32*sizeof(char));
}
cheatsList[i].status = 0; cheatsList[i].status = 0;
if(!cheatsList[i].codestring[0]) { if(!cheatsList[i].codestring[0]) {
switch(cheatsList[i].size) { switch(cheatsList[i].size) {
@ -2599,7 +2694,7 @@ void cheatsSaveCheatList(const char *file)
return; return;
int version = 1; int version = 1;
fwrite(&version, 1, sizeof(version), f); fwrite(&version, 1, sizeof(version), f);
int type = 0; int type = 1;
fwrite(&type, 1, sizeof(type), f); fwrite(&type, 1, sizeof(type), f);
fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f); fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f);
fwrite(cheatsList, 1, sizeof(cheatsList), f); fwrite(cheatsList, 1, sizeof(cheatsList), f);
@ -2608,7 +2703,6 @@ void cheatsSaveCheatList(const char *file)
bool cheatsLoadCheatList(const char *file) bool cheatsLoadCheatList(const char *file)
{ {
cheatsNumber = 0;
int count = 0; int count = 0;
@ -2637,7 +2731,8 @@ bool cheatsLoadCheatList(const char *file)
return false; return false;
} }
if(type != 0) {
if((type != 0) && (type != 1)) {
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE, systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE,
N_("Unsupported cheat list type %d"), type); N_("Unsupported cheat list type %d"), type);
fclose(f); fclose(f);
@ -2648,11 +2743,32 @@ bool cheatsLoadCheatList(const char *file)
fclose(f); fclose(f);
return false; return false;
} }
if (type == 1)
{
if(fread(cheatsList, 1, sizeof(cheatsList), f) != sizeof(cheatsList)) { if(fread(cheatsList, 1, sizeof(cheatsList), f) != sizeof(cheatsList)) {
fclose(f); fclose(f);
return false; return false;
} }
}
else if (type == 0)
{
for(int i = 0; i < count; i++) {
fread(&cheatsList[i].code, 1, sizeof(int),f);
fread(&cheatsList[i].size, 1, sizeof(int),f);
fread(&cheatsList[i].status, 1, sizeof(int),f);
fread(&cheatsList[i].enabled, 1, sizeof(int),f);
cheatsList[i].enabled = cheatsList[i].enabled ? true : false;
fread(&cheatsList[i].address, 1, sizeof(u32),f);
cheatsList[i].rawaddress = cheatsList[i].address;
fread(&cheatsList[i].value, 1, sizeof(u32),f);
fread(&cheatsList[i].oldValue, 1, sizeof(u32),f);
fread(&cheatsList[i].codestring, 1, 20*sizeof(char),f);
if(fread(&cheatsList[i].desc, 1, 32*sizeof(char),f) != 32*sizeof(char)) {
fclose(f);
return false;
}
}
}
bool firstCodeBreaker = true; bool firstCodeBreaker = true;
@ -2710,6 +2826,15 @@ static u8 cheatsGetType(u32 address)
return freezeWorkRAM[address & 0x3FFFF]; return freezeWorkRAM[address & 0x3FFFF];
case 3: case 3:
return freezeInternalRAM[address & 0x7FFF]; return freezeInternalRAM[address & 0x7FFF];
case 5:
return freezePRAM[address & 0x3FC];
case 6:
if (address > 0x06010000)
return freezeVRAM[address & 0x17FFF];
else
return freezeVRAM[address & 0x1FFFF];
case 7:
return freezeOAM[address & 0x3FC];
} }
return 0; return 0;
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -43,7 +43,7 @@ extern void cheatsDeleteAll(bool restore);
extern void cheatsEnable(int number); extern void cheatsEnable(int number);
extern void cheatsDisable(int number); extern void cheatsDisable(int number);
extern void cheatsSaveGame(gzFile file); extern void cheatsSaveGame(gzFile file);
extern void cheatsReadGame(gzFile file); extern void cheatsReadGame(gzFile file, int version);
extern void cheatsSaveCheatList(const char *file); extern void cheatsSaveCheatList(const char *file);
extern bool cheatsLoadCheatList(const char *file); extern bool cheatsLoadCheatList(const char *file);
extern void cheatsWriteMemory(u32, u32); extern void cheatsWriteMemory(u32, u32);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <memory.h>
#include "GBA.h" #include "GBA.h"
#include "EEprom.h" #include "EEprom.h"
#include "Util.h" #include "Util.h"
@ -42,6 +43,11 @@ variable_desc eepromSaveData[] = {
{ NULL, 0 } { NULL, 0 }
}; };
void eepromInit()
{
memset(eepromData, 255, sizeof(eepromData));
}
void eepromReset() void eepromReset()
{ {
eepromMode = EEPROM_IDLE; eepromMode = EEPROM_IDLE;

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -20,10 +20,11 @@
#ifndef VBA_EEPROM_H #ifndef VBA_EEPROM_H
#define VBA_EEPROM_H #define VBA_EEPROM_H
extern void eepromSaveGame(gzFile gzFile); extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile gzFile, int version); extern void eepromReadGame(gzFile _gzFile, int version);
extern int eepromRead(u32 address); extern int eepromRead(u32 address);
extern void eepromWrite(u32 address, u8 value); extern void eepromWrite(u32 address, u8 value);
extern void eepromInit();
extern void eepromReset(); extern void eepromReset();
extern u8 eepromData[0x2000]; extern u8 eepromData[0x2000];
extern bool eepromInUse; extern bool eepromInUse;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -100,7 +100,6 @@ void flashReadGame(gzFile gzFile, int version)
void flashSetSize(int size) void flashSetSize(int size)
{ {
// log("Setting flash size to %d\n", size); // log("Setting flash size to %d\n", size);
flashSize = size;
if(size == 0x10000) { if(size == 0x10000) {
flashDeviceID = 0x1b; flashDeviceID = 0x1b;
flashManufacturerID = 0x32; flashManufacturerID = 0x32;
@ -108,6 +107,11 @@ void flashSetSize(int size)
flashDeviceID = 0x13; //0x09; flashDeviceID = 0x13; //0x09;
flashManufacturerID = 0x62; //0xc2; flashManufacturerID = 0x62; //0xc2;
} }
// Added to make 64k saves compatible with 128k ones
// (allow wrongfuly set 64k saves to work for Pokemon games)
if ((size == 0x20000) && (flashSize == 0x10000))
memcpy((u8 *)(flashSaveMemory+0x10000), (u8 *)(flashSaveMemory), 0x10000);
flashSize = size;
} }
u8 flashRead(u32 address) u8 flashRead(u32 address)

View File

@ -20,8 +20,8 @@
#ifndef VBA_FLASH_H #ifndef VBA_FLASH_H
#define VBA_FLASH_H #define VBA_FLASH_H
extern void flashSaveGame(gzFile gzFile); extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile gzFile, int version); extern void flashReadGame(gzFile _gzFile, int version);
extern u8 flashRead(u32 address); extern u8 flashRead(u32 address);
extern void flashWrite(u32 address, u8 byte); extern void flashWrite(u32 address, u8 byte);
extern void flashDelayedWrite(u32 address, u8 byte); extern void flashDelayedWrite(u32 address, u8 byte);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -30,7 +30,8 @@
#define SAVE_GAME_VERSION_6 6 #define SAVE_GAME_VERSION_6 6
#define SAVE_GAME_VERSION_7 7 #define SAVE_GAME_VERSION_7 7
#define SAVE_GAME_VERSION_8 8 #define SAVE_GAME_VERSION_8 8
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_8 #define SAVE_GAME_VERSION_9 9
#define SAVE_GAME_VERSION SAVE_GAME_VERSION_9
typedef struct { typedef struct {
u8 *address; u8 *address;
@ -85,6 +86,13 @@ extern void (*cpuSaveGameFunc)(u32,u8);
extern u8 freezeWorkRAM[0x40000]; extern u8 freezeWorkRAM[0x40000];
extern u8 freezeInternalRAM[0x8000]; extern u8 freezeInternalRAM[0x8000];
extern u8 freezeVRAM[0x18000];
extern u8 freezeOAM[0x400];
extern u8 freezePRAM[0x400];
extern bool debugger_last;
extern int oldreg[17];
extern char oldbuffer[10];
extern bool CPUReadGSASnapshot(const char *); extern bool CPUReadGSASnapshot(const char *);
extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *); extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
extern bool CPUWriteBatteryFile(const char *); extern bool CPUWriteBatteryFile(const char *);
@ -100,17 +108,20 @@ extern bool CPUReadState(const char *);
extern bool CPUWriteMemState(char *, int); extern bool CPUWriteMemState(char *, int);
extern bool CPUWriteState(const char *); extern bool CPUWriteState(const char *);
extern int CPULoadRom(const char *); extern int CPULoadRom(const char *);
extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16); extern void CPUUpdateRegister(u32, u16);
extern void applyTimer ();
extern void CPUWriteHalfWord(u32, u16); extern void CPUWriteHalfWord(u32, u16);
extern void CPUWriteByte(u32, u8); extern void CPUWriteByte(u32, u8);
extern void CPUInit(const char *,bool); extern void CPUInit(const char *,bool);
extern void CPUReset(); extern void CPUReset();
extern void CPULoop(int); extern void CPULoop(int);
extern bool CPUCheckDMA(int,int); extern void CPUCheckDMA(int,int);
extern bool CPUIsGBAImage(const char *); extern bool CPUIsGBAImage(const char *);
extern bool CPUIsZipFile(const char *); extern bool CPUIsZipFile(const char *);
#ifdef PROFILING #ifdef PROFILING
extern void cpuProfil(char *buffer, int, u32, int); #include "prof/prof.h"
extern void cpuProfil(profile_segment *seg);
extern void cpuEnableProfiling(int hz); extern void cpuEnableProfiling(int hz);
#endif #endif

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -23,18 +23,26 @@
#include "System.h" #include "System.h"
#include "Port.h" #include "Port.h"
#include "RTC.h" #include "RTC.h"
#include "Sound.h"
extern bool cpuSramEnabled; extern bool cpuSramEnabled;
extern bool cpuFlashEnabled; extern bool cpuFlashEnabled;
extern bool cpuEEPROMEnabled; extern bool cpuEEPROMEnabled;
extern bool cpuEEPROMSensorEnabled; extern bool cpuEEPROMSensorEnabled;
extern bool cpuDmaHack; extern bool cpuDmaHack;
extern bool cpuDmaHack2;
extern u32 cpuDmaLast; extern u32 cpuDmaLast;
extern bool timer0On;
extern int lspeed; extern int timer0Ticks;
extern void LinkSStop(void); extern int timer0ClockReload;
extern bool timer1On;
extern int timer1Ticks;
extern int timer1ClockReload;
extern bool timer2On;
extern int timer2Ticks;
extern int timer2ClockReload;
extern bool timer3On;
extern int timer3Ticks;
extern int timer3ClockReload;
extern int cpuTotalTicks;
#define CPUReadByteQuick(addr) \ #define CPUReadByteQuick(addr) \
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask] map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
@ -45,7 +53,7 @@ extern void LinkSStop(void);
#define CPUReadMemoryQuick(addr) \ #define CPUReadMemoryQuick(addr) \
READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask])) READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
inline u32 CPUReadMemory(u32 address) static inline u32 CPUReadMemory(u32 address)
{ {
#ifdef DEV_VERSION #ifdef DEV_VERSION
@ -82,20 +90,26 @@ inline u32 CPUReadMemory(u32 address)
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC])); value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break; break;
case 4: case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fc]) { if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2]) if(ioReadable[(address & 0x3fc) + 2])
value = soundRead32(address & 0x3fC); value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
else else
value = soundRead16(address & 0x3fc); value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
} else goto unreadable; } else goto unreadable;
break; break;
case 5: case 5:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC])); value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break; break;
case 6: case 6:
value = READ32LE(((u32 *)&vram[address & 0x1fffc])); address = (address & 0x1fffc);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
value = 0;
break;
}
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
value = READ32LE(((u32 *)&vram[address]));
break; break;
case 7: case 7:
value = READ32LE(((u32 *)&oam[address & 0x3FC])); value = READ32LE(((u32 *)&oam[address & 0x3FC]));
@ -126,7 +140,7 @@ inline u32 CPUReadMemory(u32 address)
} }
#endif #endif
if(cpuDmaHack || cpuDmaHack2) { if(cpuDmaHack) {
value = cpuDmaLast; value = cpuDmaLast;
} else { } else {
if(armState) { if(armState) {
@ -164,7 +178,7 @@ inline u32 CPUReadMemory(u32 address)
extern u32 myROM[]; extern u32 myROM[];
inline u32 CPUReadHalfWord(u32 address) static inline u32 CPUReadHalfWord(u32 address)
{ {
#ifdef DEV_VERSION #ifdef DEV_VERSION
if(address & 1) { if(address & 1) {
@ -199,17 +213,39 @@ inline u32 CPUReadHalfWord(u32 address)
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe])); value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break; break;
case 4: case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fe]) if((address < 0x4000400) && ioReadable[address & 0x3fe])
{
value = READ16LE(((u16 *)&ioMem[address & 0x3fe])); value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
{
if (((address & 0x3fe) == 0x100) && timer0On)
value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload);
else
if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4))
value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload);
else
if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4))
value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload);
else
if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4))
value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
}
}
else goto unreadable; else goto unreadable;
break; break;
case 5: case 5:
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe])); value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
break; break;
case 6: case 6:
value = READ16LE(((u16 *)&vram[address & 0x1fffe])); address = (address & 0x1fffe);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
{
value = 0;
break;
}
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
value = READ16LE(((u16 *)&vram[address]));
break; break;
case 7: case 7:
value = READ16LE(((u16 *)&oam[address & 0x3fe])); value = READ16LE(((u16 *)&oam[address & 0x3fe]));
@ -242,7 +278,7 @@ if((address>=0x4000120||address<=0x4000126)&&lspeed)
armNextPC - 4 : armNextPC - 2); armNextPC - 4 : armNextPC - 2);
} }
#endif #endif
if(cpuDmaHack2 || cpuDmaHack) { if(cpuDmaHack) {
value = cpuDmaLast & 0xFFFF; value = cpuDmaLast & 0xFFFF;
} else { } else {
if(armState) { if(armState) {
@ -261,7 +297,7 @@ if((address>=0x4000120||address<=0x4000126)&&lspeed)
return value; return value;
} }
inline u16 CPUReadHalfWordSigned(u32 address) static inline u16 CPUReadHalfWordSigned(u32 address)
{ {
u16 value = CPUReadHalfWord(address); u16 value = CPUReadHalfWord(address);
if((address & 1)) if((address & 1))
@ -269,7 +305,7 @@ inline u16 CPUReadHalfWordSigned(u32 address)
return value; return value;
} }
inline u8 CPUReadByte(u32 address) static inline u8 CPUReadByte(u32 address)
{ {
switch(address >> 24) { switch(address >> 24) {
case 0: case 0:
@ -290,15 +326,18 @@ inline u8 CPUReadByte(u32 address)
case 3: case 3:
return internalRAM[address & 0x7fff]; return internalRAM[address & 0x7fff];
case 4: case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3ff]) if((address < 0x4000400) && ioReadable[address & 0x3ff])
return soundRead(address & 0x3ff); return ioMem[address & 0x3ff];
else goto unreadable; else goto unreadable;
case 5: case 5:
return paletteRAM[address & 0x3ff]; return paletteRAM[address & 0x3ff];
case 6: case 6:
return vram[address & 0x1ffff]; address = (address & 0x1ffff);
if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return 0;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
return vram[address];
case 7: case 7:
return oam[address & 0x3ff]; return oam[address & 0x3ff];
case 8: case 8:
@ -335,7 +374,7 @@ inline u8 CPUReadByte(u32 address)
armNextPC - 4 : armNextPC - 2); armNextPC - 4 : armNextPC - 2);
} }
#endif #endif
if(cpuDmaHack || cpuDmaHack2) { if(cpuDmaHack) {
return cpuDmaLast & 0xFF; return cpuDmaLast & 0xFF;
} else { } else {
if(armState) { if(armState) {
@ -348,12 +387,13 @@ inline u8 CPUReadByte(u32 address)
} }
} }
inline void CPUWriteMemory(u32 address, u32 value) static inline void CPUWriteMemory(u32 address, u32 value)
{ {
#ifdef DEV_VERSION #ifdef DEV_VERSION
if(address & 3) { if(address & 3) {
if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) { if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
log("Unaliagned word write: %08x to %08x from %08x\n", log("Unaligned word write: %08x to %08x from %08x\n",
value, value,
address, address,
armMode ? armNextPC - 4 : armNextPC - 2); armMode ? armNextPC - 4 : armNextPC - 2);
@ -363,7 +403,7 @@ inline void CPUWriteMemory(u32 address, u32 value)
switch(address >> 24) { switch(address >> 24) {
case 0x02: case 0x02:
#ifdef SDL #ifdef BKPT_SUPPORT
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC])) if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
cheatsWriteMemory(address & 0x203FFFC, cheatsWriteMemory(address & 0x203FFFC,
value); value);
@ -372,7 +412,7 @@ inline void CPUWriteMemory(u32 address, u32 value)
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value); WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
break; break;
case 0x03: case 0x03:
#ifdef SDL #ifdef BKPT_SUPPORT
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc])) if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
cheatsWriteMemory(address & 0x3007FFC, cheatsWriteMemory(address & 0x3007FFC,
value); value);
@ -387,15 +427,36 @@ inline void CPUWriteMemory(u32 address, u32 value)
} else goto unwritable; } else goto unwritable;
break; break;
case 0x05: case 0x05:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezePRAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value); WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
break; break;
case 0x06: case 0x06:
if(address & 0x10000) address = (address & 0x1fffc);
WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value); if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
return;
if ((address & 0x18000) == 0x18000)
address &= 0x17fff;
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeVRAM[address]))
cheatsWriteMemory(address + 0x06000000, value);
else else
WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value); #endif
WRITE32LE(((u32 *)&vram[address]), value);
break; break;
case 0x07: case 0x07:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeOAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value); WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
break; break;
case 0x0D: case 0x0D:

View File

@ -22,7 +22,6 @@ int coeff[32] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
u32 line0[240]; u32 line0[240];
u32 line1[240]; u32 line1[240];
u32 line2[240]; u32 line2[240];
@ -32,6 +31,7 @@ u32 lineOBJWin[240];
u32 lineMix[240]; u32 lineMix[240];
bool gfxInWin0[240]; bool gfxInWin0[240];
bool gfxInWin1[240]; bool gfxInWin1[240];
int lineOBJpixleft[128];
int gfxBG2Changed = 0; int gfxBG2Changed = 0;
int gfxBG3Changed = 0; int gfxBG3Changed = 0;

359
src/Gfx.h
View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -28,8 +28,8 @@
//#define SPRITE_DEBUG //#define SPRITE_DEBUG
void gfxDrawTextScreen(u16, u16, u16, u32 *); static void gfxDrawTextScreen(u16, u16, u16, u32 *);
void gfxDrawRotScreen(u16, static void gfxDrawRotScreen(u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
@ -37,7 +37,7 @@ void gfxDrawRotScreen(u16,
int&, int&, int&, int&,
int, int,
u32*); u32*);
void gfxDrawRotScreen16Bit(u16, static void gfxDrawRotScreen16Bit(u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
@ -45,7 +45,7 @@ void gfxDrawRotScreen16Bit(u16,
int&, int&, int&, int&,
int, int,
u32*); u32*);
void gfxDrawRotScreen256(u16, static void gfxDrawRotScreen256(u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
@ -53,7 +53,7 @@ void gfxDrawRotScreen256(u16,
int&, int&, int&, int&,
int, int,
u32*); u32*);
void gfxDrawRotScreen16Bit160(u16, static void gfxDrawRotScreen16Bit160(u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
u16, u16, u16, u16,
@ -61,10 +61,10 @@ void gfxDrawRotScreen16Bit160(u16,
int&, int&, int&, int&,
int, int,
u32*); u32*);
void gfxDrawSprites(u32 *); static void gfxDrawSprites(u32 *);
void gfxIncreaseBrightness(u32 *line, int coeff); static void gfxIncreaseBrightness(u32 *line, int coeff);
void gfxDecreaseBrightness(u32 *line, int coeff); static void gfxDecreaseBrightness(u32 *line, int coeff);
void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb); static void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
void mode0RenderLine(); void mode0RenderLine();
void mode0RenderLineNoWindow(); void mode0RenderLineNoWindow();
@ -100,6 +100,7 @@ extern u32 lineOBJWin[240];
extern u32 lineMix[240]; extern u32 lineMix[240];
extern bool gfxInWin0[240]; extern bool gfxInWin0[240];
extern bool gfxInWin1[240]; extern bool gfxInWin1[240];
extern int lineOBJpixleft[128];
extern int gfxBG2Changed; extern int gfxBG2Changed;
extern int gfxBG3Changed; extern int gfxBG3Changed;
@ -114,14 +115,14 @@ extern int gfxBG3LastX;
extern int gfxBG3LastY; extern int gfxBG3LastY;
extern int gfxLastVCOUNT; extern int gfxLastVCOUNT;
inline void gfxClearArray(u32 *array) static inline void gfxClearArray(u32 *array)
{ {
for(int i = 0; i < 240; i++) { for(int i = 0; i < 240; i++) {
*array++ = 0x80000000; *array++ = 0x80000000;
} }
} }
inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs, static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u32 *line) u32 *line)
{ {
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
@ -266,7 +267,7 @@ inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
} }
} }
inline void gfxDrawRotScreen(u16 control, static inline void gfxDrawRotScreen(u16 control,
u16 x_l, u16 x_h, u16 x_l, u16 x_h,
u16 y_l, u16 y_h, u16 y_l, u16 y_h,
u16 pa, u16 pb, u16 pa, u16 pb,
@ -305,7 +306,7 @@ inline void gfxDrawRotScreen(u16 control,
int dy = pc & 0x7FFF; int dy = pc & 0x7FFF;
if(pc & 0x8000) if(pc & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF; int dmy = pd & 0x7FFF;
if(pd & 0x8000) if(pd & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
@ -432,7 +433,7 @@ inline void gfxDrawRotScreen(u16 control,
} }
} }
inline void gfxDrawRotScreen16Bit(u16 control, static inline void gfxDrawRotScreen16Bit(u16 control,
u16 x_l, u16 x_h, u16 x_l, u16 x_h,
u16 y_l, u16 y_h, u16 y_l, u16 y_h,
u16 pa, u16 pb, u16 pa, u16 pb,
@ -462,7 +463,7 @@ inline void gfxDrawRotScreen16Bit(u16 control,
int dy = pc & 0x7FFF; int dy = pc & 0x7FFF;
if(pc & 0x8000) if(pc & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF; int dmy = pd & 0x7FFF;
if(pd & 0x8000) if(pd & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
@ -529,7 +530,7 @@ inline void gfxDrawRotScreen16Bit(u16 control,
} }
} }
inline void gfxDrawRotScreen256(u16 control, static inline void gfxDrawRotScreen256(u16 control,
u16 x_l, u16 x_h, u16 x_l, u16 x_h,
u16 y_l, u16 y_h, u16 y_l, u16 y_h,
u16 pa, u16 pb, u16 pa, u16 pb,
@ -560,7 +561,7 @@ inline void gfxDrawRotScreen256(u16 control,
int dy = pc & 0x7FFF; int dy = pc & 0x7FFF;
if(pc & 0x8000) if(pc & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF; int dmy = pd & 0x7FFF;
if(pd & 0x8000) if(pd & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
@ -630,7 +631,7 @@ inline void gfxDrawRotScreen256(u16 control,
} }
} }
inline void gfxDrawRotScreen16Bit160(u16 control, static inline void gfxDrawRotScreen16Bit160(u16 control,
u16 x_l, u16 x_h, u16 x_l, u16 x_h,
u16 y_l, u16 y_h, u16 y_l, u16 y_h,
u16 pa, u16 pb, u16 pa, u16 pb,
@ -661,7 +662,7 @@ inline void gfxDrawRotScreen16Bit160(u16 control,
int dy = pc & 0x7FFF; int dy = pc & 0x7FFF;
if(pc & 0x8000) if(pc & 0x8000)
dy |= 0xFFFF8000; dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF; int dmy = pd & 0x7FFF;
if(pd & 0x8000) if(pd & 0x8000)
dmy |= 0xFFFF8000; dmy |= 0xFFFF8000;
@ -729,8 +730,12 @@ inline void gfxDrawRotScreen16Bit160(u16 control,
} }
} }
inline void gfxDrawSprites(u32 *lineOBJ) static inline void gfxDrawSprites(u32 *lineOBJ)
{ {
// lineOBJpix is used to keep track of the drawn OBJs
// and to stop drawing them if the 'maximum number of OBJ per line'
// has been reached.
int lineOBJpix = (DISPCNT & 0x20) ? 954 : 1226;
int m=0; int m=0;
gfxClearArray(lineOBJ); gfxClearArray(lineOBJ);
if(layerEnable & 0x1000) { if(layerEnable & 0x1000) {
@ -744,55 +749,37 @@ inline void gfxDrawSprites(u32 *lineOBJ)
u16 a2 = READ16LE(sprites++); u16 a2 = READ16LE(sprites++);
sprites++; sprites++;
// ignore OBJ-WIN lineOBJpixleft[x]=lineOBJpix;
if((a0 & 0x0c00) == 0x0800)
lineOBJpix-=2;
if (lineOBJpix<=0)
continue; continue;
int sizeY = 8; if ((a0 & 0x0c00) == 0x0c00)
int sizeX = 8; a0 &=0xF3FF;
switch(((a0 >>12) & 0x0c)|(a1>>14)) { if ((a0>>14) == 3)
case 0: {
break; a0 &= 0x3FFF;
case 1: a1 &= 0x3FFF;
sizeX = sizeY = 16; }
break;
case 2: int sizeX = 8<<(a1>>14);
sizeX = sizeY = 32; int sizeY = sizeX;
break;
case 3: if ((a0>>14) & 1)
sizeX = sizeY = 64; {
break; if (sizeX<32)
case 4: sizeX<<=1;
sizeX = 16; if (sizeY>8)
break; sizeY>>=1;
case 5: }
sizeX = 32; else if ((a0>>14) & 2)
break; {
case 6: if (sizeX>8)
sizeX = 32; sizeX>>=1;
sizeY = 16; if (sizeY<32)
break; sizeY<<=1;
case 7:
sizeX = 64;
sizeY = 32;
break;
case 8:
sizeY = 16;
break;
case 9:
sizeY = 32;
break;
case 10:
sizeX = 16;
sizeY = 32;
break;
case 11:
sizeX = 32;
sizeY = 64;
break;
default:
continue;
} }
#ifdef SPRITE_DEBUG #ifdef SPRITE_DEBUG
@ -801,9 +788,45 @@ inline void gfxDrawSprites(u32 *lineOBJ)
#endif #endif
int sy = (a0 & 255); int sy = (a0 & 255);
int sx = (a1 & 0x1FF);
if(sy > 160) // computes ticks used by OBJ-WIN if OBJWIN is enabled
if (((a0 & 0x0c00) == 0x0800) && (layerEnable & 0x8000))
{
if ((a0 & 0x0300) == 0x0300)
{
sizeX<<=1;
sizeY<<=1;
}
if((sy+sizeY) > 256)
sy -= 256; sy -= 256;
if ((sx+sizeX)> 512)
sx-=512;
if (sx<0)
{
sizeX+=sx;
sx = 0;
}
else if ((sx+sizeX)>240)
sizeX=240-sx;
if ((VCOUNT>=sy) && (VCOUNT<sy+sizeY) && (sx<240))
{
if (a0 & 0x0100)
lineOBJpix-=8+2*sizeX;
else
lineOBJpix-=sizeX-2;
}
continue;
}
// else ignores OBJ-WIN if OBJWIN is disabled, and ignored disabled OBJ
else
if(((a0 & 0x0c00) == 0x0800) || ((a0 & 0x0300) == 0x0200))
continue;
if (lineOBJpix<0)
continue;
if(a0 & 0x0100) { if(a0 & 0x0100) {
int fieldX = sizeX; int fieldX = sizeX;
@ -812,11 +835,18 @@ inline void gfxDrawSprites(u32 *lineOBJ)
fieldX <<= 1; fieldX <<= 1;
fieldY <<= 1; fieldY <<= 1;
} }
if((sy+fieldY) > 256)
sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) { if((t >= 0) && (t < fieldY)) {
int sx = (a1 & 0x1FF); int startpix = 0;
if((sx < 240) || (((sx + fieldX) & 511) < 240)) { if ((sx+fieldX)> 512)
{
startpix=512-sx;
}
if (lineOBJpix>0)
if((sx < 240) || startpix) {
lineOBJpix-=8;
// int t2 = t - (fieldY >> 1); // int t2 = t - (fieldY >> 1);
int rot = (a1 >> 9) & 0x1F; int rot = (a1 >> 9) & 0x1F;
u16 *OAM = (u16 *)oam; u16 *OAM = (u16 *)oam;
@ -854,6 +884,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
else else
c &= 0x3FE; c &= 0x3FE;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
@ -885,7 +919,7 @@ inline void gfxDrawSprites(u32 *lineOBJ)
lineOBJ[sx] = 0x001F; lineOBJ[sx] = 0x001F;
#endif #endif
} }
sx = (sx+1)&511;; sx = (sx+1)&511;
realX += dx; realX += dx;
realY += dy; realY += dy;
} }
@ -899,6 +933,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
inc = sizeX >> 3; inc = sizeX >> 3;
int palette = (a2 >> 8) & 0xF0; int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
if(xxx < 0 || xxx >= sizeX || if(xxx < 0 || xxx >= sizeX ||
@ -934,7 +972,7 @@ inline void gfxDrawSprites(u32 *lineOBJ)
if(t == 0 || t == maskY || x == 0 || x == maskX) if(t == 0 || t == maskY || x == 0 || x == maskX)
lineOBJ[sx] = 0x001F; lineOBJ[sx] = 0x001F;
#endif #endif
sx = (sx+1)&511;; sx = (sx+1)&511;
realX += dx; realX += dx;
realY += dy; realY += dy;
@ -943,10 +981,17 @@ inline void gfxDrawSprites(u32 *lineOBJ)
} }
} }
} else { } else {
if(sy+sizeY > 256)
sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) { if((t >= 0) && (t < sizeY)) {
int sx = (a1 & 0x1FF); int startpix = 0;
if(((sx < 240)||(((sx+sizeX)&511)<240)) && !(a0 & 0x0200)) { if ((sx+sizeX)> 512)
{
startpix=512-sx;
}
if((sx < 240) || startpix) {
lineOBJpix+=2;
if(a0 & 0x2000) { if(a0 & 0x2000) {
if(a1 & 0x2000) if(a1 & 0x2000)
t = sizeY - t - 1; t = sizeY - t - 1;
@ -976,6 +1021,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) { for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if ((color==0) && (((prio >> 25)&3) < if ((color==0) && (((prio >> 25)&3) <
@ -1048,6 +1097,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx = 7; xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) { for(int xx = sizeX - 1; xx >= 0; xx--) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
@ -1088,6 +1141,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
} }
} else { } else {
for(int xx = 0; xx < sizeX; xx++) { for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
@ -1136,74 +1193,55 @@ inline void gfxDrawSprites(u32 *lineOBJ)
} }
} }
inline void gfxDrawOBJWin(u32 *lineOBJWin) static inline void gfxDrawOBJWin(u32 *lineOBJWin)
{ {
gfxClearArray(lineOBJWin); gfxClearArray(lineOBJWin);
if(layerEnable & 0x8000) { if((layerEnable & 0x9000) == 0x9000) {
u16 *sprites = (u16 *)oam; u16 *sprites = (u16 *)oam;
// u16 *spritePalette = &((u16 *)paletteRAM)[256]; // u16 *spritePalette = &((u16 *)paletteRAM)[256];
for(int x = 0; x < 128 ; x++) { for(int x = 0; x < 128 ; x++) {
int lineOBJpix = lineOBJpixleft[x];
u16 a0 = READ16LE(sprites++); u16 a0 = READ16LE(sprites++);
u16 a1 = READ16LE(sprites++); u16 a1 = READ16LE(sprites++);
u16 a2 = READ16LE(sprites++); u16 a2 = READ16LE(sprites++);
sprites++; sprites++;
// ignore non OBJ-WIN if (lineOBJpix<=0)
if((a0 & 0x0c00) != 0x0800)
continue; continue;
int sizeY = 8; // ignores non OBJ-WIN and disabled OBJ-WIN
int sizeX = 8; if(((a0 & 0x0c00) != 0x0800) || ((a0 & 0x0300) == 0x0200))
switch(((a0 >>12) & 0x0c)|(a1>>14)) {
case 0:
break;
case 1:
sizeX = sizeY = 16;
break;
case 2:
sizeX = sizeY = 32;
break;
case 3:
sizeX = sizeY = 64;
break;
case 4:
sizeX = 16;
break;
case 5:
sizeX = 32;
break;
case 6:
sizeX = 32;
sizeY = 16;
break;
case 7:
sizeX = 64;
sizeY = 32;
break;
case 8:
sizeY = 16;
break;
case 9:
sizeY = 32;
break;
case 10:
sizeX = 16;
sizeY = 32;
break;
case 11:
sizeX = 32;
sizeY = 64;
break;
default:
continue; continue;
if ((a0 & 0x0c00) == 0x0c00)
a0 &=0xF3FF;
if ((a0>>14) == 3)
{
a0 &= 0x3FFF;
a1 &= 0x3FFF;
}
int sizeX = 8<<(a1>>14);
int sizeY = sizeX;
if ((a0>>14) & 1)
{
if (sizeX<32)
sizeX<<=1;
if (sizeY>8)
sizeY>>=1;
}
else if ((a0>>14) & 2)
{
if (sizeX>8)
sizeX>>=1;
if (sizeY<32)
sizeY<<=1;
} }
int sy = (a0 & 255); int sy = (a0 & 255);
if(sy > 160)
sy -= 256;
if(a0 & 0x0100) { if(a0 & 0x0100) {
int fieldX = sizeX; int fieldX = sizeX;
int fieldY = sizeY; int fieldY = sizeY;
@ -1211,11 +1249,18 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
fieldX <<= 1; fieldX <<= 1;
fieldY <<= 1; fieldY <<= 1;
} }
if((sy+fieldY) > 256)
sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) { if((t >= 0) && (t < fieldY)) {
int sx = (a1 & 0x1FF); int sx = (a1 & 0x1FF);
if((sx < 240) || (((sx + fieldX) & 511) < 240)) { int startpix = 0;
if ((sx+fieldX)> 512)
{
startpix=512-sx;
}
if((sx < 240) || startpix) {
lineOBJpix-=8;
// int t2 = t - (fieldY >> 1); // int t2 = t - (fieldY >> 1);
int rot = (a1 >> 9) & 0x1F; int rot = (a1 >> 9) & 0x1F;
u16 *OAM = (u16 *)oam; u16 *OAM = (u16 *)oam;
@ -1249,6 +1294,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
else else
c &= 0x3FE; c &= 0x3FE;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
@ -1263,7 +1312,7 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
lineOBJWin[sx] = 1; lineOBJWin[sx] = 1;
} }
} }
sx = (sx+1)&511;; sx = (sx+1)&511;
realX += dx; realX += dx;
realY += dy; realY += dy;
} }
@ -1277,6 +1326,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
inc = sizeX >> 3; inc = sizeX >> 3;
// int palette = (a2 >> 8) & 0xF0; // int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) { for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8; int xxx = realX >> 8;
int yyy = realY >> 8; int yyy = realY >> 8;
@ -1301,7 +1354,7 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} }
// } // }
sx = (sx+1)&511;; sx = (sx+1)&511;
realX += dx; realX += dx;
realY += dy; realY += dy;
} }
@ -1309,10 +1362,18 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} }
} else { } else {
if((sy+sizeY) > 256)
sy -= 256;
int t = VCOUNT - sy; int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) { if((t >= 0) && (t < sizeY)) {
int sx = (a1 & 0x1FF); int sx = (a1 & 0x1FF);
if(((sx < 240)||(((sx+sizeX)&511)<240)) && !(a0 & 0x0200)) { int startpix = 0;
if ((sx+sizeX)> 512)
{
startpix=512-sx;
}
if((sx < 240) || startpix) {
lineOBJpix+=2;
if(a0 & 0x2000) { if(a0 & 0x2000) {
if(a1 & 0x2000) if(a1 & 0x2000)
t = sizeY - t - 1; t = sizeY - t - 1;
@ -1335,6 +1396,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
xxx = 7; xxx = 7;
// u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6); // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) { for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(color) { if(color) {
@ -1384,6 +1449,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(a1 & 0x1000) { if(a1 & 0x1000) {
xxx = 7; xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) { for(int xx = sizeX - 1; xx >= 0; xx--) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
@ -1408,6 +1477,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} else { } else {
for(int xx = 0; xx < sizeX; xx++) { for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) { if(sx < 240) {
u8 color = vram[address]; u8 color = vram[address];
if(xx & 1) { if(xx & 1) {
@ -1439,7 +1512,7 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
} }
} }
inline u32 gfxIncreaseBrightness(u32 color, int coeff) static inline u32 gfxIncreaseBrightness(u32 color, int coeff)
{ {
int r = (color & 0x1F); int r = (color & 0x1F);
int g = ((color >> 5) & 0x1F); int g = ((color >> 5) & 0x1F);
@ -1458,7 +1531,7 @@ inline u32 gfxIncreaseBrightness(u32 color, int coeff)
return color; return color;
} }
inline void gfxIncreaseBrightness(u32 *line, int coeff) static inline void gfxIncreaseBrightness(u32 *line, int coeff)
{ {
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++) {
u32 color = *line; u32 color = *line;
@ -1479,7 +1552,7 @@ inline void gfxIncreaseBrightness(u32 *line, int coeff)
} }
} }
inline u32 gfxDecreaseBrightness(u32 color, int coeff) static inline u32 gfxDecreaseBrightness(u32 color, int coeff)
{ {
int r = (color & 0x1F); int r = (color & 0x1F);
int g = ((color >> 5) & 0x1F); int g = ((color >> 5) & 0x1F);
@ -1499,7 +1572,7 @@ inline u32 gfxDecreaseBrightness(u32 color, int coeff)
return color; return color;
} }
inline void gfxDecreaseBrightness(u32 *line, int coeff) static inline void gfxDecreaseBrightness(u32 *line, int coeff)
{ {
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++) {
u32 color = *line; u32 color = *line;
@ -1520,7 +1593,7 @@ inline void gfxDecreaseBrightness(u32 *line, int coeff)
} }
} }
inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb) static inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
{ {
if(color < 0x80000000) { if(color < 0x80000000) {
int r = (color & 0x1F); int r = (color & 0x1F);
@ -1530,9 +1603,9 @@ inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
int g0 = ((color2 >> 5) & 0x1F); int g0 = ((color2 >> 5) & 0x1F);
int b0 = ((color2 >> 10) & 0x1F); int b0 = ((color2 >> 10) & 0x1F);
r = ((r * ca) >> 4) + ((r0 * cb) >> 4); r = ((r * ca) + (r0 * cb)) >> 4;
g = ((g * ca) >> 4) + ((g0 * cb) >> 4); g = ((g * ca) + (g0 * cb)) >> 4;
b = ((b * ca) >> 4) + ((b0 * cb) >> 4); b = ((b * ca) + (b0 * cb)) >> 4;
if(r > 31) if(r > 31)
r = 31; r = 31;
@ -1546,7 +1619,7 @@ inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
return color; return color;
} }
inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb) static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
{ {
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++) {
u32 color = *ta; u32 color = *ta;
@ -1559,9 +1632,9 @@ inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
int g0 = ((color2 >> 5) & 0x1F); int g0 = ((color2 >> 5) & 0x1F);
int b0 = ((color2 >> 10) & 0x1F); int b0 = ((color2 >> 10) & 0x1F);
r = ((r * ca) >> 4) + ((r0 * cb) >> 4); r = ((r * ca) + (r0 * cb)) >> 4;
g = ((g * ca) >> 4) + ((g0 * cb) >> 4); g = ((g * ca) + (g0 * cb)) >> 4;
b = ((b * ca) >> 4) + ((b0 * cb) >> 4); b = ((b * ca) + (b0 * cb)) >> 4;
if(r > 31) if(r > 31)
r = 31; r = 31;

View File

@ -16,7 +16,12 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Globals.h" #include "GBA.h"
#ifdef BKPT_SUPPORT
int oldreg[17];
char oldbuffer[10];
#endif
reg_pair reg[45]; reg_pair reg[45];
memoryMap map[256]; memoryMap map[256];
@ -43,8 +48,8 @@ int layerSettings = 0xff00;
int layerEnable = 0xff00; int layerEnable = 0xff00;
bool speedHack = false; bool speedHack = false;
int cpuSaveType = 0; int cpuSaveType = 0;
bool cpuEnhancedDetection = true;
bool cheatsEnabled = true; bool cheatsEnabled = true;
bool mirroringEnable = false;
u8 *bios = NULL; u8 *bios = NULL;
u8 *rom = NULL; u8 *rom = NULL;

View File

@ -57,8 +57,8 @@ extern int layerSettings;
extern int layerEnable; extern int layerEnable;
extern bool speedHack; extern bool speedHack;
extern int cpuSaveType; extern int cpuSaveType;
extern bool cpuEnhancedDetection;
extern bool cheatsEnabled; extern bool cheatsEnabled;
extern bool mirroringEnable;
extern u8 *bios; extern u8 *bios;
extern u8 *rom; extern u8 *rom;

View File

@ -25,8 +25,8 @@
#define MSG_SAVE_GAME_USING_BIOS 4 #define MSG_SAVE_GAME_USING_BIOS 4
#define MSG_UNSUPPORTED_SAVE_TYPE 5 #define MSG_UNSUPPORTED_SAVE_TYPE 5
#define MSG_CANNOT_OPEN_FILE 6 #define MSG_CANNOT_OPEN_FILE 6
#define MSG_BAD_ARCHIVE_FILE 7 #define MSG_BAD_ZIP_FILE 7
#define MSG_NO_IMAGE_ON_ARCHIVE 8 #define MSG_NO_IMAGE_ON_ZIP 8
#define MSG_ERROR_OPENING_IMAGE 9 #define MSG_ERROR_OPENING_IMAGE 9
#define MSG_ERROR_READING_IMAGE 10 #define MSG_ERROR_READING_IMAGE 10
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11 #define MSG_UNSUPPORTED_BIOS_FUNCTION 11
@ -60,3 +60,5 @@
#define MSG_INVALID_CBA_CODE 39 #define MSG_INVALID_CBA_CODE 39
#define MSG_CBA_CODE_WARNING 40 #define MSG_CBA_CODE_WARNING 40
#define MSG_OUT_OF_MEMORY 41 #define MSG_OUT_OF_MEMORY 41
#define MSG_WRONG_GAMESHARK_CODE 42
#define MSG_UNSUPPORTED_GAMESHARK_CODE 43

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -119,6 +119,8 @@ bool rtcWrite(u32 address, u16 value)
rtcClockData.data[0] = 0x40; rtcClockData.data[0] = 0x40;
rtcClockData.state = DATA; rtcClockData.state = DATA;
break; break;
case 0x64:
break;
case 0x65: case 0x65:
{ {
struct tm *newtime; struct tm *newtime;

View File

@ -659,40 +659,17 @@ void soundChannel4()
{ {
} }
#include <stdio.h>
inline void soundDirectSoundA() inline void soundDirectSoundA()
{ {
#ifdef ENHANCED_RATE
double cr = calc_rate(soundDSATimer);
static int cnt = 0;
static double lastcr = 0;
static FILE *fp = NULL;
if (fp==NULL)
fp=fopen("C:\\cr.txt", "at");
if (cr!=lastcr)
{
fprintf(fp, "%f %d\n", lastcr, cnt);
cnt=0;
lastcr=cr;
}
else
cnt++;
directBuffer[0][soundIndex] = interp_pop(0, calc_rate(soundDSATimer)); //soundDSAValue;
#else
directBuffer[0][soundIndex] = interp_pop(0); //soundDSAValue; directBuffer[0][soundIndex] = interp_pop(0); //soundDSAValue;
#endif
} }
void soundDirectSoundATimer() void soundDirectSoundATimer()
{ {
if(soundDSAEnabled) { if(soundDSAEnabled) {
if(soundDSFifoACount <= 16) { if(soundDSFifoACount <= 16) {
cpuDmaHack2 = CPUCheckDMA(3, 2); CPUCheckDMA(3, 2);
if(soundDSFifoACount <= 16) { if(soundDSFifoACount <= 16) {
soundEvent(FIFOA_L, (u16)0); soundEvent(FIFOA_L, (u16)0);
soundEvent(FIFOA_H, (u16)0); soundEvent(FIFOA_H, (u16)0);
@ -714,18 +691,15 @@ void soundDirectSoundATimer()
inline void soundDirectSoundB() inline void soundDirectSoundB()
{ {
#ifdef ENHANCED_RATE
directBuffer[1][soundIndex] = interp_pop(1, calc_rate(soundDSBTimer)); //soundDSBValue;
#else
directBuffer[1][soundIndex] = interp_pop(1); //soundDSBValue; directBuffer[1][soundIndex] = interp_pop(1); //soundDSBValue;
#endif
} }
void soundDirectSoundBTimer() void soundDirectSoundBTimer()
{ {
if(soundDSBEnabled) { if(soundDSBEnabled) {
if(soundDSFifoBCount <= 16) { if(soundDSFifoBCount <= 16) {
cpuDmaHack2 = CPUCheckDMA(3, 4); //cpuDmaHack2 =
CPUCheckDMA(3, 4);
if(soundDSFifoBCount <= 16) { if(soundDSFifoBCount <= 16) {
soundEvent(FIFOB_L, (u16)0); soundEvent(FIFOB_L, (u16)0);
soundEvent(FIFOB_H, (u16)0); soundEvent(FIFOB_H, (u16)0);

View File

@ -2,6 +2,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2004-2006 VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -95,7 +96,6 @@ extern Multi_Buffer * apu_out;
extern Gb_Apu * apu; extern Gb_Apu * apu;
extern const BOOST::uint8_t sound_data [Gb_Apu::register_count]; extern const BOOST::uint8_t sound_data [Gb_Apu::register_count];
extern void interp_rate(); extern void interp_rate();

View File

@ -106,6 +106,12 @@ extern void system10Frames(int);
extern void systemFrame(); extern void systemFrame();
extern void systemGbBorderOn(); extern void systemGbBorderOn();
extern void Sm60FPS_Init();
extern bool Sm60FPS_CanSkipFrame();
extern void Sm60FPS_Sleep();
extern void DbgMsg(const char *msg, ...);
extern void winlog(const char *,...);
extern bool systemSoundOn; extern bool systemSoundOn;
extern u16 systemColorMap16[0x10000]; extern u16 systemColorMap16[0x10000];
extern u32 systemColorMap32[0x10000]; extern u32 systemColorMap32[0x10000];
@ -118,6 +124,7 @@ extern int systemDebug;
extern int systemVerbose; extern int systemVerbose;
extern int systemFrameSkip; extern int systemFrameSkip;
extern int systemSaveUpdateCounter; extern int systemSaveUpdateCounter;
extern int systemSpeed;
#define SYSTEM_SAVE_UPDATED 30 #define SYSTEM_SAVE_UPDATED 30
#define SYSTEM_SAVE_NOT_UPDATED 0 #define SYSTEM_SAVE_NOT_UPDATED 0

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -37,8 +37,11 @@ extern "C" {
#include "Globals.h" #include "Globals.h"
#include "RTC.h" #include "RTC.h"
#include "Port.h" #include "Port.h"
extern "C" {
#include "memgzio.h" #include "memgzio.h"
#include "gbafilter.h" }
#ifndef _MSC_VER #ifndef _MSC_VER
#define _stricmp strcasecmp #define _stricmp strcasecmp
@ -483,7 +486,7 @@ bool utilIsGBAImage(const char * file)
{ {
cpuIsMultiBoot = false; cpuIsMultiBoot = false;
if(strlen(file) > 4) { if(strlen(file) > 4) {
char * p = (char *)strrchr(file,'.'); const char * p = strrchr(file,'.');
if(p != NULL) { if(p != NULL) {
if(_stricmp(p, ".gba") == 0) if(_stricmp(p, ".gba") == 0)
@ -507,7 +510,7 @@ bool utilIsGBAImage(const char * file)
bool utilIsGBImage(const char * file) bool utilIsGBImage(const char * file)
{ {
if(strlen(file) > 4) { if(strlen(file) > 4) {
char * p = (char *)strrchr(file,'.'); const char * p = strrchr(file,'.');
if(p != NULL) { if(p != NULL) {
if(_stricmp(p, ".gb") == 0) if(_stricmp(p, ".gb") == 0)
@ -527,7 +530,7 @@ bool utilIsGBImage(const char * file)
bool utilIsZipFile(const char *file) bool utilIsZipFile(const char *file)
{ {
if(strlen(file) > 4) { if(strlen(file) > 4) {
char * p = (char *)strrchr(file,'.'); const char * p = strrchr(file,'.');
if(p != NULL) { if(p != NULL) {
if(_stricmp(p, ".zip") == 0) if(_stricmp(p, ".zip") == 0)
@ -542,7 +545,7 @@ bool utilIsZipFile(const char *file)
bool utilIsRarFile(const char *file) bool utilIsRarFile(const char *file)
{ {
if(strlen(file) > 4) { if(strlen(file) > 4) {
const char * p = strrchr(file,'.'); char * p = strrchr(file,'.');
if(p != NULL) { if(p != NULL) {
if(_stricmp(p, ".rar") == 0) if(_stricmp(p, ".rar") == 0)
@ -554,24 +557,10 @@ bool utilIsRarFile(const char *file)
} }
#endif #endif
bool utilIs7ZipFile(const char *file)
{
if(strlen(file) > 3) {
const char * p = strrchr(file,'.');
if(p != NULL) {
if(_stricmp(p, ".7z") == 0)
return true;
}
}
return false;
}
bool utilIsGzipFile(const char *file) bool utilIsGzipFile(const char *file)
{ {
if(strlen(file) > 3) { if(strlen(file) > 3) {
char * p = (char *)strrchr(file,'.'); const char * p = strrchr(file,'.');
if(p != NULL) { if(p != NULL) {
if(_stricmp(p, ".gz") == 0) if(_stricmp(p, ".gz") == 0)
@ -612,7 +601,7 @@ IMAGE_TYPE utilFindType(const char *file)
if(r != UNZ_OK) { if(r != UNZ_OK) {
unzClose(unz); unzClose(unz);
systemMessage(MSG_BAD_ARCHIVE_FILE, N_("Bad ZIP file %s"), file); systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
return IMAGE_UNKNOWN; return IMAGE_UNKNOWN;
} }
@ -632,7 +621,7 @@ IMAGE_TYPE utilFindType(const char *file)
if(r != UNZ_OK) { if(r != UNZ_OK) {
unzClose(unz); unzClose(unz);
systemMessage(MSG_BAD_ARCHIVE_FILE, N_("Bad ZIP file %s"), file); systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
return IMAGE_UNKNOWN; return IMAGE_UNKNOWN;
} }
@ -654,7 +643,7 @@ IMAGE_TYPE utilFindType(const char *file)
unzClose(unz); unzClose(unz);
if(found == IMAGE_UNKNOWN) { if(found == IMAGE_UNKNOWN) {
systemMessage(MSG_NO_IMAGE_ON_ARCHIVE, systemMessage(MSG_NO_IMAGE_ON_ZIP,
N_("No image found on ZIP file %s"), file); N_("No image found on ZIP file %s"), file);
return found; return found;
} }
@ -723,7 +712,7 @@ static u8 *utilLoadFromZip(const char *file,
if(r != UNZ_OK) { if(r != UNZ_OK) {
unzClose(unz); unzClose(unz);
systemMessage(MSG_BAD_ARCHIVE_FILE, N_("Bad ZIP file %s"), file); systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
return NULL; return NULL;
} }
@ -743,7 +732,7 @@ static u8 *utilLoadFromZip(const char *file,
if(r != UNZ_OK) { if(r != UNZ_OK) {
unzClose(unz); unzClose(unz);
systemMessage(MSG_BAD_ARCHIVE_FILE, N_("Bad ZIP file %s"), file); systemMessage(MSG_BAD_ZIP_FILE, N_("Bad ZIP file %s"), file);
return NULL; return NULL;
} }
@ -760,7 +749,7 @@ static u8 *utilLoadFromZip(const char *file,
if(!found) { if(!found) {
unzClose(unz); unzClose(unz);
systemMessage(MSG_NO_IMAGE_ON_ARCHIVE, systemMessage(MSG_NO_IMAGE_ON_ZIP,
N_("No image found on ZIP file %s"), file); N_("No image found on ZIP file %s"), file);
return NULL; return NULL;
} }
@ -956,11 +945,11 @@ u8 *utilLoad(const char *file,
} }
size = fileSize; size = fileSize;
} }
int read = fileSize <= size ? fileSize : size; size_t read = fileSize <= size ? fileSize : size;
int r = fread(image, 1, read, f); size_t r = fread(image, 1, read, f);
fclose(f); fclose(f);
if(r != (int)read) { if(r != read) {
systemMessage(MSG_ERROR_READING_IMAGE, systemMessage(MSG_ERROR_READING_IMAGE,
N_("Error reading image %s"), file); N_("Error reading image %s"), file);
if(data == NULL) if(data == NULL)
@ -1053,22 +1042,22 @@ void utilGBAFindSave(const u8 *data, const int size)
if(d == 0x52504545) { if(d == 0x52504545) {
if(memcmp(p, "EEPROM_", 7) == 0) { if(memcmp(p, "EEPROM_", 7) == 0) {
if(saveType == 0) if(saveType == 0)
saveType = 1; saveType = 3;
} }
} else if (d == 0x4D415253) { } else if (d == 0x4D415253) {
if(memcmp(p, "SRAM_", 5) == 0) { if(memcmp(p, "SRAM_", 5) == 0) {
if(saveType == 0) if(saveType == 0)
saveType = 2; saveType = 1;
} }
} else if (d == 0x53414C46) { } else if (d == 0x53414C46) {
if(memcmp(p, "FLASH1M_", 8) == 0) { if(memcmp(p, "FLASH1M_", 8) == 0) {
if(saveType == 0) { if(saveType == 0) {
saveType = 3; saveType = 2;
flashSize = 0x20000; flashSize = 0x20000;
} }
} else if(memcmp(p, "FLASH", 5) == 0) { } else if(memcmp(p, "FLASH", 5) == 0) {
if(saveType == 0) { if(saveType == 0) {
saveType = 3; saveType = 2;
flashSize = 0x10000; flashSize = 0x10000;
} }
} }
@ -1087,7 +1076,7 @@ void utilGBAFindSave(const u8 *data, const int size)
flashSetSize(flashSize); flashSetSize(flashSize);
} }
void utilUpdateSystemColorMaps(int lcd) void utilUpdateSystemColorMaps()
{ {
switch(systemColorDepth) { switch(systemColorDepth) {
case 16: case 16:
@ -1097,7 +1086,6 @@ void utilUpdateSystemColorMaps(int lcd)
(((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x3e0) >> 5) << systemGreenShift) |
(((i & 0x7c00) >> 10) << systemBlueShift); (((i & 0x7c00) >> 10) << systemBlueShift);
} }
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
} }
break; break;
case 24: case 24:
@ -1108,7 +1096,6 @@ void utilUpdateSystemColorMaps(int lcd)
(((i & 0x3e0) >> 5) << systemGreenShift) | (((i & 0x3e0) >> 5) << systemGreenShift) |
(((i & 0x7c00) >> 10) << systemBlueShift); (((i & 0x7c00) >> 10) << systemBlueShift);
} }
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
} }
break; break;
} }

View File

@ -61,5 +61,5 @@ extern int utilGzRead(gzFile file, voidp buffer, unsigned int len);
extern int utilGzClose(gzFile file); extern int utilGzClose(gzFile file);
extern long utilGzMemTell(gzFile file); extern long utilGzMemTell(gzFile file);
extern void utilGBAFindSave(const u8 *, const int); extern void utilGBAFindSave(const u8 *, const int);
extern void utilUpdateSystemColorMaps(int lcd); extern void utilUpdateSystemColorMaps();
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -117,8 +117,8 @@ const Opcodes thumbOpcodes[] = {
{0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]"}, {0xfa00, 0x5800, "ldr%b %r0, [%r3, %r6]"},
// Format 8 // Format 8
{0xfe00, 0x5200, "strh %r0, [%r3, %r6]"}, {0xfe00, 0x5200, "strh %r0, [%r3, %r6]"},
{0xfe00, 0x5600, "ldrh %r0, [%r3, %r6]"}, {0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]"},
{0xfe00, 0x5a00, "ldsb %r0, [%r3, %r6]"}, {0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]"},
{0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"}, {0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"},
// Format 9 // Format 9
{0xe800, 0x6000, "str%B %r0, [%r3, %p]"}, {0xe800, 0x6000, "str%B %r0, [%r3, %p]"},

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -100,16 +100,16 @@ void BIOS_ArcTan2()
} }
#endif #endif
s16 x = reg[0].I; s32 x = reg[0].I;
s16 y = reg[1].I; s32 y = reg[1].I;
s16 res = 0; u32 res = 0;
if (y == 0) { if (y == 0) {
res = 0x8000 & x; res = ((x>>16) & 0x8000);
} else { } else {
if (x == 0) { if (x == 0) {
res = (0x8000 & y) + 0x4000; res = ((y>>16) & 0x8000) + 0x4000;
} else { } else {
if (abs(x) > abs(y)) { if ((abs(x) > abs(y)) || ((abs(x) == abs(y)) && (!((x<0) && (y<0))))) {
reg[1].I = x; reg[1].I = x;
reg[0].I = y << 14; reg[0].I = y << 14;
BIOS_Div(); BIOS_Div();
@ -117,16 +117,16 @@ void BIOS_ArcTan2()
if (x < 0) if (x < 0)
res = 0x8000 + reg[0].I; res = 0x8000 + reg[0].I;
else else
res = ((y & 0x8000) << 1 ) + reg[0].I; res = (((y>>16) & 0x8000)<<1) + reg[0].I;
} else { } else {
reg[0].I = x << 14; reg[0].I = x << 14;
BIOS_Div(); BIOS_Div();
BIOS_ArcTan(); BIOS_ArcTan();
res = (0x4000 + (y & 0x8000)) - reg[0].I; res = (0x4000 + ((y>>16) & 0x8000)) - reg[0].I;
} }
} }
} }
reg[0].I = ((u32)res) & 0xffff; reg[0].I = res;
#ifdef DEV_VERSION #ifdef DEV_VERSION
if(systemVerbose & VERBOSE_SWI) { if(systemVerbose & VERBOSE_SWI) {
@ -154,6 +154,10 @@ void BIOS_BitUnPack()
int len = CPUReadHalfWord(header); int len = CPUReadHalfWord(header);
// check address // check address
if(((source & 0xe000000) == 0) ||
((source + len) & 0xe000000) == 0)
return;
int bits = CPUReadByte(header+2); int bits = CPUReadByte(header+2);
int revbits = 8 - bits; int revbits = 8 - bits;
// u32 value = 0; // u32 value = 0;
@ -177,7 +181,7 @@ void BIOS_BitUnPack()
break; break;
u32 d = b & mask; u32 d = b & mask;
u32 temp = d >> bitcount; u32 temp = d >> bitcount;
if(!temp && addBase) { if(d || addBase) {
temp += base; temp += base;
} }
data |= temp << bitwritecount; data |= temp << bitwritecount;
@ -194,6 +198,11 @@ void BIOS_BitUnPack()
} }
} }
void BIOS_GetBiosChecksum()
{
reg[0].I=0xBAAE187F;
}
void BIOS_BgAffineSet() void BIOS_BgAffineSet()
{ {
#ifdef DEV_VERSION #ifdef DEV_VERSION
@ -278,7 +287,7 @@ void BIOS_CpuSet()
dest &= 0xFFFFFFFC; dest &= 0xFFFFFFFC;
// fill ? // fill ?
if((cnt >> 24) & 1) { if((cnt >> 24) & 1) {
u32 value = CPUReadMemory(source); u32 value = (source>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source));
while(count) { while(count) {
CPUWriteMemory(dest, value); CPUWriteMemory(dest, value);
dest += 4; dest += 4;
@ -287,7 +296,7 @@ void BIOS_CpuSet()
} else { } else {
// copy // copy
while(count) { while(count) {
CPUWriteMemory(dest, CPUReadMemory(source)); CPUWriteMemory(dest, (source>0x0EFFFFFF ? 0x1CAD1CAD : CPUReadMemory(source)));
source += 4; source += 4;
dest += 4; dest += 4;
count--; count--;
@ -296,7 +305,7 @@ void BIOS_CpuSet()
} else { } else {
// 16-bit fill? // 16-bit fill?
if((cnt >> 24) & 1) { if((cnt >> 24) & 1) {
u16 value = CPUReadHalfWord(source); u16 value = (source>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source));
while(count) { while(count) {
CPUWriteHalfWord(dest, value); CPUWriteHalfWord(dest, value);
dest += 2; dest += 2;
@ -305,7 +314,7 @@ void BIOS_CpuSet()
} else { } else {
// copy // copy
while(count) { while(count) {
CPUWriteHalfWord(dest, CPUReadHalfWord(source)); CPUWriteHalfWord(dest, (source>0x0EFFFFFF ? 0x1CAD : CPUReadHalfWord(source)));
source += 2; source += 2;
dest += 2; dest += 2;
count--; count--;
@ -341,7 +350,7 @@ void BIOS_CpuFastSet()
if((cnt >> 24) & 1) { if((cnt >> 24) & 1) {
while(count > 0) { while(count > 0) {
// BIOS always transfers 32 bytes at a time // BIOS always transfers 32 bytes at a time
u32 value = CPUReadMemory(source); u32 value = (source>0x0EFFFFFF ? 0xBAFFFFFB : CPUReadMemory(source));
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
CPUWriteMemory(dest, value); CPUWriteMemory(dest, value);
dest += 4; dest += 4;
@ -353,7 +362,7 @@ void BIOS_CpuFastSet()
while(count > 0) { while(count > 0) {
// BIOS always transfers 32 bytes at a time // BIOS always transfers 32 bytes at a time
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
CPUWriteMemory(dest, CPUReadMemory(source)); CPUWriteMemory(dest, (source>0x0EFFFFFF ? 0xBAFFFFFB :CPUReadMemory(source)));
source += 4; source += 4;
dest += 4; dest += 4;
} }
@ -865,6 +874,8 @@ void BIOS_RegisterRamReset(u32 flags)
// no need to trace here. this is only called directly from GBA.cpp // no need to trace here. this is only called directly from GBA.cpp
// to emulate bios initialization // to emulate bios initialization
CPUUpdateRegister(0x0, 0x80);
if(flags) { if(flags) {
if(flags & 0x01) { if(flags & 0x01) {
// clear work RAM // clear work RAM
@ -889,18 +900,16 @@ void BIOS_RegisterRamReset(u32 flags)
if(flags & 0x80) { if(flags & 0x80) {
int i; int i;
for(i = 0; i < 8; i++) for(i = 0; i < 0x10; i++)
CPUUpdateRegister(0x200+i*2, 0); CPUUpdateRegister(0x200+i*2, 0);
CPUUpdateRegister(0x202, 0xFFFF); for(i = 0; i < 0xF; i++)
for(i = 0; i < 8; i++)
CPUUpdateRegister(0x4+i*2, 0); CPUUpdateRegister(0x4+i*2, 0);
for(i = 0; i < 16; i++) for(i = 0; i < 0x20; i++)
CPUUpdateRegister(0x20+i*2, 0); CPUUpdateRegister(0x20+i*2, 0);
for(i = 0; i < 24; i++) for(i = 0; i < 0x18; i++)
CPUUpdateRegister(0xb0+i*2, 0); CPUUpdateRegister(0xb0+i*2, 0);
CPUUpdateRegister(0x130, 0); CPUUpdateRegister(0x130, 0);
@ -963,7 +972,7 @@ void BIOS_RLUnCompVram()
u32 source = reg[0].I; u32 source = reg[0].I;
u32 dest = reg[1].I; u32 dest = reg[1].I;
u32 header = CPUReadMemory(source); u32 header = CPUReadMemory(source & 0xFFFFFFFC);
source += 4; source += 4;
if(((source & 0xe000000) == 0) || if(((source & 0xe000000) == 0) ||
@ -1032,7 +1041,7 @@ void BIOS_RLUnCompWram()
u32 source = reg[0].I; u32 source = reg[0].I;
u32 dest = reg[1].I; u32 dest = reg[1].I;
u32 header = CPUReadMemory(source); u32 header = CPUReadMemory(source & 0xFFFFFFFC);
source += 4; source += 4;
if(((source & 0xe000000) == 0) || if(((source & 0xe000000) == 0) ||

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
extern void BIOS_ArcTan(); extern void BIOS_ArcTan();
extern void BIOS_ArcTan2(); extern void BIOS_ArcTan2();
extern void BIOS_BitUnPack(); extern void BIOS_BitUnPack();
extern void BIOS_GetBiosChecksum();
extern void BIOS_BgAffineSet(); extern void BIOS_BgAffineSet();
extern void BIOS_CpuSet(); extern void BIOS_CpuSet();
extern void BIOS_CpuFastSet(); extern void BIOS_CpuFastSet();

View File

@ -820,7 +820,7 @@ char *elfReadString(u8 *data, int *bytesRead)
*bytesRead = 1; *bytesRead = 1;
return NULL; return NULL;
} }
*bytesRead = strlen((char *)data) + 1; *bytesRead = (int)strlen((char *)data) + 1;
return (char *)data; return (char *)data;
} }
@ -961,8 +961,7 @@ u8 *elfReadAttribute(u8 *data, ELFAttr *attr)
data += bytes; data += bytes;
break; break;
case DW_FORM_ref_addr: case DW_FORM_ref_addr:
attr->value = (elfDebugInfo->infodata + elfRead4Bytes(data)) - attr->value = (u32)((elfDebugInfo->infodata + elfRead4Bytes(data)) - elfGetCompileUnitForData(data)->top);
elfGetCompileUnitForData(data)->top;
data += 4; data += 4;
break; break;
case DW_FORM_ref4: case DW_FORM_ref4:
@ -970,11 +969,7 @@ u8 *elfReadAttribute(u8 *data, ELFAttr *attr)
data += 4; data += 4;
break; break;
case DW_FORM_ref_udata: case DW_FORM_ref_udata:
attr->value = (elfDebugInfo->infodata + attr->value = (u32)((elfDebugInfo->infodata + (elfGetCompileUnitForData(data)->top - elfDebugInfo->infodata) + elfReadLEB128(data, &bytes)) - elfCurrentUnit->top);
(elfGetCompileUnitForData(data)->top -
elfDebugInfo->infodata) +
elfReadLEB128(data, &bytes)) -
elfCurrentUnit->top;
data += bytes; data += bytes;
break; break;
case DW_FORM_indirect: case DW_FORM_indirect:
@ -1070,7 +1065,7 @@ void elfParseCFA(u8 *top)
ELFcie *cies = NULL; ELFcie *cies = NULL;
while(data < end) { while(data < end) {
u32 offset = data - topOffset; u32 offset = (u32)(data - topOffset);
u32 len = elfRead4Bytes(data); u32 len = elfRead4Bytes(data);
data += 4; data += 4;
@ -1110,7 +1105,7 @@ void elfParseCFA(u8 *top)
cie->returnAddress = *data++; cie->returnAddress = *data++;
cie->data = data; cie->data = data;
cie->dataLen = dataEnd - data; cie->dataLen = (u32)(dataEnd - data);
} else { } else {
ELFfde *fde = (ELFfde *)calloc(1, sizeof(ELFfde)); ELFfde *fde = (ELFfde *)calloc(1, sizeof(ELFfde));
@ -1136,7 +1131,7 @@ void elfParseCFA(u8 *top)
data += 4; data += 4;
fde->data = data; fde->data = data;
fde->dataLen = dataEnd - data; fde->dataLen = (u32)(dataEnd - data);
if((elfFdeCount %10) == 0) { if((elfFdeCount %10) == 0) {
elfFdes = (ELFfde **)realloc(elfFdes, (elfFdeCount+10) * elfFdes = (ELFfde **)realloc(elfFdes, (elfFdeCount+10) *
@ -2762,7 +2757,7 @@ bool elfReadProgram(ELFHeader *eh, u8 *data, int& size, bool parseDebug)
while(ddata < end) { while(ddata < end) {
unit = elfParseCompUnit(ddata, abbrevdata); unit = elfParseCompUnit(ddata, abbrevdata);
unit->offset = ddata-debugdata; unit->offset = (u32)(ddata-debugdata);
elfParseLineInfo(unit, data); elfParseLineInfo(unit, data);
if(last == NULL) if(last == NULL)
elfCompileUnits = unit; elfCompileUnits = unit;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -38,11 +38,15 @@ typedef union {
extern bool gbLoadRom(const char *); extern bool gbLoadRom(const char *);
extern void gbEmulate(int); extern void gbEmulate(int);
extern void gbWriteMemory(register u16, register u8);
extern void gbDrawLine();
extern bool gbIsGameboyRom(const char *); extern bool gbIsGameboyRom(const char *);
extern void gbSoundReset(); extern void gbSoundReset();
extern void gbSoundSetQuality(int); extern void gbSoundSetQuality(int);
extern void gbGetHardwareType();
extern void gbReset(); extern void gbReset();
extern void gbCleanUp(); extern void gbCleanUp();
extern void gbCPUInit(const char *,bool);
extern bool gbWriteBatteryFile(const char *); extern bool gbWriteBatteryFile(const char *);
extern bool gbWriteBatteryFile(const char *, bool); extern bool gbWriteBatteryFile(const char *, bool);
extern bool gbReadBatteryFile(const char *); extern bool gbReadBatteryFile(const char *);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -27,9 +27,11 @@
#include "gbCheats.h" #include "gbCheats.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "GB.h"
gbCheat gbCheatList[100]; gbCheat gbCheatList[100];
int gbCheatNumber = 0; int gbCheatNumber = 0;
int gbNextCheat = 0;
bool gbCheatMap[0x10000]; bool gbCheatMap[0x10000];
extern bool cheatsEnabled; extern bool cheatsEnabled;
@ -50,7 +52,7 @@ void gbCheatUpdateMap()
void gbCheatsSaveGame(gzFile gzFile) void gbCheatsSaveGame(gzFile gzFile)
{ {
utilWriteInt(gzFile, gbCheatNumber); utilWriteInt(gzFile, gbCheatNumber);
if(gbCheatNumber) if(gbCheatNumber>0)
utilGzWrite(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber); utilGzWrite(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
} }
@ -81,7 +83,7 @@ void gbCheatsReadGame(gzFile gzFile, int version)
} else { } else {
gbCheatNumber = utilReadInt(gzFile); gbCheatNumber = utilReadInt(gzFile);
if(gbCheatNumber) { if(gbCheatNumber>0) {
utilGzRead(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber); utilGzRead(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
} }
} }
@ -163,7 +165,7 @@ bool gbCheatsLoadCheatList(const char *file)
bool gbVerifyGsCode(const char *code) bool gbVerifyGsCode(const char *code)
{ {
int len = strlen(code); size_t len = strlen(code);
if(len == 0) if(len == 0)
return true; return true;
@ -180,10 +182,6 @@ bool gbVerifyGsCode(const char *code)
GBCHEAT_HEX_VALUE(code[4]) << 4 | GBCHEAT_HEX_VALUE(code[4]) << 4 |
GBCHEAT_HEX_VALUE(code[5]); GBCHEAT_HEX_VALUE(code[5]);
if(address < 0xa000 ||
address > 0xdfff)
return false;
return true; return true;
} }
@ -221,14 +219,22 @@ void gbAddGsCheat(const char *code, const char *desc)
gbCheatList[i].enabled = true; gbCheatList[i].enabled = true;
gbCheatMap[gbCheatList[i].address] = true; int gsCode = gbCheatList[i].code;
if ((gsCode !=1) && ((gsCode & 0xF0) !=0x80) && ((gsCode & 0xF0) !=0x90) &&
((gsCode & 0xF0) !=0xA0) && ((gsCode) !=0xF0) && ((gsCode) !=0xF1))
systemMessage(MSG_WRONG_GAMESHARK_CODE,
N_("Wrong GameShark code type : %s"), code);
else if (((gsCode & 0xF0) ==0xA0) || ((gsCode) ==0xF0) || ((gsCode) ==0xF1))
systemMessage(MSG_UNSUPPORTED_GAMESHARK_CODE,
N_("Unsupported GameShark code type : %s"), code);
gbCheatNumber++; gbCheatNumber++;
} }
bool gbVerifyGgCode(const char *code) bool gbVerifyGgCode(const char *code)
{ {
int len = strlen(code); size_t len = strlen(code);
if(len != 11 && if(len != 11 &&
len != 7 && len != 7 &&
@ -313,12 +319,12 @@ void gbAddGgCheat(const char *code, const char *desc)
int i = gbCheatNumber; int i = gbCheatNumber;
int len = strlen(code); size_t len = strlen(code);
strcpy(gbCheatList[i].cheatCode, code); strcpy(gbCheatList[i].cheatCode, code);
strcpy(gbCheatList[i].cheatDesc, desc); strcpy(gbCheatList[i].cheatDesc, desc);
gbCheatList[i].code = 1; gbCheatList[i].code = 0x101;
gbCheatList[i].value = (GBCHEAT_HEX_VALUE(code[0]) << 4) + gbCheatList[i].value = (GBCHEAT_HEX_VALUE(code[0]) << 4) +
GBCHEAT_HEX_VALUE(code[1]); GBCHEAT_HEX_VALUE(code[1]);
@ -338,9 +344,12 @@ void gbAddGgCheat(const char *code, const char *desc)
compare ^= 0x45; compare ^= 0x45;
gbCheatList[i].compare = compare; gbCheatList[i].compare = compare;
gbCheatList[i].code = 0; //gbCheatList[i].code = 0;
gbCheatList[i].code = 0x100; // fix for compare value
} }
gbCheatList[i].enabled = true; gbCheatList[i].enabled = true;
gbCheatMap[gbCheatList[i].address] = true; gbCheatMap[gbCheatList[i].address] = true;
@ -425,6 +434,7 @@ bool gbCheatReadGSCodeFile(const char *fileName)
return true; return true;
} }
// Used to emulated GG codes
u8 gbCheatRead(u16 address) u8 gbCheatRead(u16 address)
{ {
if(!cheatsEnabled) if(!cheatsEnabled)
@ -437,10 +447,36 @@ u8 gbCheatRead(u16 address)
if(gbMemoryMap[address>>12][address&0xFFF] == gbCheatList[i].compare) if(gbMemoryMap[address>>12][address&0xFFF] == gbCheatList[i].compare)
return gbCheatList[i].value; return gbCheatList[i].value;
break; break;
case 0x00: case 0x101: // GameGenie 6 digits code support
case 0x01:
case 0x80:
return gbCheatList[i].value; return gbCheatList[i].value;
break;
}
}
}
return gbMemoryMap[address>>12][address&0xFFF];
}
// Used to emulate GS codes.
void gbCheatWrite(bool reboot)
{
if(cheatsEnabled)
{
u16 address = 0;
if (gbNextCheat >= gbCheatNumber)
gbNextCheat = 0;
for(int i = gbNextCheat; i < gbCheatNumber; i++) {
if(gbCheatList[i].enabled) {
address = gbCheatList[i].address;
if ((!reboot) && (address >= 0x8000) && !((address>=0xA000) && (address<0xC000)))
{ // These codes are executed one per one, at each Vblank
switch(gbCheatList[i].code) {
case 0x01:
gbWriteMemory(address, gbCheatList[i].value);
gbNextCheat = i+1;
return;
case 0x90: case 0x90:
case 0x91: case 0x91:
case 0x92: case 0x92:
@ -449,14 +485,34 @@ u8 gbCheatRead(u16 address)
case 0x95: case 0x95:
case 0x96: case 0x96:
case 0x97: case 0x97:
if(address >= 0xd000 && address < 0xe000) { case 0x98:
if(((gbMemoryMap[0x0d] - gbWram)/0x1000) == case 0x99:
(gbCheatList[i].code - 0x90)) case 0x9A:
return gbCheatList[i].value; case 0x9B:
} else case 0x9C:
return gbCheatList[i].value; case 0x9D:
case 0x9E:
case 0x9F:
int oldbank = gbMemory[0xff70];
gbWriteMemory(0xff70, gbCheatList[i].code & 0xf);
gbWriteMemory(address, gbCheatList[i].value);
gbWriteMemory(0xff70, oldbank);
gbNextCheat = i+1;
return;
}
}
else // These codes are only executed when the game is booted
{
switch(gbCheatList[i].code & 0xF0) {
case 0x80:
gbWriteMemory(0x0000, 0x0A);
gbWriteMemory(0x4000, gbCheatList[i].value & 0xF);
gbWriteMemory(address, gbCheatList[i].value);
gbNextCheat = i+1;
return;
}
}
} }
} }
} }
return gbMemoryMap[address>>12][address&0xFFF];
} }

View File

@ -50,6 +50,7 @@ extern void gbCheatRemoveAll();
extern void gbCheatEnable(int); extern void gbCheatEnable(int);
extern void gbCheatDisable(int); extern void gbCheatDisable(int);
extern u8 gbCheatRead(u16); extern u8 gbCheatRead(u16);
extern void gbCheatWrite(bool);
extern int gbCheatNumber; extern int gbCheatNumber;
extern gbCheat gbCheatList[100]; extern gbCheat gbCheatList[100];

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -22,8 +22,8 @@
break; break;
case 0x01: case 0x01:
// LD BC, NNNN // LD BC, NNNN
BC.B.B0=gbReadMemory(PC.W++); BC.B.B0=gbReadOpcode(PC.W++);
BC.B.B1=gbReadMemory(PC.W++); BC.B.B1=gbReadOpcode(PC.W++);
break; break;
case 0x02: case 0x02:
// LD (BC),A // LD (BC),A
@ -102,7 +102,9 @@
opcode = gbReadOpcode(PC.W++); opcode = gbReadOpcode(PC.W++);
if(gbCgbMode) { if(gbCgbMode) {
if(gbMemory[0xff4d] & 1) { if(gbMemory[0xff4d] & 1) {
gbSpeedSwitch(); gbSpeedSwitch();
//clockTicks += 228*144-(gbSpeed ? 62 : 63);
if(gbSpeed == 0) if(gbSpeed == 0)
gbMemory[0xff4d] = 0x00; gbMemory[0xff4d] = 0x00;
@ -113,8 +115,8 @@
break; break;
case 0x11: case 0x11:
// LD DE, NNNN // LD DE, NNNN
DE.B.B0=gbReadMemory(PC.W++); DE.B.B0=gbReadOpcode(PC.W++);
DE.B.B1=gbReadMemory(PC.W++); DE.B.B1=gbReadOpcode(PC.W++);
break; break;
case 0x12: case 0x12:
// LD (DE),A // LD (DE),A
@ -147,7 +149,7 @@
break; break;
case 0x18: case 0x18:
// JR NN // JR NN
PC.W+=(s8)gbReadMemory(PC.W)+1; PC.W+=(s8)gbReadOpcode(PC.W)+1;
break; break;
case 0x19: case 0x19:
// ADD HL,DE // ADD HL,DE
@ -190,14 +192,14 @@
if(AF.B.B0&Z_FLAG) if(AF.B.B0&Z_FLAG)
PC.W++; PC.W++;
else { else {
PC.W+=(s8)gbReadMemory(PC.W)+1; PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++; clockTicks++;
} }
break; break;
case 0x21: case 0x21:
// LD HL,NNNN // LD HL,NNNN
HL.B.B0=gbReadMemory(PC.W++); HL.B.B0=gbReadOpcode(PC.W++);
HL.B.B1=gbReadMemory(PC.W++); HL.B.B1=gbReadOpcode(PC.W++);
break; break;
case 0x22: case 0x22:
// LDI (HL),A // LDI (HL),A
@ -233,7 +235,7 @@
case 0x28: case 0x28:
// JR Z,NN // JR Z,NN
if(AF.B.B0&Z_FLAG) { if(AF.B.B0&Z_FLAG) {
PC.W+=(s8)gbReadMemory(PC.W)+1; PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++; clockTicks++;
} else } else
PC.W++; PC.W++;
@ -278,14 +280,14 @@
if(AF.B.B0&C_FLAG) if(AF.B.B0&C_FLAG)
PC.W++; PC.W++;
else { else {
PC.W+=(s8)gbReadMemory(PC.W)+1; PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++; clockTicks++;
} }
break; break;
case 0x31: case 0x31:
// LD SP,NNNN // LD SP,NNNN
SP.B.B0=gbReadMemory(PC.W++); SP.B.B0=gbReadOpcode(PC.W++);
SP.B.B1=gbReadMemory(PC.W++); SP.B.B1=gbReadOpcode(PC.W++);
break; break;
case 0x32: case 0x32:
// LDD (HL),A // LDD (HL),A
@ -318,7 +320,7 @@
case 0x38: case 0x38:
// JR C,NN // JR C,NN
if(AF.B.B0&C_FLAG) { if(AF.B.B0&C_FLAG) {
PC.W+=(s8)gbReadMemory(PC.W)+1; PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks ++; clockTicks ++;
} else } else
PC.W++; PC.W++;
@ -575,16 +577,24 @@ case 0x38:
break; break;
case 0x76: case 0x76:
// HALT // HALT
if(IFF & 1) { // If an EI is pending, the interrupts are triggered before Halt state !!
// Fix Torpedo Range's intro.
if (IFF & 0x40)
{
IFF &= ~0x70;
IFF |=1;
PC.W--; PC.W--;
IFF |= 0x80;
} else {
if((register_IE & register_IF) > 0)
IFF |= 0x100;
else {
PC.W--;
IFF |= 0x81;
} }
else
{
// if (IE & IF) and interrupts are disabeld,
// Halt is cancelled.
if ((register_IE & register_IF & 0x1f) && !(IFF & 1))
{
IFF|=2;
}
else
IFF |= 0x80;
} }
break; break;
case 0x77: case 0x77:
@ -1036,16 +1046,16 @@ case 0x38:
if(AF.B.B0&Z_FLAG) if(AF.B.B0&Z_FLAG)
PC.W+=2; PC.W+=2;
else { else {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W); tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W; PC.W=tempRegister.W;
clockTicks++; clockTicks++;
} }
break; break;
case 0xc3: case 0xc3:
// JP NNNN // JP NNNN
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W); tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W; PC.W=tempRegister.W;
break; break;
case 0xc4: case 0xc4:
@ -1053,8 +1063,8 @@ case 0x38:
if(AF.B.B0&Z_FLAG) if(AF.B.B0&Z_FLAG)
PC.W+=2; PC.W+=2;
else { else {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++); tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1); gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0); gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W; PC.W=tempRegister.W;
@ -1096,8 +1106,8 @@ case 0x38:
case 0xca: case 0xca:
// JP Z,NNNN // JP Z,NNNN
if(AF.B.B0&Z_FLAG) { if(AF.B.B0&Z_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W); tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W; PC.W=tempRegister.W;
clockTicks++; clockTicks++;
} else } else
@ -1107,8 +1117,8 @@ case 0x38:
case 0xcc: case 0xcc:
// CALL Z,NNNN // CALL Z,NNNN
if(AF.B.B0&Z_FLAG) { if(AF.B.B0&Z_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++); tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1); gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0); gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W; PC.W=tempRegister.W;
@ -1118,8 +1128,8 @@ case 0x38:
break; break;
case 0xcd: case 0xcd:
// CALL NNNN // CALL NNNN
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++); tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1); gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0); gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W; PC.W=tempRegister.W;
@ -1156,20 +1166,24 @@ case 0x38:
if(AF.B.B0&C_FLAG) if(AF.B.B0&C_FLAG)
PC.W+=2; PC.W+=2;
else { else {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W); tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W; PC.W=tempRegister.W;
clockTicks++; clockTicks++;
} }
break; break;
// D3 illegal // D3 illegal
case 0xd3:
PC.W--;
IFF = 0;
break;
case 0xd4: case 0xd4:
// CALL NC,NNNN // CALL NC,NNNN
if(AF.B.B0&C_FLAG) if(AF.B.B0&C_FLAG)
PC.W+=2; PC.W+=2;
else { else {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++); tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1); gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0); gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W; PC.W=tempRegister.W;
@ -1200,7 +1214,7 @@ case 0x38:
if(AF.B.B0&C_FLAG) { if(AF.B.B0&C_FLAG) {
PC.B.B0=gbReadMemory(SP.W++); PC.B.B0=gbReadMemory(SP.W++);
PC.B.B1=gbReadMemory(SP.W++); PC.B.B1=gbReadMemory(SP.W++);
clockTicks += 4; clockTicks += 3;
} }
break; break;
case 0xd9: case 0xd9:
@ -1212,19 +1226,23 @@ case 0x38:
case 0xda: case 0xda:
// JP C,NNNN // JP C,NNNN
if(AF.B.B0&C_FLAG) { if(AF.B.B0&C_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W); tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W; PC.W=tempRegister.W;
clockTicks++; clockTicks++;
} else } else
PC.W+=2; PC.W+=2;
break; break;
// DB illegal // DB illegal
case 0xdb:
PC.W--;
IFF = 0;
break;
case 0xdc: case 0xdc:
// CALL C,NNNN // CALL C,NNNN
if(AF.B.B0&C_FLAG) { if(AF.B.B0&C_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++); tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++); tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1); gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0); gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W; PC.W=tempRegister.W;
@ -1233,6 +1251,10 @@ case 0x38:
PC.W+=2; PC.W+=2;
break; break;
// DD illegal // DD illegal
case 0xdd:
PC.W--;
IFF = 0;
break;
case 0xde: case 0xde:
// SBC NN // SBC NN
tempValue=gbReadOpcode(PC.W++); tempValue=gbReadOpcode(PC.W++);
@ -1262,6 +1284,11 @@ case 0x38:
break; break;
// E3 illegal // E3 illegal
// E4 illegal // E4 illegal
case 0xe3:
case 0xe4:
PC.W--;
IFF = 0;
break;
case 0xe5: case 0xe5:
// PUSH HL // PUSH HL
gbWriteMemory(--SP.W,HL.B.B1); gbWriteMemory(--SP.W,HL.B.B1);
@ -1308,6 +1335,12 @@ case 0x38:
// EB illegal // EB illegal
// EC illegal // EC illegal
// ED illegal // ED illegal
case 0xeb:
case 0xec:
case 0xed:
PC.W--;
IFF = 0;
break;
case 0xee: case 0xee:
// XOR NN // XOR NN
tempValue=gbReadOpcode(PC.W++); tempValue=gbReadOpcode(PC.W++);
@ -1336,9 +1369,13 @@ case 0x38:
case 0xf3: case 0xf3:
// DI // DI
// IFF&=0xFE; // IFF&=0xFE;
IFF&=(~0x21); IFF|=0x08;
break; break;
// F4 illegal // F4 illegal
case 0xf4:
PC.W--;
IFF = 0;
break;
case 0xf5: case 0xf5:
// PUSH AF // PUSH AF
gbWriteMemory(--SP.W,AF.B.B1); gbWriteMemory(--SP.W,AF.B.B1);
@ -1383,10 +1420,23 @@ case 0x38:
break; break;
case 0xfb: case 0xfb:
// EI // EI
IFF|=0x20; if (!(IFF & 0x30))
// If an EI is executed right before HALT,
// the interrupts are triggered before the Halt state !!
// Fix Torpedo Range Intro.
// IFF |= 0x10 : 1 ticks before the EI enables the interrupts
// IFF |= 0x40 : marks that an EI is being executed.
IFF|=0x50;
break;
// FC illegal (FC = breakpoint)
case 0xfc:
breakpoint = true;
break; break;
// FC illegal
// FD illegal // FD illegal
case 0xfd:
PC.W--;
IFF = 0;
break;
case 0xfe: case 0xfe:
// CP NN // CP NN
tempValue=gbReadOpcode(PC.W++); tempValue=gbReadOpcode(PC.W++);
@ -1401,7 +1451,10 @@ case 0x38:
PC.W=0x0038; PC.W=0x0038;
break; break;
default: default:
if (gbSystemMessage == false)
{
systemMessage(0, N_("Unknown opcode %02x at %04x"), systemMessage(0, N_("Unknown opcode %02x at %04x"),
gbReadOpcode(PC.W-1),PC.W-1); gbReadOpcode(PC.W-1),PC.W-1);
emulating = false; gbSystemMessage =true;
}
return; return;

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -1282,7 +1282,10 @@
AF.B.B1|=1<<7; AF.B.B1|=1<<7;
break; break;
default: default:
if (gbSystemMessage == false)
{
systemMessage(0, N_("Unknown opcode %02x at %04x"), systemMessage(0, N_("Unknown opcode %02x at %04x"),
gbReadOpcode(PC.W-1),PC.W-1); gbReadOpcode(PC.W-1),PC.W-1);
emulating = false; gbSystemMessage =true;
}
return; return;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -58,9 +58,12 @@ u8 gbInvertTab[256] = {
}; };
u16 gbLineMix[160]; u16 gbLineMix[160];
u16 gbWindowColor[160];
extern int inUseRegister_WY;
void gbRenderLine() void gbRenderLine()
{ {
memset(gbLineMix, 0, sizeof(gbLineMix));
u8 * bank0; u8 * bank0;
u8 * bank1; u8 * bank1;
if(gbCgbMode) { if(gbCgbMode) {
@ -86,10 +89,9 @@ void gbRenderLine()
if(y >= 144) if(y >= 144)
return; return;
// int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip; int SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
int sx = gbSCXLine[(gbSpeed ? 0 : 4)+SpritesTicks];
int sx = register_SCX; int sy = gbSCYLine[(gbSpeed ? 11 : 5)+SpritesTicks];
int sy = register_SCY;
sy+=y; sy+=y;
@ -113,16 +115,17 @@ void gbRenderLine()
tile_map_address++; tile_map_address++;
if((register_LCDC & 16) == 0) { if(!(register_LCDC & 0x10))
if(tile < 128) tile += 128; tile ^= 0x80;
else tile -= 128;
}
int tile_pattern_address = tile_pattern + tile * 16 + by*2; int tile_pattern_address = tile_pattern + tile * 16 + by*2;
if(register_LCDC & 0x80) { if(register_LCDC & 0x80) {
if((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) { if((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while(x < 160) { while(x < 160) {
u8 tile_a = 0; u8 tile_a = 0;
u8 tile_b = 0; u8 tile_b = 0;
@ -155,7 +158,7 @@ void gbRenderLine()
if(gbCgbMode) { if(gbCgbMode) {
c = c + (attrs & 7)*4; c = c + (attrs & 7)*4;
} else { } else {
c = gbBgp[c]; c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+SpritesTicks]>>(c<<1)) &3;
if(gbSgbMode && !gbCgbMode) { if(gbSgbMode && !gbCgbMode) {
int dx = x >> 3; int dx = x >> 3;
int dy = y >> 3; int dy = y >> 3;
@ -168,42 +171,92 @@ void gbRenderLine()
c = c + 4*palette; c = c + 4*palette;
} }
} }
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c]] : gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c]; gbPalette[c] & 0x7FFF;
x++; x++;
if(x >= 160) if(x >= 160)
break; break;
bx >>= 1; bx >>= 1;
} }
tx++;
if(tx == 32)
tx = 0;
bx = 128; bx = 128;
SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
sx = gbSCXLine[x+(gbSpeed ? 0 : 4)+SpritesTicks];
sy = gbSCYLine[x+(gbSpeed ? 11 : 5)+SpritesTicks];
tx = ((sx+x)>>3) & 0x1f;
sy+=y;
sy &= 255;
ty = sy >> 3;
by = sy & 7;
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
tile_map_line_y = tile_map + ty * 32;
tile_map_address = tile_map_line_y + tx;
if(bank1) if(bank1)
attrs = bank1[tile_map_line_y + tx]; attrs = bank1[tile_map_line_y + tx];
tile = bank0[tile_map_line_y + tx]; tile = bank0[tile_map_line_y + tx];
if((register_LCDC & 16) == 0) { if(!(register_LCDC & 0x10))
if(tile < 128) tile += 128; tile ^= 0x80;
else tile -= 128;
}
tile_pattern_address = tile_pattern + tile * 16 + by * 2; tile_pattern_address = tile_pattern + tile * 16 + by * 2;
} }
} else { } else {
for(int i = 0; i < 160; i++) { // Use gbBgp[0] instead of 0 (?)
gbLineMix[i] = gbPalette[0]; // (this fixes white flashes on Last Bible II)
// Also added the gbColorOption (fixes Dracula Densetsu II color problems)
for(int i = 0; i < 160; i++)
{
u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
0x7FFF;
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[gbBgpLine[i+(gbSpeed ? 5 : 11)+gbSpritesTicks[i]*(gbSpeed ? 2 : 4)]&3] & 0x7FFF] :
gbPalette[gbBgpLine[i+(gbSpeed ? 5 : 11)+gbSpritesTicks[i]*(gbSpeed ? 2 : 4)]&3] & 0x7FFF;
gbLineMix[i] = color;
gbLineBuffer[i] = 0; gbLineBuffer[i] = 0;
} }
} }
// do the window display // do the window display
if((register_LCDC & 0x20) && (layerSettings & 0x2000)) { // LCDC.0 also enables/disables the window in !gbCgbMode ?!?!
int wy = register_WY; // (tested on real hardware)
// This fixes Last Bible II & Zankurou Musouken
if((register_LCDC & 0x01 || gbCgbMode) && (register_LCDC & 0x20) &&
(layerSettings & 0x2000) && (gbWindowLine != -2)) {
int i = 0;
// Fix (accurate emulation) for most of the window display problems
// (ie. Zen - Intergalactic Ninja, Urusei Yatsura...).
if ((gbWindowLine == -1) || (gbWindowLine>144))
{
inUseRegister_WY = oldRegister_WY;
if (register_LY>oldRegister_WY)
gbWindowLine = 146;
// for (i = 0; i<160; i++)
// gbWindowColor[i] = gbLineMix[i];
}
int wy = inUseRegister_WY;
if(y >= inUseRegister_WY) {
if (gbWindowLine == -1)
gbWindowLine = 0;
if(y >= wy) {
int wx = register_WX; int wx = register_WX;
int swx = 0;
wx -= 7; wx -= 7;
if( wx <= 159 && gbWindowLine <= 143) { if( wx <= 159 && gbWindowLine <= 143) {
@ -213,9 +266,6 @@ void gbRenderLine()
if((register_LCDC & 0x40) != 0) if((register_LCDC & 0x40) != 0)
tile_map = 0x1c00; tile_map = 0x1c00;
if(gbWindowLine == -1) {
gbWindowLine = 0;
}
tx = 0; tx = 0;
ty = gbWindowLine >> 3; ty = gbWindowLine >> 3;
@ -223,6 +273,25 @@ void gbRenderLine()
bx = 128; bx = 128;
by = gbWindowLine & 7; by = gbWindowLine & 7;
// Tries to emulate the 'window scrolling bug' when wx == 0 (ie. wx-7 == -7).
// Nothing close to perfect, but good enought for now...
if (wx == -7)
{
swx = 7-((gbSCXLine[0]-1) & 7);
bx >>= ((gbSCXLine[0]+((swx != 1) ? 1 : 0)) & 7);
if (swx == 1)
swx = 2;
//bx >>= ((gbSCXLine[0]+(((swx>1) && (swx != 7)) ? 1 : 0)) & 7);
if ((swx == 7))
{
//wx = 0;
if ((gbWindowLine>0) || (wy == 0))
swx = 0;
}
}
else
if(wx < 0) { if(wx < 0) {
bx >>= (-wx); bx >>= (-wx);
wx = 0; wx = 0;
@ -247,6 +316,10 @@ void gbRenderLine()
tile_pattern_address = tile_pattern + tile * 16 + by*2; tile_pattern_address = tile_pattern + tile * 16 + by*2;
if (wx)
for (i = 0; i<swx; i++)
gbLineMix[i] = gbWindowColor[i];
while(x < 160) { while(x < 160) {
u8 tile_a = 0; u8 tile_a = 0;
u8 tile_b = 0; u8 tile_b = 0;
@ -272,6 +345,8 @@ void gbRenderLine()
u8 c = (tile_a & bx) != 0 ? 1 : 0; u8 c = (tile_a & bx) != 0 ? 1 : 0;
c += ((tile_b & bx) != 0 ? 2 : 0); c += ((tile_b & bx) != 0 ? 2 : 0);
if (x>=0)
{
if(attrs & 0x80) if(attrs & 0x80)
gbLineBuffer[x] = 0x300 + c; gbLineBuffer[x] = 0x300 + c;
else else
@ -280,7 +355,7 @@ void gbRenderLine()
if(gbCgbMode) { if(gbCgbMode) {
c = c + (attrs & 7) * 4; c = c + (attrs & 7) * 4;
} else { } else {
c = gbBgp[c]; c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)]>>(c<<1)) &3;
if(gbSgbMode && !gbCgbMode) { if(gbSgbMode && !gbCgbMode) {
int dx = x >> 3; int dx = x >> 3;
int dy = y >> 3; int dy = y >> 3;
@ -293,8 +368,9 @@ void gbRenderLine()
c = c + 4*palette; c = c + 4*palette;
} }
} }
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c]] : gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c]; gbPalette[c] & 0x7FFF;
}
x++; x++;
if(x >= 160) if(x >= 160)
break; break;
@ -314,13 +390,30 @@ void gbRenderLine()
} }
tile_pattern_address = tile_pattern + tile * 16 + by * 2; tile_pattern_address = tile_pattern + tile * 16 + by * 2;
} }
//for (i = swx; i<160; i++)
// gbLineMix[i] = gbWindowColor[i];
gbWindowLine++; gbWindowLine++;
} }
} }
} }
else if (gbWindowLine == -2)
{
inUseRegister_WY = oldRegister_WY;
if (register_LY>oldRegister_WY)
gbWindowLine = 146;
else
gbWindowLine = 0;
}
} else { } else {
for(int i = 0; i < 160; i++) { u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
gbLineMix[i] = gbPalette[0]; 0x7FFF;
if (!gbCgbMode)
color = gbColorOption ? gbColorFilter[gbPalette[0] & 0x7FFF] :
gbPalette[0] & 0x7FFF;
for(int i = 0; i < 160; i++)
{
gbLineMix[i] = color;
gbLineBuffer[i] = 0; gbLineBuffer[i] = 0;
} }
} }
@ -346,8 +439,11 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int init = 0x0000; int init = 0x0000;
// int yLine = (y+gbBorderRowSkip) * gbBorderLineSkip; for (int i = 0; i<4; i++)
{
gbObp0[i] = (gbObp0Line[x+11+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)]>>(i<<1)) & 3;
gbObp1[i] = (gbObp1Line[x+11+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)]>>(i<<1)) & 3;
}
u8 *pal = gbObp0; u8 *pal = gbObp0;
int flipx = (flags & 0x20); int flipx = (flags & 0x20);
@ -366,7 +462,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int a = 0; int a = 0;
int b = 0; int b = 0;
if(gbCgbMode && flags & 0x08) { if(gbCgbMode && (flags & 0x08)) {
a = bank1[address++]; a = bank1[address++];
b = bank1[address++]; b = bank1[address++];
} else { } else {
@ -393,11 +489,13 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
u16 color = gbLineBuffer[xxx]; u16 color = gbLineBuffer[xxx];
if(prio) { // Fixes OAM-BG priority
if(prio && (register_LCDC & 1)) {
if(color < 0x200 && ((color & 0xFF) != 0)) if(color < 0x200 && ((color & 0xFF) != 0))
continue; continue;
} }
if(color >= 0x300 && color != 0x300) // Fixes OAM-BG priority for Moorhuhn 2
if(color >= 0x300 && color != 0x300 && (register_LCDC & 1))
continue; continue;
else if(color >= 0x200 && color < 0x300) { else if(color >= 0x200 && color < 0x300) {
int sprite = color & 0xff; int sprite = color & 0xff;
@ -412,7 +510,9 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if(sprite < spriteNumber) if(sprite < spriteNumber)
continue; continue;
} else { } else {
if(spriteX < x+8) // Fixes GB sprites priorities (was '< x + 8' before)
// ('A boy and his blob...' sprites' emulation is now correct)
if(spriteX < x)
continue; continue;
} }
} }
@ -442,12 +542,12 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
} }
} }
gbLineMix[xxx] = gbColorOption ? gbColorFilter[gbPalette[c]] : gbLineMix[xxx] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c]; gbPalette[c] & 0x7FFF;
} }
} }
void gbDrawSprites() void gbDrawSprites(bool draw)
{ {
int x = 0; int x = 0;
int y = 0; int y = 0;
@ -455,6 +555,9 @@ void gbDrawSprites()
int size = (register_LCDC & 4); int size = (register_LCDC & 4);
if (!draw)
memset (gbSpritesTicks, 0, sizeof(gbSpritesTicks));
if(!(register_LCDC & 0x80)) if(!(register_LCDC & 0x80))
return; return;
@ -473,11 +576,19 @@ void gbDrawSprites()
if(x > 0 && y > 0 && x < 168 && y < 160) { if(x > 0 && y > 0 && x < 168 && y < 160) {
// check if sprite intersects current line // check if sprite intersects current line
int t = yc -y + 16; int t = yc -y + 16;
if(size && t >=0 && t < 16) { if((size && t >=0 && t < 16) || (!size && t >= 0 && t < 8)) {
gbDrawSpriteTile(tile,x-8,yc,t,flags,size,i); if (draw)
count++;
} else if(!size && t >= 0 && t < 8) {
gbDrawSpriteTile(tile,x-8,yc,t,flags,size,i); gbDrawSpriteTile(tile,x-8,yc,t,flags,size,i);
else
{
for (int j = x-8; j<300; j++)
if (j>=0)
if (gbSpeed)
gbSpritesTicks[j] += 5;
else
gbSpritesTicks[j] += 2+(count&1);
}
count++; count++;
} }
} }
@ -486,5 +597,5 @@ void gbDrawSprites()
break; break;
} }
} }
return;
} }

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@ int gbRomSizeMask = 0;
int gbRomSize = 0; int gbRomSize = 0;
int gbRamSizeMask = 0; int gbRamSizeMask = 0;
int gbRamSize = 0; int gbRamSize = 0;
int gbTAMA5ramSize = 0;
u8 *gbMemory = NULL; u8 *gbMemory = NULL;
u8 *gbVram = NULL; u8 *gbVram = NULL;
@ -31,6 +32,7 @@ u8 *gbRom = NULL;
u8 *gbRam = NULL; u8 *gbRam = NULL;
u8 *gbWram = NULL; u8 *gbWram = NULL;
u16 *gbLineBuffer = NULL; u16 *gbLineBuffer = NULL;
u8 *gbTAMA5ram = NULL;
u16 gbPalette[128]; u16 gbPalette[128];
u8 gbBgp[4] = { 0, 1, 2, 3}; u8 gbBgp[4] = { 0, 1, 2, 3};
@ -38,6 +40,7 @@ u8 gbObp0[4] = { 0, 1, 2, 3};
u8 gbObp1[4] = { 0, 1, 2, 3}; u8 gbObp1[4] = { 0, 1, 2, 3};
int gbWindowLine = -1; int gbWindowLine = -1;
bool genericflashcardEnable = false;
int gbCgbMode = 0; int gbCgbMode = 0;
u16 gbColorFilter[32768]; u16 gbColorFilter[32768];

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -21,6 +21,11 @@ extern int gbRomSizeMask;
extern int gbRomSize; extern int gbRomSize;
extern int gbRamSize; extern int gbRamSize;
extern int gbRamSizeMask; extern int gbRamSizeMask;
extern int gbTAMA5ramSize;
extern bool useBios;
extern bool skipBios;
extern u8 *bios;
extern u8 *gbRom; extern u8 *gbRom;
extern u8 *gbRam; extern u8 *gbRam;
@ -28,6 +33,7 @@ extern u8 *gbVram;
extern u8 *gbWram; extern u8 *gbWram;
extern u8 *gbMemory; extern u8 *gbMemory;
extern u16 *gbLineBuffer; extern u16 *gbLineBuffer;
extern u8 *gbTAMA5ram;
extern u8 *gbMemoryMap[16]; extern u8 *gbMemoryMap[16];
@ -46,6 +52,19 @@ extern u8 gbBgp[4];
extern u8 gbObp0[4]; extern u8 gbObp0[4];
extern u8 gbObp1[4]; extern u8 gbObp1[4];
extern u16 gbPalette[128]; extern u16 gbPalette[128];
extern bool gbScreenOn;
extern bool gbDrawWindow;
extern u8 gbSCYLine[300];
// gbSCXLine is used for the emulation (bug) of the SX change
// found in the Artic Zone game.
extern u8 gbSCXLine[300];
// gbBgpLine is used for the emulation of the
// Prehistorik Man's title screen scroller.
extern u8 gbBgpLine[300];
extern u8 gbObp0Line [300];
extern u8 gbObp1Line [300];
// gbSpritesTicks is used for the emulation of Parodius' Laser Beam.
extern u8 gbSpritesTicks[300];
extern u8 register_LCDC; extern u8 register_LCDC;
extern u8 register_LY; extern u8 register_LY;
@ -54,8 +73,10 @@ extern u8 register_SCX;
extern u8 register_WY; extern u8 register_WY;
extern u8 register_WX; extern u8 register_WX;
extern u8 register_VBK; extern u8 register_VBK;
extern u8 oldRegister_WY;
extern int emulating; extern int emulating;
extern bool genericflashcardEnable;
extern int gbBorderLineSkip; extern int gbBorderLineSkip;
extern int gbBorderRowSkip; extern int gbBorderRowSkip;
@ -63,6 +84,6 @@ extern int gbBorderColumnSkip;
extern int gbDmaTicks; extern int gbDmaTicks;
extern void gbRenderLine(); extern void gbRenderLine();
extern void gbDrawSprites(); extern void gbDrawSprites(bool);
extern u8 (*gbSerialFunction)(u8); extern u8 (*gbSerialFunction)(u8);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -20,6 +20,12 @@
#include "../Port.h" #include "../Port.h"
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbMemory.h" #include "gbMemory.h"
#include "GB.h"
u8 gbDaysinMonth [12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const u8 gbDisabledRam [8] = {0x80, 0xff, 0xf0, 0x00, 0x30, 0xbf, 0xbf, 0xbf};
extern int gbHardware;
extern int gbGBCColorType;
extern gbRegister PC;
mapperMBC1 gbDataMBC1 = { mapperMBC1 gbDataMBC1 = {
0, // RAM enable 0, // RAM enable
@ -27,7 +33,8 @@ mapperMBC1 gbDataMBC1 = {
0, // RAM bank 0, // RAM bank
0, // memory model 0, // memory model
0, // ROM high address 0, // ROM high address
0 // RAM address 0, // RAM address
0 // Rom Bank 0 remapping
}; };
// MBC1 ROM write registers // MBC1 ROM write registers
@ -41,17 +48,25 @@ void mapperMBC1ROM(u16 address, u8 value)
break; break;
case 0x2000: // ROM bank select case 0x2000: // ROM bank select
// value = value & 0x1f; // value = value & 0x1f;
if(value == 0) if ((value == 1) && (address == 0x2100))
value = 1; gbDataMBC1.mapperRomBank0Remapping = 1;
if((value & 0x1f) == 0)
value += 1;
if(value == gbDataMBC1.mapperROMBank) if(value == gbDataMBC1.mapperROMBank)
break; break;
tmpAddress = value << 14; tmpAddress = value << 14;
// check current model // check current model
if (gbDataMBC1.mapperRomBank0Remapping == 3) {
tmpAddress = (value & 0xf) << 14;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 18;
}
else
if(gbDataMBC1.mapperMemoryModel == 0) { if(gbDataMBC1.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use // model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMBC1.mapperROMHighAddress) << 19; tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
} }
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
@ -63,16 +78,39 @@ void mapperMBC1ROM(u16 address, u8 value)
break; break;
case 0x4000: // RAM bank select case 0x4000: // RAM bank select
if(gbDataMBC1.mapperMemoryModel == 1) { if(gbDataMBC1.mapperMemoryModel == 1) {
if (!gbRamSize)
{
if (gbDataMBC1.mapperRomBank0Remapping == 3)
{
gbDataMBC1.mapperROMHighAddress = value & 0x03;
tmpAddress = (gbDataMBC1.mapperROMHighAddress) << 18;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x00] = &gbRom[tmpAddress];
gbMemoryMap[0x01] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x02] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x03] = &gbRom[tmpAddress + 0x3000];
gbMemoryMap[0x04] = &gbRom[tmpAddress + 0x4000];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x5000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x6000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x7000];
}
else gbDataMBC1.mapperRomBank0Remapping = 0;
}
// 4/32 model, RAM bank switching provided // 4/32 model, RAM bank switching provided
value = value & 0x03; value = value & 0x03;
if(value == gbDataMBC1.mapperRAMBank) if(value == gbDataMBC1.mapperRAMBank)
break; break;
tmpAddress = value << 13; tmpAddress = value << 13;
tmpAddress &= gbRamSizeMask; tmpAddress &= gbRamSizeMask;
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[tmpAddress]; gbMemoryMap[0x0a] = &gbRam[tmpAddress];
gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000]; gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000];
}
gbDataMBC1.mapperRAMBank = value; gbDataMBC1.mapperRAMBank = value;
gbDataMBC1.mapperRAMAddress = tmpAddress; gbDataMBC1.mapperRAMAddress = tmpAddress;
if (gbDataMBC1.mapperRomBank0Remapping != 3)
gbDataMBC1.mapperROMHighAddress = 0;
} else { } else {
// 16/8, set the high address // 16/8, set the high address
gbDataMBC1.mapperROMHighAddress = value & 0x03; gbDataMBC1.mapperROMHighAddress = value & 0x03;
@ -83,10 +121,57 @@ void mapperMBC1ROM(u16 address, u8 value)
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000]; gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000]; gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[0];
gbMemoryMap[0x0b] = &gbRam[0x1000];
}
gbDataMBC1.mapperRAMBank = 0;
} }
break; break;
case 0x6000: // memory model select case 0x6000: // memory model select
gbDataMBC1.mapperMemoryModel = value & 1; gbDataMBC1.mapperMemoryModel = value & 1;
if(gbDataMBC1.mapperMemoryModel == 1) {
// 4/32 model, RAM bank switching provided
value = gbDataMBC1.mapperRAMBank & 0x03;
tmpAddress = value << 13;
tmpAddress &= gbRamSizeMask;
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress];
gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000];
gbDataMBC1.mapperRomBank0Remapping = 0;
}
else gbDataMBC1.mapperRomBank0Remapping |=2;
gbDataMBC1.mapperRAMBank = value;
gbDataMBC1.mapperRAMAddress = tmpAddress;
tmpAddress = gbDataMBC1.mapperROMBank << 14;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
} else {
// 16/8, set the high address
tmpAddress = gbDataMBC1.mapperROMBank << 14;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress) << 19;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[0];
gbMemoryMap[0x0b] = &gbRam[0x1000];
}
}
break; break;
} }
} }
@ -102,14 +187,62 @@ void mapperMBC1RAM(u16 address, u8 value)
} }
} }
// MBC1 read RAM
u8 mapperMBC1ReadRAM(u16 address)
{
if(gbDataMBC1.mapperRAMEnable)
return gbMemoryMap[address>>12][address & 0x0fff];
if (!genericflashcardEnable)
return 0xff;
else
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W>=0xff80)
return 0xff;
else
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1)
return 0xfb;
else
return 0x7a;
}
else
return 0x0a;
}
else
return gbDisabledRam[address & 7];
}
void memoryUpdateMapMBC1() void memoryUpdateMapMBC1()
{ {
int tmpAddress = gbDataMBC1.mapperROMBank << 14; int tmpAddress = gbDataMBC1.mapperROMBank << 14;
// check current model // check current model
if(gbDataMBC1.mapperMemoryModel == 1) { if (gbDataMBC1.mapperRomBank0Remapping == 3) {
tmpAddress = (gbDataMBC1.mapperROMHighAddress & 3) << 18;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x00] = &gbRom[tmpAddress];
gbMemoryMap[0x01] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x02] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x03] = &gbRom[tmpAddress + 0x3000];
tmpAddress |= (gbDataMBC1.mapperROMBank & 0xf) << 14;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
}
else
{
if(gbDataMBC1.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use // model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMBC1.mapperROMHighAddress) << 19; tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
} }
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
@ -117,8 +250,9 @@ void memoryUpdateMapMBC1()
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000]; gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000]; gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000]; gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
}
if(gbRamSize) { if((gbRamSize) && (gbDataMBC1.mapperMemoryModel == 1)){
gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress]; gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress];
gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000]; gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000];
} }
@ -210,7 +344,7 @@ void memoryUpdateMBC3Clock()
time_t diff = now - gbDataMBC3.mapperLastTime; time_t diff = now - gbDataMBC3.mapperLastTime;
if(diff > 0) { if(diff > 0) {
// update the clock according to the last update time // update the clock according to the last update time
gbDataMBC3.mapperSeconds += diff % 60; gbDataMBC3.mapperSeconds += (int)(diff % 60);
if(gbDataMBC3.mapperSeconds > 59) { if(gbDataMBC3.mapperSeconds > 59) {
gbDataMBC3.mapperSeconds -= 60; gbDataMBC3.mapperSeconds -= 60;
gbDataMBC3.mapperMinutes++; gbDataMBC3.mapperMinutes++;
@ -218,22 +352,22 @@ void memoryUpdateMBC3Clock()
diff /= 60; diff /= 60;
gbDataMBC3.mapperMinutes += diff % 60; gbDataMBC3.mapperMinutes += (int)(diff % 60);
if(gbDataMBC3.mapperMinutes > 60) { if(gbDataMBC3.mapperMinutes > 59) {
gbDataMBC3.mapperMinutes -= 60; gbDataMBC3.mapperMinutes -= 60;
gbDataMBC3.mapperHours++; gbDataMBC3.mapperHours++;
} }
diff /= 60; diff /= 60;
gbDataMBC3.mapperHours += diff % 24; gbDataMBC3.mapperHours += (int)(diff % 24);
if(gbDataMBC3.mapperHours > 24) { if(gbDataMBC3.mapperHours > 23) {
gbDataMBC3.mapperHours -= 24; gbDataMBC3.mapperHours -= 24;
gbDataMBC3.mapperDays++; gbDataMBC3.mapperDays++;
} }
diff /= 24; diff /= 24;
gbDataMBC3.mapperDays += diff; gbDataMBC3.mapperDays += (int)(diff & 0xffffffff);
if(gbDataMBC3.mapperDays > 255) { if(gbDataMBC3.mapperDays > 255) {
if(gbDataMBC3.mapperDays > 511) { if(gbDataMBC3.mapperDays > 511) {
gbDataMBC3.mapperDays %= 512; gbDataMBC3.mapperDays %= 512;
@ -365,7 +499,30 @@ u8 mapperMBC3ReadRAM(u16 address)
return gbDataMBC3.mapperLControl; return gbDataMBC3.mapperLControl;
} }
} }
return 0;
if (!genericflashcardEnable)
return 0xff;
else
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W>=0xff80)
return 0xff;
else
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1)
return 0xfb;
else
return 0x7a;
}
else
return 0x0a;
}
else
return gbDisabledRam[address & 7];
} }
void memoryUpdateMapMBC3() void memoryUpdateMapMBC3()
@ -406,6 +563,7 @@ void mapperMBC5ROM(u16 address, u8 value)
gbDataMBC5.mapperRAMEnable = ( ( value & 0x0a) == 0x0a ? 1 : 0); gbDataMBC5.mapperRAMEnable = ( ( value & 0x0a) == 0x0a ? 1 : 0);
break; break;
case 0x2000: // ROM bank select case 0x2000: // ROM bank select
if(address < 0x3000) { if(address < 0x3000) {
value = value & 0xff; value = value & 0xff;
if(value == gbDataMBC5.mapperROMBank) if(value == gbDataMBC5.mapperROMBank)
@ -466,6 +624,38 @@ void mapperMBC5RAM(u16 address, u8 value)
} }
} }
// MBC5 read RAM
u8 mapperMBC5ReadRAM(u16 address)
{
if(gbDataMBC5.mapperRAMEnable)
return gbMemoryMap[address>>12][address & 0x0fff];
if (!genericflashcardEnable)
return 0xff;
else
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W>=0xff80)
return 0xff;
else
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1)
return 0xfb;
else
return 0x7a;
}
else
return 0x0a;
}
else
return gbDisabledRam[address & 7];
}
void memoryUpdateMapMBC5() void memoryUpdateMapMBC5()
{ {
int tmpAddress = (gbDataMBC5.mapperROMBank << 14) | int tmpAddress = (gbDataMBC5.mapperROMBank << 14) |
@ -568,7 +758,30 @@ u8 mapperMBC7ReadRAM(u16 address)
case 0xa080: case 0xa080:
return gbDataMBC7.value; return gbDataMBC7.value;
} }
if (!genericflashcardEnable)
return 0xff; return 0xff;
else
if ((address & 0x1000) >= 0x1000)
{
// The value returned when reading RAM while it's disabled
// is constant, exept for the GBASP hardware.
// (actually, is the address that read is out of the ROM, the returned value if 0xff...)
if (PC.W>=0xff80)
return 0xff;
else
if ((gbHardware & 0x08) && (gbGBCColorType == 2))
{
if (address & 1)
return 0xfb;
else
return 0x7a;
}
else
return 0x0a;
}
else
return gbDisabledRam[address & 7];
} }
// MBC7 RAM write // MBC7 RAM write
@ -717,7 +930,7 @@ void mapperMBC7RAM(u16 address, u8 value)
void memoryUpdateMapMBC7() void memoryUpdateMapMBC7()
{ {
int tmpAddress = (gbDataMBC5.mapperROMBank << 14); int tmpAddress = (gbDataMBC7.mapperROMBank << 14);
tmpAddress &= gbRomSizeMask; tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress]; gbMemoryMap[0x04] = &gbRom[tmpAddress];
@ -965,3 +1178,540 @@ void memoryUpdateMapHuC3()
gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000]; gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000];
} }
} }
// TAMA5 (for Tamagotchi 3 (gb)).
// Very basic (and ugly :p) support, only rom bank switching is actually working...
mapperTAMA5 gbDataTAMA5 = {
1, // RAM enable
1, // ROM bank
0, // RAM bank
0, // RAM address
0, // RAM Byte select
0, // mapper command number
0, // mapper last command;
0, // commands 0x0
0, // commands 0x1
0, // commands 0x2
0, // commands 0x3
0, // commands 0x4
0, // commands 0x5
0, // commands 0x6
0, // commands 0x7
0, // commands 0x8
0, // commands 0x9
0, // commands 0xa
0, // commands 0xb
0, // commands 0xc
0, // commands 0xd
0, // commands 0xe
0, // commands 0xf
0, // register
0, // timer clock latch
0, // timer clock register
0, // timer seconds
0, // timer minutes
0, // timer hours
0, // timer days
0, // timer months
0, // timer years
0, // timer control
0, // timer latched seconds
0, // timer latched minutes
0, // timer latched hours
0, // timer latched days
0, // timer latched months
0, // timer latched years
0, // timer latched control
(time_t)-1 // last time
};
void memoryUpdateTAMA5Clock()
{
if ((gbDataTAMA5.mapperYears & 3) == 0)
gbDaysinMonth[1] = 29;
else
gbDaysinMonth[1] = 28;
time_t now = time(NULL);
time_t diff = now - gbDataTAMA5.mapperLastTime;
if(diff > 0) {
// update the clock according to the last update time
gbDataTAMA5.mapperSeconds += (int)(diff % 60);
if(gbDataTAMA5.mapperSeconds > 59) {
gbDataTAMA5.mapperSeconds -= 60;
gbDataTAMA5.mapperMinutes++;
}
diff /= 60;
gbDataTAMA5.mapperMinutes += (int)(diff % 60);
if(gbDataTAMA5.mapperMinutes > 59) {
gbDataTAMA5.mapperMinutes -= 60;
gbDataTAMA5.mapperHours++;
}
diff /= 60;
gbDataTAMA5.mapperHours += (int)(diff % 24);
diff /= 24;
if(gbDataTAMA5.mapperHours > 23) {
gbDataTAMA5.mapperHours -= 24;
diff++;
}
time_t days = diff;
while (days)
{
gbDataTAMA5.mapperDays++;
days--;
if (gbDataTAMA5.mapperDays>gbDaysinMonth[gbDataTAMA5.mapperMonths-1])
{
gbDataTAMA5.mapperDays = 1;
gbDataTAMA5.mapperMonths++;
if (gbDataTAMA5.mapperMonths>12)
{
gbDataTAMA5.mapperMonths = 1;
gbDataTAMA5.mapperYears++;
if ((gbDataTAMA5.mapperYears & 3) == 0)
gbDaysinMonth[1] = 29;
else
gbDaysinMonth[1] = 28;
}
}
}
}
gbDataTAMA5.mapperLastTime = now;
}
// TAMA5 RAM write
void mapperTAMA5RAM(u16 address, u8 value)
{
if ((address & 0xffff) <= 0xa001)
{
switch (address & 1)
{
case 0: // 'Values' Register
{
value &= 0xf;
gbDataTAMA5.mapperCommands[gbDataTAMA5.mapperCommandNumber] = value;
gbMemoryMap[0xa][0] = value;
int test = gbDataTAMA5.mapperCommands[gbDataTAMA5.mapperCommandNumber & 0x0e] |
(gbDataTAMA5.mapperCommands[(gbDataTAMA5.mapperCommandNumber & 0x0e) +1]<<4);
if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 0) // Read Command !!!
{
gbDataTAMA5.mapperROMBank = gbDataTAMA5.mapperCommands[0] |
(gbDataTAMA5.mapperCommands[1]<<4);
int tmpAddress = (gbDataTAMA5.mapperROMBank << 14);
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
gbDataTAMA5.mapperCommands[0x0f] = 0;
}
else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 4)
{
gbDataTAMA5.mapperCommands[0x0f] = 1;
if (gbDataTAMA5.mapperCommandNumber == 4)
gbDataTAMA5.mapperCommands[5] =0; // correct ?
}
else if ((gbDataTAMA5.mapperCommandNumber & 0xe) == 6)
{
gbDataTAMA5.mapperRamByteSelect = (gbDataTAMA5.mapperCommands[7]<<4) |
(gbDataTAMA5.mapperCommands[6]&0x0f);
// Write Commands !!!
if (gbDataTAMA5.mapperCommands[0x0f] && (gbDataTAMA5.mapperCommandNumber == 7))
{
int data = gbDataTAMA5.mapperCommands[0x04] & 0x0f |
(gbDataTAMA5.mapperCommands[0x05] <<4);
// Not sure when the write command should reset...
// but it doesn't seem to matter.
// gbDataTAMA5.mapperCommands[0x0f] = 0;
if (gbDataTAMA5.mapperRamByteSelect == 0x8) // Timer stuff
{
switch (data & 0xf)
{
case 0x7:
gbDataTAMA5.mapperDays = ((gbDataTAMA5.mapperDays)/10)*10 + (data >> 4);
break;
case 0x8:
gbDataTAMA5.mapperDays = (gbDataTAMA5.mapperDays%10) + (data >>4)*10;
break;
case 0x9:
gbDataTAMA5.mapperMonths = ((gbDataTAMA5.mapperMonths)/10)*10 + (data >> 4);
break;
case 0xa:
gbDataTAMA5.mapperMonths = (gbDataTAMA5.mapperMonths%10) + (data >>4)*10;
break;
case 0xb:
gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears)%1000) + (data >> 4)*1000;
break;
case 0xc:
gbDataTAMA5.mapperYears = (gbDataTAMA5.mapperYears%100) + (gbDataTAMA5.mapperYears/1000)*1000 +
(data >>4)*100;
break;
default :
break;
}
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x18) // Timer stuff again
{
memoryUpdateTAMA5Clock();
gbDataTAMA5.mapperLSeconds = gbDataTAMA5.mapperSeconds;
gbDataTAMA5.mapperLMinutes = gbDataTAMA5.mapperMinutes;
gbDataTAMA5.mapperLHours = gbDataTAMA5.mapperHours;
gbDataTAMA5.mapperLDays = gbDataTAMA5.mapperDays;
gbDataTAMA5.mapperLMonths = gbDataTAMA5.mapperMonths;
gbDataTAMA5.mapperLYears = gbDataTAMA5.mapperYears;
gbDataTAMA5.mapperLControl = gbDataTAMA5.mapperControl;
int seconds = (gbDataTAMA5.mapperLSeconds / 10)*16 + gbDataTAMA5.mapperLSeconds %10;
int secondsL = (gbDataTAMA5.mapperLSeconds % 10);
int secondsH = (gbDataTAMA5.mapperLSeconds / 10);
int minutes = (gbDataTAMA5.mapperLMinutes / 10)*16 + gbDataTAMA5.mapperLMinutes %10;
int hours = (gbDataTAMA5.mapperLHours / 10)*16 + gbDataTAMA5.mapperLHours %10;
int DaysL = gbDataTAMA5.mapperLDays % 10;
int DaysH = gbDataTAMA5.mapperLDays /10;
int MonthsL = gbDataTAMA5.mapperLMonths % 10;
int MonthsH = gbDataTAMA5.mapperLMonths / 10;
int Years3 = (gbDataTAMA5.mapperLYears / 100) % 10;
int Years4 = (gbDataTAMA5.mapperLYears / 1000);
switch (data & 0x0f)
{
// I guess cases 0 and 1 are used for secondsL and secondsH
// so the game would update the timer values on screen when
// the seconds reset to 0... ?
case 0x0:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = secondsL;
break;
case 0x1:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = secondsH;
break;
case 0x7:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = DaysL; // days low
break;
case 0x8:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = DaysH; // days high
break;
case 0x9:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = MonthsL; // month low
break;
case 0xa:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = MonthsH; // month high
break;
case 0xb:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = Years4; // years 4th digit
break;
case 0xc:
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = Years3; // years 3rd digit
break;
default :
break;
}
gbTAMA5ram[0x54] = seconds; // incorrect ? (not used by the game) ?
gbTAMA5ram[0x64] = minutes;
gbTAMA5ram[0x74] = hours;
gbTAMA5ram[0x84] = DaysH*16+DaysL; // incorrect ? (not used by the game) ?
gbTAMA5ram[0x94] = MonthsH*16+MonthsL; // incorrect ? (not used by the game) ?
time(&gbDataTAMA5.mapperLastTime);
gbMemoryMap[0xa][0] = 1;
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x28) // Timer stuff again
{
if ((data & 0xf) == 0xb)
gbDataTAMA5.mapperYears = ((gbDataTAMA5.mapperYears>>2)<<2) + (data & 3);
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x44)
{
gbDataTAMA5.mapperMinutes = (data/16)*10 + data%16;
}
else if (gbDataTAMA5.mapperRamByteSelect == 0x54)
{
gbDataTAMA5.mapperHours = (data/16)*10 + data%16;
}
else
{
gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect] = data;
}
}
}
}
break;
case 1: // 'Commands' Register
{
gbMemoryMap[0xa][1] = gbDataTAMA5.mapperCommandNumber = value;
// This should be only a 'is the flashrom ready ?' command.
// However as I couldn't find any 'copy' command
// (that seems to be needed for the saving system to work)
// I put it there...
if (value == 0x0a)
{
for (int i = 0; i<0x10; i++)
for (int j = 0; j<0x10; j++)
if (!(j&2))
gbTAMA5ram[(i*0x10)+j | 2] = gbTAMA5ram[(i*0x10)+j];
// Enable this to see the content of the flashrom in 0xe000
/*for (int k = 0; k<0x100; k++)
gbMemoryMap[0xe][k] = gbTAMA5ram[k];*/
gbMemoryMap[0xa][0] = gbDataTAMA5.mapperRAMEnable = 1;
}
else
{
if ((value & 0x0e) == 0x0c)
{
gbDataTAMA5.mapperRamByteSelect = gbDataTAMA5.mapperCommands[6] |
(gbDataTAMA5.mapperCommands[7]<<4);
u8 byte = gbTAMA5ram[gbDataTAMA5.mapperRamByteSelect];
gbMemoryMap[0xa][0] = (value & 1) ? byte >> 4 : byte & 0x0f;
gbDataTAMA5.mapperCommands[0x0f] = 0;
}
}
break;
}
}
}
else
{
if(gbDataTAMA5.mapperRAMEnable) {
if(gbDataTAMA5.mapperRAMBank != -1) {
if(gbRamSize) {
gbMemoryMap[address>>12][address & 0x0fff] = value;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
}
}
}
}
}
// TAMA5 read RAM
u8 mapperTAMA5ReadRAM(u16 address)
{
return gbMemoryMap[address>>12][address & 0xfff];
}
void memoryUpdateMapTAMA5()
{
int tmpAddress = (gbDataTAMA5.mapperROMBank << 14);
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
if(gbRamSize) {
tmpAddress = 0 << 13;
tmpAddress &= gbRamSizeMask;
gbMemoryMap[0x0a] = &gbRam[tmpAddress];
gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000];
}
}
// MMM01 Used in Momotarou collection (however the rom is corrupted)
mapperMMM01 gbDataMMM01 ={
0, // RAM enable
1, // ROM bank
0, // RAM bank
0, // memory model
0, // ROM high address
0, // RAM address
0 // Rom Bank 0 remapping
};
// MMM01 ROM write registers
void mapperMMM01ROM(u16 address, u8 value)
{
int tmpAddress = 0;
switch(address & 0x6000) {
case 0x0000: // RAM enable register
gbDataMMM01.mapperRAMEnable = ( ( value & 0x0a) == 0x0a ? 1 : 0);
break;
case 0x2000: // ROM bank select
// value = value & 0x1f;
if(value == 0)
value = 1;
if(value == gbDataMMM01.mapperROMBank)
break;
tmpAddress = value << 14;
// check current model
if(gbDataMMM01.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMMM01.mapperROMHighAddress) << 19;
}
else
tmpAddress |= gbDataMMM01.mapperRomBank0Remapping << 18;
tmpAddress &= gbRomSizeMask;
gbDataMMM01.mapperROMBank = value;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
break;
case 0x4000: // RAM bank select
if(gbDataMMM01.mapperMemoryModel == 1) {
// 4/32 model, RAM bank switching provided
value = value & 0x03;
if(value == gbDataMBC1.mapperRAMBank)
break;
tmpAddress = value << 13;
tmpAddress &= gbRamSizeMask;
gbMemoryMap[0x0a] = &gbRam[tmpAddress];
gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000];
gbDataMMM01.mapperRAMBank = value;
gbDataMMM01.mapperRAMAddress = tmpAddress;
} else {
// 16/8, set the high address
gbDataMMM01.mapperROMHighAddress = value & 0x03;
tmpAddress = gbDataMMM01.mapperROMBank << 14;
tmpAddress |= (gbDataMMM01.mapperROMHighAddress) << 19;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
gbDataMMM01.mapperRomBank0Remapping = ((value<<1) | (value & 0x40 ? 1 : 0)) & 0xff;
tmpAddress = gbDataMMM01.mapperRomBank0Remapping << 18;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x00] = &gbRom[tmpAddress];
gbMemoryMap[0x01] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x02] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x03] = &gbRom[tmpAddress + 0x3000];
}
break;
case 0x6000: // memory model select
gbDataMMM01.mapperMemoryModel = value & 1;
break;
}
}
// MMM01 RAM write
void mapperMMM01RAM(u16 address, u8 value)
{
if(gbDataMMM01.mapperRAMEnable) {
if(gbRamSize) {
gbMemoryMap[address >> 12][address & 0x0fff] = value;
systemSaveUpdateCounter = SYSTEM_SAVE_UPDATED;
}
}
}
void memoryUpdateMapMMM01()
{
int tmpAddress = gbDataMMM01.mapperROMBank << 14;
// check current model
if(gbDataMMM01.mapperMemoryModel == 1) {
// model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMMM01.mapperROMHighAddress) << 19;
}
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
tmpAddress = gbDataMMM01.mapperRomBank0Remapping << 18;
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x00] = &gbRom[tmpAddress];
gbMemoryMap[0x01] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x02] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x03] = &gbRom[tmpAddress + 0x3000];
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[gbDataMMM01.mapperRAMAddress];
gbMemoryMap[0x0b] = &gbRam[gbDataMMM01.mapperRAMAddress + 0x1000];
}
}
// GameGenie ROM write registers
void mapperGGROM(u16 address, u8 value)
{
int tmpAddress = 0;
switch(address & 0x6000) {
case 0x0000: // RAM enable register
break;
case 0x2000: // GameGenie has only a half bank
break;
case 0x4000: // GameGenie has no RAM
if ((address >=0x4001) && (address <= 0x4020)) // GG Hardware Registers
gbMemoryMap[address >> 12][address & 0x0fff] = value;
break;
case 0x6000: // GameGenie has only a half bank
break;
}
}
// GS3 Used to emulate the GS V3.0 rom bank switching
mapperGS3 gbDataGS3 = { 1 }; // ROM bank
void mapperGS3ROM(u16 address, u8 value)
{
int tmpAddress = 0;
switch(address & 0x6000) {
case 0x0000: // GS has no ram
break;
case 0x2000: // GS has no 'classic' ROM bank select
break;
case 0x4000: // GS has no ram
break;
case 0x6000: // 0x6000 area is RW, and used for GS hardware registers
if (address == 0x7FE1) // This is the (half) ROM bank select register
{
if(value == gbDataGS3.mapperROMBank)
break;
tmpAddress = value << 13;
tmpAddress &= gbRomSizeMask;
gbDataGS3.mapperROMBank = value;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
}
else
gbMemoryMap[address>>12][address & 0x0fff] = value;
break;
}
}
void memoryUpdateMapGS3()
{
int tmpAddress = gbDataGS3.mapperROMBank << 13;
tmpAddress &= gbRomSizeMask;
// GS can only change a half ROM bank
gbMemoryMap[0x04] = &gbRom[tmpAddress];
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@ struct mapperMBC1 {
int mapperMemoryModel; int mapperMemoryModel;
int mapperROMHighAddress; int mapperROMHighAddress;
int mapperRAMAddress; int mapperRAMAddress;
int mapperRomBank0Remapping;
}; };
struct mapperMBC2 { struct mapperMBC2 {
@ -106,15 +107,62 @@ struct mapperHuC3 {
int mapperRegister8; int mapperRegister8;
}; };
struct mapperTAMA5 {
int mapperRAMEnable;
int mapperROMBank;
int mapperRAMBank;
int mapperRAMAddress;
int mapperRamByteSelect;
int mapperCommandNumber;
int mapperLastCommandNumber;
int mapperCommands[0x10];
int mapperRegister;
int mapperClockLatch;
int mapperClockRegister;
int mapperSeconds;
int mapperMinutes;
int mapperHours;
int mapperDays;
int mapperMonths;
int mapperYears;
int mapperControl;
int mapperLSeconds;
int mapperLMinutes;
int mapperLHours;
int mapperLDays;
int mapperLMonths;
int mapperLYears;
int mapperLControl;
time_t mapperLastTime;
};
struct mapperMMM01 {
int mapperRAMEnable;
int mapperROMBank;
int mapperRAMBank;
int mapperMemoryModel;
int mapperROMHighAddress;
int mapperRAMAddress;
int mapperRomBank0Remapping;
};
struct mapperGS3 {
int mapperROMBank;
};
extern mapperMBC1 gbDataMBC1; extern mapperMBC1 gbDataMBC1;
extern mapperMBC2 gbDataMBC2; extern mapperMBC2 gbDataMBC2;
extern mapperMBC3 gbDataMBC3; extern mapperMBC3 gbDataMBC3;
extern mapperMBC5 gbDataMBC5; extern mapperMBC5 gbDataMBC5;
extern mapperHuC1 gbDataHuC1; extern mapperHuC1 gbDataHuC1;
extern mapperHuC3 gbDataHuC3; extern mapperHuC3 gbDataHuC3;
extern mapperTAMA5 gbDataTAMA5;
extern mapperMMM01 gbDataMMM01;
extern mapperGS3 gbDataGS3;
void mapperMBC1ROM(u16,u8); void mapperMBC1ROM(u16,u8);
void mapperMBC1RAM(u16,u8); void mapperMBC1RAM(u16,u8);
u8 mapperMBC1ReadRAM(u16);
void mapperMBC2ROM(u16,u8); void mapperMBC2ROM(u16,u8);
void mapperMBC2RAM(u16,u8); void mapperMBC2RAM(u16,u8);
void mapperMBC3ROM(u16,u8); void mapperMBC3ROM(u16,u8);
@ -122,6 +170,7 @@ void mapperMBC3RAM(u16,u8);
u8 mapperMBC3ReadRAM(u16); u8 mapperMBC3ReadRAM(u16);
void mapperMBC5ROM(u16,u8); void mapperMBC5ROM(u16,u8);
void mapperMBC5RAM(u16,u8); void mapperMBC5RAM(u16,u8);
u8 mapperMBC5ReadRAM(u16);
void mapperMBC7ROM(u16,u8); void mapperMBC7ROM(u16,u8);
void mapperMBC7RAM(u16,u8); void mapperMBC7RAM(u16,u8);
u8 mapperMBC7ReadRAM(u16); u8 mapperMBC7ReadRAM(u16);
@ -130,7 +179,13 @@ void mapperHuC1RAM(u16,u8);
void mapperHuC3ROM(u16,u8); void mapperHuC3ROM(u16,u8);
void mapperHuC3RAM(u16,u8); void mapperHuC3RAM(u16,u8);
u8 mapperHuC3ReadRAM(u16); u8 mapperHuC3ReadRAM(u16);
void mapperTAMA5RAM(u16,u8);
u8 mapperTAMA5ReadRAM(u16);
void memoryUpdateTAMA5Clock();
void mapperMMM01ROM(u16,u8);
void mapperMMM01RAM(u16,u8);
void mapperGGROM(u16,u8);
void mapperGS3ROM(u16,u8);
//extern void (*mapper)(u16,u8); //extern void (*mapper)(u16,u8);
//extern void (*mapperRAM)(u16,u8); //extern void (*mapperRAM)(u16,u8);
//extern u8 (*mapperReadRAM)(u16); //extern u8 (*mapperReadRAM)(u16);
@ -142,7 +197,9 @@ extern void memoryUpdateMapMBC5();
extern void memoryUpdateMapMBC7(); extern void memoryUpdateMapMBC7();
extern void memoryUpdateMapHuC1(); extern void memoryUpdateMapHuC1();
extern void memoryUpdateMapHuC3(); extern void memoryUpdateMapHuC3();
extern void memoryUpdateMapTAMA5();
extern void memoryUpdateMapMMM01();
extern void memoryUpdateMapGS3();

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -19,8 +19,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <memory.h>
#include "../win32/stdafx.h"
#include "../win32/VBA.h"
#include "../System.h" #include "../System.h"
#include "../Port.h" #include "../Port.h"
#include "../Util.h" #include "../Util.h"
@ -29,6 +27,7 @@
extern u8 *pix; extern u8 *pix;
extern bool speedup; extern bool speedup;
extern bool gbSgbResetFlag;
#define GBSGB_NONE 0 #define GBSGB_NONE 0
#define GBSGB_RESET 1 #define GBSGB_RESET 1
@ -98,7 +97,7 @@ void gbSgbReset()
gbSgbBorder[i] = 1 << 2; gbSgbBorder[i] = 1 << 2;
} }
for(i = 0; i < 4; i++) { for(i = 0; i < 32; i++) {
gbPalette[i*4] = (0x1f) | (0x1f << 5) | (0x1f << 10); gbPalette[i*4] = (0x1f) | (0x1f << 5) | (0x1f << 10);
gbPalette[i*4+1] = (0x15) | (0x15 << 5) | (0x15 << 10); gbPalette[i*4+1] = (0x15) | (0x15 << 5) | (0x15 << 10);
gbPalette[i*4+2] = (0x0c) | (0x0c << 5) | (0x0c << 10); gbPalette[i*4+2] = (0x0c) | (0x0c << 5) | (0x0c << 10);
@ -257,9 +256,12 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
yyy = 7 - yy; yyy = 7 - yy;
u16 c = gbPalette[palette + color]; u16 c = gbPalette[palette + color];
if(!color)
c = gbPalette[0]; // Fix for Super Snaky ???
if((yy < 40 || yy >= 184) || (xx < 48 || xx >= 208)) { // (it allows SGB borders to not redraw on the GB screen)
//if(!color)
// c = gbPalette[0];
if(((yy < 40 || yy >= 184) || (xx < 48 || xx >= 208)) && (color || (gbSgbResetFlag == true))) {
switch(systemColorDepth) { switch(systemColorDepth) {
case 16: case 16:
gbSgbDraw16Bit(dest + yyy*(256+2) + xxx, c); gbSgbDraw16Bit(dest + yyy*(256+2) + xxx, c);
@ -287,7 +289,6 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
void gbSgbRenderBorder() void gbSgbRenderBorder()
{ {
if(gbBorderOn) { if(gbBorderOn) {
if (theApp.filterLCD) utilUpdateSystemColorMaps(0);
u8 *fromAddress = gbSgbBorder; u8 *fromAddress = gbSgbBorder;
for(u8 y = 0; y < 28; y++) { for(u8 y = 0; y < 28; y++) {
@ -298,7 +299,6 @@ void gbSgbRenderBorder()
gbSgbDrawBorderTile(x*8,y*8,tile,attr); gbSgbDrawBorderTile(x*8,y*8,tile,attr);
} }
} }
if (theApp.filterLCD) utilUpdateSystemColorMaps(1);
} }
} }

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -23,9 +23,6 @@
#include "gbGlobals.h" #include "gbGlobals.h"
#include "gbSound.h" #include "gbSound.h"
#include "../Gb_Apu/Multi_Buffer.h"
#include "../Gb_Apu/Gb_Apu.h"
extern u8 soundBuffer[6][735]; extern u8 soundBuffer[6][735];
extern u16 soundFinalWave[1470]; extern u16 soundFinalWave[1470];
extern int soundVolume; extern int soundVolume;
@ -35,6 +32,7 @@ extern int soundVolume;
#define NOISE_MAGIC 5 #define NOISE_MAGIC 5
extern int speed; extern int speed;
extern int gbHardware;
extern void soundResume(); extern void soundResume();
@ -58,11 +56,11 @@ extern int soundBufferIndex;
int soundVIN = 0; int soundVIN = 0;
extern int soundDebug; extern int soundDebug;
extern Multi_Buffer * apu_out;
extern Gb_Apu * apu;
extern int sound1On; extern int sound1On;
extern int sound1ATL; extern int sound1ATL;
int sound1ATLreload;
int freq1low;
int freq1high;
extern int sound1Skip; extern int sound1Skip;
extern int sound1Index; extern int sound1Index;
extern int sound1Continue; extern int sound1Continue;
@ -79,6 +77,9 @@ extern u8 *sound1Wave;
extern int sound2On; extern int sound2On;
extern int sound2ATL; extern int sound2ATL;
int sound2ATLreload;
int freq2low;
int freq2high;
extern int sound2Skip; extern int sound2Skip;
extern int sound2Index; extern int sound2Index;
extern int sound2Continue; extern int sound2Continue;
@ -90,6 +91,9 @@ extern u8 *sound2Wave;
extern int sound3On; extern int sound3On;
extern int sound3ATL; extern int sound3ATL;
int sound3ATLreload;
int freq3low;
int freq3high;
extern int sound3Skip; extern int sound3Skip;
extern int sound3Index; extern int sound3Index;
extern int sound3Continue; extern int sound3Continue;
@ -99,6 +103,8 @@ extern int sound3Last;
extern int sound4On; extern int sound4On;
extern int sound4Clock; extern int sound4Clock;
extern int sound4ATL; extern int sound4ATL;
int sound4ATLreload;
int freq4;
extern int sound4Skip; extern int sound4Skip;
extern int sound4Index; extern int sound4Index;
extern int sound4ShiftRight; extern int sound4ShiftRight;
@ -126,45 +132,7 @@ extern bool soundLowPass;
extern bool soundReverse; extern bool soundReverse;
extern bool soundOffFlag; extern bool soundOffFlag;
u8 gbSoundRead(u16 address) bool gbDigitalSound = false;
{
if (address < NR10 || address > 0xFF3F || !apu) return gbMemory[address];
if (address == NR51) return soundBalance;
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
int ret = apu->read_register(clock, address);
switch ( address )
{
case NR10:
ret |= 0x80; break;
case NR11:
case NR21:
ret |= 0x3F; break;
case NR13:
case NR23:
case NR31:
case NR33:
ret = 0xFF; break;
case NR14:
case NR24:
case NR34:
case NR44:
ret |= 0xBF; break;
case NR30:
ret |= 0x7F; break;
case NR32:
ret |= 0x9F; break;
}
return ret;
}
void gbSoundEvent(register u16 address, register int data) void gbSoundEvent(register u16 address, register int data)
{ {
@ -178,58 +146,481 @@ void gbSoundEvent(register u16 address, register int data)
log("Sound event: %08lx %02x\n", address, data); log("Sound event: %08lx %02x\n", address, data);
} }
#endif #endif
if (apu && address >= NR10 && address <= 0xFF3F) switch(address) {
{ case NR10:
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1)); gbMemory[address] = data | 0x80;
if (address == NR50) sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
{ sound1SweepSteps = data & 7;
apu->write_register(clock, address, data); sound1SweepUpDown = data & 0x08;
sound1SweepStep = 0;
break;
case NR11:
gbMemory[address] = data | 0x3f;
sound1Wave = soundWavePattern[data >> 6];
sound1ATL = sound1ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR12:
sound1EnvelopeVolume = data >> 4;
sound1EnvelopeUpDown = data & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
break;
case NR13:
gbMemory[address] = 0xff;
freq1low = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
sound1ATL = sound1ATLreload;
freq = 2048 - freq;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
break;
case NR14:
gbMemory[address] = data | 0xbf;
freq1high = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
freq = 2048 - freq;
sound1ATL = sound1ATLreload;
sound1Continue = data & 0x40;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 1;
sound1EnvelopeVolume = gbMemory[NR12] >> 4;
sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
sound1SweepSteps = gbMemory[NR10] & 7;
sound1SweepUpDown = gbMemory[NR10] & 0x08;
sound1SweepStep = 0;
sound1Index = 0;
sound1On = 1;
} }
else if (address == NR51) break;
{ case NR21:
soundBalance = data; gbMemory[address] = data | 0x3f;
apu->write_register(clock, address, data & soundEnableFlag); sound2Wave = soundWavePattern[data >> 6];
sound2ATL = sound2ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR22:
sound2EnvelopeVolume = data >> 4;
sound2EnvelopeUpDown = data & 0x08;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
break;
case NR23:
gbMemory[address] = 0xff;
freq2low = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
sound2ATL = sound2ATLreload;
freq = 2048 - freq;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
break;
case NR24:
gbMemory[address] = data | 0xbf;
freq2high = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
freq = 2048 - freq;
sound2ATL = sound2ATLreload;
sound2Continue = data & 0x40;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 2;
sound2EnvelopeVolume = gbMemory[NR22] >> 4;
sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
sound2ATL = sound2ATLreload;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
sound2Index = 0;
sound2On = 1;
} }
break;
case NR30:
gbMemory[address] = data | 0x7f;
if(!(data & 0x80)) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
break;
case NR31:
gbMemory[address] = 0xff;
sound3ATL = sound3ATLreload = 172 * (256-data);
break;
case NR32:
gbMemory[address] = data | 0x9f;
sound3OutputLevel = (data >> 5) & 3;
break;
case NR33:
gbMemory[address] = 0xff;
freq3low = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else
sound3Skip = 0;
break;
case NR34:
gbMemory[address] = data | 0xbf;
freq3high = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else {
sound3Skip = 0;
}
sound3Continue = data & 0x40;
if((data & 0x80) && (gbMemory[NR30] & 0x80)) {
gbMemory[NR52] |= 4;
sound3ATL = sound3ATLreload;
sound3Index = 0;
sound3On = 1;
}
break;
case NR41:
sound4ATL = sound4ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR42:
sound4EnvelopeVolume = data >> 4;
sound4EnvelopeUpDown = data & 0x08;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
break;
case NR43:
freq = freq4 = soundFreqRatio[data & 7];
sound4NSteps = data & 0x08;
sound4Skip = (freq << 8) / NOISE_MAGIC;
sound4Clock = data >> 4;
freq = freq / soundShiftClock[sound4Clock];
sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
break;
case NR44:
gbMemory[address] = data | 0xbf;
sound4Continue = data & 0x40;
if(data & 0x80) {
gbMemory[NR52] |= 8;
sound4EnvelopeVolume = gbMemory[NR42] >> 4;
sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
sound4ATL = sound4ATLreload;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
sound4On = 1;
sound4Index = 0;
sound4ShiftIndex = 0;
if(sound4NSteps)
sound4ShiftRight = 0x7fff;
else else
apu->write_register(clock, address, data); sound4ShiftRight = 0x7f;
} }
break;
case NR50:
soundVIN = data & 0x88;
soundLevel1 = data & 7;
soundLevel2 = (data >> 4) & 7;
break;
case NR51:
soundBalance = (data & soundEnableFlag);
break;
case NR52:
soundMasterOn = data & 0x80;
if(!(data & 0x80)) {
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
gbMemory[address] &= 0xf0;
}
gbMemory[address] = data & 0x80 | 0x70 | (gbMemory[address] & 0xf);
break;
}
gbDigitalSound = true;
if(sound1On && sound1EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound2On && sound2EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound3On && sound3OutputLevel != 0)
gbDigitalSound = false;
if(sound4On && sound4EnvelopeVolume != 0)
gbDigitalSound = false;
} }
void gbSoundChannel1() void gbSoundChannel1()
{ {
int vol = sound1EnvelopeVolume;
int freq = 0;
int value = 0;
if(sound1On && (sound1ATL || !sound1Continue)) {
sound1Index += soundQuality*sound1Skip;
sound1Index &= 0x1fffffff;
value = ((s8)sound1Wave[sound1Index>>24]) * vol;
}
soundBuffer[0][soundIndex] = value;
if(sound1On) {
if(sound1ATL) {
sound1ATL-=soundQuality;
if(sound1ATL <=0 && sound1Continue) {
gbMemory[NR52] &= 0xfe;
sound1On = 0;
}
}
if(sound1EnvelopeATL) {
sound1EnvelopeATL-=soundQuality;
if(sound1EnvelopeATL<=0) {
if(sound1EnvelopeUpDown) {
if(sound1EnvelopeVolume < 15)
sound1EnvelopeVolume++;
} else {
if(sound1EnvelopeVolume)
sound1EnvelopeVolume--;
}
sound1EnvelopeATL += sound1EnvelopeATLReload;
}
}
if(sound1SweepATL) {
sound1SweepATL-=soundQuality;
if(sound1SweepATL<=0) {
freq = (((int)(freq1high & 7)) << 8) | freq1low;
int updown = 1;
if(sound1SweepUpDown)
updown = -1;
int newfreq = 0;
if(sound1SweepSteps) {
newfreq = freq + updown * freq / (1 << sound1SweepSteps);
if(newfreq == freq)
newfreq = 0;
} else
newfreq = freq;
if(newfreq < 0) {
sound1SweepATL += sound1SweepATLReload;
} else if(newfreq > 2047) {
sound1SweepATL = 0;
sound1On = 0;
gbMemory[NR52] &= 0xfe;
} else {
sound1SweepATL += sound1SweepATLReload;
sound1Skip = SOUND_MAGIC/(2048 - newfreq);
freq1low = newfreq & 0xff;
freq1high = (freq1high & 0xf8) |((newfreq >> 8) & 7);
}
}
}
}
} }
void gbSoundChannel2() void gbSoundChannel2()
{ {
// int freq = 0;
int vol = sound2EnvelopeVolume;
int value = 0;
if(sound2On && (sound2ATL || !sound2Continue)) {
sound2Index += soundQuality*sound2Skip;
sound2Index &= 0x1fffffff;
value = ((s8)sound2Wave[sound2Index>>24]) * vol;
}
soundBuffer[1][soundIndex] = value;
if(sound2On) {
if(sound2ATL) {
sound2ATL-=soundQuality;
if(sound2ATL <= 0 && sound2Continue) {
gbMemory[NR52] &= 0xfd;
sound2On = 0;
}
}
if(sound2EnvelopeATL) {
sound2EnvelopeATL-=soundQuality;
if(sound2EnvelopeATL <= 0) {
if(sound2EnvelopeUpDown) {
if(sound2EnvelopeVolume < 15)
sound2EnvelopeVolume++;
} else {
if(sound2EnvelopeVolume)
sound2EnvelopeVolume--;
}
sound2EnvelopeATL += sound2EnvelopeATLReload;
}
}
}
} }
void gbSoundChannel3() void gbSoundChannel3()
{ {
int value = 0;
if(sound3On && (sound3ATL || !sound3Continue)) {
value = sound3Last;
sound3Index += soundQuality*sound3Skip;
sound3Index &= 0x1fffffff;
value = gbMemory[0xff30 + (sound3Index>>25)];
if( (sound3Index & 0x01000000)) {
value &= 0x0f;
} else {
value >>= 4;
}
value -= 8;
switch(sound3OutputLevel) {
case 0:
value = 0;
break;
case 1:
break;
case 2:
value = (value >> 1);
break;
case 3:
value = (value >> 2);
break;
}
sound3Last = value;
}
soundBuffer[2][soundIndex] = value;
if(sound3On) {
if(sound3ATL) {
sound3ATL-=soundQuality;
if(sound3ATL <= 0 && sound3Continue) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
}
}
} }
void gbSoundChannel4() void gbSoundChannel4()
{ {
int vol = sound4EnvelopeVolume;
int value = 0;
if(sound4Clock <= 0x0c) {
if(sound4On && (sound4ATL || !sound4Continue)) {
sound4Index += soundQuality*sound4Skip;
sound4ShiftIndex += soundQuality*sound4ShiftSkip;
if(sound4NSteps) {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 6) ^
(sound4ShiftRight << 5)) & 0x40) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
} else {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 14) ^
(sound4ShiftRight << 13)) & 0x4000) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
}
sound4Index &= 0x1fffff;
sound4ShiftIndex &= 0x1fffff;
value = ((sound4ShiftRight & 1)*2-1) * vol;
} else {
value = 0;
}
}
soundBuffer[3][soundIndex] = value;
if(sound4On) {
if(sound4ATL) {
sound4ATL-=soundQuality;
if(sound4ATL <= 0 && sound4Continue) {
gbMemory[NR52] &= 0xf7;
sound4On = 0;
}
}
if(sound4EnvelopeATL) {
sound4EnvelopeATL-=soundQuality;
if(sound4EnvelopeATL <= 0) {
if(sound4EnvelopeUpDown) {
if(sound4EnvelopeVolume < 15)
sound4EnvelopeVolume++;
} else {
if(sound4EnvelopeVolume)
sound4EnvelopeVolume--;
}
sound4EnvelopeATL += sound4EnvelopeATLReload;
}
}
}
} }
void gbSoundMix() void gbSoundMix()
{ {
int res = 0; int res = 0;
blip_sample_t out[2] = {0, 0}; if(soundBalance & 16) {
res += ((s8)soundBuffer[0][soundIndex]);
if ( ! apu_out ) return; }
if(soundBalance & 32) {
while (!apu_out->read_samples(&out[0], 2)) res += ((s8)soundBuffer[1][soundIndex]);
{ }
int ticks = SOUND_CLOCK_TICKS * 95 / (24 * (gbSpeed ? 2 : 1)); if(soundBalance & 64) {
bool was_stereo = apu->end_frame( ticks ); res += ((s8)soundBuffer[2][soundIndex]);
apu_out->end_frame( ticks, was_stereo ); }
if(soundBalance & 128) {
res += ((s8)soundBuffer[3][soundIndex]);
} }
res = out[0]; if(gbDigitalSound)
res *= soundLevel1*256;
//res = (res * 7 * 60) >> 8; else
res *= soundLevel1*60;
if(soundEcho) { if(soundEcho) {
res *= 2; res *= 2;
@ -273,7 +664,25 @@ void gbSoundMix()
else else
soundFinalWave[soundBufferIndex++] = res; soundFinalWave[soundBufferIndex++] = res;
res = out[1]; res = 0;
if(soundBalance & 1) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 2) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 4) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 8) {
res += ((s8)soundBuffer[3][soundIndex]);
}
if(gbDigitalSound)
res *= soundLevel2*256;
else
res *= soundLevel2*60;
if(soundEcho) { if(soundEcho) {
res *= 2; res *= 2;
@ -325,10 +734,10 @@ void gbSoundTick()
{ {
if(systemSoundOn) { if(systemSoundOn) {
if(soundMasterOn) { if(soundMasterOn) {
/*gbSoundChannel1(); gbSoundChannel1();
gbSoundChannel2(); gbSoundChannel2();
gbSoundChannel3(); gbSoundChannel3();
gbSoundChannel4();*/ gbSoundChannel4();
gbSoundMix(); gbSoundMix();
} else { } else {
@ -354,7 +763,7 @@ void gbSoundTick()
void gbSoundReset() void gbSoundReset()
{ {
soundPaused = 1; soundPaused = true;
soundPlay = 0; soundPlay = 0;
SOUND_CLOCK_TICKS = soundQuality * 24; SOUND_CLOCK_TICKS = soundQuality * 24;
soundTicks = SOUND_CLOCK_TICKS; soundTicks = SOUND_CLOCK_TICKS;
@ -366,42 +775,99 @@ void gbSoundReset()
soundLevel2 = 7; soundLevel2 = 7;
soundVIN = 0; soundVIN = 0;
sound1On = 0;
sound1ATL = 0;
sound1Skip = 0;
sound1Index = 0;
sound1Continue = 0;
sound1EnvelopeVolume = 0;
sound1EnvelopeATL = 0;
sound1EnvelopeUpDown = 0;
sound1EnvelopeATLReload = 0;
sound1SweepATL = 0;
sound1SweepATLReload = 0;
sound1SweepSteps = 0;
sound1SweepUpDown = 0;
sound1SweepStep = 0;
sound1Wave = soundWavePattern[2];
sound2On = 0;
sound2ATL = 0;
sound2Skip = 0;
sound2Index = 0;
sound2Continue = 0;
sound2EnvelopeVolume = 0;
sound2EnvelopeATL = 0;
sound2EnvelopeUpDown = 0;
sound2EnvelopeATLReload = 0;
sound2Wave = soundWavePattern[2];
sound3On = 0;
sound3ATL = 0;
sound3Skip = 0;
sound3Index = 0;
sound3Continue = 0;
sound3OutputLevel = 0;
sound4On = 0;
sound4Clock = 0;
sound4ATL = 0;
sound4Skip = 0;
sound4Index = 0;
sound4ShiftRight = 0x7f;
sound4NSteps = 0;
sound4CountDown = 0;
sound4Continue = 0;
sound4EnvelopeVolume = 0;
sound4EnvelopeATL = 0;
sound4EnvelopeUpDown = 0;
sound4EnvelopeATLReload = 0;
// don't translate // don't translate
if(soundDebug) { if(soundDebug) {
log("*** Sound Init ***\n"); log("*** Sound Init ***\n");
} }
gbSoundEvent(0xff10, 0x80);
gbSoundEvent(0xff11, 0xbf);
gbSoundEvent(0xff12, 0xf3);
gbSoundEvent(0xff14, 0xbf);
gbSoundEvent(0xff16, 0x3f);
gbSoundEvent(0xff17, 0x00);
gbSoundEvent(0xff19, 0xbf);
if (apu_out) gbSoundEvent(0xff1a, 0x7f);
{ gbSoundEvent(0xff1b, 0xff);
apu_out->clear(); gbSoundEvent(0xff1c, 0xbf);
apu->reset(false); gbSoundEvent(0xff1e, 0xbf);
extern const BOOST::uint8_t sound_data[Gb_Apu::end_addr - Gb_Apu::start_addr + 1]; gbSoundEvent(0xff20, 0xff);
gbSoundEvent(0xff21, 0x00);
gbSoundEvent(0xff22, 0x00);
gbSoundEvent(0xff23, 0xbf);
gbSoundEvent(0xff24, 0x77);
gbSoundEvent(0xff25, 0xf3);
int addr = 0; if (gbHardware & 0x4)
gbSoundEvent(0xff26, 0xf0);
else
gbSoundEvent(0xff26, 0xf1);
while (addr < 0x30) {
apu->write_register( 0, 0xFF10 + addr, sound_data [ addr ] );
addr++;
}
}
// don't translate // don't translate
if(soundDebug) { if(soundDebug) {
log("*** Sound Init Complete ***\n"); log("*** Sound Init Complete ***\n");
} }
if (apu) sound1On = 0;
{ sound2On = 0;
sound3On = 0;
sound4On = 0;
int addr = 0xff30; int addr = 0xff30;
while(addr < 0xff40) { while(addr < 0xff40) {
/*gbMemory[addr++] = 0x00; gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;*/ gbMemory[addr++] = 0xff;
gbSoundEvent(addr++, 0x00);
gbSoundEvent(addr++, 0xFF);
}
} }
memset(soundFinalWave, 0x00, soundBufferLen); memset(soundFinalWave, 0x00, soundBufferLen);
@ -411,7 +877,7 @@ void gbSoundReset()
soundEchoIndex = 0; soundEchoIndex = 0;
} }
extern bool soundInit(bool gba = true); extern bool soundInit(bool gb);
extern void soundShutdown(); extern void soundShutdown();
void gbSoundSetQuality(int quality) void gbSoundSetQuality(int quality)
@ -497,6 +963,18 @@ void gbSoundSaveGame(gzFile gzFile)
{ {
utilWriteData(gzFile, gbSoundSaveStruct); utilWriteData(gzFile, gbSoundSaveStruct);
utilWriteInt(gzFile, sound1ATLreload);
utilWriteInt(gzFile, freq1low);
utilWriteInt(gzFile, freq1high);
utilWriteInt(gzFile, sound2ATLreload);
utilWriteInt(gzFile, freq2low);
utilWriteInt(gzFile, freq2high);
utilWriteInt(gzFile, sound3ATLreload);
utilWriteInt(gzFile, freq3low);
utilWriteInt(gzFile, freq3high);
utilWriteInt(gzFile, sound4ATLreload);
utilWriteInt(gzFile, freq4);
utilGzWrite(gzFile, soundBuffer, 4*735); utilGzWrite(gzFile, soundBuffer, 4*735);
utilGzWrite(gzFile, soundFinalWave, 2*735); utilGzWrite(gzFile, soundFinalWave, 2*735);
utilGzWrite(gzFile, &soundQuality, sizeof(int)); utilGzWrite(gzFile, &soundQuality, sizeof(int));
@ -506,6 +984,35 @@ void gbSoundReadGame(int version,gzFile gzFile)
{ {
utilReadData(gzFile, gbSoundSaveStruct); utilReadData(gzFile, gbSoundSaveStruct);
if (version<11)
{
sound1ATLreload = 172 * (64 - (gbMemory[NR11] & 0x3f));
freq1low = gbMemory[NR13];
freq1high = gbMemory[NR14] & 7;
sound2ATLreload = 172 * (64 - (gbMemory[NR21] & 0x3f));
freq2low = gbMemory[NR23];
freq2high = gbMemory[NR24] & 7;
sound3ATLreload = 172 * (256 - gbMemory[NR31]);
freq3low = gbMemory[NR33];
freq3high = gbMemory[NR34] & 7;
sound4ATLreload = 172 * (64 - (gbMemory[NR41] & 0x3f));
freq4 = soundFreqRatio[gbMemory[NR43] & 7];
}
else
{
sound1ATLreload = utilReadInt(gzFile);
freq1low = utilReadInt(gzFile);
freq1high = utilReadInt(gzFile);
sound2ATLreload = utilReadInt(gzFile);
freq2low = utilReadInt(gzFile);
freq2high = utilReadInt(gzFile);
sound3ATLreload = utilReadInt(gzFile);
freq3low = utilReadInt(gzFile);
freq3high = utilReadInt(gzFile);
sound4ATLreload = utilReadInt(gzFile);
freq4 = utilReadInt(gzFile);
}
soundBufferIndex = soundIndex * 2; soundBufferIndex = soundIndex * 2;
utilGzRead(gzFile, soundBuffer, 4*735); utilGzRead(gzFile, soundBuffer, 4*735);

View File

@ -54,8 +54,6 @@ extern void gbSoundReadGame(int,gzFile);
extern void gbSoundEvent(register u16, register int); extern void gbSoundEvent(register u16, register int);
extern void gbSoundSetQuality(int); extern void gbSoundSetQuality(int);
extern u8 gbSoundRead(u16 address);
extern int soundTicks; extern int soundTicks;
extern int soundQuality; extern int soundQuality;
extern int SOUND_CLOCK_TICKS; extern int SOUND_CLOCK_TICKS;

File diff suppressed because it is too large Load Diff

View File

@ -131,10 +131,7 @@ extern int getopt ();
extern int getopt_long (); extern int getopt_long ();
extern int getopt_long_only (); extern int getopt_long_only ();
extern int _getopt_internal (int argc, char *const *argv, extern int _getopt_internal ();
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#endif /* __STDC__ */ #endif /* __STDC__ */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,180 +0,0 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "getopt.h"
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -66,9 +66,6 @@ static void SmartIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src2 = (u16 *)frm2; u16 *src2 = (u16 *)frm2;
u16 *src3 = (u16 *)frm3; u16 *src3 = (u16 *)frm3;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 2; int count = width >> 2;
for(int i = 0; i < height; i++) { for(int i = 0; i < height; i++) {
@ -166,10 +163,10 @@ static void SmartIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms; emms;
} }
#endif #endif
src0+= sPitch; src0+=2;
src1+= sPitch; src1+=2;
src2+= sPitch; src2+=2;
src3+= sPitch; src3+=2;
} }
/* Swap buffers around */ /* Swap buffers around */
@ -200,12 +197,10 @@ void SmartIB(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src3 = (u16 *)frm3; u16 *src3 = (u16 *)frm3;
int sPitch = srcPitch >> 1; int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0; int pos = 0;
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++) { for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos]; u16 color = src0[pos];
src0[pos] = src0[pos] =
(src1[pos] != src2[pos]) && (src1[pos] != src2[pos]) &&
@ -216,8 +211,6 @@ void SmartIB(u8 *srcPtr, u32 srcPitch, int width, int height)
src3[pos] = color; /* oldest buffer now holds newest frame */ src3[pos] = color; /* oldest buffer now holds newest frame */
pos++; pos++;
} }
pos += sPitch;
}
/* Swap buffers around */ /* Swap buffers around */
u8 *temp = frm1; u8 *temp = frm1;
@ -234,9 +227,6 @@ static void SmartIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 *src2 = (u32 *)frm2; u32 *src2 = (u32 *)frm2;
u32 *src3 = (u32 *)frm3; u32 *src3 = (u32 *)frm3;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 1; int count = width >> 1;
for(int i = 0; i < height; i++) { for(int i = 0; i < height; i++) {
@ -335,10 +325,10 @@ static void SmartIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
} }
#endif #endif
src0 += sPitch; src0++;
src1 += sPitch; src1++;
src2 += sPitch; src2++;
src3 += sPitch; src3++;
} }
/* Swap buffers around */ /* Swap buffers around */
u8 *temp = frm1; u8 *temp = frm1;
@ -368,12 +358,10 @@ void SmartIB32(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 colorMask = 0xfefefe; u32 colorMask = 0xfefefe;
int sPitch = srcPitch >> 2; int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0; int pos = 0;
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++) { for (int i = 0; i < sPitch; i++) {
u32 color = src0[pos]; u32 color = src0[pos];
src0[pos] = src0[pos] =
(src1[pos] != src2[pos]) && (src1[pos] != src2[pos]) &&
@ -384,8 +372,6 @@ void SmartIB32(u8 *srcPtr, u32 srcPitch, int width, int height)
src3[pos] = color; /* oldest buffer now holds newest frame */ src3[pos] = color; /* oldest buffer now holds newest frame */
pos++; pos++;
} }
pos += sPitch;
}
/* Swap buffers around */ /* Swap buffers around */
u8 *temp = frm1; u8 *temp = frm1;
@ -400,9 +386,6 @@ static void MotionBlurIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src0 = (u16 *)srcPtr; u16 *src0 = (u16 *)srcPtr;
u16 *src1 = (u16 *)frm1; u16 *src1 = (u16 *)frm1;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 2; int count = width >> 2;
for(int i = 0; i < height; i++) { for(int i = 0; i < height; i++) {
@ -460,8 +443,8 @@ static void MotionBlurIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms; emms;
} }
#endif #endif
src0 += sPitch; src0+=2;
src1 += sPitch; src1+=2;
} }
} }
#endif #endif
@ -485,20 +468,16 @@ void MotionBlurIB(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src1 = (u16 *)frm1; u16 *src1 = (u16 *)frm1;
int sPitch = srcPitch >> 1; int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0; int pos = 0;
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++) { for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos]; u16 color = src0[pos];
src0[pos] = src0[pos] =
(((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1)); (((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1));
src1[pos] = color; src1[pos] = color;
pos++; pos++;
} }
pos += sPitch;
}
} }
#ifdef MMX #ifdef MMX
@ -507,9 +486,6 @@ static void MotionBlurIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 *src0 = (u32 *)srcPtr; u32 *src0 = (u32 *)srcPtr;
u32 *src1 = (u32 *)frm1; u32 *src1 = (u32 *)frm1;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 1; int count = width >> 1;
for(int i = 0; i < height; i++) { for(int i = 0; i < height; i++) {
@ -567,8 +543,8 @@ static void MotionBlurIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms; emms;
} }
#endif #endif
src0 += sPitch; src0++;
src1 += sPitch; src1++;
} }
} }
#endif #endif
@ -592,57 +568,14 @@ void MotionBlurIB32(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 colorMask = 0xfefefe; u32 colorMask = 0xfefefe;
int sPitch = srcPitch >> 2; int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0; int pos = 0;
for (int j = 0; j < height; j++) { for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++) { for (int i = 0; i < sPitch; i++) {
u32 color = src0[pos]; u32 color = src0[pos];
src0[pos] = (((color & colorMask) >> 1) + src0[pos] = (((color & colorMask) >> 1) +
((src1[pos] & colorMask) >> 1)); ((src1[pos] & colorMask) >> 1));
src1[pos] = color; src1[pos] = color;
pos++; pos++;
} }
pos += sPitch;
}
}
static int count = 0;
void InterlaceIB(u8 *srcPtr, u32 srcPitch, int width, int height)
{
if(frm1 == NULL) {
Init();
}
u16 colorMask = ~RGB_LOW_BITS_MASK;
u16 *src0 = (u16 *)srcPtr;
u16 *src1 = (u16 *)frm1;
int sPitch = srcPitch >> 1;
int pos = 0;
for (int j = 0; j < height; j++) {
bool render = count ? (j & 1) != 0 : (j & 1) == 0;
if(render) {
for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos];
src0[pos] =
(((color & colorMask) >> 1) + ((((src1[pos] & colorMask) >> 1) & colorMask) >> 1));
src1[pos] = color;
pos++;
}
} else {
for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos];
src0[pos] =
(((((color & colorMask) >> 1) & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1));
src1[pos] = color;
pos++;
}
}
}
count = count ^ 1;
} }

View File

@ -40,11 +40,6 @@
static unsigned interp_mask[2]; static unsigned interp_mask[2];
static unsigned interp_bits_per_pixel; static unsigned interp_bits_per_pixel;
typedef unsigned short interp_uint16;
typedef unsigned int interp_uint32;
#define restrict
#define INTERP_16_MASK_1(v) (v & interp_mask[0]) #define INTERP_16_MASK_1(v) (v & interp_mask[0])
#define INTERP_16_MASK_2(v) (v & interp_mask[1]) #define INTERP_16_MASK_2(v) (v & interp_mask[1])

View File

@ -9,7 +9,7 @@
* Adapted from original gzio.c from zlib library by Forgotten * Adapted from original gzio.c from zlib library by Forgotten
*/ */
/* @(#) $Id: memgzio.c,v 1.3 2004/01/17 23:07:32 kxu Exp $ */ /* @(#) $Id: memgzio.c,v 1.5 2006/06/06 21:04:20 spacy51 Exp $ */
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -125,7 +125,7 @@ local size_t memWrite(const void *buffer, size_t size, size_t count,
total = file->available; total = file->available;
} }
memcpy(file->next, buffer, total); memcpy(file->next, buffer, total);
file->available -= total; file->available -= (int)total;
file->next += total; file->next += total;
return total; return total;
} }
@ -147,7 +147,7 @@ local size_t memRead(void *buffer, size_t size, size_t count,
total = file->available; total = file->available;
} }
memcpy(buffer, file->next, total); memcpy(buffer, file->next, total);
file->available -= total; file->available -= (int)total;
file->next += total; file->next += total;
return total; return total;
} }
@ -170,7 +170,7 @@ local int memPutc(int c, MEMFILE *file)
local long memTell(MEMFILE *f) local long memTell(MEMFILE *f)
{ {
return (f->next - f->memory) - 8; return (long)(f->next - f->memory) - 8;
} }
local int memError(MEMFILE *f) local int memError(MEMFILE *f)
@ -197,7 +197,7 @@ local int memPrintf(MEMFILE *f, const char *format, ...)
len = vsprintf(buffer, format, list); len = vsprintf(buffer, format, list);
va_end(list); va_end(list);
return memWrite(buffer, 1, len, f); return (int)memWrite(buffer, 1, len, f);
} }
/* =========================================================================== /* ===========================================================================
@ -209,7 +209,10 @@ local int memPrintf(MEMFILE *f, const char *format, ...)
can be checked to distinguish the two cases (if errno is zero, the can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
*/ */
local gzFile gz_open (char *memory, const int available, const char *mode) local gzFile gz_open (memory, available, mode)
char *memory;
const int available;
const char *mode;
{ {
int err; int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */ int level = Z_DEFAULT_COMPRESSION; /* compression level */
@ -309,7 +312,10 @@ local gzFile gz_open (char *memory, const int available, const char *mode)
/* =========================================================================== /* ===========================================================================
Opens a gzip (.gz) file for reading or writing. Opens a gzip (.gz) file for reading or writing.
*/ */
gzFile ZEXPORT memgzopen (char *memory, int available, const char *mode) gzFile ZEXPORT memgzopen (memory, available, mode)
char *memory;
int available;
const char *mode;
{ {
return gz_open (memory, available, mode); return gz_open (memory, available, mode);
} }
@ -319,12 +325,13 @@ gzFile ZEXPORT memgzopen (char *memory, int available, const char *mode)
for end of file. for end of file.
IN assertion: the stream s has been sucessfully opened for reading. IN assertion: the stream s has been sucessfully opened for reading.
*/ */
local int get_byte(mem_stream *s) local int get_byte(s)
mem_stream *s;
{ {
if (s->z_eof) return EOF; if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
errno = 0; errno = 0;
s->stream.avail_in = memRead(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = (uInt)memRead(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (memError(s->file)) s->z_err = Z_ERRNO; if (memError(s->file)) s->z_err = Z_ERRNO;
@ -345,7 +352,8 @@ local int get_byte(mem_stream *s)
s->stream.avail_in is zero for the first time, but may be non-zero s->stream.avail_in is zero for the first time, but may be non-zero
for concatenated .gz files. for concatenated .gz files.
*/ */
local void check_header(mem_stream *s) local void check_header(s)
mem_stream *s;
{ {
int method; /* method byte */ int method; /* method byte */
int flags; /* flags byte */ int flags; /* flags byte */
@ -397,7 +405,8 @@ local void check_header(mem_stream *s)
* Cleanup then free the given mem_stream. Return a zlib error code. * Cleanup then free the given mem_stream. Return a zlib error code.
Try freeing in the reverse order of allocations. Try freeing in the reverse order of allocations.
*/ */
local int destroy (mem_stream *s) local int destroy (s)
mem_stream *s;
{ {
int err = Z_OK; int err = Z_OK;
@ -434,7 +443,10 @@ local int destroy (mem_stream *s)
Reads the given number of uncompressed bytes from the compressed file. Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file). gzread returns the number of bytes actually read (0 for end of file).
*/ */
int ZEXPORT memgzread (gzFile file, voidp buf, unsigned len) int ZEXPORT memgzread (file, buf, len)
gzFile file;
voidp buf;
unsigned len;
{ {
mem_stream *s = (mem_stream*)file; mem_stream *s = (mem_stream*)file;
Bytef *start = (Bytef*)buf; /* starting point for crc computation */ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
@ -464,8 +476,7 @@ int ZEXPORT memgzread (gzFile file, voidp buf, unsigned len)
s->stream.avail_in -= n; s->stream.avail_in -= n;
} }
if (s->stream.avail_out > 0) { if (s->stream.avail_out > 0) {
s->stream.avail_out -= memRead(next_out, 1, s->stream.avail_out, s->stream.avail_out -= (uInt)memRead(next_out, 1, s->stream.avail_out, s->file);
s->file);
} }
len -= s->stream.avail_out; len -= s->stream.avail_out;
s->stream.total_in += (uLong)len; s->stream.total_in += (uLong)len;
@ -476,7 +487,7 @@ int ZEXPORT memgzread (gzFile file, voidp buf, unsigned len)
if (s->stream.avail_in == 0 && !s->z_eof) { if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0; errno = 0;
s->stream.avail_in = memRead(s->inbuf, 1, Z_BUFSIZE, s->file); s->stream.avail_in = (uInt)memRead(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
if (memError(s->file)) { if (memError(s->file)) {
@ -526,7 +537,10 @@ int ZEXPORT memgzread (gzFile file, voidp buf, unsigned len)
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of bytes actually written (0 in case of error). gzwrite returns the number of bytes actually written (0 in case of error).
*/ */
int ZEXPORT memgzwrite (gzFile file, const voidp buf, unsigned len) int ZEXPORT memgzwrite (file, buf, len)
gzFile file;
const voidp buf;
unsigned len;
{ {
mem_stream *s = (mem_stream*)file; mem_stream *s = (mem_stream*)file;
@ -558,7 +572,9 @@ int ZEXPORT memgzwrite (gzFile file, const voidp buf, unsigned len)
Flushes all pending output into the compressed file. The parameter Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function. flush is as in the deflate() function.
*/ */
local int do_flush (gzFile file, int flush) local int do_flush (file, flush)
gzFile file;
int flush;
{ {
uInt len; uInt len;
int done = 0; int done = 0;
@ -598,7 +614,9 @@ local int do_flush (gzFile file, int flush)
/* =========================================================================== /* ===========================================================================
Outputs a long in LSB order to the given file Outputs a long in LSB order to the given file
*/ */
local void putLong (MEMFILE *file, uLong x) local void putLong (file, x)
MEMFILE *file;
uLong x;
{ {
int n; int n;
for (n = 0; n < 4; n++) { for (n = 0; n < 4; n++) {
@ -611,7 +629,8 @@ local void putLong (MEMFILE *file, uLong x)
Reads a long in LSB order from the given mem_stream. Sets z_err in case Reads a long in LSB order from the given mem_stream. Sets z_err in case
of error. of error.
*/ */
local uLong getLong (mem_stream *s) local uLong getLong (s)
mem_stream *s;
{ {
uLong x = (uLong)get_byte(s); uLong x = (uLong)get_byte(s);
int c; int c;
@ -628,7 +647,8 @@ local uLong getLong (mem_stream *s)
Flushes all pending output if necessary, closes the compressed file Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state. and deallocates all the (de)compression state.
*/ */
int ZEXPORT memgzclose (gzFile file) int ZEXPORT memgzclose (file)
gzFile file;
{ {
int err; int err;
mem_stream *s = (mem_stream*)file; mem_stream *s = (mem_stream*)file;
@ -649,7 +669,8 @@ int ZEXPORT memgzclose (gzFile file)
return destroy((mem_stream*)file); return destroy((mem_stream*)file);
} }
long ZEXPORT memtell(gzFile file) long ZEXPORT memtell(file)
gzFile file;
{ {
mem_stream *s = (mem_stream*)file; mem_stream *s = (mem_stream*)file;

View File

@ -8,7 +8,12 @@
/* memgzio.c - IO on .gz files in memory /* memgzio.c - IO on .gz files in memory
* Adapted from original gzio.c from zlib library by Forgotten * Adapted from original gzio.c from zlib library by Forgotten
*/ */
#if defined(HAVE_ZUTIL_H) || defined(_WIN32)
# include <zutil.h> # include <zutil.h>
#else
# include "../win32/dependencies/zlib/zutil.h"
#endif
gzFile ZEXPORT memgzopen(char *memory, int, const char *); gzFile ZEXPORT memgzopen(char *memory, int, const char *);
int ZEXPORT memgzread(gzFile, voidp, unsigned); int ZEXPORT memgzread(gzFile, voidp, unsigned);

View File

@ -20,7 +20,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifndef WIN32 #ifndef _WIN32
# include <unistd.h> # include <unistd.h>
# include <sys/socket.h> # include <sys/socket.h>
# include <netdb.h> # include <netdb.h>
@ -32,14 +32,15 @@
# else // ! HAVE_ARPA_INET_H # else // ! HAVE_ARPA_INET_H
# define socklen_t int # define socklen_t int
# endif // ! HAVE_ARPA_INET_H # endif // ! HAVE_ARPA_INET_H
#else // WIN32 # define SOCKET int
#else // _WIN32
# include <winsock.h> # include <winsock.h>
# include <io.h> # include <io.h>
# define socklen_t int # define socklen_t int
# define close closesocket # define close closesocket
# define read _read # define read _read
# define write _write # define write _write
#endif // WIN32 #endif // _WIN32
#include "GBA.h" #include "GBA.h"
@ -54,8 +55,8 @@ extern void debuggerSignal(int,int);
int remotePort = 55555; int remotePort = 55555;
int remoteSignal = 5; int remoteSignal = 5;
int remoteSocket = -1; SOCKET remoteSocket = -1;
int remoteListenSocket = -1; SOCKET remoteListenSocket = -1;
bool remoteConnected = false; bool remoteConnected = false;
bool remoteResumed = false; bool remoteResumed = false;
@ -85,11 +86,11 @@ int remoteTcpRecv(char *data, int len)
bool remoteTcpInit() bool remoteTcpInit()
{ {
if(remoteSocket == -1) { if(remoteSocket == -1) {
#ifdef WIN32 #ifdef _WIN32
WSADATA wsaData; WSADATA wsaData;
int error = WSAStartup(MAKEWORD(1,1),&wsaData); int error = WSAStartup(MAKEWORD(1,1),&wsaData);
#endif // WIN32 #endif // _WIN32
int s = socket(PF_INET, SOCK_STREAM, 0); SOCKET s = socket(PF_INET, SOCK_STREAM, 0);
remoteListenSocket = s; remoteListenSocket = s;
@ -131,19 +132,19 @@ bool remoteTcpInit()
} }
socklen_t len = sizeof(addr); socklen_t len = sizeof(addr);
#ifdef WIN32 #ifdef _WIN32
int flag = 0; int flag = 0;
ioctlsocket(s, FIONBIO, (unsigned long *)&flag); ioctlsocket(s, FIONBIO, (unsigned long *)&flag);
#endif // WIN32 #endif // _WIN32
int s2 = accept(s, (sockaddr *)&addr, &len); SOCKET s2 = accept(s, (sockaddr *)&addr, &len);
if(s2 > 0) { if(s2 > 0) {
fprintf(stderr, "Got a connection from %s %d\n", fprintf(stderr, "Got a connection from %s %d\n",
inet_ntoa((in_addr)addr.sin_addr), inet_ntoa((in_addr)addr.sin_addr),
ntohs(addr.sin_port)); ntohs(addr.sin_port));
} else { } else {
#ifdef WIN32 #ifdef _WIN32
int error = WSAGetLastError(); int error = WSAGetLastError();
#endif // WIN32 #endif // _WIN32
} }
char dummy; char dummy;
recv(s2, &dummy, 1, 0); recv(s2, &dummy, 1, 0);
@ -230,14 +231,14 @@ void remotePutPacket(char *packet)
char *hex = "0123456789abcdef"; char *hex = "0123456789abcdef";
char buffer[1024]; char buffer[1024];
int count = strlen(packet); size_t count = strlen(packet);
unsigned char csum = 0; unsigned char csum = 0;
char *p = buffer; char *p = buffer;
*p++ = '$'; *p++ = '$';
for(int i = 0 ;i < count; i++) { for(size_t i = 0 ;i < count; i++) {
csum += packet[i]; csum += packet[i];
*p++ = packet[i]; *p++ = packet[i];
} }
@ -246,7 +247,7 @@ void remotePutPacket(char *packet)
*p++ = hex[csum & 15]; *p++ = hex[csum & 15];
*p++ = 0; *p++ = 0;
// printf("Sending %s\n", buffer); // printf("Sending %s\n", buffer);
remoteSendFnc(buffer, count + 4); remoteSendFnc(buffer, (int)count + 4);
char c = 0; char c = 0;
remoteRecvFnc(&c, 1); remoteRecvFnc(&c, 1);

File diff suppressed because it is too large Load Diff

View File

@ -154,7 +154,7 @@ typedef struct
local int unzlocal_getByte(FILE *fin,int *pi) local int unzlocal_getByte(FILE *fin,int *pi)
{ {
unsigned char c; unsigned char c;
int err = fread(&c, 1, 1, fin); size_t err = fread(&c, 1, 1, fin);
if (err==1) if (err==1)
{ {
*pi = (int)c; *pi = (int)c;

View File

@ -19,8 +19,9 @@
// AboutDialog.cpp : implementation file // AboutDialog.cpp : implementation file
// //
#include "stdafx.h"
#include "AboutDialog.h" #include "AboutDialog.h"
#include "..\..\res\resource.h" #include "../AutoBuild.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -63,15 +64,13 @@ BOOL AboutDialog::OnInitDialog()
{ {
CDialog::OnInitDialog(); CDialog::OnInitDialog();
CWnd *p = GetDlgItem(IDC_TRANSLATOR_URL);
if(p) {
m_translator.SubclassDlgItem(IDC_TRANSLATOR_URL, this);
}
m_link.SetWindowText("http://vba.ngemu.com"); m_link.SetWindowText("http://vba.ngemu.com");
return TRUE; // return TRUE unless you set the focus to a control return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE // EXCEPTION: OCX Property Pages should return FALSE
} }
void AboutDialog::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
}

View File

@ -27,7 +27,7 @@
// //
#include "stdafx.h" #include "stdafx.h"
#include "Hyperlink.h" #include "Hyperlink.h"
#include "..\..\res\resource.h" #include "resource.h"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// AboutDialog dialog // AboutDialog dialog
@ -60,7 +60,6 @@ class AboutDialog : public CDialog
// Generated message map functions // Generated message map functions
//{{AFX_MSG(AboutDialog) //{{AFX_MSG(AboutDialog)
virtual BOOL OnInitDialog(); virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG //}}AFX_MSG

View File

@ -156,7 +156,7 @@ void AccelEditor::OnSelchangeCommands()
pAccel->GetString(szBuffer); pAccel->GetString(szBuffer);
index = m_currents.AddString(szBuffer); index = m_currents.AddString(szBuffer);
// and a pointer to the accel object. // and a pointer to the accel object.
m_currents.SetItemData(index, (DWORD)pAccel); m_currents.SetItemData(index, (DWORD_PTR)pAccel);
} }
} }
// Init the key editor // Init the key editor
@ -180,12 +180,12 @@ void AccelEditor::OnAssign()
WORD wKey; WORD wKey;
bool bCtrl, bAlt, bShift; bool bCtrl, bAlt, bShift;
int index;
if (!m_key.GetAccelKey(wKey, bCtrl, bAlt, bShift)) if (!m_key.GetAccelKey(wKey, bCtrl, bAlt, bShift))
return; // no valid key, abort return; // no valid key, abort
int count = m_commands.GetCount(); int count = m_commands.GetCount();
int index;
for (index = 0; index < count; index++) { for (index = 0; index < count; index++) {
wIDCommand = LOWORD(m_commands.GetItemData(index)); wIDCommand = LOWORD(m_commands.GetItemData(index));
@ -235,7 +235,7 @@ void AccelEditor::OnAssign()
pAccel->GetString(szBuffer); pAccel->GetString(szBuffer);
index = m_currents.AddString(szBuffer); index = m_currents.AddString(szBuffer);
m_currents.SetItemData(index, (DWORD)pAccel); m_currents.SetItemData(index, (DWORD_PTR)pAccel);
// Reset the key editor. // Reset the key editor.
m_key.ResetKey(); m_key.ResetKey();

View File

@ -27,7 +27,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "stdafx.h"
//#include "..\..\res\resource.h" //#include "resource.h"
#include "../System.h" #include "../System.h"
#include "AcceleratorManager.h" #include "AcceleratorManager.h"
@ -247,7 +247,7 @@ bool CAcceleratorManager::UpdateWndTable()
} }
} }
int nAccel = arrayACCEL.GetSize(); INT_PTR nAccel = arrayACCEL.GetSize();
LPACCEL lpAccel = (LPACCEL)LocalAlloc(LPTR, nAccel * sizeof(ACCEL)); LPACCEL lpAccel = (LPACCEL)LocalAlloc(LPTR, nAccel * sizeof(ACCEL));
if (!lpAccel) { if (!lpAccel) {
for (iLoop = 0; iLoop < nAccel; iLoop++) for (iLoop = 0; iLoop < nAccel; iLoop++)
@ -268,7 +268,7 @@ bool CAcceleratorManager::UpdateWndTable()
} }
arrayACCEL.RemoveAll(); arrayACCEL.RemoveAll();
HACCEL hNewTable = CreateAcceleratorTable(lpAccel, nAccel); HACCEL hNewTable = CreateAcceleratorTable(lpAccel, (int)nAccel);
if (!hNewTable) { if (!hNewTable) {
::LocalFree(lpAccel); ::LocalFree(lpAccel);
return false; return false;
@ -709,14 +709,14 @@ bool CAcceleratorManager::Write()
} }
// AccelsDatasArray.InsertAt(0, MAKELONG(65535, iCount)); // AccelsDatasArray.InsertAt(0, MAKELONG(65535, iCount));
int count = AccelsDatasArray.GetSize(); INT_PTR count = AccelsDatasArray.GetSize();
DWORD *data = (DWORD *)malloc(count * sizeof(DWORD)); DWORD *data = (DWORD *)malloc(count * sizeof(DWORD));
ASSERT(data != NULL); ASSERT(data != NULL);
for(int index = 0; index < count; index++) for(int index = 0; index < count; index++)
data[index] = AccelsDatasArray[index]; data[index] = AccelsDatasArray[index];
regSetBinaryValue("keyboard", (char *)data, count*sizeof(DWORD)); regSetBinaryValue("keyboard", (char *)data, (int)(count*sizeof(DWORD)));
AccelsDatasArray.RemoveAll(); AccelsDatasArray.RemoveAll();
CmdDatasArray.RemoveAll(); CmdDatasArray.RemoveAll();

View File

@ -33,6 +33,7 @@
#endif // _MSC_VER >= 1000 #endif // _MSC_VER >= 1000
#include "CmdAccelOb.h" #include "CmdAccelOb.h"

View File

@ -20,7 +20,7 @@
#if !defined(AFX_BITMAPCONTROL_H__2434AADB_B6A5_4E43_AA16_7B65B6F7FA26__INCLUDED_) #if !defined(AFX_BITMAPCONTROL_H__2434AADB_B6A5_4E43_AA16_7B65B6F7FA26__INCLUDED_)
#define AFX_BITMAPCONTROL_H__2434AADB_B6A5_4E43_AA16_7B65B6F7FA26__INCLUDED_ #define AFX_BITMAPCONTROL_H__2434AADB_B6A5_4E43_AA16_7B65B6F7FA26__INCLUDED_
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@
#include "BugReport.h" #include "BugReport.h"
#include "../agbprint.h" #include "../agbprint.h"
#include "../AutoBuild.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
#include "../Port.h" #include "../Port.h"
@ -215,7 +216,6 @@ CString BugReport::createReport()
AppendFormat(report, "Using BIOS : %d\r\n", theApp.useBiosFile); AppendFormat(report, "Using BIOS : %d\r\n", theApp.useBiosFile);
AppendFormat(report, "Skip BIOS : %d\r\n", theApp.skipBiosFile); AppendFormat(report, "Skip BIOS : %d\r\n", theApp.skipBiosFile);
AppendFormat(report, "Disable SFX : %d\r\n", cpuDisableSfx); AppendFormat(report, "Disable SFX : %d\r\n", cpuDisableSfx);
AppendFormat(report, "Skip intro : %d\r\n", theApp.removeIntros);
AppendFormat(report, "Throttle : %d\r\n", theApp.throttle); AppendFormat(report, "Throttle : %d\r\n", theApp.throttle);
AppendFormat(report, "Rewind : %d\r\n", theApp.rewindTimer); AppendFormat(report, "Rewind : %d\r\n", theApp.rewindTimer);
AppendFormat(report, "Auto frame : %d\r\n", theApp.autoFrameSkip); AppendFormat(report, "Auto frame : %d\r\n", theApp.autoFrameSkip);
@ -226,6 +226,7 @@ CString BugReport::createReport()
AppendFormat(report, "Green shift : %08x\r\n", systemGreenShift); AppendFormat(report, "Green shift : %08x\r\n", systemGreenShift);
AppendFormat(report, "Blue shift : %08x\r\n", systemBlueShift); AppendFormat(report, "Blue shift : %08x\r\n", systemBlueShift);
AppendFormat(report, "Layer setting: %04X\r\n", layerSettings); AppendFormat(report, "Layer setting: %04X\r\n", layerSettings);
AppendFormat(report, "Mirroring : %d\r\n", mirroringEnable);
AppendFormat(report, "Save type : %d (%d)\r\n", AppendFormat(report, "Save type : %d (%d)\r\n",
theApp.winSaveType, cpuSaveType); theApp.winSaveType, cpuSaveType);
AppendFormat(report, "Flash size : %08X (%08x)\r\n", AppendFormat(report, "Flash size : %08X (%08x)\r\n",

View File

@ -264,14 +264,15 @@ void CAccelsOb::GetString(CString& szBuffer)
return; return;
// modifiers part // modifiers part
for (int i = 0; i < sizetable(mapVirtSysKeys); i++) { int i;
for (i = 0; i < sizetable(mapVirtSysKeys); i++) {
if (m_cVirt & mapVirtSysKeys[i].wKey) { if (m_cVirt & mapVirtSysKeys[i].wKey) {
szBuffer += mapVirtSysKeys[i].szKey; szBuffer += mapVirtSysKeys[i].szKey;
szBuffer += "+"; szBuffer += "+";
} }
} }
// and virtual key part // and virtual key part
if (1) for (int i = 0; i < sizetable(mapVirtKeys); i++) { for (i = 0; i < sizetable(mapVirtKeys); i++) {
if (m_wKey == mapVirtKeys[i].wKey) { if (m_wKey == mapVirtKeys[i].wKey) {
szBuffer += mapVirtKeys[i].szKey; szBuffer += mapVirtKeys[i].szKey;
return; return;

View File

@ -20,7 +20,7 @@
#if !defined(AFX_COLORBUTTON_H__DF02109B_B91C_49FD_954F_74A48B83C314__INCLUDED_) #if !defined(AFX_COLORBUTTON_H__DF02109B_B91C_49FD_954F_74A48B83C314__INCLUDED_)
#define AFX_COLORBUTTON_H__DF02109B_B91C_49FD_954F_74A48B83C314__INCLUDED_ #define AFX_COLORBUTTON_H__DF02109B_B91C_49FD_954F_74A48B83C314__INCLUDED_
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -20,7 +20,7 @@
#if !defined(AFX_COLORCONTROL_H__747E1E47_DDFA_4D67_B337_A473F2BACB86__INCLUDED_) #if !defined(AFX_COLORCONTROL_H__747E1E47_DDFA_4D67_B337_A473F2BACB86__INCLUDED_)
#define AFX_COLORCONTROL_H__747E1E47_DDFA_4D67_B337_A473F2BACB86__INCLUDED_ #define AFX_COLORCONTROL_H__747E1E47_DDFA_4D67_B337_A473F2BACB86__INCLUDED_
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "AcceleratorManager.h" #include "AcceleratorManager.h"
#include "..\..\res\resource.h" #include "resource.h"
#include <afxres.h> #include <afxres.h>
#include <afxtempl.h> // MFC Templates extension #include <afxtempl.h> // MFC Templates extension
@ -105,6 +105,8 @@ struct {
{ "OptionsVideoRenderDDRAW", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECTDRAW }, { "OptionsVideoRenderDDRAW", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECTDRAW },
{ "OptionsVideoRenderD3D", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECT3D }, { "OptionsVideoRenderD3D", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECT3D },
{ "OptionsVideoRenderOGL", ID_OPTIONS_VIDEO_RENDERMETHOD_OPENGL }, { "OptionsVideoRenderOGL", ID_OPTIONS_VIDEO_RENDERMETHOD_OPENGL },
{ "OptionsVideoRenderSelectSkin", ID_OPTIONS_VIDEO_RENDEROPTIONS_SELECTSKIN },
{ "OptionsVideoRenderSkin", ID_OPTIONS_VIDEO_RENDEROPTIONS_SKIN },
{ "OptionsVideoVsync", ID_OPTIONS_VIDEO_VSYNC }, { "OptionsVideoVsync", ID_OPTIONS_VIDEO_VSYNC },
{ "OptionsVideoX1", ID_OPTIONS_VIDEO_X1 }, { "OptionsVideoX1", ID_OPTIONS_VIDEO_X1 },
{ "OptionsVideoX2", ID_OPTIONS_VIDEO_X2 }, { "OptionsVideoX2", ID_OPTIONS_VIDEO_X2 },
@ -127,13 +129,13 @@ struct {
{ "OptionsEmulatorDirectories", ID_OPTIONS_EMULATOR_DIRECTORIES }, { "OptionsEmulatorDirectories", ID_OPTIONS_EMULATOR_DIRECTORIES },
{ "OptionsEmulatorSelectBIOS", ID_OPTIONS_EMULATOR_SELECTBIOSFILE }, { "OptionsEmulatorSelectBIOS", ID_OPTIONS_EMULATOR_SELECTBIOSFILE },
{ "OptionsEmulatorUseBIOS", ID_OPTIONS_EMULATOR_USEBIOSFILE }, { "OptionsEmulatorUseBIOS", ID_OPTIONS_EMULATOR_USEBIOSFILE },
{ "OptionsEmulatorGameOverrides", ID_OPTIONS_EMULATOR_GAMEOVERRIDES },
{ "OptionsEmulatorSkipBIOS", ID_OPTIONS_EMULATOR_SKIPBIOS }, { "OptionsEmulatorSkipBIOS", ID_OPTIONS_EMULATOR_SKIPBIOS },
{ "OptionsEmulatorShowSpeedNone", ID_OPTIONS_EMULATOR_SHOWSPEED_NONE }, { "OptionsEmulatorShowSpeedNone", ID_OPTIONS_EMULATOR_SHOWSPEED_NONE },
{ "OptionsEmulatorShowSpeedPercentage", ID_OPTIONS_EMULATOR_SHOWSPEED_PERCENTAGE }, { "OptionsEmulatorShowSpeedPercentage", ID_OPTIONS_EMULATOR_SHOWSPEED_PERCENTAGE },
{ "OptionsEmulatorShowSpeedDetailed", ID_OPTIONS_EMULATOR_SHOWSPEED_DETAILED }, { "OptionsEmulatorShowSpeedDetailed", ID_OPTIONS_EMULATOR_SHOWSPEED_DETAILED },
{ "OptionsEmulatorShowSpeedTransparent", ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT }, { "OptionsEmulatorShowSpeedTransparent", ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT },
{ "OptionsEmulatorSpeedupToggle", ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE }, { "OptionsEmulatorSpeedupToggle", ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE },
{ "OptionsEmulatorRemoveIntros", ID_OPTIONS_EMULATOR_REMOVEINTROSGBA },
{ "OptionsEmulatorAutoHideMenu", ID_OPTIONS_EMULATOR_AUTOHIDEMENU }, { "OptionsEmulatorAutoHideMenu", ID_OPTIONS_EMULATOR_AUTOHIDEMENU },
{ "OptionsEmulatorSaveAuto", ID_OPTIONS_EMULATOR_SAVETYPE_AUTOMATIC }, { "OptionsEmulatorSaveAuto", ID_OPTIONS_EMULATOR_SAVETYPE_AUTOMATIC },
{ "OptionsEmulatorSaveEEPROM", ID_OPTIONS_EMULATOR_SAVETYPE_EEPROM }, { "OptionsEmulatorSaveEEPROM", ID_OPTIONS_EMULATOR_SAVETYPE_EEPROM },
@ -145,9 +147,10 @@ struct {
{ "OptionsEmulatorAutoIPSPatch", ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH }, { "OptionsEmulatorAutoIPSPatch", ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH },
{ "OptionsEmulatorAGBPrint", ID_OPTIONS_EMULATOR_AGBPRINT }, { "OptionsEmulatorAGBPrint", ID_OPTIONS_EMULATOR_AGBPRINT },
{ "OptionsEmulatorRTC", ID_OPTIONS_EMULATOR_REALTIMECLOCK }, { "OptionsEmulatorRTC", ID_OPTIONS_EMULATOR_REALTIMECLOCK },
{ "OptionsEmulatorGenericflashcard", ID_OPTIONS_EMULATOR_GENERICFLASHCARD },
{ "OptionsEmulatorRewindInterval", ID_OPTIONS_EMULATOR_REWINDINTERVAL }, { "OptionsEmulatorRewindInterval", ID_OPTIONS_EMULATOR_REWINDINTERVAL },
{ "OptionsSoundOff", ID_OPTIONS_SOUND_OFF }, { "OptionsSoundOff", ID_OPTIONS_SOUND_OFF },
{ "OptionsSoundMute", ID_OPTIONS_SOUND_OFF }, /* mute hax */ { "OptionsSoundMute", ID_OPTIONS_SOUND_MUTE },
{ "OptionsSoundOn", ID_OPTIONS_SOUND_ON }, { "OptionsSoundOn", ID_OPTIONS_SOUND_ON },
{ "OptionsSoundChannel1", ID_OPTIONS_SOUND_CHANNEL1 }, { "OptionsSoundChannel1", ID_OPTIONS_SOUND_CHANNEL1 },
{ "OptionsSoundChannel2", ID_OPTIONS_SOUND_CHANNEL2 }, { "OptionsSoundChannel2", ID_OPTIONS_SOUND_CHANNEL2 },
@ -174,6 +177,7 @@ struct {
{ "OptionsFilterSuper2xSaI", ID_OPTIONS_FILTER_SUPER2XSAI }, { "OptionsFilterSuper2xSaI", ID_OPTIONS_FILTER_SUPER2XSAI },
{ "OptionsFilterSuperEagle", ID_OPTIONS_FILTER_SUPEREAGLE }, { "OptionsFilterSuperEagle", ID_OPTIONS_FILTER_SUPEREAGLE },
{ "OptionsFilterPixelate", ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL }, { "OptionsFilterPixelate", ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL },
{ "OptionsFilterMotionBlur", ID_OPTIONS_FILTER16BIT_MOTIONBLUREXPERIMENTAL },
{ "OptionsFilterAdMameScale2x", ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X }, { "OptionsFilterAdMameScale2x", ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X },
{ "OptionsFilterSimple2x", ID_OPTIONS_FILTER16BIT_SIMPLE2X }, { "OptionsFilterSimple2x", ID_OPTIONS_FILTER16BIT_SIMPLE2X },
{ "OptionsFilterBilinear", ID_OPTIONS_FILTER_BILINEAR }, { "OptionsFilterBilinear", ID_OPTIONS_FILTER_BILINEAR },
@ -224,7 +228,8 @@ struct {
{ "ToolsCustomize", ID_TOOLS_CUSTOMIZE }, { "ToolsCustomize", ID_TOOLS_CUSTOMIZE },
{ "HelpBugReport", ID_HELP_BUGREPORT }, { "HelpBugReport", ID_HELP_BUGREPORT },
{ "HelpFAQ", ID_HELP_FAQ }, { "HelpFAQ", ID_HELP_FAQ },
{ "HelpAbout", ID_HELP_ABOUT } { "HelpAbout", ID_HELP_ABOUT },
{ "SystemMinimize", ID_SYSTEM_MINIMIZE }
}; };
bool winAccelGetID(const char *command, WORD& id) bool winAccelGetID(const char *command, WORD& id)

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,6 @@
#define DIRECTDRAW_VERSION 0x0700 #define DIRECTDRAW_VERSION 0x0700
#include <ddraw.h> #include <ddraw.h>
#include <mmsystem.h>
#include "../System.h" #include "../System.h"
#include "../gb/gbGlobals.h" #include "../gb/gbGlobals.h"
#include "../GBA.h" #include "../GBA.h"
@ -33,7 +31,9 @@
#include "VBA.h" #include "VBA.h"
#include "MainWnd.h" #include "MainWnd.h"
#include "Reg.h" #include "Reg.h"
#include "..\..\res\resource.h" #include "resource.h"
#include "Display.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -58,18 +58,7 @@ private:
int height; int height;
bool failed; bool failed;
volatile unsigned wait_lastscanline;
volatile unsigned wait_screenheight;
volatile unsigned wait_maxheight;
volatile unsigned wait_firstline;
HANDLE wait_event;
UINT wait_timerres;
UINT wait_timerid;
bool initializeOffscreen(int w, int h); bool initializeOffscreen(int w, int h);
bool StartTimer();
void StopTimer();
static void CALLBACK g_timer_proc( UINT id, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 );
public: public:
DirectDrawDisplay(); DirectDrawDisplay();
virtual ~DirectDrawDisplay(); virtual ~DirectDrawDisplay();
@ -83,9 +72,8 @@ public:
virtual bool changeRenderSize(int w, int h); virtual bool changeRenderSize(int w, int h);
virtual DISPLAY_TYPE getType() { return DIRECT_DRAW; }; virtual DISPLAY_TYPE getType() { return DIRECT_DRAW; };
virtual void setOption(const char *, int) {} virtual void setOption(const char *, int) {}
virtual bool isSkinSupported() { return true; }
virtual int selectFullScreenMode(GUID **); virtual int selectFullScreenMode(GUID **);
void timer_proc( UINT id, UINT msg, DWORD_PTR dw1, DWORD_PTR dw2 );
}; };
static HRESULT WINAPI checkModesAvailable(LPDDSURFACEDESC2 surf, LPVOID lpContext) static HRESULT WINAPI checkModesAvailable(LPDDSURFACEDESC2 surf, LPVOID lpContext)
@ -144,10 +132,6 @@ DirectDrawDisplay::DirectDrawDisplay()
width = 0; width = 0;
height = 0; height = 0;
failed = false; failed = false;
wait_screenheight = 0;
wait_event = 0;
wait_timerres = 0;
wait_timerid = 0;
} }
DirectDrawDisplay::~DirectDrawDisplay() DirectDrawDisplay::~DirectDrawDisplay()
@ -158,15 +142,6 @@ DirectDrawDisplay::~DirectDrawDisplay()
void DirectDrawDisplay::cleanup() void DirectDrawDisplay::cleanup()
{ {
if(pDirectDraw != NULL) { if(pDirectDraw != NULL) {
if ( wait_timerid ) {
StopTimer();
}
if ( wait_event ) {
CloseHandle( wait_event );
wait_event = 0;
}
if(ddsClipper != NULL) { if(ddsClipper != NULL) {
ddsClipper->Release(); ddsClipper->Release();
ddsClipper = NULL; ddsClipper = NULL;
@ -192,7 +167,11 @@ void DirectDrawDisplay::cleanup()
} }
if(ddrawDLL != NULL) { if(ddrawDLL != NULL) {
#ifdef _AFXDLL
AfxFreeLibrary( ddrawDLL );
#else
FreeLibrary( ddrawDLL ); FreeLibrary( ddrawDLL );
#endif
ddrawDLL = NULL; ddrawDLL = NULL;
} }
width = 0; width = 0;
@ -228,13 +207,13 @@ bool DirectDrawDisplay::initialize()
case VIDEO_1280x1024: case VIDEO_1280x1024:
case VIDEO_OTHER: case VIDEO_OTHER:
{ {
float scaleX = ((float)theApp.fsWidth / (float)theApp.sizeX); int scaleX = (theApp.fsWidth / theApp.sizeX);
float scaleY = ((float)theApp.fsHeight / (float)theApp.sizeY); int scaleY = (theApp.fsHeight / theApp.sizeY);
float min = scaleX < scaleY ? scaleX : scaleY; int min = scaleX < scaleY ? scaleX : scaleY;
if(theApp.fsMaxScale) if(theApp.fsMaxScale)
min = min > theApp.fsMaxScale ? theApp.fsMaxScale : min; min = min > theApp.fsMaxScale ? theApp.fsMaxScale : min;
theApp.surfaceSizeX = (int)(theApp.sizeX * min); theApp.surfaceSizeX = theApp.sizeX * min;
theApp.surfaceSizeY = (int)(theApp.sizeY * min); theApp.surfaceSizeY = theApp.sizeY * min;
if(theApp.fullScreenStretch) { if(theApp.fullScreenStretch) {
theApp.surfaceSizeX = theApp.fsWidth; theApp.surfaceSizeX = theApp.fsWidth;
theApp.surfaceSizeY = theApp.fsHeight; theApp.surfaceSizeY = theApp.fsHeight;
@ -306,7 +285,12 @@ bool DirectDrawDisplay::initialize()
if(theApp.pVideoDriverGUID) if(theApp.pVideoDriverGUID)
guid = theApp.pVideoDriverGUID; guid = theApp.pVideoDriverGUID;
ddrawDLL = LoadLibrary("DDRAW.DLL"); #ifdef _AFXDLL
ddrawDLL = AfxLoadLibrary("ddraw.dll");
#else
ddrawDLL = LoadLibrary( _T("ddraw.dll") );
#endif
HRESULT (WINAPI *DDrawCreateEx)(GUID *,LPVOID *,REFIID,IUnknown *); HRESULT (WINAPI *DDrawCreateEx)(GUID *,LPVOID *,REFIID,IUnknown *);
if(ddrawDLL != NULL) { if(ddrawDLL != NULL) {
DDrawCreateEx = (HRESULT (WINAPI *)(GUID *,LPVOID *,REFIID,IUnknown *)) DDrawCreateEx = (HRESULT (WINAPI *)(GUID *,LPVOID *,REFIID,IUnknown *))
@ -459,12 +443,6 @@ bool DirectDrawDisplay::initialize()
} }
// } // }
wait_event = CreateEvent( NULL, FALSE, FALSE, NULL );
if ( ! StartTimer() ) {
return FALSE;
}
DDPIXELFORMAT px; DDPIXELFORMAT px;
px.dwSize = sizeof(px); px.dwSize = sizeof(px);
@ -633,7 +611,7 @@ bool DirectDrawDisplay::initializeOffscreen(int w, int h)
winlog("B shift: %d\n", systemBlueShift); winlog("B shift: %d\n", systemBlueShift);
} }
utilUpdateSystemColorMaps(theApp.filterLCD); utilUpdateSystemColorMaps();
width = w; width = w;
height = h; height = h;
return true; return true;
@ -671,6 +649,7 @@ void DirectDrawDisplay::checkFullScreen()
void DirectDrawDisplay::render() void DirectDrawDisplay::render()
{ {
HRESULT hret; HRESULT hret;
unsigned int nBytesPerPixel = systemColorDepth>>3;
if(pDirectDraw == NULL || if(pDirectDraw == NULL ||
ddsOffscreen == NULL || ddsOffscreen == NULL ||
@ -743,62 +722,9 @@ void DirectDrawDisplay::render()
copyY = 144; copyY = 144;
} }
} }
// MMX doesn't seem to be faster to copy the data copyImage( pix, ddsDesc.lpSurface, copyX, copyY, ddsDesc.lPitch, systemColorDepth );
__asm {
mov eax, copyX;
mov ebx, copyY;
mov esi, pix;
mov edi, ddsDesc.lpSurface;
mov edx, ddsDesc.lPitch;
cmp systemColorDepth, 16;
jnz gbaOtherColor;
sub edx, eax;
sub edx, eax;
lea esi,[esi+2*eax+4];
shr eax, 1;
gbaLoop16bit:
mov ecx, eax;
repz movsd;
inc esi;
inc esi;
inc esi;
inc esi;
add edi, edx;
dec ebx;
jnz gbaLoop16bit;
jmp gbaLoopEnd;
gbaOtherColor:
cmp systemColorDepth, 32;
jnz gbaOtherColor2;
sub edx, eax;
sub edx, eax;
sub edx, eax;
sub edx, eax;
lea esi, [esi+4*eax+4];
gbaLoop32bit:
mov ecx, eax;
repz movsd;
add esi, 4;
add edi, edx;
dec ebx;
jnz gbaLoop32bit;
jmp gbaLoopEnd;
gbaOtherColor2:
lea eax, [eax+2*eax];
sub edx, eax;
gbaLoop24bit:
mov ecx, eax;
shr ecx, 2;
repz movsd;
add edi, edx;
dec ebx;
jnz gbaLoop24bit;
gbaLoopEnd:
} }
} if(theApp.showSpeed && (theApp.videoOption > VIDEO_4X || theApp.skin != NULL)) {
if(theApp.showSpeed && theApp.videoOption > VIDEO_4X) {
char buffer[30]; char buffer[30];
if(theApp.showSpeed == 1) if(theApp.showSpeed == 1)
sprintf(buffer, "%3d%%", systemSpeed); sprintf(buffer, "%3d%%", systemSpeed);
@ -826,8 +752,7 @@ void DirectDrawDisplay::render()
if(hret == DD_OK) { if(hret == DD_OK) {
if(theApp.vsync && !(theApp.tripleBuffering && theApp.videoOption > VIDEO_4X) && !speedup) { // isn't the Flip() call synced unless a certain flag is passed to it? if(theApp.vsync && !(theApp.tripleBuffering && theApp.videoOption > VIDEO_4X) && !speedup) { // isn't the Flip() call synced unless a certain flag is passed to it?
//hret = pDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0); hret = pDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
WaitForSingleObject( wait_event, 100 );
} }
ddsOffscreen->PageLock(0); ddsOffscreen->PageLock(0);
if(theApp.tripleBuffering && theApp.videoOption > VIDEO_4X) { if(theApp.tripleBuffering && theApp.videoOption > VIDEO_4X) {
@ -865,7 +790,7 @@ void DirectDrawDisplay::render()
SetTextColor(hdc, RGB(255,0,0)); SetTextColor(hdc, RGB(255,0,0));
SetBkMode(hdc,TRANSPARENT); SetBkMode(hdc,TRANSPARENT);
TextOut(hdc, theApp.dest.left+10, theApp.dest.bottom - 20, theApp.screenMessageBuffer, TextOut(hdc, theApp.dest.left+10, theApp.dest.bottom - 20, theApp.screenMessageBuffer,
strlen(theApp.screenMessageBuffer)); (int)_tcslen(theApp.screenMessageBuffer));
ddsPrimary->ReleaseDC(hdc); ddsPrimary->ReleaseDC(hdc);
} else { } else {
theApp.screenMessage = false; theApp.screenMessage = false;
@ -883,74 +808,8 @@ int DirectDrawDisplay::selectFullScreenMode(GUID **pGUID)
return winVideoModeSelect(theApp.m_pMainWnd, pGUID); return winVideoModeSelect(theApp.m_pMainWnd, pGUID);
} }
bool DirectDrawDisplay::StartTimer()
{
MMRESULT result;
TIMECAPS tc;
if ( TIMERR_NOERROR == timeGetDevCaps( & tc, sizeof( TIMECAPS ) ) ) {
wait_timerres = min( max( tc.wPeriodMin, 1 ), tc.wPeriodMax );
timeBeginPeriod( wait_timerres );
} else {
return false;
}
result = timeSetEvent( wait_timerres, wait_timerres, & DirectDrawDisplay::g_timer_proc, ( DWORD_PTR ) this, TIME_PERIODIC );
if (NULL != result) {
wait_timerid = (UINT)result;
return true;
}
return false;
}
void DirectDrawDisplay::StopTimer()
{
MMRESULT result;
result = timeKillEvent( wait_timerid );
if ( TIMERR_NOERROR == result ) {
wait_timerid = 0;
}
if ( 0 != wait_timerres ) {
timeEndPeriod( wait_timerres );
wait_timerres = 0;
}
}
void CALLBACK DirectDrawDisplay::g_timer_proc( UINT id, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 )
{
DirectDrawDisplay * p_this = reinterpret_cast< DirectDrawDisplay * >( dwUser );
if ( p_this ) {
p_this->timer_proc( id, msg, dw1, dw2 );
}
}
void DirectDrawDisplay::timer_proc( UINT id, UINT msg, DWORD_PTR dw1, DWORD_PTR dw2 )
{
DWORD scanline;
if ( pDirectDraw->GetScanLine( & scanline ) == DD_OK ) {
unsigned height = GetSystemMetrics( SM_CYSCREEN );
if ( wait_screenheight != height ) {
wait_screenheight = height;
wait_maxheight = height;
}
if ( scanline >= wait_maxheight ) wait_maxheight = scanline + 1;
scanline = ( scanline + wait_maxheight - min( theApp.dest.bottom, wait_screenheight ) ) % wait_maxheight;
if ( scanline < wait_lastscanline ) {
PulseEvent( wait_event );
}
wait_lastscanline = scanline;
}
}
IDisplay *newDirectDrawDisplay() IDisplay *newDirectDrawDisplay()
{ {
return new DirectDrawDisplay(); return new DirectDrawDisplay();
} }

View File

@ -1,28 +1,36 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify /* VisualBoyAdvance S - GB & GBA emulator
// it under the terms of the GNU General Public License as published by Copyright (C) 2006 Spacy
// the Free Software Foundation; either version 2, or(at your option)
// any later version. Original VBA Credits:
// Copyright (C) 1999-2003 Forgotten
// This program is distributed in the hope that it will be useful, Copyright (C) 2004-2006 VBA development team
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the This program is free software; you can redistribute it and/or modify
// GNU General Public License for more details. it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// You should have received a copy of the GNU General Public License (at your option) any later version.
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 "stdafx.h" #include "stdafx.h"
#include "VBA.h"
#include "Input.h"
#include "Reg.h" #include "Reg.h"
#include "WinResUtil.h" #include "WinResUtil.h"
#include "Input.h"
#define DIRECTINPUT_VERSION 0x0500 #define DIRECTINPUT_VERSION 0x0800
#include <dinput.h> #include <Dinput.h>
#pragma comment(lib, "Dinput8")
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -39,9 +47,6 @@ extern void winlog(const char *msg,...);
#define POV_LEFT 8 #define POV_LEFT 8
class DirectInput : public Input { class DirectInput : public Input {
private:
HINSTANCE dinputDLL;
public: public:
virtual void checkDevices(); virtual void checkDevices();
DirectInput(); DirectInput();
@ -50,7 +55,7 @@ public:
virtual bool initialize(); virtual bool initialize();
virtual bool readDevices(); virtual bool readDevices();
virtual u32 readDevice(int which); virtual u32 readDevice(int which);
virtual CString getKeyName(int key); virtual CString getKeyName(LONG_PTR key);
virtual void checkKeys(); virtual void checkKeys();
virtual void checkMotionKeys(); virtual void checkMotionKeys();
virtual void activate(); virtual void activate();
@ -59,7 +64,7 @@ public:
}; };
struct deviceInfo { struct deviceInfo {
LPDIRECTINPUTDEVICE device; LPDIRECTINPUTDEVICE8 device;
BOOL isPolled; BOOL isPolled;
int nButtons; int nButtons;
int nAxes; int nAxes;
@ -81,15 +86,13 @@ struct deviceInfo {
static deviceInfo *currentDevice = NULL; static deviceInfo *currentDevice = NULL;
static int numDevices = 1; static int numDevices = 1;
static deviceInfo *pDevices = NULL; static deviceInfo *pDevices = NULL;
static LPDIRECTINPUT pDirectInput = NULL; static LPDIRECTINPUT8 pDirectInput = NULL;
static int joyDebug = 0;
static int axisNumber = 0; static int axisNumber = 0;
//KeyList joypad[JOYPADS * KEYS_PER_PAD + MOTION_KEYS];
USHORT defvalues[JOYPADS * KEYS_PER_PAD + MOTION_KEYS] = LONG_PTR defvalues[JOYPADS * KEYS_PER_PAD + MOTION_KEYS] =
{ {
DIK_LEFT, DIK_RIGHT, DIK_LEFT, DIK_RIGHT,
DIK_UP, DIK_DOWN, DIK_UP, DIK_DOWN,
@ -131,24 +134,24 @@ void winReadKeys()
{ {
for(int i = 0; i < JOYPADS; i++) { for(int i = 0; i < JOYPADS; i++) {
winReadKey("Left", i, joypad[JOYPAD(i,KEY_LEFT)]); winReadKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
winReadKey("Right", i, joypad[JOYPAD(i, KEY_RIGHT)]); winReadKey("Right", i, theApp.input->joypaddata[JOYPAD(i, KEY_RIGHT)]);
winReadKey("Up", i, joypad[JOYPAD(i,KEY_UP)]); winReadKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
winReadKey("Down", i, joypad[JOYPAD(i,KEY_DOWN)]); winReadKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
winReadKey("A", i, joypad[JOYPAD(i,KEY_BUTTON_A)]); winReadKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
winReadKey("B", i, joypad[JOYPAD(i,KEY_BUTTON_B)]); winReadKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
winReadKey("L", i, joypad[JOYPAD(i,KEY_BUTTON_L)]); winReadKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
winReadKey("R", i, joypad[JOYPAD(i,KEY_BUTTON_R)]); winReadKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
winReadKey("Start", i, joypad[JOYPAD(i,KEY_BUTTON_START)]); winReadKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
winReadKey("Select", i, joypad[JOYPAD(i,KEY_BUTTON_SELECT)]); winReadKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
winReadKey("Speed", i, joypad[JOYPAD(i,KEY_BUTTON_SPEED)]); winReadKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
winReadKey("Capture", i, joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)]); winReadKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winReadKey("GS", i, joypad[JOYPAD(i,KEY_BUTTON_GS)]); winReadKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
} }
winReadKey("Motion_Left", joypad[MOTION(KEY_LEFT)]); winReadKey("Motion_Left", theApp.input->joypaddata[MOTION(KEY_LEFT)]);
winReadKey("Motion_Right", joypad[MOTION(KEY_RIGHT)]); winReadKey("Motion_Right", theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
winReadKey("Motion_Up", joypad[MOTION(KEY_UP)]); winReadKey("Motion_Up", theApp.input->joypaddata[MOTION(KEY_UP)]);
winReadKey("Motion_Down", joypad[MOTION(KEY_DOWN)]); winReadKey("Motion_Down", theApp.input->joypaddata[MOTION(KEY_DOWN)]);
} }
void winSaveKey(char *name, KeyList& value) void winSaveKey(char *name, KeyList& value)
@ -178,30 +181,30 @@ static void winSaveKey(char *name, int num, KeyList& value)
void winSaveKeys() void winSaveKeys()
{ {
for(int i = 0; i < JOYPADS; i++) { for(int i = 0; i < JOYPADS; i++) {
winSaveKey("Left", i, joypad[JOYPAD(i,KEY_LEFT)]); winSaveKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
winSaveKey("Right", i, joypad[JOYPAD(i,KEY_RIGHT)]); winSaveKey("Right", i, theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]);
winSaveKey("Up", i, joypad[JOYPAD(i,KEY_UP)]); winSaveKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
winSaveKey("Speed", i, joypad[JOYPAD(i,KEY_BUTTON_SPEED)]); winSaveKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
winSaveKey("Capture", i, joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)]); winSaveKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winSaveKey("GS", i, joypad[JOYPAD(i,KEY_BUTTON_GS)]); winSaveKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
winSaveKey("Down", i, joypad[JOYPAD(i,KEY_DOWN)]); winSaveKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
winSaveKey("A", i, joypad[JOYPAD(i,KEY_BUTTON_A)]); winSaveKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
winSaveKey("B", i, joypad[JOYPAD(i,KEY_BUTTON_B)]); winSaveKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
winSaveKey("L", i, joypad[JOYPAD(i,KEY_BUTTON_L)]); winSaveKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
winSaveKey("R", i, joypad[JOYPAD(i,KEY_BUTTON_R)]); winSaveKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
winSaveKey("Start", i, joypad[JOYPAD(i,KEY_BUTTON_START)]); winSaveKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
winSaveKey("Select", i, joypad[JOYPAD(i,KEY_BUTTON_SELECT)]); winSaveKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
} }
regSetDwordValue("joyVersion", 1); regSetDwordValue("joyVersion", 1);
winSaveKey("Motion_Left", winSaveKey("Motion_Left",
joypad[MOTION(KEY_LEFT)]); theApp.input->joypaddata[MOTION(KEY_LEFT)]);
winSaveKey("Motion_Right", winSaveKey("Motion_Right",
joypad[MOTION(KEY_RIGHT)]); theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
winSaveKey("Motion_Up", winSaveKey("Motion_Up",
joypad[MOTION(KEY_UP)]); theApp.input->joypaddata[MOTION(KEY_UP)]);
winSaveKey("Motion_Down", winSaveKey("Motion_Down",
joypad[MOTION(KEY_DOWN)]); theApp.input->joypaddata[MOTION(KEY_DOWN)]);
} }
static BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, static BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
@ -286,15 +289,9 @@ static BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE pInst,
pDevices[numDevices].axis[i].negative = 0x4000; pDevices[numDevices].axis[i].negative = 0x4000;
pDevices[numDevices].axis[i].positive = 0xc000; pDevices[numDevices].axis[i].positive = 0xc000;
} }
} else if(joyDebug)
winlog("Failed to get device capabilities %08x\n", hRet);
if(joyDebug) {
// don't translate. debug only
winlog("******************************\n");
winlog("Joystick %2d name : %s\n", numDevices, pInst->tszProductName);
} }
numDevices++; numDevices++;
@ -327,17 +324,17 @@ static int getPovState(DWORD value)
static void checkKeys() static void checkKeys()
{ {
int dev = 0; LONG_PTR dev = 0;
int i; int i;
for(i = 0; i < (sizeof(joypad) / sizeof(joypad[0])); i++) for(i = 0; i < (sizeof(theApp.input->joypaddata) / sizeof(theApp.input->joypaddata[0])); i++)
{ {
if (joypad[i].IsEmpty() && defvalues[i]) if (theApp.input->joypaddata[i].IsEmpty() && defvalues[i])
joypad[i].AddTail(defvalues[i]); theApp.input->joypaddata[i].AddTail(defvalues[i]);
POSITION p = joypad[i].GetHeadPosition(); POSITION p = theApp.input->joypaddata[i].GetHeadPosition();
while(p!=NULL) while(p!=NULL)
{ {
USHORT k = joypad[i].GetNext(p); LONG_PTR k = theApp.input->joypaddata[i].GetNext(p);
if (k > 0 && DEVICEOF(k) < numDevices) if (k > 0 && DEVICEOF(k) < numDevices)
pDevices[DEVICEOF(k)].needed = true; pDevices[DEVICEOF(k)].needed = true;
} }
@ -349,10 +346,6 @@ static void checkKeys()
static bool readKeyboard() static bool readKeyboard()
{ {
if (pDevices[0].needed) { if (pDevices[0].needed) {
if (!theApp.dinputKeyFocus) {
memset(pDevices[0].data, 0, 256);
return true;
}
HRESULT hret = pDevices[0].device-> HRESULT hret = pDevices[0].device->
GetDeviceState(256, GetDeviceState(256,
(LPVOID)pDevices[0].data); (LPVOID)pDevices[0].data);
@ -401,10 +394,18 @@ static bool readJoystick(int joy)
static void checkKeyboard() static void checkKeyboard()
{ {
// mham fix. Patch #1378104
UCHAR keystate[256];
HRESULT hret = pDevices[0].device->Acquire(); HRESULT hret = pDevices[0].device->Acquire();
if (pDevices[0].first) {
pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data);
pDevices[0].first = FALSE;
return;
}
hret = pDevices[0].device-> hret = pDevices[0].device->
GetDeviceState(256, GetDeviceState(256, (LPVOID)keystate);
(LPVOID)pDevices[0].data);
if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) { if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) {
return; return;
@ -412,12 +413,14 @@ static void checkKeyboard()
if (hret == DI_OK) { if (hret == DI_OK) {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
if(KEYDOWN(pDevices[0].data, i)) { if (keystate[i] == pDevices[0].data[i]) continue;
if (KEYDOWN(keystate, i)) {
SendMessage(GetFocus(), JOYCONFIG_MESSAGE,0,i); SendMessage(GetFocus(), JOYCONFIG_MESSAGE,0,i);
break; break;
} }
} }
} }
memcpy(pDevices[0].data, keystate, sizeof(UCHAR) * 256);
} }
static void checkJoypads() static void checkJoypads()
@ -522,16 +525,17 @@ static void checkJoypads()
} }
} }
BOOL checkKey(int key) BOOL checkKey(LONG_PTR key)
{ {
int dev = DEVICEOF(key); LONG_PTR dev = (key >> 8);
int k = KEYOF(key);
LONG_PTR k = (key & 255);
if (dev == 0) { if (dev == 0) {
return KEYDOWN(pDevices[0].data,k); return KEYDOWN(pDevices[0].data,k);
} else { } else {
if (k < 16) { if (k < 16) {
int axis = k >> 1; LONG_PTR axis = k >> 1;
LONG value = pDevices[dev].axis[axis].center; LONG value = pDevices[dev].axis[axis].center;
switch (pDevices[dev].axis[axis].offset) { switch (pDevices[dev].axis[axis].offset) {
case DIJOFS_X: case DIJOFS_X:
@ -564,7 +568,7 @@ BOOL checkKey(int key)
return value > pDevices[dev].axis[axis].positive; return value > pDevices[dev].axis[axis].positive;
return value < pDevices[dev].axis[axis].negative; return value < pDevices[dev].axis[axis].negative;
} else if (k < 48) { } else if (k < 48) {
int hat = (k >> 2) & 3; LONG_PTR hat = (k >> 2) & 3;
int state = getPovState(pDevices[dev].state.rgdwPOV[hat]); int state = getPovState(pDevices[dev].state.rgdwPOV[hat]);
BOOL res = FALSE; BOOL res = FALSE;
switch (k & 3) { switch (k & 3) {
@ -602,9 +606,7 @@ BOOL checkKey(KeyList &k)
} }
DirectInput::DirectInput() DirectInput::DirectInput()
{ {}
dinputDLL = NULL;
}
DirectInput::~DirectInput() DirectInput::~DirectInput()
{ {
@ -625,44 +627,29 @@ DirectInput::~DirectInput()
pDirectInput->Release(); pDirectInput->Release();
pDirectInput = NULL; pDirectInput = NULL;
} }
}
if(dinputDLL) {
FreeLibrary(dinputDLL);
dinputDLL = NULL;
}
}
bool DirectInput::initialize() bool DirectInput::initialize()
{ {
joyDebug = GetPrivateProfileInt("config",
"joyDebug",
0,
"VBA.ini");
dinputDLL = LoadLibrary("DINPUT.DLL");
HRESULT (WINAPI *DInputCreate)(HINSTANCE,DWORD,LPDIRECTINPUT *,IUnknown *);
if(dinputDLL != NULL) {
DInputCreate = (HRESULT (WINAPI *)(HINSTANCE,DWORD,LPDIRECTINPUT *,IUnknown *))
GetProcAddress(dinputDLL, "DirectInputCreateA");
if(DInputCreate == NULL) { HRESULT hr;
directXMessage("DirectInputCreateA");
return false;
}
} else {
directXMessage("DINPUT.DLL");
return false;
}
HRESULT hret = DInputCreate(AfxGetInstanceHandle(), hr = DirectInput8Create(
AfxGetInstanceHandle(),
DIRECTINPUT_VERSION, DIRECTINPUT_VERSION,
&pDirectInput, IID_IDirectInput8,
(LPVOID*)&pDirectInput,
NULL ); NULL );
if(hret != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_CREATE), hret); if ( hr != DI_OK ) {
return false; return false;
} }
hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK,
hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
DIEnumDevicesCallback2, DIEnumDevicesCallback2,
NULL, NULL,
DIEDFL_ATTACHEDONLY); DIEDFL_ATTACHEDONLY);
@ -671,68 +658,49 @@ bool DirectInput::initialize()
pDevices = (deviceInfo *)calloc(numDevices, sizeof(deviceInfo)); pDevices = (deviceInfo *)calloc(numDevices, sizeof(deviceInfo));
hret = pDirectInput->CreateDevice(GUID_SysKeyboard,&pDevices[0].device,NULL); hr = pDirectInput->CreateDevice(GUID_SysKeyboard,&pDevices[0].device,NULL);
pDevices[0].isPolled = false; pDevices[0].isPolled = false;
pDevices[0].needed = true; pDevices[0].needed = true;
pDevices[0].first = true;
if(hret != DI_OK) { if (hr != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_CREATEDEVICE), hret);
return false; return false;
} }
numDevices = 1; numDevices = 1;
hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK, hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
DIEnumDevicesCallback, DIEnumDevicesCallback,
NULL, NULL,
DIEDFL_ATTACHEDONLY); DIEDFL_ATTACHEDONLY);
// hret = pDevices[0].device->SetCooperativeLevel(hWindow,
// DISCL_FOREGROUND|
// DISCL_NONEXCLUSIVE);
if(hret != DI_OK) { if (hr != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_LEVEL), hret);
return false; return false;
} }
hret = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard); hr = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard);
if(hret != DI_OK) { if (hr != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_DATAFORMAT), hret);
return false; return false;
} }
for(int i = 1; i < numDevices; i++) { int i;
for (i = 1; i < numDevices; i++) {
pDevices[i].device->SetDataFormat(&c_dfDIJoystick); pDevices[i].device->SetDataFormat(&c_dfDIJoystick);
pDevices[i].needed = false; pDevices[i].needed = false;
pDevices[i].first = true;
currentDevice = &pDevices[i]; currentDevice = &pDevices[i];
axisNumber = 0; axisNumber = 0;
currentDevice->device->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS); currentDevice->device->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS);
currentDevice->device->EnumObjects(EnumPovsCallback, NULL, DIDFT_POV); currentDevice->device->EnumObjects(EnumPovsCallback, NULL, DIDFT_POV);
if(joyDebug) {
// don't translate. debug only
winlog("Joystick %2d polled : %d\n", i, currentDevice->isPolled);
winlog("Joystick %2d buttons : %d\n", i, currentDevice->nButtons);
winlog("Joystick %2d povs : %d\n", i, currentDevice->nPovs);
winlog("Joystick %2d axes : %d\n", i, currentDevice->nAxes);
for(int j = 0; j < currentDevice->nAxes; j++) {
winlog("Axis %2d offset : %08lx\n", j, currentDevice->axis[j].
offset);
winlog("Axis %2d center : %08lx\n", j, currentDevice->axis[j].
center);
winlog("Axis %2d negative : %08lx\n", j, currentDevice->axis[j].
negative);
winlog("Axis %2d positive : %08lx\n", j, currentDevice->axis[j].
positive);
}
}
currentDevice = NULL; currentDevice = NULL;
} }
if (1) for(int i = 0; i < numDevices; i++) for (i = 0; i < numDevices; i++)
pDevices[i].device->Acquire(); pDevices[i].device->Acquire();
return true; return true;
@ -759,28 +727,28 @@ u32 DirectInput::readDevice(int which)
if(which >= 0 && which <= 3) if(which >= 0 && which <= 3)
i = which; i = which;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_A)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]))
res |= 1; res |= 1;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_B)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]))
res |= 2; res |= 2;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_SELECT)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]))
res |= 4; res |= 4;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_START)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]))
res |= 8; res |= 8;
if(checkKey(joypad[JOYPAD(i,KEY_RIGHT)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]))
res |= 16; res |= 16;
if(checkKey(joypad[JOYPAD(i,KEY_LEFT)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]))
res |= 32; res |= 32;
if(checkKey(joypad[JOYPAD(i,KEY_UP)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_UP)]))
res |= 64; res |= 64;
if(checkKey(joypad[JOYPAD(i,KEY_DOWN)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]))
res |= 128; res |= 128;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_R)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]))
res |= 256; res |= 256;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_L)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]))
res |= 512; res |= 512;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_GS)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]))
res |= 4096; res |= 4096;
if(theApp.autoFire) { if(theApp.autoFire) {
@ -813,18 +781,18 @@ u32 DirectInput::readDevice(int which)
res = theApp.movieLastJoypad; res = theApp.movieLastJoypad;
} }
// we don't record speed up or screen capture buttons // we don't record speed up or screen capture buttons
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_SPEED)]) || theApp.speedupToggle) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]) || theApp.speedupToggle)
res |= 1024; res |= 1024;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)])) if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]))
res |= 2048; res |= 2048;
return res; return res;
} }
CString DirectInput::getKeyName(int key) CString DirectInput::getKeyName(LONG_PTR key)
{ {
int d = (key >> 8); LONG_PTR d = (key >> 8);
int k = key & 255; LONG_PTR k = key & 255;
DIDEVICEOBJECTINSTANCE di; DIDEVICEOBJECTINSTANCE di;
@ -835,7 +803,7 @@ CString DirectInput::getKeyName(int key)
CString winBuffer = winResLoadString(IDS_ERROR); CString winBuffer = winResLoadString(IDS_ERROR);
if (d == 0) { if (d == 0) {
pDevices[0].device->GetObjectInfo(&di,key,DIPH_BYOFFSET); pDevices[0].device->GetObjectInfo( &di, (DWORD)key, DIPH_BYOFFSET );
winBuffer = di.tszName; winBuffer = di.tszName;
} else { } else {
if (k < 16) { if (k < 16) {
@ -864,12 +832,12 @@ CString DirectInput::getKeyName(int key)
winBuffer.Format("Joy %d %s -", d, di.tszName); winBuffer.Format("Joy %d %s -", d, di.tszName);
} }
} else if (k < 48) { } else if (k < 48) {
int hat = (k >> 2) & 3; LONG_PTR hat = (k >> 2) & 3;
pDevices[d].device->GetObjectInfo(&di, pDevices[d].device->GetObjectInfo(&di,
DIJOFS_POV(hat), (DWORD)DIJOFS_POV(hat),
DIPH_BYOFFSET); DIPH_BYOFFSET);
char *dir = "up"; char *dir = "up";
int dd = k & 3; LONG_PTR dd = k & 3;
if (dd == 1) if (dd == 1)
dir = "down"; dir = "down";
else if (dd == 2) else if (dd == 2)
@ -879,7 +847,7 @@ CString DirectInput::getKeyName(int key)
winBuffer.Format("Joy %d %s %s", d, di.tszName, dir); winBuffer.Format("Joy %d %s %s", d, di.tszName, dir);
} else { } else {
pDevices[d].device->GetObjectInfo(&di, pDevices[d].device->GetObjectInfo(&di,
DIJOFS_BUTTON(k-128), (DWORD)DIJOFS_BUTTON(k-128),
DIPH_BYOFFSET); DIPH_BYOFFSET);
winBuffer.Format(winResLoadString(IDS_JOY_BUTTON),d,di.tszName); winBuffer.Format(winResLoadString(IDS_JOY_BUTTON),d,di.tszName);
} }
@ -895,13 +863,13 @@ void DirectInput::checkKeys()
void DirectInput::checkMotionKeys() void DirectInput::checkMotionKeys()
{ {
if(checkKey(joypad[MOTION(KEY_LEFT)])) { if(checkKey(theApp.input->joypaddata[MOTION(KEY_LEFT)])) {
theApp.sensorX += 3; theApp.sensorX += 3;
if(theApp.sensorX > 2197) if(theApp.sensorX > 2197)
theApp.sensorX = 2197; theApp.sensorX = 2197;
if(theApp.sensorX < 2047) if(theApp.sensorX < 2047)
theApp.sensorX = 2057; theApp.sensorX = 2057;
} else if(checkKey(joypad[MOTION(KEY_RIGHT)])) { } else if(checkKey(theApp.input->joypaddata[MOTION(KEY_RIGHT)])) {
theApp.sensorX -= 3; theApp.sensorX -= 3;
if(theApp.sensorX < 1897) if(theApp.sensorX < 1897)
theApp.sensorX = 1897; theApp.sensorX = 1897;
@ -917,13 +885,13 @@ void DirectInput::checkMotionKeys()
theApp.sensorX = 2047; theApp.sensorX = 2047;
} }
if(checkKey(joypad[MOTION(KEY_UP)])) { if(checkKey(theApp.input->joypaddata[MOTION(KEY_UP)])) {
theApp.sensorY += 3; theApp.sensorY += 3;
if(theApp.sensorY > 2197) if(theApp.sensorY > 2197)
theApp.sensorY = 2197; theApp.sensorY = 2197;
if(theApp.sensorY < 2047) if(theApp.sensorY < 2047)
theApp.sensorY = 2057; theApp.sensorY = 2057;
} else if(checkKey(joypad[MOTION(KEY_DOWN)])) { } else if(checkKey(theApp.input->joypaddata[MOTION(KEY_DOWN)])) {
theApp.sensorY -= 3; theApp.sensorY -= 3;
if(theApp.sensorY < 1897) if(theApp.sensorY < 1897)
theApp.sensorY = 1897; theApp.sensorY = 1897;

View File

@ -1,6 +1,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004-2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2004-2006 VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -16,47 +17,52 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// MFC
#include "stdafx.h" #include "stdafx.h"
#include "VBA.h"
// Tools
#include "AVIWrite.h" #include "AVIWrite.h"
#include "Sound.h"
#include "WavWriter.h" #include "WavWriter.h"
// Internals
#include "../System.h" #include "../System.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
#include "../Sound.h" #include "../Sound.h"
#include <mmreg.h> // DirectSound8
#include <Dsound.h> //DirectSound #include <Dsound.h>
#pragma comment( lib, "Dsound" )
#pragma comment( lib, "Dxguid" )
extern bool soundBufferLow; extern bool soundBufferLow;
class DirectSound : public ISound class DirectSound : public ISound
{ {
private: private:
HINSTANCE dsoundDLL; LPDIRECTSOUND8 pDirectSound; // DirectSound interface
LPDIRECTSOUND pDirectSound; LPDIRECTSOUNDBUFFER dsbPrimary; // Primary DirectSound buffer
LPDIRECTSOUNDBUFFER dsbPrimary; LPDIRECTSOUNDBUFFER dsbSecondary; // Secondary DirectSound buffer
LPDIRECTSOUNDBUFFER dsbSecondary; LPDIRECTSOUNDNOTIFY8 dsbNotify;
LPDIRECTSOUNDNOTIFY dsbNotify;
HANDLE dsbEvent; HANDLE dsbEvent;
WAVEFORMATEX wfx; WAVEFORMATEX wfx; // Primary buffer wave format
public: public:
DirectSound(); DirectSound();
virtual ~DirectSound(); virtual ~DirectSound();
bool init(); bool init(); // initialize the primary and secondary sound buffer
void pause(); void pause(); // pause the secondary sound buffer
void reset(); void reset(); // stop and reset the secondary sound buffer
void resume(); void resume(); // resume the secondary sound buffer
void write(); void write(); // write the emulated sound to the secondary sound buffer
}; };
DirectSound::DirectSound() DirectSound::DirectSound()
{ {
dsoundDLL = NULL; CoInitialize( NULL );
pDirectSound = NULL; pDirectSound = NULL;
dsbPrimary = NULL; dsbPrimary = NULL;
dsbSecondary = NULL; dsbSecondary = NULL;
@ -64,39 +70,40 @@ DirectSound::DirectSound()
dsbEvent = NULL; dsbEvent = NULL;
} }
DirectSound::~DirectSound() DirectSound::~DirectSound()
{ {
if(theApp.aviRecorder != NULL) { if(theApp.aviRecorder) {
delete theApp.aviRecorder; delete theApp.aviRecorder;
theApp.aviRecorder = NULL; theApp.aviRecorder = NULL;
theApp.aviFrameNumber = 0; theApp.aviFrameNumber = 0;
} }
if(theApp.soundRecording) { if(theApp.soundRecording) {
if(theApp.soundRecorder != NULL) { if(theApp.soundRecorder) {
delete theApp.soundRecorder; delete theApp.soundRecorder;
theApp.soundRecorder = NULL; theApp.soundRecorder = NULL;
} }
theApp.soundRecording = false; theApp.soundRecording = false;
} }
if(dsbNotify != NULL) { if(dsbNotify) {
dsbNotify->Release(); dsbNotify->Release();
dsbNotify = NULL; dsbNotify = NULL;
} }
if(dsbEvent != NULL) { if(dsbEvent) {
CloseHandle(dsbEvent); CloseHandle(dsbEvent);
dsbEvent = NULL; dsbEvent = NULL;
} }
if(pDirectSound != NULL) { if(pDirectSound) {
if(dsbPrimary != NULL) { if(dsbPrimary) {
dsbPrimary->Release(); dsbPrimary->Release();
dsbPrimary = NULL; dsbPrimary = NULL;
} }
if(dsbSecondary != NULL) { if(dsbSecondary) {
dsbSecondary->Release(); dsbSecondary->Release();
dsbSecondary = NULL; dsbSecondary = NULL;
} }
@ -105,126 +112,106 @@ DirectSound::~DirectSound()
pDirectSound = NULL; pDirectSound = NULL;
} }
if(dsoundDLL != NULL) { CoUninitialize();
FreeLibrary(dsoundDLL);
dsoundDLL = NULL;
}
} }
bool DirectSound::init() bool DirectSound::init()
{ {
HRESULT hr; HRESULT hr;
DWORD freq;
dsoundDLL = LoadLibrary("dsound.dll");
HRESULT (WINAPI *DSoundCreate)(LPCGUID,LPDIRECTSOUND *,IUnknown *);
if(dsoundDLL != NULL) {
DSoundCreate = (HRESULT (WINAPI *)(LPCGUID,LPDIRECTSOUND *,IUnknown *))
GetProcAddress(dsoundDLL, "DirectSoundCreate8");
if(DSoundCreate == NULL) {
theApp.directXMessage("DirectSoundCreate8");
return false;
}
} else {
theApp.directXMessage("dsound.dll");
return false;
}
if((hr = DSoundCreate(NULL,&pDirectSound,NULL) != DS_OK)) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_CREATE), hr);
systemMessage(IDS_CANNOT_CREATE_DIRECTSOUND,
"Cannot create DirectSound %08x", hr);
pDirectSound = NULL;
dsbSecondary = NULL;
return false;
}
if((hr=pDirectSound->SetCooperativeLevel((HWND)*theApp.m_pMainWnd,
DSSCL_EXCLUSIVE)) != DS_OK) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_LEVEL), hr);
systemMessage(IDS_CANNOT_SETCOOPERATIVELEVEL,
"Cannot SetCooperativeLevel %08x", hr);
return false;
}
DSBUFFERDESC dsbdesc; DSBUFFERDESC dsbdesc;
int i;
// Initialize DirectSound
if( FAILED( hr = DirectSoundCreate8( &DSDEVID_DefaultPlayback, &pDirectSound, NULL ) ) ) {
systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, _T("Cannot create DirectSound %08x"), hr );
pDirectSound = NULL;
return false;
}
if( FAILED( hr = pDirectSound->SetCooperativeLevel( theApp.m_pMainWnd->GetSafeHwnd(), DSSCL_EXCLUSIVE ) ) ) {
systemMessage( IDS_CANNOT_SETCOOPERATIVELEVEL, _T("Cannot SetCooperativeLevel %08x"), hr );
return false;
}
// Create primary sound buffer
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
if( theApp.dsoundDisableHardwareAcceleration ) {
dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
}
if((hr=pDirectSound->CreateSoundBuffer(&dsbdesc, if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) {
&dsbPrimary, systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, _T("Cannot CreateSoundBuffer %08x"), hr);
NULL) != DS_OK)) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_BUFFER),hr);
systemMessage(IDS_CANNOT_CREATESOUNDBUFFER,
"Cannot CreateSoundBuffer %08x", hr);
return false; return false;
} }
// Set primary buffer format switch(soundQuality)
{
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
switch(soundQuality) {
case 2:
wfx.nSamplesPerSec = 22050;
soundBufferLen = 736*2;
soundBufferTotalLen = 7360*2;
break;
case 4: case 4:
wfx.nSamplesPerSec = 11025; freq = 11025;
soundBufferLen = 368*2; break;
soundBufferTotalLen = 3680*2; case 2:
freq = 22050;
break; break;
default: default:
soundQuality = 1; soundQuality = 1;
wfx.nSamplesPerSec = 44100; case 1:
soundBufferLen = 1470*2; freq = 44100;
soundBufferTotalLen = 14700*2; break;
} }
soundBufferLen = freq*2/30;
soundBufferTotalLen = soundBufferLen * 10;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = freq;
wfx.wBitsPerSample = 16; wfx.wBitsPerSample = 16;
wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels; wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
if((hr = dsbPrimary->SetFormat(&wfx)) != DS_OK) { if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_PRIMARY),hr); systemMessage( IDS_CANNOT_SETFORMAT_PRIMARY, _T("CreateSoundBuffer(primary) failed %08x"), hr );
systemMessage(IDS_CANNOT_SETFORMAT_PRIMARY,
"Cannot SetFormat for primary %08x", hr);
return false; return false;
} }
// Create secondary sound buffer
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) ); ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY; dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
if( theApp.dsoundDisableHardwareAcceleration ) {
dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
}
dsbdesc.dwBufferBytes = soundBufferTotalLen; dsbdesc.dwBufferBytes = soundBufferTotalLen;
dsbdesc.lpwfxFormat = &wfx; dsbdesc.lpwfxFormat = &wfx;
if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL)) if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) {
!= DS_OK) { systemMessage( IDS_CANNOT_CREATESOUNDBUFFER, _T("CreateSoundBuffer(secondary) failed %08x"), hr );
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))
!= DS_OK) {
systemMessage(IDS_CANNOT_CREATESOUNDBUFFER_SEC,
"Cannot CreateSoundBuffer secondary %08x", hr);
return false; return false;
} }
if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) {
systemMessage( 0, _T("dsbSecondary->SetCurrentPosition failed %08x"), hr );
return false;
} }
dsbSecondary->SetCurrentPosition(0);
if( !theApp.useOldSync ) { if( !theApp.useOldSync ) {
hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify, if( FAILED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) {
(void **)&dsbNotify);
if(!FAILED(hr)) {
dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
DSBPOSITIONNOTIFY notify[10]; DSBPOSITIONNOTIFY notify[10];
for( i = 0; i < 10; i++ ) {
for(int i = 0; i < 10; i++) {
notify[i].dwOffset = i * soundBufferLen; notify[i].dwOffset = i * soundBufferLen;
notify[i].hEventNotify = dsbEvent; notify[i].hEventNotify = dsbEvent;
} }
if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) { if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) {
dsbNotify->Release(); dsbNotify->Release();
dsbNotify = NULL; dsbNotify = NULL;
@ -234,94 +221,96 @@ bool DirectSound::init()
} }
} }
hr = dsbPrimary->Play(0,0,DSBPLAY_LOOPING);
if(hr != DS_OK) { // Play primary buffer
// errorMessage(myLoadString(IDS_ERROR_SOUND_PLAYPRIM), hr); if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) {
systemMessage(IDS_CANNOT_PLAY_PRIMARY, "Cannot Play primary %08x", hr); systemMessage( IDS_CANNOT_PLAY_PRIMARY, _T("Cannot Play primary %08x"), hr );
return false; return false;
} }
setsystemSoundOn(true); systemSoundOn = true;
return true; return true;
} }
void DirectSound::pause() void DirectSound::pause()
{ {
if(dsbSecondary != NULL) { if( dsbSecondary == NULL ) return;
DWORD status = 0;
DWORD status;
dsbSecondary->GetStatus( &status ); dsbSecondary->GetStatus( &status );
if(status & DSBSTATUS_PLAYING) { if( status & DSBSTATUS_PLAYING ) dsbSecondary->Stop();
dsbSecondary->Stop();
}
}
} }
void DirectSound::reset() void DirectSound::reset()
{ {
if(dsbSecondary) { if( dsbSecondary == NULL ) return;
dsbSecondary->Stop(); dsbSecondary->Stop();
dsbSecondary->SetCurrentPosition( 0 ); dsbSecondary->SetCurrentPosition( 0 );
} }
}
void DirectSound::resume() void DirectSound::resume()
{ {
if(dsbSecondary != NULL) { if( dsbSecondary == NULL ) return;
dsbSecondary->Play( 0, 0, DSBPLAY_LOOPING ); dsbSecondary->Play( 0, 0, DSBPLAY_LOOPING );
} }
}
void DirectSound::write() void DirectSound::write()
{ {
int len = soundBufferLen; if(!pDirectSound) return;
LPVOID lpvPtr1;
DWORD dwBytes1;
LPVOID lpvPtr2; HRESULT hr;
DWORD dwBytes2; DWORD status = 0;
DWORD play = 0;
WAVEFORMATEX format;
LPVOID lpvPtr1;
DWORD dwBytes1 = 0;
LPVOID lpvPtr2;
DWORD dwBytes2 = 0;
if(!pDirectSound)
return;
if( theApp.soundRecording ) { if( theApp.soundRecording ) {
if( dsbSecondary ) { if( dsbSecondary ) {
if(theApp.soundRecorder == NULL) { if( theApp.soundRecorder ) {
theApp.soundRecorder->AddSound( (u8 *)soundFinalWave, soundBufferLen );
} else {
theApp.soundRecorder = new WavWriter; theApp.soundRecorder = new WavWriter;
WAVEFORMATEX format;
dsbSecondary->GetFormat( &format, sizeof(format), NULL ); dsbSecondary->GetFormat( &format, sizeof(format), NULL );
if(theApp.soundRecorder->Open(theApp.soundRecordName)) if( theApp.soundRecorder->Open( theApp.soundRecordName ) ) {
theApp.soundRecorder->SetFormat( &format ); theApp.soundRecorder->SetFormat( &format );
} }
} }
}
}
if(theApp.soundRecorder) {
theApp.soundRecorder->AddSound((u8 *)soundFinalWave, len);
}
}
if( theApp.aviRecording ) { if( theApp.aviRecording ) {
if( theApp.aviRecorder ) { if( theApp.aviRecorder ) {
if( dsbSecondary ) { if( dsbSecondary ) {
if( !theApp.aviRecorder->IsSoundAdded() ) { if( !theApp.aviRecorder->IsSoundAdded() ) {
WAVEFORMATEX format;
dsbSecondary->GetFormat( &format, sizeof(format), NULL ); dsbSecondary->GetFormat( &format, sizeof(format), NULL );
theApp.aviRecorder->SetSoundFormat( &format ); theApp.aviRecorder->SetSoundFormat( &format );
} }
} }
theApp.aviRecorder->AddSound( (const char *)soundFinalWave, soundBufferLen );
theApp.aviRecorder->AddSound((const char *)soundFinalWave, len);
} }
} }
HRESULT hr;
if( !speedup && synchronize && !theApp.throttle ) { if( !speedup && synchronize && !theApp.throttle ) {
DWORD status=0;
hr = dsbSecondary->GetStatus(&status); hr = dsbSecondary->GetStatus(&status);
if(status && DSBSTATUS_PLAYING) { if( status & DSBSTATUS_PLAYING ) {
if( !soundPaused ) { if( !soundPaused ) {
DWORD play;
while( true ) { while( true ) {
dsbSecondary->GetCurrentPosition(&play, NULL); dsbSecondary->GetCurrentPosition(&play, NULL);
int BufferLeft = ((soundNextPosition <= play) ? int BufferLeft = ((soundNextPosition <= play) ?
@ -345,35 +334,49 @@ void DirectSound::write()
setsoundPaused(true); setsoundPaused(true);
} }
} }
// Obtain memory address of write block. This will be in two parts
// if the block wraps around.
hr = dsbSecondary->Lock(soundNextPosition, soundBufferLen, &lpvPtr1,
&dwBytes1, &lpvPtr2, &dwBytes2,
0);
// Obtain memory address of write block.
// This will be in two parts if the block wraps around.
if( DSERR_BUFFERLOST == ( hr = dsbSecondary->Lock(
soundNextPosition,
soundBufferLen,
&lpvPtr1,
&dwBytes1,
&lpvPtr2,
&dwBytes2,
0 ) ) ) {
// If DSERR_BUFFERLOST is returned, restore and retry lock. // If DSERR_BUFFERLOST is returned, restore and retry lock.
if (DSERR_BUFFERLOST == hr) {
dsbSecondary->Restore(); dsbSecondary->Restore();
hr = dsbSecondary->Lock(soundNextPosition, soundBufferLen,&lpvPtr1, hr = dsbSecondary->Lock(
&dwBytes1, &lpvPtr2, &dwBytes2, soundNextPosition,
soundBufferLen,
&lpvPtr1,
&dwBytes1,
&lpvPtr2,
&dwBytes2,
0 ); 0 );
} }
soundNextPosition += soundBufferLen; soundNextPosition += soundBufferLen;
soundNextPosition = soundNextPosition % soundBufferTotalLen; soundNextPosition = soundNextPosition % soundBufferTotalLen;
if SUCCEEDED(hr) { if( SUCCEEDED( hr ) ) {
// Write to pointers. // Write to pointers.
CopyMemory( lpvPtr1, soundFinalWave, dwBytes1 ); CopyMemory( lpvPtr1, soundFinalWave, dwBytes1 );
if (NULL != lpvPtr2) { if ( lpvPtr2 ) {
CopyMemory( lpvPtr2, soundFinalWave + dwBytes1, dwBytes2 ); CopyMemory( lpvPtr2, soundFinalWave + dwBytes1, dwBytes2 );
} }
// Release the data back to DirectSound. // Release the data back to DirectSound.
hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2, hr = dsbSecondary->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 );
dwBytes2); } else {
systemMessage( 0, _T("dsbSecondary->Lock() failed: %08x"), hr );
return;
} }
} }
ISound *newDirectSound() ISound *newDirectSound()
{ {
return new DirectSound(); return new DirectSound();

View File

@ -26,6 +26,7 @@
#include "WinResUtil.h" #include "WinResUtil.h"
#include <shlobj.h> #include <shlobj.h>
#include <shlwapi.h>
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -54,27 +55,21 @@ static int CALLBACK browseCallbackProc(HWND hWnd, UINT msg,
Directories::Directories(CWnd* pParent /*=NULL*/) Directories::Directories(CWnd* pParent /*=NULL*/)
: CDialog(Directories::IDD, pParent) : CDialog(Directories::IDD, pParent)
{ {
//{{AFX_DATA_INIT(Directories)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
} }
void Directories::DoDataExchange(CDataExchange* pDX) void Directories::DoDataExchange(CDataExchange* pDX)
{ {
CDialog::DoDataExchange(pDX); CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(Directories)
DDX_Control(pDX, IDC_SAVE_PATH, m_savePath); DDX_Control(pDX, IDC_SAVE_PATH, m_savePath);
DDX_Control(pDX, IDC_ROM_PATH, m_romPath); DDX_Control(pDX, IDC_ROM_PATH, m_romPath);
DDX_Control(pDX, IDC_GBROM_PATH, m_gbromPath); DDX_Control(pDX, IDC_GBROM_PATH, m_gbromPath);
DDX_Control(pDX, IDC_CAPTURE_PATH, m_capturePath); DDX_Control(pDX, IDC_CAPTURE_PATH, m_capturePath);
DDX_Control(pDX, IDC_BATTERY_PATH, m_batteryPath); DDX_Control(pDX, IDC_BATTERY_PATH, m_batteryPath);
//}}AFX_DATA_MAP
} }
BEGIN_MESSAGE_MAP(Directories, CDialog) BEGIN_MESSAGE_MAP(Directories, CDialog)
//{{AFX_MSG_MAP(Directories)
ON_BN_CLICKED(IDC_BATTERY_DIR, OnBatteryDir) ON_BN_CLICKED(IDC_BATTERY_DIR, OnBatteryDir)
ON_BN_CLICKED(IDC_BATTERY_DIR_RESET, OnBatteryDirReset) ON_BN_CLICKED(IDC_BATTERY_DIR_RESET, OnBatteryDirReset)
ON_BN_CLICKED(IDC_CAPTURE_DIR, OnCaptureDir) ON_BN_CLICKED(IDC_CAPTURE_DIR, OnCaptureDir)
@ -85,7 +80,6 @@ BEGIN_MESSAGE_MAP(Directories, CDialog)
ON_BN_CLICKED(IDC_ROM_DIR_RESET, OnRomDirReset) ON_BN_CLICKED(IDC_ROM_DIR_RESET, OnRomDirReset)
ON_BN_CLICKED(IDC_SAVE_DIR, OnSaveDir) ON_BN_CLICKED(IDC_SAVE_DIR, OnSaveDir)
ON_BN_CLICKED(IDC_SAVE_DIR_RESET, OnSaveDirReset) ON_BN_CLICKED(IDC_SAVE_DIR_RESET, OnSaveDirReset)
//}}AFX_MSG_MAP
END_MESSAGE_MAP() END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -206,22 +200,75 @@ void Directories::OnCancel()
void Directories::OnOK() void Directories::OnOK()
{ {
char baseDir[MAX_PATH+1];
char temp[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
CString buffer; CString buffer;
m_romPath.GetWindowText(buffer); m_romPath.GetWindowText(buffer);
if( !buffer.IsEmpty() ) if( !buffer.IsEmpty() )
regSetStringValue( "romdir", buffer ); regSetStringValue( "romdir", buffer );
if( buffer[0] == '.' ) {
strcpy( temp, baseDir );
strcat( temp, "\\" );
strcat( temp, buffer );
buffer = temp;
}
if( !directoryDoesExist( buffer ) )
SHCreateDirectoryEx( NULL, buffer, NULL );
m_gbromPath.GetWindowText(buffer); m_gbromPath.GetWindowText(buffer);
if( !buffer.IsEmpty() ) if( !buffer.IsEmpty() )
regSetStringValue( "gbromdir", buffer ); regSetStringValue( "gbromdir", buffer );
if( buffer[0] == '.' ) {
strcpy( temp, baseDir );
strcat( temp, "\\" );
strcat( temp, buffer );
buffer = temp;
}
if( !directoryDoesExist( buffer ) )
SHCreateDirectoryEx( NULL, buffer, NULL );
m_batteryPath.GetWindowText(buffer); m_batteryPath.GetWindowText(buffer);
if( !buffer.IsEmpty() ) if( !buffer.IsEmpty() )
regSetStringValue( "batteryDir", buffer ); regSetStringValue( "batteryDir", buffer );
if( buffer[0] == '.' ) {
strcpy( temp, baseDir );
strcat( temp, "\\" );
strcat( temp, buffer );
buffer = temp;
}
if( !directoryDoesExist( buffer ) )
SHCreateDirectoryEx( NULL, buffer, NULL );
m_savePath.GetWindowText(buffer); m_savePath.GetWindowText(buffer);
if( !buffer.IsEmpty() ) if( !buffer.IsEmpty() )
regSetStringValue( "saveDir", buffer ); regSetStringValue( "saveDir", buffer );
if( buffer[0] == '.' ) {
strcpy( temp, baseDir );
strcat( temp, "\\" );
strcat( temp, buffer );
buffer = temp;
}
if( !directoryDoesExist( buffer ) )
SHCreateDirectoryEx( NULL, buffer, NULL );
m_capturePath.GetWindowText(buffer); m_capturePath.GetWindowText(buffer);
if( !buffer.IsEmpty() ) if( !buffer.IsEmpty() )
regSetStringValue( "captureDir", buffer ); regSetStringValue( "captureDir", buffer );
if( buffer[0] == '.' ) {
strcpy( temp, baseDir );
strcat( temp, "\\" );
strcat( temp, buffer );
buffer = temp;
}
if( !directoryDoesExist( buffer ) )
SHCreateDirectoryEx( NULL, buffer, NULL );
EndDialog(TRUE); EndDialog(TRUE);
} }

View File

@ -75,6 +75,23 @@ class Directories : public CDialog
virtual void OnOK(); virtual void OnOK();
//}}AFX_MSG //}}AFX_MSG
DECLARE_MESSAGE_MAP() DECLARE_MESSAGE_MAP()
private:
bool directoryDoesExist(const char *directory)
{ // returns true if the directory does exist
HANDLE hDir;
hDir = CreateFile(
directory,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL );
bool retval = (hDir == INVALID_HANDLE_VALUE) ? false : true;
CloseHandle( hDir );
return retval;
}
}; };
//{{AFX_INSERT_LOCATION}} //{{AFX_INSERT_LOCATION}}

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -118,6 +118,7 @@ void Disassemble::OnAutomatic()
void Disassemble::OnArm() void Disassemble::OnArm()
{ {
mode = 1; mode = 1;
address&=0xfffffffC;
refresh(); refresh();
} }
@ -133,10 +134,16 @@ void Disassemble::OnGo()
CString buffer; CString buffer;
m_address.GetWindowText(buffer); m_address.GetWindowText(buffer);
sscanf(buffer, "%x", &address); sscanf(buffer, "%x", &address);
if (mode==1)
address&=0xfffffffc;
else if (mode==2)
address&=0xfffffffe;
refresh(); refresh();
} }
void Disassemble::OnGopc() void Disassemble::OnGopc()
{
if(rom != NULL)
{ {
if(armState) if(armState)
address = armNextPC - 16; address = armNextPC - 16;
@ -145,8 +152,11 @@ void Disassemble::OnGopc()
refresh(); refresh();
} }
}
void Disassemble::OnNext() void Disassemble::OnNext()
{
if(rom != NULL)
{ {
CPULoop(1); CPULoop(1);
if(armState) { if(armState) {
@ -164,6 +174,7 @@ void Disassemble::OnNext()
} }
refresh(); refresh();
} }
}
void Disassemble::OnRefresh() void Disassemble::OnRefresh()
{ {
@ -173,6 +184,7 @@ void Disassemble::OnRefresh()
void Disassemble::OnThumb() void Disassemble::OnThumb()
{ {
mode = 2; mode = 2;
address&=0xfffffffe;
refresh(); refresh();
} }

View File

@ -17,6 +17,8 @@
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma once
enum DISPLAY_TYPE { enum DISPLAY_TYPE {
GDI = 0, GDI = 0,
DIRECT_DRAW = 1, DIRECT_DRAW = 1,
@ -37,8 +39,10 @@ class IDisplay {
virtual void clear() = 0; virtual void clear() = 0;
virtual bool changeRenderSize(int w, int h) { return true; }; virtual bool changeRenderSize(int w, int h) { return true; };
virtual void resize(int w, int h) {}; virtual void resize(int w, int h) {};
virtual void setOption(const char *option, int value) = 0; virtual void setOption(const char *option, int value) {};
virtual DISPLAY_TYPE getType() = 0; virtual DISPLAY_TYPE getType() = 0;
virtual bool isSkinSupported() { return false; }
virtual int selectFullScreenMode(GUID **) = 0; virtual int selectFullScreenMode(GUID **) = 0;
virtual int selectFullScreenMode2() { return 0; };
}; };
void copyImage( void *source, void *destination, unsigned int width, unsigned int height, unsigned int destinationPitch, unsigned int colorDepth );

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
// FileDlg.cpp: implementation of the FileDlg class. // FileDlg.cpp: implementation of the FileDlg class.
// //
//////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "stdafx.h"
#include <commdlg.h> #include <commdlg.h>
#include <dlgs.h> #include <dlgs.h>
@ -26,7 +26,7 @@
#include "VBA.h" #include "VBA.h"
#include "FileDlg.h" #include "FileDlg.h"
#include "../System.h" #include "../System.h"
#include "..\..\res\resource.h" #include "resource.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -159,15 +159,17 @@ void FileDlg::OnTypeChange(HWND hwnd)
ASSERT(typeControl != NULL); ASSERT(typeControl != NULL);
int sel = ::SendMessage(typeControl, CB_GETCURSEL, 0, 0); LRESULT sel = ::SendMessage(typeControl, CB_GETCURSEL, 0, 0);
ASSERT(sel != -1); ASSERT(sel != -1);
LPCTSTR typeName = extensions[sel]; LPCTSTR typeName = extensions[sel];
if(filename.GetLength() == 0) { if(filename.GetLength() == 0) {
if(strlen(typeName) != 0)
filename.Format("*%s", typeName); filename.Format("*%s", typeName);
} else { } else {
if(strlen(typeName) != 0) {
int index = filename.Find('.'); int index = filename.Find('.');
if (index == -1) { if (index == -1) {
filename = filename + typeName; filename = filename + typeName;
@ -175,6 +177,7 @@ void FileDlg::OnTypeChange(HWND hwnd)
filename = filename.Left(index) + typeName; filename = filename.Left(index) + typeName;
} }
} }
}
SetWindowText(fileNameControl, filename); SetWindowText(fileNameControl, filename);
} }

View File

@ -772,9 +772,9 @@ void GBACheatList::OnEnable()
if(m_list.GetItem(&item)) { if(m_list.GetItem(&item)) {
if(item.state & LVIS_SELECTED) { if(item.state & LVIS_SELECTED) {
if(cheatsList[item.lParam].enabled) if(cheatsList[item.lParam].enabled)
cheatsDisable(item.lParam); cheatsDisable((int)(item.lParam & 0xFFFFFFFF));
else else
cheatsEnable(item.lParam); cheatsEnable((int)(item.lParam & 0xFFFFFFFF));
} }
} }
} }
@ -796,7 +796,7 @@ void GBACheatList::OnRemove()
item.stateMask = LVIS_SELECTED; item.stateMask = LVIS_SELECTED;
if(m_list.GetItem(&item)) { if(m_list.GetItem(&item)) {
if(item.state & LVIS_SELECTED) { if(item.state & LVIS_SELECTED) {
cheatsDelete(item.lParam, restoreValues); cheatsDelete((int)(item.lParam & 0xFFFFFFFF), restoreValues);
} }
} }
} }
@ -838,9 +838,9 @@ void GBACheatList::OnItemchangedCheatList(NMHDR* pNMHDR, LRESULT* pResult)
if(((l->uOldState & LVIS_STATEIMAGEMASK)>>12) != if(((l->uOldState & LVIS_STATEIMAGEMASK)>>12) !=
(((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) { (((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) {
if(m_list.GetCheck(l->iItem)) if(m_list.GetCheck(l->iItem))
cheatsEnable(l->lParam); cheatsEnable((int)(l->lParam & 0xFFFFFFFF));
else else
cheatsDisable(l->lParam); cheatsDisable((int)(l->lParam & 0xFFFFFFFF));
refresh(); refresh();
} }
} }

View File

@ -20,7 +20,7 @@
#if !defined(AFX_GBACHEATS_H__FC31D47D_52C8_42B2_95C7_7C3FD09316A4__INCLUDED_) #if !defined(AFX_GBACHEATS_H__FC31D47D_52C8_42B2_95C7_7C3FD09316A4__INCLUDED_)
#define AFX_GBACHEATS_H__FC31D47D_52C8_42B2_95C7_7C3FD09316A4__INCLUDED_ #define AFX_GBACHEATS_H__FC31D47D_52C8_42B2_95C7_7C3FD09316A4__INCLUDED_
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -637,7 +637,7 @@ bool AddGBCheat::addCheat()
m_desc.GetWindowText(buffer); m_desc.GetWindowText(buffer);
int bank = (address >> 16); LONG_PTR bank = (address >> 16);
address &= 0xFFFF; address &= 0xFFFF;
if(address >= 0xd000) if(address >= 0xd000)
@ -689,9 +689,7 @@ BOOL AddGBCheat::OnInitDialog()
buffer.Format("%02x:%08x", (address>>16), address&0xFFFF); buffer.Format("%02x:%08x", (address>>16), address&0xFFFF);
m_address.SetWindowText(buffer); m_address.SetWindowText(buffer);
m_address.EnableWindow(FALSE); m_address.EnableWindow(FALSE);
::SetWindowLong(m_address, ::SetWindowLongPtr( m_address.GetSafeHwnd(), GWLP_USERDATA, address);
GWL_USERDATA,
address);
numberType = regQueryDwordValue("gbCheatsNumberType", 2); numberType = regQueryDwordValue("gbCheatsNumberType", 2);
if(numberType < 0 || numberType > 2) if(numberType < 0 || numberType > 2)
@ -826,9 +824,9 @@ void GBCheatList::OnEnable()
item.iItem = mark; item.iItem = mark;
if(m_list.GetItem(&item)) { if(m_list.GetItem(&item)) {
if(gbCheatList[item.lParam].enabled) if(gbCheatList[item.lParam].enabled)
gbCheatDisable(item.lParam); gbCheatDisable((int)item.lParam);
else else
gbCheatEnable(item.lParam); gbCheatEnable((int)item.lParam);
refresh(); refresh();
} }
} }
@ -844,7 +842,7 @@ void GBCheatList::OnRemove()
item.mask = LVIF_PARAM; item.mask = LVIF_PARAM;
item.iItem = mark; item.iItem = mark;
if(m_list.GetItem(&item)) { if(m_list.GetItem(&item)) {
gbCheatRemove(item.lParam); gbCheatRemove((int)item.lParam);
refresh(); refresh();
} }
} }
@ -872,9 +870,9 @@ void GBCheatList::OnItemchangedCheatList(NMHDR* pNMHDR, LRESULT* pResult)
if(((l->uOldState & LVIS_STATEIMAGEMASK)>>12) != if(((l->uOldState & LVIS_STATEIMAGEMASK)>>12) !=
(((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) { (((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) {
if(m_list.GetCheck(l->iItem)) if(m_list.GetCheck(l->iItem))
gbCheatEnable(l->lParam); gbCheatEnable((int)l->lParam);
else else
gbCheatDisable(l->lParam); gbCheatDisable((int)l->lParam);
refresh(); refresh();
} }
} }

View File

@ -121,7 +121,7 @@ class AddGBCheat : public CDialog
// Implementation // Implementation
protected: protected:
u32 address; LONG_PTR address;
// Generated message map functions // Generated message map functions
//{{AFX_MSG(AddGBCheat) //{{AFX_MSG(AddGBCheat)

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -53,7 +53,10 @@ static u16 defaultPalettes[][24] = {
0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010, 0x621F, 0x401F, 0x001F, 0x2010,
}, },
{ {
0x421F, 0x03E0, 0x7C00, 0x401F, 0x021F, 0x2200, 0x4008, 0x2010, 0x1B8E, 0x02C0, 0x0DA0, 0x1140, 0x1B8E, 0x02C0, 0x0DA0, 0x1140,
},
{
0x7BDE, /*0x23F0*/ 0x5778, /*0x5DC0*/ 0x5640, 0x0000, 0x7BDE, /*0x3678*/ 0x529C, /*0x0980*/ 0x2990, 0x0000,
} }
}; };
@ -70,9 +73,6 @@ static char THIS_FILE[] = __FILE__;
GBColorDlg::GBColorDlg(CWnd* pParent /*=NULL*/) GBColorDlg::GBColorDlg(CWnd* pParent /*=NULL*/)
: CDialog(GBColorDlg::IDD, pParent) : CDialog(GBColorDlg::IDD, pParent)
{ {
//{{AFX_DATA_INIT(GBColorDlg)
which = -1;
//}}AFX_DATA_INIT
which = gbPaletteOption; which = gbPaletteOption;
} }
@ -80,10 +80,8 @@ GBColorDlg::GBColorDlg(CWnd* pParent /*=NULL*/)
void GBColorDlg::DoDataExchange(CDataExchange* pDX) void GBColorDlg::DoDataExchange(CDataExchange* pDX)
{ {
CDialog::DoDataExchange(pDX); CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(GBColorDlg)
DDX_Control(pDX, IDC_PREDEFINED, m_predefined); DDX_Control(pDX, IDC_PREDEFINED, m_predefined);
DDX_Radio(pDX, IDC_DEFAULT, which); DDX_Radio(pDX, IDC_DEFAULT, which);
//}}AFX_DATA_MAP
} }
@ -167,10 +165,12 @@ BOOL GBColorDlg::OnInitDialog()
"Green Forest", "Green Forest",
"Hot Desert", "Hot Desert",
"Pink Dreams", "Pink Dreams",
"Weird Colors" "Weird Colors",
"Real GB Colors",
"Real 'GB on GBASP' Colors"
}; };
for(int j = 0; j < 7; j++) { for(int j = 0; j < 9; j++) {
int index = m_predefined.AddString(names[j]); int index = m_predefined.AddString(names[j]);
m_predefined.SetItemData(index, j); m_predefined.SetItemData(index, j);
} }
@ -222,15 +222,20 @@ void GBColorDlg::OnColorClicked(UINT id)
{ {
id -= IDC_COLOR_BG0; id -= IDC_COLOR_BG0;
u16 color = colors[id]; u16 color = colors[which*8+id];
CColorDialog dlg(RGB(color & 0x1f, (color >> 5) & 0x1f, (color >> 10) & 0x1f), COLORREF colorInit =
RGB((color & 0x1f) << 3, ((color >> 5) & 0x1f) << 3, ((color >> 10) & 0x1f) << 3);
CColorDialog dlg(colorInit,
CC_FULLOPEN | CC_ANYCOLOR, this); CC_FULLOPEN | CC_ANYCOLOR, this);
if(dlg.DoModal()) {
if(IDOK == dlg.DoModal())
{
COLORREF c = dlg.GetColor(); COLORREF c = dlg.GetColor();
colors[which*8+id] = (u16)((c >> 3) & 0x1f | ((c >> 11) & 0x1f) << 5 | colors[which*8+id] = (u16)((c >> 3) & 0x1f | ((c >> 11) & 0x1f) << 5 | ((c >> 19) & 0x1f) << 10);
((c >> 19) & 0x1f) << 10);
colorControls[id].setColor(colors[which*8+id]); colorControls[id].setColor(colors[which*8+id]);
} }
} }
@ -246,7 +251,7 @@ void GBColorDlg::OnSelchangePredefined()
int sel = m_predefined.GetCurSel(); int sel = m_predefined.GetCurSel();
if(sel != -1) { if(sel != -1) {
int data = m_predefined.GetItemData(sel); DWORD_PTR data = m_predefined.GetItemData(sel);
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
colorControls[i].setColor(defaultPalettes[data][i]); colorControls[i].setColor(defaultPalettes[data][i]);
colors[which*8+i] = defaultPalettes[data][i]; colors[which*8+i] = defaultPalettes[data][i];

View File

@ -21,7 +21,7 @@
#define AFX_GBCOLORDLG_H__8D6126EF_06BB_48CF_ABB3_2CC4B1B60358__INCLUDED_ #define AFX_GBCOLORDLG_H__8D6126EF_06BB_48CF_ABB3_2CC4B1B60358__INCLUDED_
#include "ColorButton.h" // Added by ClassView #include "ColorButton.h" // Added by ClassView
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -39,6 +39,7 @@ extern gbRegister DE;
extern gbRegister HL; extern gbRegister HL;
extern gbRegister SP; extern gbRegister SP;
extern gbRegister PC; extern gbRegister PC;
extern u8 register_LY;
extern u16 IFF; extern u16 IFF;
extern int gbDis(char *, u16); extern int gbDis(char *, u16);
@ -114,8 +115,9 @@ void GBDisassemble::OnNext()
void GBDisassemble::OnGo() void GBDisassemble::OnGo()
{ {
CString buffer; CString buffer;
m_address.GetWindowText(buffer); m_address.GetWindowText(buffer);
sscanf(buffer, "%x", &address); sscanf(buffer, "%hx", &address);
refresh(); refresh();
} }
@ -242,6 +244,8 @@ void GBDisassemble::refresh()
GetDlgItem(IDC_R5)->SetWindowText(buffer); GetDlgItem(IDC_R5)->SetWindowText(buffer);
sprintf(buffer, "%04x", IFF); sprintf(buffer, "%04x", IFF);
GetDlgItem(IDC_R6)->SetWindowText(buffer); GetDlgItem(IDC_R6)->SetWindowText(buffer);
sprintf(buffer, "%04x", register_LY);
GetDlgItem(IDC_LY)->SetWindowText(buffer);
m_z = (AF.B.B0 & 0x80) != 0; m_z = (AF.B.B0 & 0x80) != 0;
m_n = (AF.B.B0 & 0x40) != 0; m_n = (AF.B.B0 & 0x40) != 0;

View File

@ -20,7 +20,7 @@
#if !defined(AFX_GBDISASSEMBLE_H__3EFD5B47_6DBF_4F63_8F91_A9511EC590EB__INCLUDED_) #if !defined(AFX_GBDISASSEMBLE_H__3EFD5B47_6DBF_4F63_8F91_A9511EC590EB__INCLUDED_)
#define AFX_GBDISASSEMBLE_H__3EFD5B47_6DBF_4F63_8F91_A9511EC590EB__INCLUDED_ #define AFX_GBDISASSEMBLE_H__3EFD5B47_6DBF_4F63_8F91_A9511EC590EB__INCLUDED_
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
#if _MSC_VER > 1000 #if _MSC_VER > 1000
#pragma once #pragma once
#endif // _MSC_VER > 1000 #endif // _MSC_VER > 1000

View File

@ -499,8 +499,8 @@ LRESULT GBMapView::OnMapInfo(WPARAM wParam, LPARAM lParam)
u8 *colors = (u8 *)lParam; u8 *colors = (u8 *)lParam;
mapViewZoom.setColors(colors); mapViewZoom.setColors(colors);
int x = wParam & 0xffff; int x = (int)(wParam & 0xffff);
int y = (wParam >> 16); int y = (int)(wParam >> 16);
CString buffer; CString buffer;
buffer.Format("(%d,%d)", x, y); buffer.Format("(%d,%d)", x, y);

View File

@ -31,7 +31,7 @@
#include "ZoomControl.h" #include "ZoomControl.h"
#include "ResizeDlg.h" #include "ResizeDlg.h"
#include "IUpdate.h" #include "IUpdate.h"
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// GBMapView dialog // GBMapView dialog

View File

@ -460,8 +460,8 @@ LRESULT GBTileView::OnMapInfo(WPARAM wParam, LPARAM lParam)
u8 *colors = (u8 *)lParam; u8 *colors = (u8 *)lParam;
zoom.setColors(colors); zoom.setColors(colors);
int x = (wParam & 0xFFFF)/8; int x = (int)((wParam & 0xffff)/8);
int y = ((wParam >> 16) & 0xFFFF)/8; int y = (int)(((wParam >> 16) & 0xFFFF)/8);
int tiles = 0x0000; int tiles = 0x0000;
if(charBase) if(charBase)

View File

@ -1,6 +1,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2005-2006 VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -17,22 +18,19 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h" #include "stdafx.h"
#include <stdio.h>
#include "Display.h"
#include "../System.h" #include "../System.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
#include "..\gb\gbGlobals.h"
#include "../Text.h" #include "../Text.h"
#include "../Util.h" #include "../Util.h"
#include "UniVideoModeDlg.h"
#include "VBA.h" #include "VBA.h"
#include "MainWnd.h" #include "MainWnd.h"
#include "Reg.h" #include "Reg.h"
#include "..\..\res\resource.h" #include "resource.h"
#include "../gbafilter.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -43,20 +41,16 @@ static char THIS_FILE[] = __FILE__;
extern void winlog(const char *,...); extern void winlog(const char *,...);
extern int Init_2xSaI(u32); extern int Init_2xSaI(u32);
extern int systemSpeed; extern int systemSpeed;
extern int winVideoModeSelect(CWnd *, GUID **);
class GDIDisplay : public IDisplay {
class GDIDisplay : public IDisplay
{
private: private:
u8 *filterData; u8 *filterData;
u8 info[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)]; u8 info[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
int SelectedFreq, SelectedAdapter;
public: public:
GDIDisplay(); GDIDisplay();
virtual ~GDIDisplay(); virtual ~GDIDisplay();
virtual bool changeRenderSize(int w, int h);
virtual bool initialize(); virtual bool initialize();
virtual void cleanup(); virtual void cleanup();
virtual void render(); virtual void render();
@ -65,11 +59,10 @@ public:
virtual void clear(); virtual void clear();
virtual DISPLAY_TYPE getType() { return GDI; }; virtual DISPLAY_TYPE getType() { return GDI; };
virtual void setOption(const char *, int) {} virtual void setOption(const char *, int) {}
virtual bool isSkinSupported() { return true; }
virtual int selectFullScreenMode(GUID **); virtual int selectFullScreenMode(GUID **);
virtual int selectFullScreenMode2();
}; };
static int calculateShift(u32 mask) static int calculateShift(u32 mask)
{ {
int m = 0; int m = 0;
@ -84,7 +77,7 @@ static int calculateShift(u32 mask)
GDIDisplay::GDIDisplay() GDIDisplay::GDIDisplay()
{ {
filterData = NULL; filterData = (u8 *)malloc(4*4*256*240);
} }
GDIDisplay::~GDIDisplay() GDIDisplay::~GDIDisplay()
@ -94,37 +87,17 @@ GDIDisplay::~GDIDisplay()
void GDIDisplay::cleanup() void GDIDisplay::cleanup()
{ {
if(filterData) if(filterData) {
{ free(filterData);
delete [] filterData;
filterData = NULL; filterData = NULL;
} }
} }
bool GDIDisplay::initialize() bool GDIDisplay::initialize()
{ {
switch(theApp.cartridgeType)
{
case 0:
theApp.sizeX = 240; theApp.sizeX = 240;
theApp.sizeY = 160; theApp.sizeY = 160;
break; switch(theApp.videoOption) {
case 1:
if(gbBorderOn)
{
theApp.sizeX = 256;
theApp.sizeY = 224;
}
else
{
theApp.sizeX = 160;
theApp.sizeY = 144;
}
break;
}
switch(theApp.videoOption)
{
case VIDEO_1X: case VIDEO_1X:
theApp.surfaceSizeX = theApp.sizeX; theApp.surfaceSizeX = theApp.sizeX;
theApp.surfaceSizeY = theApp.sizeY; theApp.surfaceSizeY = theApp.sizeY;
@ -144,23 +117,19 @@ bool GDIDisplay::initialize()
case VIDEO_320x240: case VIDEO_320x240:
case VIDEO_640x480: case VIDEO_640x480:
case VIDEO_800x600: case VIDEO_800x600:
case VIDEO_1024x768:
case VIDEO_1280x1024:
case VIDEO_OTHER: case VIDEO_OTHER:
float scaleX = ((float)theApp.fsWidth / theApp.sizeX); {
float scaleY = ((float)theApp.fsHeight / theApp.sizeY); int scaleX = (theApp.fsWidth / theApp.sizeX);
float min = scaleX < scaleY ? scaleX : scaleY; int scaleY = (theApp.fsHeight / theApp.sizeY);
int min = scaleX < scaleY ? scaleX : scaleY;
if(theApp.fsMaxScale) if(theApp.fsMaxScale)
min = min > theApp.fsMaxScale ? theApp.fsMaxScale : min; min = min > theApp.fsMaxScale ? theApp.fsMaxScale : min;
if(theApp.fullScreenStretch) theApp.surfaceSizeX = theApp.sizeX * min;
{ theApp.surfaceSizeY = theApp.sizeY * min;
if(theApp.fullScreenStretch) {
theApp.surfaceSizeX = theApp.fsWidth; theApp.surfaceSizeX = theApp.fsWidth;
theApp.surfaceSizeY = theApp.fsHeight; theApp.surfaceSizeY = theApp.fsHeight;
} }
else
{
theApp.surfaceSizeX = (int)(theApp.sizeX * min);
theApp.surfaceSizeY = (int)(theApp.sizeY * min);
} }
break; break;
} }
@ -225,61 +194,10 @@ bool GDIDisplay::initialize()
theApp.adjustDestRect(); theApp.adjustDestRect();
// Enumerate available display modes
theApp.mode320Available = false; theApp.mode320Available = false;
theApp.mode640Available = false; theApp.mode640Available = false;
theApp.mode800Available = false; theApp.mode800Available = false;
theApp.mode1024Available = false;
theApp.mode1280Available = false;
DISPLAY_DEVICE dev;
dev.cb = sizeof(DISPLAY_DEVICE);
EnumDisplayDevices(NULL, 0, &dev, 0);
DEVMODE mode;
for (DWORD iMode = 0;
TRUE == EnumDisplaySettings(dev.DeviceName, iMode, &mode);
iMode++)
{
if ( (mode.dmBitsPerPel == 16) &&
(mode.dmPelsWidth==320) && (mode.dmPelsHeight==240))
theApp.mode320Available = true;
if ( (mode.dmBitsPerPel == 16) &&
(mode.dmPelsWidth==640) && (mode.dmPelsHeight==480))
theApp.mode640Available = true;
if ( (mode.dmBitsPerPel == 16) &&
(mode.dmPelsWidth==800) && (mode.dmPelsHeight==600))
theApp.mode800Available = true;
if ( (mode.dmBitsPerPel == 32) &&
(mode.dmPelsWidth==1024) && (mode.dmPelsHeight==768))
theApp.mode1024Available = true;
if ( (mode.dmBitsPerPel == 32) &&
(mode.dmPelsWidth==1280) && (mode.dmPelsHeight==1024))
theApp.mode1280Available = true;
}
// Go into fullscreen
if(theApp.videoOption >= VIDEO_320x240)
{
mode.dmBitsPerPel = theApp.fsColorDepth;
mode.dmPelsWidth = theApp.fsWidth;
mode.dmPelsHeight = theApp.fsHeight;
mode.dmDisplayFrequency = theApp.fsFrequency;
mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
DISPLAY_DEVICE dd;
dd.cb = sizeof(DISPLAY_DEVICE);
EnumDisplayDevices(NULL, theApp.fsAdapter, &dd, 0);
ChangeDisplaySettingsEx(dd.DeviceName, &mode, NULL, CDS_FULLSCREEN, NULL);
}
else // Reset from fullscreen
{
ChangeDisplaySettings(NULL, 0);
}
// Initialize 2xSaI
HDC dc = GetDC(NULL); HDC dc = GetDC(NULL);
HBITMAP hbm = CreateCompatibleBitmap(dc, 1, 1); HBITMAP hbm = CreateCompatibleBitmap(dc, 1, 1);
BITMAPINFO *bi = (BITMAPINFO *)info; BITMAPINFO *bi = (BITMAPINFO *)info;
@ -313,9 +231,6 @@ bool GDIDisplay::initialize()
Init_2xSaI(32); Init_2xSaI(32);
} }
// Setup system color depth
theApp.fsColorDepth = systemColorDepth; theApp.fsColorDepth = systemColorDepth;
if(systemColorDepth == 24) if(systemColorDepth == 24)
theApp.filterFunction = NULL; theApp.filterFunction = NULL;
@ -326,7 +241,7 @@ bool GDIDisplay::initialize()
cpu_mmx = 0; cpu_mmx = 0;
#endif #endif
utilUpdateSystemColorMaps(theApp.filterLCD ); utilUpdateSystemColorMaps();
theApp.updateFilter(); theApp.updateFilter();
theApp.updateIFB(); theApp.updateIFB();
@ -335,13 +250,8 @@ bool GDIDisplay::initialize()
return TRUE; return TRUE;
} }
void GDIDisplay::clear() void GDIDisplay::clear()
{ {
CDC *dc = theApp.m_pMainWnd->GetDC();
CBrush brush(RGB(0x00, 0x00, 0x00));
dc->FillRect(CRect(0, 0, theApp.fsWidth, theApp.fsHeight), &brush);
theApp.m_pMainWnd->ReleaseDC(dc);
} }
void GDIDisplay::renderMenu() void GDIDisplay::renderMenu()
@ -356,124 +266,137 @@ void GDIDisplay::checkFullScreen()
void GDIDisplay::render() void GDIDisplay::render()
{ {
unsigned int pitch = theApp.filterWidth * (systemColorDepth / 8) + 4;
BITMAPINFO *bi = (BITMAPINFO *)info; BITMAPINFO *bi = (BITMAPINFO *)info;
bi->bmiHeader.biWidth = theApp.filterWidth+1; bi->bmiHeader.biWidth = theApp.filterWidth+1;
bi->bmiHeader.biHeight = -theApp.filterHeight; bi->bmiHeader.biHeight = -theApp.filterHeight;
if(theApp.filterFunction) int pitch = theApp.filterWidth * 2 + 4;
{ if(systemColorDepth == 24)
bi->bmiHeader.biWidth = theApp.rect.right; pitch = theApp.filterWidth * 3;
bi->bmiHeader.biHeight = -(int)theApp.rect.bottom; else if(systemColorDepth == 32)
pitch = theApp.filterWidth * 4 + 4;
(*theApp.filterFunction)( if(theApp.filterFunction) {
pix + pitch, bi->bmiHeader.biWidth = theApp.filterWidth * 2;
bi->bmiHeader.biHeight = -theApp.filterHeight * 2;
if(systemColorDepth == 16)
(*theApp.filterFunction)(pix+pitch,
pitch, pitch,
(u8*)theApp.delta, (u8*)theApp.delta,
(u8*)filterData, (u8*)filterData,
theApp.rect.right * (systemColorDepth / 8), theApp.filterWidth*2*2,
theApp.filterWidth,
theApp.filterHeight);
else
(*theApp.filterFunction)(pix+pitch,
pitch,
(u8*)theApp.delta,
(u8*)filterData,
theApp.filterWidth*4*2,
theApp.filterWidth, theApp.filterWidth,
theApp.filterHeight); theApp.filterHeight);
} }
POINT p1, p2; if(theApp.showSpeed && (theApp.videoOption > VIDEO_4X || theApp.skin != NULL)) {
p1.x = theApp.dest.left; char buffer[30];
p1.y = theApp.dest.top; if(theApp.showSpeed == 1)
sprintf(buffer, "%3d%%", systemSpeed);
else
sprintf(buffer, "%3d%%(%d, %d fps)", systemSpeed,
systemFrameSkip,
theApp.showRenderedFrames);
if(theApp.filterFunction) {
int p = theApp.filterWidth * 4;
if(systemColorDepth == 24)
p = theApp.filterWidth * 6;
else if(systemColorDepth == 32)
p = theApp.filterWidth * 8;
if(theApp.showSpeedTransparent)
drawTextTransp((u8*)filterData,
p,
10,
theApp.filterHeight*2-10,
buffer);
else
drawText((u8*)filterData,
p,
10,
theApp.filterHeight*2-10,
buffer);
} else {
if(theApp.showSpeedTransparent)
drawTextTransp((u8*)pix,
pitch,
10,
theApp.filterHeight-10,
buffer);
else
drawText((u8*)pix,
pitch,
10,
theApp.filterHeight-10,
buffer);
}
}
POINT p;
p.x = theApp.dest.left;
p.y = theApp.dest.top;
CWnd *pWnd = theApp.m_pMainWnd;
pWnd->ScreenToClient(&p);
POINT p2;
p2.x = theApp.dest.right; p2.x = theApp.dest.right;
p2.y = theApp.dest.bottom; p2.y = theApp.dest.bottom;
theApp.m_pMainWnd->ScreenToClient(&p1); pWnd->ScreenToClient(&p2);
theApp.m_pMainWnd->ScreenToClient(&p2);
CDC *dc = theApp.m_pMainWnd->GetDC(); CDC *dc = pWnd->GetDC();
// Draw bitmap to device StretchDIBits((HDC)*dc,
StretchDIBits( p.x,
dc->GetSafeHdc(), p.y,
p1.x, p1.y, p2.x - p.x,
p2.x - p1.x, p2.y - p.y,
p2.y - p1.y, 0,
theApp.rect.left, theApp.rect.top, 0,
theApp.rect.right - theApp.rect.left, theApp.rect.right,
theApp.rect.bottom - theApp.rect.top, theApp.rect.bottom,
theApp.filterFunction ? filterData : pix+pitch, theApp.filterFunction ? filterData : pix+pitch,
bi, bi,
DIB_RGB_COLORS, DIB_RGB_COLORS,
SRCCOPY); SRCCOPY);
// Draw frame counter if(theApp.screenMessage) {
if (theApp.showSpeed && (theApp.videoOption >= VIDEO_320x240)) if(((GetTickCount() - theApp.screenMessageTime) < 3000) &&
{ !theApp.disableStatusMessage) {
CString speedText; dc->SetTextColor(RGB(255,0,0));
if (theApp.showSpeed == 1)
speedText.AppendFormat("%3d%%", systemSpeed);
else
speedText.AppendFormat("%3d%%(%d, %d fps)",
systemSpeed, systemFrameSkip, theApp.showRenderedFrames);
dc->SetTextColor(RGB(0xFF, 0x3F, 0x3F));
if (theApp.showSpeedTransparent)
dc->SetBkMode(TRANSPARENT); dc->SetBkMode(TRANSPARENT);
else dc->TextOut(p.x+10, p2.y - 20, theApp.screenMessageBuffer);
dc->SetBkMode(OPAQUE); } else {
dc->SetBkColor(RGB(0xFF, 0xFF, 0xFF));
dc->TextOut(p1.x + 16, p1.y + 16, speedText);
}
// Draw screen message
if (theApp.screenMessage)
{
if ( ((GetTickCount() - theApp.screenMessageTime) < 3000) && !theApp.disableStatusMessage )
{
dc->SetTextColor(RGB(0x3F, 0x3F, 0xFF));
if (theApp.showSpeedTransparent)
dc->SetBkMode(TRANSPARENT);
else
dc->SetBkMode(OPAQUE);
dc->SetBkColor(RGB(0xFF, 0xFF, 0xFF));
dc->TextOut(p1.x + 16, p2.y - 16, theApp.screenMessageBuffer);
}
else
theApp.screenMessage = false; theApp.screenMessage = false;
} }
theApp.m_pMainWnd->ReleaseDC(dc);
} }
int GDIDisplay::selectFullScreenMode(GUID **pGUID) pWnd->ReleaseDC(dc);
{
int w, h, b;
UniVideoModeDlg dlg(0, &w, &h, &b, &SelectedFreq, &SelectedAdapter);
if (0 == dlg.DoModal())
{
return (b<<24) + (w<<12) + h;
// Bits<<24 | Width<<12 | Height
}
else
{
return -1;
}
} }
int GDIDisplay::selectFullScreenMode2() int GDIDisplay::selectFullScreenMode(GUID **)
{ {
return (SelectedAdapter<<16) + SelectedFreq; HWND wnd = GetDesktopWindow();
} RECT r;
GetWindowRect(wnd, &r);
int w = (r.right - r.left) & 4095;
int h = (r.bottom - r.top) & 4095;
HDC dc = GetDC(wnd);
int c = GetDeviceCaps(dc, BITSPIXEL);
ReleaseDC(wnd, dc);
bool GDIDisplay::changeRenderSize(int w, int h) return (c << 24) | (w << 12) | h;
{
if (filterData)
{
delete [] filterData;
filterData = NULL;
} }
filterData = new u8[w*h*(systemColorDepth>>3)];
return true;
}
IDisplay *newGDIDisplay() IDisplay *newGDIDisplay()
{ {
return new GDIDisplay(); return new GDIDisplay();
} }

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -26,7 +26,6 @@
#include "../System.h" #include "../System.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
#include "../Sound.h"
#include "IOViewerRegs.h" #include "IOViewerRegs.h"
@ -68,6 +67,22 @@ BEGIN_MESSAGE_MAP(IOViewer, CDialog)
ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate) ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses) ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses)
ON_BN_CLICKED(IDC_APPLY, OnApply) ON_BN_CLICKED(IDC_APPLY, OnApply)
ON_BN_CLICKED(IDC_BIT_0, bitChange)
ON_BN_CLICKED(IDC_BIT_1, bitChange)
ON_BN_CLICKED(IDC_BIT_2, bitChange)
ON_BN_CLICKED(IDC_BIT_3, bitChange)
ON_BN_CLICKED(IDC_BIT_4, bitChange)
ON_BN_CLICKED(IDC_BIT_5, bitChange)
ON_BN_CLICKED(IDC_BIT_6, bitChange)
ON_BN_CLICKED(IDC_BIT_7, bitChange)
ON_BN_CLICKED(IDC_BIT_8, bitChange)
ON_BN_CLICKED(IDC_BIT_9, bitChange)
ON_BN_CLICKED(IDC_BIT_10, bitChange)
ON_BN_CLICKED(IDC_BIT_11, bitChange)
ON_BN_CLICKED(IDC_BIT_12, bitChange)
ON_BN_CLICKED(IDC_BIT_13, bitChange)
ON_BN_CLICKED(IDC_BIT_14, bitChange)
ON_BN_CLICKED(IDC_BIT_15, bitChange)
//}}AFX_MSG_MAP //}}AFX_MSG_MAP
END_MESSAGE_MAP() END_MESSAGE_MAP()
@ -81,10 +96,29 @@ void IOViewer::OnClose()
DestroyWindow(); DestroyWindow();
} }
void IOViewer::bitChange()
{
CString buffer;
u16 data = 0;
for(int i = 0; i < 16; i++) {
CButton *pWnd = (CButton *)GetDlgItem(IDC_BIT_0 + i);
if(pWnd) {
if(pWnd->GetCheck())
data |= (1 << i);
}
}
buffer.Format("%04X", data);
m_value.SetWindowText(buffer);
}
void IOViewer::OnRefresh() void IOViewer::OnRefresh()
{ {
// TODO: Add your control notification handler code here // TODO: Add your control notification handler code here
update();
} }
void IOViewer::OnAutoUpdate() void IOViewer::OnAutoUpdate()
@ -165,7 +199,7 @@ void IOViewer::update()
const IOData *sel = &ioViewRegisters[selected]; const IOData *sel = &ioViewRegisters[selected];
u16 data = sel->address ? *sel->address : u16 data = sel->address ? *sel->address :
(ioMem ? soundRead16(sel->offset) : 0); (ioMem ? *((u16 *)&ioMem[sel->offset]) : 0);
for(int i = 0; i < 16; i++) { for(int i = 0; i < 16; i++) {
CButton *pWnd = (CButton *)GetDlgItem(IDC_BIT_0 + i); CButton *pWnd = (CButton *)GetDlgItem(IDC_BIT_0 + i);
@ -186,6 +220,8 @@ void IOViewer::update()
} }
void IOViewer::OnApply() void IOViewer::OnApply()
{
if(rom != NULL)
{ {
const IOData *sel = &ioViewRegisters[selected]; const IOData *sel = &ioViewRegisters[selected];
u16 res = 0; u16 res = 0;
@ -200,3 +236,4 @@ void IOViewer::OnApply()
CPUWriteHalfWord(0x4000000+sel->offset, res); CPUWriteHalfWord(0x4000000+sel->offset, res);
update(); update();
} }
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -37,6 +37,7 @@ class IOViewer : public ResizeDlg, IUpdateListener
// Construction // Construction
public: public:
void update(); void update();
void bitChange();
bool autoUpdate; bool autoUpdate;
int selected; int selected;
IOViewer(CWnd* pParent = NULL); // standard constructor IOViewer(CWnd* pParent = NULL); // standard constructor

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -258,7 +258,7 @@ const IOData ioViewRegisters[] = {
} }
}, },
{ {
&BG2HOFS, 0x18, "0x4000018-BG8HOFS", 0x01FF, &BG2HOFS, 0x18, "0x4000018-BG2HOFS", 0x01FF,
{ {
"", "",
"", "",
@ -1119,7 +1119,7 @@ const IOData ioViewRegisters[] = {
} }
}, },
{ {
NULL, 0x82, "0x4000082-SGCNT0_H", 0xFF1F, NULL, 0x82, "0x4000082-SGCNT0_H", 0xFF0F,
{ {
"", "",
"Sound 1-4 Volume (2 bits)", "Sound 1-4 Volume (2 bits)",

View File

@ -22,10 +22,6 @@
#include "../System.h" #include "../System.h"
#define JOYCONFIG_MESSAGE (WM_USER + 1000) #define JOYCONFIG_MESSAGE (WM_USER + 1000)
typedef CList<int,int> KeyList;
//typedef CList<USHORT,USHORT> KeyList;
#define JOYPADS 4 #define JOYPADS 4
#define MOTION_KEYS 4 #define MOTION_KEYS 4
#define KEYS_PER_PAD 13 #define KEYS_PER_PAD 13
@ -35,6 +31,8 @@ typedef CList<int,int> KeyList;
#define DEVICEOF(key) (key >> 8) #define DEVICEOF(key) (key >> 8)
#define KEYOF(key) (key & 255) #define KEYOF(key) (key & 255)
typedef CList<LONG_PTR,LONG_PTR> KeyList;
enum { enum {
KEY_LEFT, KEY_RIGHT, KEY_LEFT, KEY_RIGHT,
KEY_UP, KEY_DOWN, KEY_UP, KEY_DOWN,
@ -46,6 +44,7 @@ enum {
}; };
class Input { class Input {
public: public:
KeyList joypaddata[JOYPADS * KEYS_PER_PAD + MOTION_KEYS]; KeyList joypaddata[JOYPADS * KEYS_PER_PAD + MOTION_KEYS];
@ -56,7 +55,7 @@ class Input {
virtual bool readDevices() = 0; virtual bool readDevices() = 0;
virtual u32 readDevice(int which) = 0; virtual u32 readDevice(int which) = 0;
virtual CString getKeyName(int key) = 0; virtual CString getKeyName(LONG_PTR key) = 0;
virtual void checkKeys() = 0; virtual void checkKeys() = 0;
virtual void checkMotionKeys() = 0; virtual void checkMotionKeys() = 0;
virtual void checkDevices() = 0; virtual void checkDevices() = 0;
@ -65,6 +64,4 @@ class Input {
virtual void saveSettings() = 0; virtual void saveSettings() = 0;
}; };
#define joypad theApp.input->joypaddata
#endif #endif

View File

@ -100,6 +100,7 @@ LRESULT JoypadEditControl::OnJoyConfig(WPARAM wParam, LPARAM lParam)
return TRUE; return TRUE;
} }
BOOL JoypadEditControl::PreTranslateMessage(MSG *pMsg) BOOL JoypadEditControl::PreTranslateMessage(MSG *pMsg)
{ {
if(pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)) if(pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN))
@ -145,14 +146,12 @@ void JoypadConfig::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(JoypadConfig, CDialog) BEGIN_MESSAGE_MAP(JoypadConfig, CDialog)
//{{AFX_MSG_MAP(JoypadConfig)
ON_BN_CLICKED(ID_CANCEL, OnCancel) ON_BN_CLICKED(ID_CANCEL, OnCancel)
ON_BN_CLICKED(ID_OK, OnOk) ON_BN_CLICKED(ID_OK, OnOk)
ON_WM_CHAR() ON_WM_CHAR()
ON_WM_DESTROY() ON_WM_DESTROY()
ON_WM_TIMER() ON_WM_TIMER()
ON_WM_KEYDOWN() ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_APPENDMODE, &JoypadConfig::OnBnClickedAppendmode) ON_BN_CLICKED(IDC_APPENDMODE, &JoypadConfig::OnBnClickedAppendmode)
END_MESSAGE_MAP() END_MESSAGE_MAP()
@ -166,19 +165,19 @@ void JoypadConfig::OnCancel()
void JoypadConfig::OnOk() void JoypadConfig::OnOk()
{ {
AssignKeys(up.m_Keys,joypad[JOYPAD(which,KEY_UP)]); AssignKeys(up.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_UP)]);
AssignKeys(speed.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_SPEED)]); AssignKeys(speed.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SPEED)]);
AssignKeys(right.m_Keys,joypad[JOYPAD(which,KEY_RIGHT)]); AssignKeys(right.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_RIGHT)]);
AssignKeys(left.m_Keys,joypad[JOYPAD(which,KEY_LEFT)]); AssignKeys(left.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_LEFT)]);
AssignKeys(down.m_Keys,joypad[JOYPAD(which,KEY_DOWN)]); AssignKeys(down.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_DOWN)]);
AssignKeys(capture.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_CAPTURE)]); AssignKeys(capture.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_CAPTURE)]);
AssignKeys(buttonStart.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_START)]); AssignKeys(buttonStart.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_START)]);
AssignKeys(buttonSelect.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_SELECT)]); AssignKeys(buttonSelect.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SELECT)]);
AssignKeys(buttonR.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_R)]); AssignKeys(buttonR.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_R)]);
AssignKeys(buttonL.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_L)]); AssignKeys(buttonL.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_L)]);
AssignKeys(buttonGS.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_GS)]); AssignKeys(buttonGS.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_GS)]);
AssignKeys(buttonB.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_B)]); AssignKeys(buttonB.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_B)]);
AssignKeys(buttonA.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_A)]); AssignKeys(buttonA.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_A)]);
theApp.input->checkKeys(); theApp.input->checkKeys();
EndDialog(TRUE); EndDialog(TRUE);
@ -195,7 +194,7 @@ void JoypadConfig::OnDestroy()
KillTimer(timerId); KillTimer(timerId);
} }
void JoypadConfig::OnTimer(UINT nIDEvent) void JoypadConfig::OnTimer(UINT_PTR nIDEvent)
{ {
theApp.input->checkDevices(); theApp.input->checkDevices();
@ -212,35 +211,35 @@ BOOL JoypadConfig::OnInitDialog()
bAppendMode = FALSE; bAppendMode = FALSE;
timerId = SetTimer(0,200,NULL); timerId = SetTimer(0,50,NULL);
CopyKeys(up.m_Keys,joypad[JOYPAD(which,KEY_UP)]); CopyKeys(up.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_UP)]);
CopyKeys(speed.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_SPEED)]); CopyKeys(speed.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SPEED)]);
CopyKeys(right.m_Keys,joypad[JOYPAD(which,KEY_RIGHT)]); CopyKeys(right.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_RIGHT)]);
CopyKeys(left.m_Keys,joypad[JOYPAD(which,KEY_LEFT)]); CopyKeys(left.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_LEFT)]);
CopyKeys(down.m_Keys,joypad[JOYPAD(which,KEY_DOWN)]); CopyKeys(down.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_DOWN)]);
CopyKeys(capture.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_CAPTURE)]); CopyKeys(capture.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_CAPTURE)]);
CopyKeys(buttonStart.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_START)]); CopyKeys(buttonStart.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_START)]);
CopyKeys(buttonSelect.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_SELECT)]); CopyKeys(buttonSelect.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SELECT)]);
CopyKeys(buttonR.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_R)]); CopyKeys(buttonR.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_R)]);
CopyKeys(buttonL.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_L)]); CopyKeys(buttonL.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_L)]);
CopyKeys(buttonGS.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_GS)]); CopyKeys(buttonGS.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_GS)]);
CopyKeys(buttonB.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_B)]); CopyKeys(buttonB.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_B)]);
CopyKeys(buttonA.m_Keys,joypad[JOYPAD(which,KEY_BUTTON_A)]); CopyKeys(buttonA.m_Keys,theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_A)]);
up.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_UP)])); up.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_UP)]));
down.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_DOWN)])); down.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_DOWN)]));
left.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_LEFT)])); left.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_LEFT)]));
right.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_RIGHT)])); right.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_RIGHT)]));
buttonA.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_A)])); buttonA.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_A)]));
buttonB.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_B)])); buttonB.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_B)]));
buttonL.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_L)])); buttonL.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_L)]));
buttonR.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_R)])); buttonR.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_R)]));
buttonSelect.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_SELECT)])); buttonSelect.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SELECT)]));
buttonStart.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_START)])); buttonStart.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_START)]));
speed.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_SPEED)])); speed.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SPEED)]));
capture.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_CAPTURE)])); capture.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_CAPTURE)]));
buttonGS.SetWindowText(GetKeyListName(joypad[JOYPAD(which,KEY_BUTTON_GS)])); buttonGS.SetWindowText(GetKeyListName(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_GS)]));
CenterWindow(); CenterWindow();
@ -248,47 +247,47 @@ BOOL JoypadConfig::OnInitDialog()
// EXCEPTION: OCX Property Pages should return FALSE // EXCEPTION: OCX Property Pages should return FALSE
} }
void JoypadConfig::assignKey(int id, int key) void JoypadConfig::assignKey(int id, LONG_PTR key)
{ {
switch(id) { switch(id) {
case IDC_EDIT_LEFT: case IDC_EDIT_LEFT:
AssignKey(joypad[JOYPAD(which,KEY_LEFT)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_LEFT)],key);
break; break;
case IDC_EDIT_RIGHT: case IDC_EDIT_RIGHT:
AssignKey(joypad[JOYPAD(which,KEY_RIGHT)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_RIGHT)],key);
break; break;
case IDC_EDIT_UP: case IDC_EDIT_UP:
AssignKey(joypad[JOYPAD(which,KEY_UP)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_UP)],key);
break; break;
case IDC_EDIT_SPEED: case IDC_EDIT_SPEED:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_SPEED)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SPEED)],key);
break; break;
case IDC_EDIT_CAPTURE: case IDC_EDIT_CAPTURE:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_CAPTURE)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_CAPTURE)],key);
break; break;
case IDC_EDIT_DOWN: case IDC_EDIT_DOWN:
AssignKey(joypad[JOYPAD(which,KEY_DOWN)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_DOWN)],key);
break; break;
case IDC_EDIT_BUTTON_A: case IDC_EDIT_BUTTON_A:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_A)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_A)],key);
break; break;
case IDC_EDIT_BUTTON_B: case IDC_EDIT_BUTTON_B:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_B)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_B)],key);
break; break;
case IDC_EDIT_BUTTON_L: case IDC_EDIT_BUTTON_L:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_L)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_L)],key);
break; break;
case IDC_EDIT_BUTTON_R: case IDC_EDIT_BUTTON_R:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_R)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_R)],key);
break; break;
case IDC_EDIT_BUTTON_START: case IDC_EDIT_BUTTON_START:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_START)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_START)],key);
break; break;
case IDC_EDIT_BUTTON_SELECT: case IDC_EDIT_BUTTON_SELECT:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_SELECT)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_SELECT)],key);
break; break;
case IDC_EDIT_BUTTON_GS: case IDC_EDIT_BUTTON_GS:
AssignKey(joypad[JOYPAD(which,KEY_BUTTON_GS)],key); AssignKey(theApp.input->joypaddata[JOYPAD(which,KEY_BUTTON_GS)],key);
break; break;
} }
} }
@ -322,14 +321,11 @@ void MotionConfig::DoDataExchange(CDataExchange* pDX)
BEGIN_MESSAGE_MAP(MotionConfig, CDialog) BEGIN_MESSAGE_MAP(MotionConfig, CDialog)
//{{AFX_MSG_MAP(MotionConfig)
ON_BN_CLICKED(ID_CANCEL, OnCancel) ON_BN_CLICKED(ID_CANCEL, OnCancel)
ON_BN_CLICKED(ID_OK, OnOk) ON_BN_CLICKED(ID_OK, OnOk)
ON_WM_CHAR()
ON_WM_DESTROY() ON_WM_DESTROY()
ON_WM_KEYDOWN() ON_WM_KEYDOWN()
ON_WM_TIMER() ON_WM_TIMER()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_APPENDMODE, &MotionConfig::OnBnClickedAppendmode) ON_BN_CLICKED(IDC_APPENDMODE, &MotionConfig::OnBnClickedAppendmode)
END_MESSAGE_MAP() END_MESSAGE_MAP()
@ -343,16 +339,11 @@ void MotionConfig::OnCancel()
void MotionConfig::OnOk() void MotionConfig::OnOk()
{ {
assignKeys();
theApp.input->checkKeys(); theApp.input->checkKeys();
EndDialog( TRUE); EndDialog( TRUE);
} }
void MotionConfig::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
}
void MotionConfig::OnDestroy() void MotionConfig::OnDestroy()
{ {
CDialog::OnDestroy(); CDialog::OnDestroy();
@ -360,24 +351,23 @@ void MotionConfig::OnDestroy()
KillTimer(timerId); KillTimer(timerId);
} }
BOOL MotionConfig::OnInitDialog() BOOL MotionConfig::OnInitDialog()
{ {
CDialog::OnInitDialog(); CDialog::OnInitDialog();
timerId = SetTimer(0,200,NULL); timerId = SetTimer(0,50,NULL);
CopyKeys(up.m_Keys, joypad[MOTION(KEY_UP)]); CopyKeys(up.m_Keys, theApp.input->joypaddata[MOTION(KEY_UP)]);
up.SetWindowText(GetKeyListName(joypad[MOTION(KEY_UP)])); up.SetWindowText(GetKeyListName(theApp.input->joypaddata[MOTION(KEY_UP)]));
CopyKeys(down.m_Keys, joypad[MOTION(KEY_DOWN)]); CopyKeys(down.m_Keys, theApp.input->joypaddata[MOTION(KEY_DOWN)]);
down.SetWindowText(GetKeyListName(joypad[MOTION(KEY_DOWN)])); down.SetWindowText(GetKeyListName(theApp.input->joypaddata[MOTION(KEY_DOWN)]));
CopyKeys(left.m_Keys, joypad[MOTION(KEY_LEFT)]); CopyKeys(left.m_Keys, theApp.input->joypaddata[MOTION(KEY_LEFT)]);
left.SetWindowText(GetKeyListName(joypad[MOTION(KEY_LEFT)])); left.SetWindowText(GetKeyListName(theApp.input->joypaddata[MOTION(KEY_LEFT)]));
CopyKeys(right.m_Keys, joypad[MOTION(KEY_RIGHT)]); CopyKeys(right.m_Keys, theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
right.SetWindowText(GetKeyListName(joypad[MOTION(KEY_RIGHT)])); right.SetWindowText(GetKeyListName(theApp.input->joypaddata[MOTION(KEY_RIGHT)]));
CenterWindow(); CenterWindow();
@ -400,16 +390,16 @@ void MotionConfig::assignKey(int id, int key)
{ {
switch(id) { switch(id) {
case IDC_EDIT_LEFT: case IDC_EDIT_LEFT:
AssignKey(joypad[MOTION(KEY_LEFT)],key); AssignKey(theApp.input->joypaddata[MOTION(KEY_LEFT)],key);
break; break;
case IDC_EDIT_RIGHT: case IDC_EDIT_RIGHT:
AssignKey(joypad[MOTION(KEY_RIGHT)],key); AssignKey(theApp.input->joypaddata[MOTION(KEY_RIGHT)],key);
break; break;
case IDC_EDIT_UP: case IDC_EDIT_UP:
AssignKey(joypad[MOTION(KEY_UP)],key); AssignKey(theApp.input->joypaddata[MOTION(KEY_UP)],key);
break; break;
case IDC_EDIT_DOWN: case IDC_EDIT_DOWN:
AssignKey(joypad[MOTION(KEY_DOWN)],key); AssignKey(theApp.input->joypaddata[MOTION(KEY_DOWN)],key);
break; break;
} }
} }

View File

@ -74,7 +74,7 @@ class JoypadConfig : public CDialog
{ {
// Construction // Construction
public: public:
void assignKey(int id, int key); void assignKey(int id, LONG_PTR key);
JoypadConfig(int w, CWnd* pParent = NULL); // standard constructor JoypadConfig(int w, CWnd* pParent = NULL); // standard constructor
// Dialog Data // Dialog Data

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -225,7 +225,7 @@ BOOL Logging::OnInitDialog()
m_dma2 = (systemVerbose & 64) != 0; m_dma2 = (systemVerbose & 64) != 0;
m_dma3 = (systemVerbose & 128) != 0; m_dma3 = (systemVerbose & 128) != 0;
m_undefined = (systemVerbose & 256) != 0; m_undefined = (systemVerbose & 256) != 0;
m_agbprint = (systemVerbose & 256) != 0; m_agbprint = (systemVerbose & 512) != 0;
UpdateData(FALSE); UpdateData(FALSE);
m_log.LimitText(-1); m_log.LimitText(-1);
@ -237,7 +237,7 @@ BOOL Logging::OnInitDialog()
void Logging::log(const char *s) void Logging::log(const char *s)
{ {
int size = ::SendMessage(m_log, WM_GETTEXTLENGTH, 0, 0); DWORD size = (DWORD)::SendMessage(m_log, WM_GETTEXTLENGTH, 0, 0);
m_log.SetSel(size, size); m_log.SetSel(size, size);
m_log.ReplaceSel(s); m_log.ReplaceSel(s);
} }

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -24,12 +24,14 @@
#include "MainWnd.h" #include "MainWnd.h"
#include <winsock.h> #include <winsock.h>
#include <shlwapi.h>
#include "FileDlg.h" #include "FileDlg.h"
#include "Reg.h" #include "Reg.h"
#include "WinResUtil.h" #include "WinResUtil.h"
#include "../System.h" #include "../System.h"
#include "../AutoBuild.h"
#include "../cheatSearch.h" #include "../cheatSearch.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
@ -41,9 +43,6 @@
#include "../RTC.h" #include "../RTC.h"
#include "../Sound.h" #include "../Sound.h"
#include "../Util.h" #include "../Util.h"
#include ".\mainwnd.h"
#include "../Link.h" // Link
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@ -54,6 +53,7 @@ static char THIS_FILE[] = __FILE__;
#define VBA_CONFIRM_MODE WM_APP + 100 #define VBA_CONFIRM_MODE WM_APP + 100
extern void remoteCleanUp(); extern void remoteCleanUp();
extern int gbHardware;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// MainWnd // MainWnd
@ -179,6 +179,10 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLTRIANGLE, OnUpdateOptionsVideoRenderoptionsGltriangle) ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLTRIANGLE, OnUpdateOptionsVideoRenderoptionsGltriangle)
ON_COMMAND(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS, OnOptionsVideoRenderoptionsGlquads) ON_COMMAND(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS, OnOptionsVideoRenderoptionsGlquads)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS, OnUpdateOptionsVideoRenderoptionsGlquads) ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS, OnUpdateOptionsVideoRenderoptionsGlquads)
ON_COMMAND(ID_OPTIONS_VIDEO_RENDEROPTIONS_SELECTSKIN, OnOptionsVideoRenderoptionsSelectskin)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_SELECTSKIN, OnUpdateOptionsVideoRenderoptionsSelectskin)
ON_COMMAND(ID_OPTIONS_VIDEO_RENDEROPTIONS_SKIN, OnOptionsVideoRenderoptionsSkin)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_SKIN, OnUpdateOptionsVideoRenderoptionsSkin)
ON_WM_CONTEXTMENU() ON_WM_CONTEXTMENU()
ON_COMMAND(ID_OPTIONS_EMULATOR_ASSOCIATE, OnOptionsEmulatorAssociate) ON_COMMAND(ID_OPTIONS_EMULATOR_ASSOCIATE, OnOptionsEmulatorAssociate)
ON_COMMAND(ID_OPTIONS_EMULATOR_DIRECTORIES, OnOptionsEmulatorDirectories) ON_COMMAND(ID_OPTIONS_EMULATOR_DIRECTORIES, OnOptionsEmulatorDirectories)
@ -190,14 +194,14 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_PAUSEWHENINACTIVE, OnUpdateOptionsEmulatorPausewheninactive) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_PAUSEWHENINACTIVE, OnUpdateOptionsEmulatorPausewheninactive)
ON_COMMAND(ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE, OnOptionsEmulatorSpeeduptoggle) ON_COMMAND(ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE, OnOptionsEmulatorSpeeduptoggle)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE, OnUpdateOptionsEmulatorSpeeduptoggle) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE, OnUpdateOptionsEmulatorSpeeduptoggle)
ON_COMMAND(ID_OPTIONS_EMULATOR_REMOVEINTROSGBA, OnOptionsEmulatorRemoveintrosgba)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_REMOVEINTROSGBA, OnUpdateOptionsEmulatorRemoveintrosgba)
ON_COMMAND(ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH, OnOptionsEmulatorAutomaticallyipspatch) ON_COMMAND(ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH, OnOptionsEmulatorAutomaticallyipspatch)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH, OnUpdateOptionsEmulatorAutomaticallyipspatch) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH, OnUpdateOptionsEmulatorAutomaticallyipspatch)
ON_COMMAND(ID_OPTIONS_EMULATOR_AGBPRINT, OnOptionsEmulatorAgbprint) ON_COMMAND(ID_OPTIONS_EMULATOR_AGBPRINT, OnOptionsEmulatorAgbprint)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AGBPRINT, OnUpdateOptionsEmulatorAgbprint) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AGBPRINT, OnUpdateOptionsEmulatorAgbprint)
ON_COMMAND(ID_OPTIONS_EMULATOR_REALTIMECLOCK, OnOptionsEmulatorRealtimeclock) ON_COMMAND(ID_OPTIONS_EMULATOR_REALTIMECLOCK, OnOptionsEmulatorRealtimeclock)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_REALTIMECLOCK, OnUpdateOptionsEmulatorRealtimeclock) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_REALTIMECLOCK, OnUpdateOptionsEmulatorRealtimeclock)
ON_COMMAND(ID_OPTIONS_EMULATOR_GENERICFLASHCARD, OnOptionsEmulatorGenericflashcard)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_GENERICFLASHCARD, OnUpdateOptionsEmulatorGenericflashcard)
ON_COMMAND(ID_OPTIONS_EMULATOR_AUTOHIDEMENU, OnOptionsEmulatorAutohidemenu) ON_COMMAND(ID_OPTIONS_EMULATOR_AUTOHIDEMENU, OnOptionsEmulatorAutohidemenu)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOHIDEMENU, OnUpdateOptionsEmulatorAutohidemenu) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOHIDEMENU, OnUpdateOptionsEmulatorAutohidemenu)
ON_COMMAND(ID_OPTIONS_EMULATOR_REWINDINTERVAL, OnOptionsEmulatorRewindinterval) ON_COMMAND(ID_OPTIONS_EMULATOR_REWINDINTERVAL, OnOptionsEmulatorRewindinterval)
@ -226,10 +230,10 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_PNGFORMAT, OnUpdateOptionsEmulatorPngformat) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_PNGFORMAT, OnUpdateOptionsEmulatorPngformat)
ON_COMMAND(ID_OPTIONS_EMULATOR_BMPFORMAT, OnOptionsEmulatorBmpformat) ON_COMMAND(ID_OPTIONS_EMULATOR_BMPFORMAT, OnOptionsEmulatorBmpformat)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_BMPFORMAT, OnUpdateOptionsEmulatorBmpformat) ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_BMPFORMAT, OnUpdateOptionsEmulatorBmpformat)
// ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundOff) /* mute hax */ ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundOff)
// ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundOff) /* mute hax */ ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundOff)
ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundMute) /* mute hax */ ON_COMMAND(ID_OPTIONS_SOUND_MUTE, OnOptionsSoundMute)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundMute) /* mute hax */ ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_MUTE, OnUpdateOptionsSoundMute)
ON_COMMAND(ID_OPTIONS_SOUND_ON, OnOptionsSoundOn) ON_COMMAND(ID_OPTIONS_SOUND_ON, OnOptionsSoundOn)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_ON, OnUpdateOptionsSoundOn) ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_ON, OnUpdateOptionsSoundOn)
ON_COMMAND(ID_OPTIONS_SOUND_USEOLDSYNCHRONIZATION, OnOptionsSoundUseoldsynchronization) ON_COMMAND(ID_OPTIONS_SOUND_USEOLDSYNCHRONIZATION, OnOptionsSoundUseoldsynchronization)
@ -374,7 +378,9 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND(ID_CHEATS_DISABLECHEATS, OnCheatsDisablecheats) ON_COMMAND(ID_CHEATS_DISABLECHEATS, OnCheatsDisablecheats)
ON_UPDATE_COMMAND_UI(ID_CHEATS_DISABLECHEATS, OnUpdateCheatsDisablecheats) ON_UPDATE_COMMAND_UI(ID_CHEATS_DISABLECHEATS, OnUpdateCheatsDisablecheats)
ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREENMAXSCALE, OnOptionsVideoFullscreenmaxscale) ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREENMAXSCALE, OnOptionsVideoFullscreenmaxscale)
ON_COMMAND(ID_OPTIONS_EMULATOR_GAMEOVERRIDES, OnOptionsEmulatorGameoverrides)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_GAMEOVERRIDES, OnUpdateOptionsEmulatorGameoverrides)
ON_COMMAND(ID_HELP_GNUPUBLICLICENSE, OnHelpGnupubliclicense)
ON_COMMAND(ID_OPTIONS_LINK_OPTIONS, OnLinkOptions) ON_COMMAND(ID_OPTIONS_LINK_OPTIONS, OnLinkOptions)
ON_COMMAND(ID_OPTIONS_LINK_LOG, OnOptionsLinkLog) ON_COMMAND(ID_OPTIONS_LINK_LOG, OnOptionsLinkLog)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_LINK_LOG, OnUpdateOptionsLinkLog) ON_UPDATE_COMMAND_UI(ID_OPTIONS_LINK_LOG, OnUpdateOptionsLinkLog)
@ -391,6 +397,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND_EX_RANGE(ID_OPTIONS_VIDEO_X1, ID_OPTIONS_VIDEO_X4, OnOptionVideoSize) ON_COMMAND_EX_RANGE(ID_OPTIONS_VIDEO_X1, ID_OPTIONS_VIDEO_X4, OnOptionVideoSize)
ON_COMMAND_EX_RANGE(ID_OPTIONS_VIDEO_LAYERS_BG0, ID_OPTIONS_VIDEO_LAYERS_OBJWIN, OnVideoLayer) ON_COMMAND_EX_RANGE(ID_OPTIONS_VIDEO_LAYERS_BG0, ID_OPTIONS_VIDEO_LAYERS_OBJWIN, OnVideoLayer)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_VIDEO_LAYERS_BG0, ID_OPTIONS_VIDEO_LAYERS_OBJWIN, OnUpdateVideoLayer) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_VIDEO_LAYERS_BG0, ID_OPTIONS_VIDEO_LAYERS_OBJWIN, OnUpdateVideoLayer)
ON_COMMAND(ID_SYSTEM_MINIMIZE, OnSystemMinimize)
ON_COMMAND_EX_RANGE(ID_OPTIONS_EMULATOR_SHOWSPEED_NONE, ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT, OnOptionsEmulatorShowSpeed) ON_COMMAND_EX_RANGE(ID_OPTIONS_EMULATOR_SHOWSPEED_NONE, ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT, OnOptionsEmulatorShowSpeed)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_EMULATOR_SHOWSPEED_NONE, ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT, OnUpdateOptionsEmulatorShowSpeed) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_EMULATOR_SHOWSPEED_NONE, ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT, OnUpdateOptionsEmulatorShowSpeed)
ON_COMMAND_EX_RANGE(ID_OPTIONS_SOUND_VOLUME_1X, ID_OPTIONS_SOUND_VOLUME_4X, OnOptionsSoundVolume) ON_COMMAND_EX_RANGE(ID_OPTIONS_SOUND_VOLUME_1X, ID_OPTIONS_SOUND_VOLUME_4X, OnOptionsSoundVolume)
@ -398,7 +405,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND_EX_RANGE(ID_OPTIONS_PRIORITY_HIGHEST, ID_OPTIONS_PRIORITY_BELOWNORMAL, OnOptionsPriority) ON_COMMAND_EX_RANGE(ID_OPTIONS_PRIORITY_HIGHEST, ID_OPTIONS_PRIORITY_BELOWNORMAL, OnOptionsPriority)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_PRIORITY_HIGHEST, ID_OPTIONS_PRIORITY_BELOWNORMAL, OnUpdateOptionsPriority) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_PRIORITY_HIGHEST, ID_OPTIONS_PRIORITY_BELOWNORMAL, OnUpdateOptionsPriority)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_NORMAL, ID_OPTIONS_FILTER_TVMODE, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_NORMAL, ID_OPTIONS_FILTER_TVMODE, OnOptionsFilter)
ON_COMMAND_EX(ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL, ID_OPTIONS_FILTER16BIT_MOTIONBLUREXPERIMENTAL, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X, ID_OPTIONS_FILTER16BIT_SIMPLE2X, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X, ID_OPTIONS_FILTER16BIT_SIMPLE2X, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnOptionsFilter)
ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnOptionsFilter) ON_COMMAND_EX_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnOptionsFilter)
@ -408,7 +415,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND_EX(ID_OPTIONS_FILTER_SIMPLE3X, OnOptionsFilter) ON_COMMAND_EX(ID_OPTIONS_FILTER_SIMPLE3X, OnOptionsFilter)
ON_COMMAND_EX(ID_OPTIONS_FILTER_SIMPLE4X, OnOptionsFilter) ON_COMMAND_EX(ID_OPTIONS_FILTER_SIMPLE4X, OnOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_NORMAL, ID_OPTIONS_FILTER_TVMODE, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_NORMAL, ID_OPTIONS_FILTER_TVMODE, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL, ID_OPTIONS_FILTER16BIT_MOTIONBLUREXPERIMENTAL, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X, ID_OPTIONS_FILTER16BIT_SIMPLE2X, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X, ID_OPTIONS_FILTER16BIT_SIMPLE2X, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, OnUpdateOptionsFilter)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnUpdateOptionsFilter) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_FILTER_SCANLINES, ID_OPTIONS_FILTER_SCANLINES, OnUpdateOptionsFilter)
@ -425,6 +432,8 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_JOYPAD_AUTOFIRE_A, ID_OPTIONS_JOYPAD_AUTOFIRE_R, OnUpdateOptionsJoypadAutofire) ON_UPDATE_COMMAND_UI_RANGE(ID_OPTIONS_JOYPAD_AUTOFIRE_A, ID_OPTIONS_JOYPAD_AUTOFIRE_R, OnUpdateOptionsJoypadAutofire)
ON_MESSAGE(VBA_CONFIRM_MODE, OnConfirmMode) ON_MESSAGE(VBA_CONFIRM_MODE, OnConfirmMode)
ON_MESSAGE(WM_SYSCOMMAND, OnMySysCommand) ON_MESSAGE(WM_SYSCOMMAND, OnMySysCommand)
ON_COMMAND(ID_OPTIONS_SOUND_HARDWAREACCELERATION, &MainWnd::OnOptionsSoundHardwareacceleration)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_HARDWAREACCELERATION, &MainWnd::OnUpdateOptionsSoundHardwareacceleration)
ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREEN1280X1024, OnOptionsVideoFullscreen1280x1024) ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREEN1280X1024, OnOptionsVideoFullscreen1280x1024)
ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREEN1024X768, OnOptionsVideoFullscreen1024x768) ON_COMMAND(ID_OPTIONS_VIDEO_FULLSCREEN1024X768, OnOptionsVideoFullscreen1024x768)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_FULLSCREEN1024X768, OnUpdateOptionsVideoFullscreen1024x768) ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_FULLSCREEN1024X768, OnUpdateOptionsVideoFullscreen1024x768)
@ -443,6 +452,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
void MainWnd::OnClose() void MainWnd::OnClose()
{ {
emulating = false;
CWnd::OnClose(); CWnd::OnClose();
delete this; delete this;
@ -493,13 +503,40 @@ bool MainWnd::FileRun()
return false; return false;
} }
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
theApp.cartridgeType = (int)type; theApp.cartridgeType = type;
if(type == IMAGE_GB) { if(type == IMAGE_GB) {
genericflashcardEnable = theApp.winGenericflashcardEnable;
if(!gbLoadRom(theApp.szFile)) if(!gbLoadRom(theApp.szFile))
return false; return false;
gbGetHardwareType();
// used for the handling of the gb Boot Rom
if (gbHardware & 5)
{
char tempName[2048];
GetModuleFileName(NULL, tempName, 2048);
char *p = strrchr(tempName, '\\');
if(p)
*p = 0;
strcat(tempName, "\\DMG_ROM.bin");
skipBios = theApp.skipBiosFile ? true : false;
gbCPUInit(tempName, theApp.useBiosFile ? true : false);
}
gbReset();
theApp.emulator = GBSystem; theApp.emulator = GBSystem;
gbBorderOn = theApp.winGbBorderOn; gbBorderOn = theApp.winGbBorderOn;
theApp.romSize = gbRomSize; theApp.romSize = gbRomSize;
if(theApp.autoIPS) { if(theApp.autoIPS) {
int size = gbRomSize; int size = gbRomSize;
utilApplyIPS(ipsname, &gbRom, &size); utilApplyIPS(ipsname, &gbRom, &size);
@ -521,9 +558,6 @@ bool MainWnd::FileRun()
rtcEnable(theApp.winRtcEnable); rtcEnable(theApp.winRtcEnable);
cpuSaveType = theApp.winSaveType; cpuSaveType = theApp.winSaveType;
// if(cpuEnhancedDetection && winSaveType == 0) {
// utilGBAFindSave(rom, size);
// }
GetModuleFileName(NULL, tempName, 2048); GetModuleFileName(NULL, tempName, 2048);
char *p = strrchr(tempName, '\\'); char *p = strrchr(tempName, '\\');
@ -556,6 +590,12 @@ bool MainWnd::FileRun()
tempName); tempName);
if(i != (UINT)-1 && (i <= 5)) if(i != (UINT)-1 && (i <= 5))
cpuSaveType = (int)i; cpuSaveType = (int)i;
i = GetPrivateProfileInt(buffer,
"mirroringEnabled",
-1,
tempName);
if(i != (UINT)-1)
doMirroring (i == 0 ? false : true);
theApp.emulator = GBASystem; theApp.emulator = GBASystem;
/* disabled due to problems /* disabled due to problems
@ -579,10 +619,8 @@ bool MainWnd::FileRun()
else else
soundReset(); soundReset();
} else { } else {
//if(!soundOffFlag) /* mute hax */ if(!soundOffFlag)
soundInit(!theApp.cartridgeType); soundInit(!(theApp.cartridgeType==1));
if ( soundOffFlag )
soundDisable(0x30f);
theApp.soundInitialized = true; theApp.soundInitialized = true;
} }
@ -760,6 +798,16 @@ void MainWnd::winSaveCheatListDefault()
else else
name = theApp.filename; name = theApp.filename;
CString dir = regQueryStringValue("saveDir", NULL); CString dir = regQueryStringValue("saveDir", NULL);
if( dir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, dir );
dir = baseDir;
}
if(!dir.GetLength()) if(!dir.GetLength())
dir = getDirFromFile(filename); dir = getDirFromFile(filename);
@ -792,6 +840,16 @@ void MainWnd::winLoadCheatListDefault()
else else
name = theApp.filename; name = theApp.filename;
CString dir = regQueryStringValue("saveDir", NULL); CString dir = regQueryStringValue("saveDir", NULL);
if( dir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, dir );
dir = baseDir;
}
if(!dir.GetLength()) if(!dir.GetLength())
dir = getDirFromFile(filename); dir = getDirFromFile(filename);
@ -854,6 +912,16 @@ void MainWnd::writeBatteryFile()
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("batteryDir", NULL); CString saveDir = regQueryStringValue("batteryDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -881,6 +949,16 @@ void MainWnd::readBatteryFile()
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("batteryDir", NULL); CString saveDir = regQueryStringValue("batteryDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -924,39 +1002,128 @@ bool MainWnd::writeSaveGame(const char *name)
void MainWnd::OnContextMenu(CWnd* pWnd, CPoint point) void MainWnd::OnContextMenu(CWnd* pWnd, CPoint point)
{ {
winMouseOn(); winMouseOn();
if(theApp.skin) {
if(theApp.popup == NULL) {
theApp.winAccelMgr.UpdateMenu(theApp.menu);
theApp.popup = CreatePopupMenu();
if(theApp.menu != NULL) {
int count = GetMenuItemCount(theApp.menu);
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
if(info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
for(int i = 0; i < count; i++) {
char buffer[256];
MENUITEMINFO info;
ZeroMemory(&info, sizeof(info));
info.cbSize = sizeof(info) - sizeof(HBITMAP);
info.fMask = MIIM_STRING | MIIM_SUBMENU;
info.dwTypeData = buffer;
info.cch = 256;
if(!GetMenuItemInfo(theApp.menu, i, MF_BYPOSITION, &info)) {
}
if(!AppendMenu(theApp.popup, MF_POPUP|MF_STRING, (UINT_PTR)info.hSubMenu, buffer)) {
}
}
} else {
for(int i = 0; i < count; i++) {
wchar_t buffer[256];
MENUITEMINFOW info;
ZeroMemory(&info, sizeof(info));
info.cbSize = sizeof(info) - sizeof(HBITMAP);
info.fMask = MIIM_STRING | MIIM_SUBMENU;
info.dwTypeData = buffer;
info.cch = 256;
if(!GetMenuItemInfoW(theApp.menu, i, MF_BYPOSITION, &info)) {
}
if(!AppendMenuW(theApp.popup, MF_POPUP|MF_STRING, (UINT_PTR)info.hSubMenu, buffer)) {
}
}
}
}
}
int x = point.x;
int y = point.y;
if(x == -1 && y == -1) {
x = (theApp.dest.left + theApp.dest.right) / 2;
y = (theApp.dest.top + theApp.dest.bottom) / 2;
}
if(!TrackPopupMenu(theApp.popup, 0, x, y, 0, m_hWnd, NULL)) {
}
}
} }
bool MainWnd::fileOpenSelect() void MainWnd::OnSystemMinimize()
{ {
theApp.dir = ""; ShowWindow(SW_SHOWMINIMIZED);
CString initialDir = regQueryStringValue("romdir","."); }
if(!initialDir.IsEmpty())
bool MainWnd::fileOpenSelect( bool gb )
{
theApp.dir = _T("");
CString initialDir;
if( gb ) {
initialDir = regQueryStringValue( _T("gbromdir"), _T(".") );
} else {
initialDir = regQueryStringValue( _T("romdir"), _T(".") );
}
if( initialDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, initialDir );
initialDir = baseDir;
}
if( !initialDir.IsEmpty() ) {
theApp.dir = initialDir; theApp.dir = initialDir;
}
int selectedFilter = regQueryDwordValue("selectedFilter", 0); int selectedFilter = 0;
if(selectedFilter < 0 || selectedFilter > 2) if( !gb ) {
selectedFilter = regQueryDwordValue( _T("selectedFilter"), 0);
if( (selectedFilter < 0) || (selectedFilter > 2) ) {
selectedFilter = 0; selectedFilter = 0;
}
}
theApp.szFile = ""; theApp.szFile = _T("");
LPCTSTR exts[] = { "" }; LPCTSTR exts[] = { _T(""), _T(""), _T(""), _T("") };
CString filter = winLoadFilter(IDS_FILTER_ROM); CString filter;
CString title = winResLoadString(IDS_SELECT_ROM); CString title;
if( gb ) {
filter = winLoadFilter( IDS_FILTER_GBROM );
title = winResLoadString( IDS_SELECT_ROM );
} else {
filter = winLoadFilter( IDS_FILTER_ROM );
title = winResLoadString( IDS_SELECT_ROM );
}
FileDlg dlg(this, "", filter, selectedFilter, "", exts, theApp.dir, title, false); FileDlg dlg( this, _T(""), filter, selectedFilter, _T(""), exts, theApp.dir, title, false);
if( dlg.DoModal() == IDOK ) { if( dlg.DoModal() == IDOK ) {
regSetDwordValue("selectedFilter", dlg.m_ofn.nFilterIndex); if( !gb ) {
regSetDwordValue( _T("selectedFilter"), dlg.m_ofn.nFilterIndex );
}
theApp.szFile = dlg.GetPathName(); theApp.szFile = dlg.GetPathName();
theApp.dir = theApp.szFile.Left( dlg.m_ofn.nFileOffset ); theApp.dir = theApp.szFile.Left( dlg.m_ofn.nFileOffset );
if(theApp.dir.GetLength() > 3 && theApp.dir[theApp.dir.GetLength()-1] == '\\') if( (theApp.dir.GetLength() > 3) && (theApp.dir[theApp.dir.GetLength()-1] == _T('\\')) ) {
theApp.dir = theApp.dir.Left( theApp.dir.GetLength() - 1 ); theApp.dir = theApp.dir.Left( theApp.dir.GetLength() - 1 );
regSetStringValue("romdir", theApp.dir); }
SetCurrentDirectory( theApp.dir );
return true; return true;
} }
return false; return false;
} }
void MainWnd::OnPaint() void MainWnd::OnPaint()
{ {
CPaintDC dc(this); // device context for painting CPaintDC dc(this); // device context for painting
@ -986,6 +1153,16 @@ void MainWnd::screenCapture(int captureNumber)
CString buffer; CString buffer;
CString captureDir = regQueryStringValue("captureDir", ""); CString captureDir = regQueryStringValue("captureDir", "");
if( captureDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, captureDir );
captureDir = baseDir;
}
int index = theApp.filename.ReverseFind('\\'); int index = theApp.filename.ReverseFind('\\');
CString name; CString name;
@ -1014,6 +1191,15 @@ void MainWnd::screenCapture(int captureNumber)
captureNumber, captureNumber,
ext); ext);
// check if file exists
DWORD dwAttr = GetFileAttributes( buffer );
if( dwAttr != INVALID_FILE_ATTRIBUTES ) {
// screenshot file already exists
screenCapture(++captureNumber);
// this will recursively use the first non-existent screenshot number
return;
}
if(theApp.captureFormat == 0) if(theApp.captureFormat == 0)
theApp.emulator.emuWritePNG(buffer); theApp.emulator.emuWritePNG(buffer);
else else
@ -1126,12 +1312,3 @@ LRESULT MainWnd::OnMySysCommand(WPARAM wParam, LPARAM lParam)
return Default(); return Default();
} }
void MainWnd::OnSetFocus(CWnd * pOldWnd)
{
theApp.dinputKeyFocus = true;
}
void MainWnd::OnKillFocus(CWnd * pNewWnd)
{
theApp.dinputKeyFocus = false;
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -55,7 +55,7 @@ class MainWnd : public CWnd
void winMouseOn(); void winMouseOn();
void screenCapture(int captureNumber); void screenCapture(int captureNumber);
HACCEL m_hAccelTable; HACCEL m_hAccelTable;
bool fileOpenSelect(); bool fileOpenSelect( bool gb = false );
afx_msg LRESULT OnConfirmMode(WPARAM, LPARAM); afx_msg LRESULT OnConfirmMode(WPARAM, LPARAM);
afx_msg LRESULT OnMySysCommand(WPARAM, LPARAM); afx_msg LRESULT OnMySysCommand(WPARAM, LPARAM);
afx_msg void OnUpdateFileLoadGameSlot(CCmdUI *pCmdUI); afx_msg void OnUpdateFileLoadGameSlot(CCmdUI *pCmdUI);
@ -70,9 +70,6 @@ class MainWnd : public CWnd
afx_msg BOOL OnOptionsFilter(UINT nID); afx_msg BOOL OnOptionsFilter(UINT nID);
afx_msg void OnUpdateOptionsPriority(CCmdUI *pCmdUI); afx_msg void OnUpdateOptionsPriority(CCmdUI *pCmdUI);
afx_msg BOOL OnOptionsPriority(UINT nID); afx_msg BOOL OnOptionsPriority(UINT nID);
afx_msg void OnSetFocus(CWnd * pOldWnd);
afx_msg void OnKillFocus(CWnd * pNewWnd);
void updateSoundChannels(UINT nID); void updateSoundChannels(UINT nID);
afx_msg void OnUpdateOptionsSoundVolume(CCmdUI *pCmdUI); afx_msg void OnUpdateOptionsSoundVolume(CCmdUI *pCmdUI);
afx_msg BOOL OnOptionsSoundVolume(UINT nID); afx_msg BOOL OnOptionsSoundVolume(UINT nID);
@ -209,6 +206,10 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoRenderoptionsGlquads(); afx_msg void OnOptionsVideoRenderoptionsGlquads();
afx_msg void OnUpdateOptionsVideoRenderoptionsGlquads(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsVideoRenderoptionsGlquads(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoRenderoptionsSelectskin();
afx_msg void OnUpdateOptionsVideoRenderoptionsSelectskin(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoRenderoptionsSkin();
afx_msg void OnUpdateOptionsVideoRenderoptionsSkin(CCmdUI* pCmdUI);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnOptionsEmulatorAssociate(); afx_msg void OnOptionsEmulatorAssociate();
afx_msg void OnOptionsEmulatorDirectories(); afx_msg void OnOptionsEmulatorDirectories();
@ -220,14 +221,14 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsEmulatorPausewheninactive(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorPausewheninactive(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorSpeeduptoggle(); afx_msg void OnOptionsEmulatorSpeeduptoggle();
afx_msg void OnUpdateOptionsEmulatorSpeeduptoggle(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorSpeeduptoggle(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRemoveintrosgba();
afx_msg void OnUpdateOptionsEmulatorRemoveintrosgba(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAutomaticallyipspatch(); afx_msg void OnOptionsEmulatorAutomaticallyipspatch();
afx_msg void OnUpdateOptionsEmulatorAutomaticallyipspatch(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorAutomaticallyipspatch(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAgbprint(); afx_msg void OnOptionsEmulatorAgbprint();
afx_msg void OnUpdateOptionsEmulatorAgbprint(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorAgbprint(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRealtimeclock(); afx_msg void OnOptionsEmulatorRealtimeclock();
afx_msg void OnUpdateOptionsEmulatorRealtimeclock(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorRealtimeclock(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorGenericflashcard();
afx_msg void OnUpdateOptionsEmulatorGenericflashcard(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAutohidemenu(); afx_msg void OnOptionsEmulatorAutohidemenu();
afx_msg void OnUpdateOptionsEmulatorAutohidemenu(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorAutohidemenu(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRewindinterval(); afx_msg void OnOptionsEmulatorRewindinterval();
@ -256,8 +257,8 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsEmulatorPngformat(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorPngformat(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorBmpformat(); afx_msg void OnOptionsEmulatorBmpformat();
afx_msg void OnUpdateOptionsEmulatorBmpformat(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsEmulatorBmpformat(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundOff(); /* mute hax */ afx_msg void OnOptionsSoundOff();
afx_msg void OnUpdateOptionsSoundOff(CCmdUI* pCmdUI); /* mute hax */ afx_msg void OnUpdateOptionsSoundOff(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundMute(); afx_msg void OnOptionsSoundMute();
afx_msg void OnUpdateOptionsSoundMute(CCmdUI* pCmdUI); afx_msg void OnUpdateOptionsSoundMute(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundOn(); afx_msg void OnOptionsSoundOn();
@ -408,6 +409,9 @@ class MainWnd : public CWnd
afx_msg void OnCheatsDisablecheats(); afx_msg void OnCheatsDisablecheats();
afx_msg void OnUpdateCheatsDisablecheats(CCmdUI* pCmdUI); afx_msg void OnUpdateCheatsDisablecheats(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoFullscreenmaxscale(); afx_msg void OnOptionsVideoFullscreenmaxscale();
afx_msg void OnOptionsEmulatorGameoverrides();
afx_msg void OnUpdateOptionsEmulatorGameoverrides(CCmdUI* pCmdUI);
afx_msg void OnHelpGnupubliclicense();
//}}AFX_MSG //}}AFX_MSG
DECLARE_MESSAGE_MAP() DECLARE_MESSAGE_MAP()
@ -420,6 +424,8 @@ class MainWnd : public CWnd
afx_msg BOOL OnOptionsSoundPcminterpolation(UINT nID); afx_msg BOOL OnOptionsSoundPcminterpolation(UINT nID);
afx_msg void OnUpdateOptionsSoundPcminterpolation(CCmdUI *pCmdUI); afx_msg void OnUpdateOptionsSoundPcminterpolation(CCmdUI *pCmdUI);
public: public:
afx_msg void OnOptionsSoundHardwareacceleration();
afx_msg void OnUpdateOptionsSoundHardwareacceleration(CCmdUI *pCmdUI);
afx_msg void OnOptionsVideoFullscreen1280x1024(); afx_msg void OnOptionsVideoFullscreen1280x1024();
afx_msg void OnOptionsVideoFullscreen1024x768(); afx_msg void OnOptionsVideoFullscreen1024x768();
afx_msg void OnUpdateOptionsVideoFullscreen1024x768(CCmdUI *pCmdUI); afx_msg void OnUpdateOptionsVideoFullscreen1024x768(CCmdUI *pCmdUI);
@ -430,8 +436,6 @@ public:
void OnOptionsLinkRFU() ; void OnOptionsLinkRFU() ;
void OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI) ; void OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI) ;
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005-2006 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -19,6 +19,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "MainWnd.h" #include "MainWnd.h"
#include <shlwapi.h>
#include "ExportGSASnapshot.h" #include "ExportGSASnapshot.h"
#include "FileDlg.h" #include "FileDlg.h"
#include "GSACodeSelect.h" #include "GSACodeSelect.h"
@ -33,20 +35,22 @@
#include "../gb/GB.h" #include "../gb/GB.h"
#include "../gb/gbCheats.h" #include "../gb/gbCheats.h"
#include "../gb/gbGlobals.h" #include "../gb/gbGlobals.h"
#include "../Link.h"
extern int emulating; extern int emulating;
extern void remoteCleanUp(); extern void remoteCleanUp();
extern void InterframeCleanup();
void MainWnd::OnFileOpen() void MainWnd::OnFileOpen()
{ {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
if(fileOpenSelect()) { if( fileOpenSelect( false ) ) {
FileRun(); FileRun();
} }
} }
void MainWnd::OnFilePause() void MainWnd::OnFilePause()
{ {
theApp.paused = !theApp.paused; theApp.paused = !theApp.paused;
@ -159,32 +163,16 @@ void MainWnd::OnUpdateFileClose(CCmdUI* pCmdUI)
pCmdUI->Enable(emulating); pCmdUI->Enable(emulating);
} }
void MainWnd::OnFileOpengameboy() void MainWnd::OnFileOpengameboy()
{ {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
theApp.dir = ""; if( fileOpenSelect( true ) ) {
CString initialDir = regQueryStringValue("gbromdir",".");
if(!initialDir.IsEmpty())
theApp.dir = initialDir;
theApp.szFile = "";
LPCTSTR exts[] = { "" };
CString filter = winLoadFilter(IDS_FILTER_GBROM);
CString title = winResLoadString(IDS_SELECT_ROM);
FileDlg dlg(this, "", filter, 0, "", exts, initialDir, title, false);
if(dlg.DoModal() == IDOK) {
theApp.szFile = dlg.GetPathName();
theApp.dir = theApp.szFile.Left(dlg.m_ofn.nFileOffset);
if(theApp.dir.GetLength() > 3 && theApp.dir[theApp.dir.GetLength()-1] == '\\')
theApp.dir = theApp.dir.Left(theApp.dir.GetLength()-1);
regSetStringValue("gbromdir", theApp.dir);
FileRun(); FileRun();
} }
} }
void MainWnd::OnFileLoad() void MainWnd::OnFileLoad()
{ {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
@ -199,6 +187,16 @@ void MainWnd::OnFileLoad()
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -246,6 +244,16 @@ BOOL MainWnd::OnFileLoadSlot(UINT nID)
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -255,17 +263,22 @@ BOOL MainWnd::OnFileLoadSlot(UINT nID)
else else
filename.Format("%s\\%s%d.sgm", saveDir, buffer, nID); filename.Format("%s\\%s%d.sgm", saveDir, buffer, nID);
bool res = loadSaveGame(filename);
theApp.rewindCount = 0;
theApp.rewindCounter = 0;
theApp.rewindSaveNeeded = false;
CString format = winResLoadString(IDS_LOADED_STATE_N); CString format = winResLoadString(IDS_LOADED_STATE_N);
buffer.Format(format, nID); buffer.Format(format, nID);
bool res = loadSaveGame(filename);
if (theApp.paused)
InterframeCleanup();
systemScreenMessage(buffer); systemScreenMessage(buffer);
systemDrawScreen();
//theApp.rewindCount = 0;
//theApp.rewindCounter = 0;
//theApp.rewindSaveNeeded = false;
return res; return res;
} }
@ -283,6 +296,16 @@ void MainWnd::OnFileSave()
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -325,6 +348,16 @@ BOOL MainWnd::OnFileSaveSlot(UINT nID)
buffer = theApp.filename; buffer = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -341,6 +374,8 @@ BOOL MainWnd::OnFileSaveSlot(UINT nID)
systemScreenMessage(buffer); systemScreenMessage(buffer);
systemDrawScreen();
return res; return res;
} }
@ -352,6 +387,16 @@ void MainWnd::OnFileImportBatteryfile()
CString title = winResLoadString(IDS_SELECT_BATTERY_FILE); CString title = winResLoadString(IDS_SELECT_BATTERY_FILE);
CString saveDir = regQueryStringValue("batteryDir", NULL); CString saveDir = regQueryStringValue("batteryDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -376,7 +421,8 @@ void MainWnd::OnFileImportBatteryfile()
if(!res) if(!res)
systemMessage(MSG_CANNOT_OPEN_FILE, "Cannot open file %s", dlg.GetPathName()); systemMessage(MSG_CANNOT_OPEN_FILE, "Cannot open file %s", dlg.GetPathName());
else { else {
theApp.emulator.emuReset(); //Removed the reset to allow loading a battery file 'within' a save state.
//theApp.emulator.emuReset();
} }
} }
@ -422,7 +468,7 @@ void MainWnd::OnUpdateFileImportGamesharkcodefile(CCmdUI* pCmdUI)
void MainWnd::OnFileImportGamesharksnapshot() void MainWnd::OnFileImportGamesharksnapshot()
{ {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
LPCTSTR exts[] = { "" }; LPCTSTR exts[] = { ".gbs" };
CString filter = theApp.cartridgeType == 1 ? winLoadFilter(IDS_FILTER_GBS) : winLoadFilter(IDS_FILTER_SPS); CString filter = theApp.cartridgeType == 1 ? winLoadFilter(IDS_FILTER_GBS) : winLoadFilter(IDS_FILTER_SPS);
CString title = winResLoadString(IDS_SELECT_SNAPSHOT_FILE); CString title = winResLoadString(IDS_SELECT_SNAPSHOT_FILE);
@ -468,6 +514,16 @@ void MainWnd::OnFileExportBatteryfile()
CString title = winResLoadString(IDS_SELECT_BATTERY_FILE); CString title = winResLoadString(IDS_SELECT_BATTERY_FILE);
CString saveDir = regQueryStringValue("batteryDir", NULL); CString saveDir = regQueryStringValue("batteryDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -565,8 +621,18 @@ void MainWnd::OnFileScreencapture()
name = theApp.filename; name = theApp.filename;
CString capdir = regQueryStringValue("captureDir", ""); CString capdir = regQueryStringValue("captureDir", "");
if( capdir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, capdir );
capdir = baseDir;
}
if(capdir.IsEmpty()) if(capdir.IsEmpty())
capdir = getDirFromFile(name); capdir = getDirFromFile(theApp.filename);
CString ext = "png"; CString ext = "png";
@ -648,7 +714,6 @@ void MainWnd::OnFileTogglemenu()
theApp.adjustDestRect(); theApp.adjustDestRect();
if(theApp.display) if(theApp.display)
theApp.display->resize(theApp.dest.right-theApp.dest.left, theApp.dest.bottom-theApp.dest.top); theApp.display->resize(theApp.dest.right-theApp.dest.left, theApp.dest.bottom-theApp.dest.top);
} }
void MainWnd::OnUpdateFileTogglemenu(CCmdUI* pCmdUI) void MainWnd::OnUpdateFileTogglemenu(CCmdUI* pCmdUI)
@ -684,7 +749,7 @@ bool MainWnd::fileImportGSACodeFile(CString& fileName)
} }
fseek(f, 0x1e, SEEK_SET); fseek(f, 0x1e, SEEK_SET);
fread(&len, 1, 4, f); fread(&len, 1, 4, f);
int game = 0; INT_PTR game = 0;
if(len > 1) { if(len > 1) {
GSACodeSelect dlg(f); GSACodeSelect dlg(f);
game = dlg.DoModal(); game = dlg.DoModal();
@ -701,7 +766,7 @@ bool MainWnd::fileImportGSACodeFile(CString& fileName)
} }
if(game != -1) { if(game != -1) {
return cheatsImportGSACodeFile(fileName, game, v3); return cheatsImportGSACodeFile(fileName, (int)game, v3);
} }
return true; return true;
@ -722,6 +787,16 @@ void MainWnd::OnFileSavegameOldestslot()
filename = theApp.filename; filename = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -732,15 +807,15 @@ void MainWnd::OnFileSavegameOldestslot()
CString name; CString name;
CFileStatus status; CFileStatus status;
CString str; CString str;
unsigned long time = (unsigned long)-1; time_t time = (time_t)-1;
int found = 0; int found = 0;
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
name.Format("%s%s%d.sgm", saveDir, filename, i+1); name.Format("%s%s%d.sgm", saveDir, filename, i+1);
if(emulating && CFile::GetStatus(name, status)) { if(emulating && CFile::GetStatus(name, status)) {
if((unsigned long)status.m_mtime.GetTime() < time) { if(status.m_mtime.GetTime() < time) {
time = (time_t)status.m_mtime.GetTime(); time = status.m_mtime.GetTime();
found = i; found = i;
} }
} else { } else {
@ -766,6 +841,16 @@ void MainWnd::OnUpdateFileSavegameOldestslot(CCmdUI* pCmdUI)
filename = theApp.filename; filename = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -808,6 +893,16 @@ void MainWnd::OnFileLoadgameMostrecent()
filename = theApp.filename; filename = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);
@ -818,15 +913,15 @@ void MainWnd::OnFileLoadgameMostrecent()
CString name; CString name;
CFileStatus status; CFileStatus status;
CString str; CString str;
unsigned long time = 0; time_t time = 0;
int found = -1; int found = -1;
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
name.Format("%s%s%d.sgm", saveDir, filename, i+1); name.Format("%s%s%d.sgm", saveDir, filename, i+1);
if(emulating && CFile::GetStatus(name, status)) { if(emulating && CFile::GetStatus(name, status)) {
if((unsigned long)status.m_mtime.GetTime() > time) { if(status.m_mtime.GetTime() < time) {
time = (time_t)status.m_mtime.GetTime(); time = status.m_mtime.GetTime();
found = i; found = i;
} }
} }
@ -852,6 +947,16 @@ void MainWnd::OnUpdateFileLoadgameMostrecent(CCmdUI* pCmdUI)
filename = theApp.filename; filename = theApp.filename;
CString saveDir = regQueryStringValue("saveDir", NULL); CString saveDir = regQueryStringValue("saveDir", NULL);
if( saveDir[0] == '.' ) {
// handle as relative path
char baseDir[MAX_PATH+1];
GetModuleFileName( NULL, baseDir, MAX_PATH );
baseDir[MAX_PATH] = '\0'; // for security reasons
PathRemoveFileSpec( baseDir ); // removes the trailing file name and backslash
strcat( baseDir, "\\" );
strcat( baseDir, saveDir );
saveDir = baseDir;
}
if(saveDir.IsEmpty()) if(saveDir.IsEmpty())
saveDir = getDirFromFile(theApp.filename); saveDir = getDirFromFile(theApp.filename);

View File

@ -44,3 +44,9 @@ void MainWnd::OnHelpBugreport()
dlg.DoModal(); dlg.DoModal();
} }
void MainWnd::OnHelpGnupubliclicense()
{
::ShellExecute(0, _T("open"), "http://www.gnu.org/licenses/gpl.html",
0, 0, SW_SHOWNORMAL);
}

View File

@ -22,26 +22,28 @@
#include "Associate.h" #include "Associate.h"
#include "Directories.h" #include "Directories.h"
#include "FileDlg.h" #include "FileDlg.h"
#include "GameOverrides.h"
#include "LinkOptions.h"
#include "GBColorDlg.h" #include "GBColorDlg.h"
#include "Joypad.h" #include "Joypad.h"
#include "MaxScale.h" #include "MaxScale.h"
#include "ModeConfirm.h" #include "ModeConfirm.h"
#include "Reg.h" #include "Reg.h"
#include "RewindInterval.h" #include "RewindInterval.h"
#include "skin.h"
#include "Throttle.h" #include "Throttle.h"
#include "WinResUtil.h" #include "WinResUtil.h"
#include "LinkOptions.h"
#include "../System.h" #include "../System.h"
#include "../agbprint.h" #include "../agbprint.h"
#include "../GBA.h" #include "../GBA.h"
#include "../Globals.h" #include "../Globals.h"
#include "../Sound.h" #include "../Sound.h"
#include "../Util.h"
#include "../gb/GB.h" #include "../gb/GB.h"
#include "../gb/gbGlobals.h" #include "../gb/gbGlobals.h"
#include "../gb/gbPrinter.h" #include "../gb/gbPrinter.h"
#include "../Link.h" #include "../Link.h"
#include <tchar.h>
extern int emulating; extern int emulating;
@ -52,6 +54,7 @@ extern void CPUUpdateRenderBuffers(bool force);
void MainWnd::OnOptionsFrameskipThrottleNothrottle() void MainWnd::OnOptionsFrameskipThrottleNothrottle()
{ {
theApp.throttle = 0; theApp.throttle = 0;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
@ -62,6 +65,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle25() void MainWnd::OnOptionsFrameskipThrottle25()
{ {
theApp.throttle = 25; theApp.throttle = 25;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
@ -72,6 +76,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle50() void MainWnd::OnOptionsFrameskipThrottle50()
{ {
theApp.throttle = 50; theApp.throttle = 50;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
@ -82,6 +87,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle100() void MainWnd::OnOptionsFrameskipThrottle100()
{ {
theApp.throttle = 100; theApp.throttle = 100;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
@ -92,6 +98,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle150() void MainWnd::OnOptionsFrameskipThrottle150()
{ {
theApp.throttle = 150; theApp.throttle = 150;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
@ -102,6 +109,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle200() void MainWnd::OnOptionsFrameskipThrottle200()
{ {
theApp.throttle = 200; theApp.throttle = 200;
theApp.autoFrameSkip = false;
} }
void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
@ -109,13 +117,18 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.throttle == 200); pCmdUI->SetCheck(theApp.throttle == 200);
} }
void MainWnd::OnOptionsFrameskipThrottleOther() void MainWnd::OnOptionsFrameskipThrottleOther()
{ {
Throttle dlg; Throttle dlg;
int v = dlg.DoModal(); int v = (int)dlg.DoModal();
if(v)
if( v ) {
theApp.throttle = v; theApp.throttle = v;
theApp.autoFrameSkip = false;
} }
}
void MainWnd::OnUpdateOptionsFrameskipThrottleOther(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipThrottleOther(CCmdUI* pCmdUI)
{ {
@ -130,6 +143,12 @@ void MainWnd::OnOptionsFrameskipAutomatic()
theApp.autoFrameSkip = !theApp.autoFrameSkip; theApp.autoFrameSkip = !theApp.autoFrameSkip;
if(!theApp.autoFrameSkip && emulating) if(!theApp.autoFrameSkip && emulating)
theApp.updateFrameSkip(); theApp.updateFrameSkip();
else
{
theApp.throttle = false;
frameSkip = 0;
systemFrameSkip = 0;
}
} }
void MainWnd::OnUpdateOptionsFrameskipAutomatic(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsFrameskipAutomatic(CCmdUI* pCmdUI)
@ -146,26 +165,28 @@ BOOL MainWnd::OnOptionsFrameskip(UINT nID)
case ID_OPTIONS_VIDEO_FRAMESKIP_3: case ID_OPTIONS_VIDEO_FRAMESKIP_3:
case ID_OPTIONS_VIDEO_FRAMESKIP_4: case ID_OPTIONS_VIDEO_FRAMESKIP_4:
case ID_OPTIONS_VIDEO_FRAMESKIP_5: case ID_OPTIONS_VIDEO_FRAMESKIP_5:
if(theApp.cartridgeType == 0) { if(theApp.cartridgeType == IMAGE_GBA) {
frameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0; frameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0;
} else { } else {
gbFrameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0; gbFrameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0;
} }
if(emulating) if(emulating)
theApp.updateFrameSkip(); theApp.updateFrameSkip();
theApp.autoFrameSkip = false;
return TRUE; return TRUE;
break; break;
case ID_OPTIONS_VIDEO_FRAMESKIP_6: case ID_OPTIONS_VIDEO_FRAMESKIP_6:
case ID_OPTIONS_VIDEO_FRAMESKIP_7: case ID_OPTIONS_VIDEO_FRAMESKIP_7:
case ID_OPTIONS_VIDEO_FRAMESKIP_8: case ID_OPTIONS_VIDEO_FRAMESKIP_8:
case ID_OPTIONS_VIDEO_FRAMESKIP_9: case ID_OPTIONS_VIDEO_FRAMESKIP_9:
if(theApp.cartridgeType == 0) { if(theApp.cartridgeType == IMAGE_GBA) {
frameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6; frameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6;
} else { } else {
gbFrameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6; gbFrameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6;
} }
if(emulating) if(emulating)
theApp.updateFrameSkip(); theApp.updateFrameSkip();
theApp.autoFrameSkip = false;
return TRUE; return TRUE;
break; break;
} }
@ -174,59 +195,63 @@ BOOL MainWnd::OnOptionsFrameskip(UINT nID)
void MainWnd::OnUpdateOptionsVideoFrameskip0(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip0(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 0 : gbFrameSkip == 0); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 0 : gbFrameSkip == 0);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip1(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip1(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 1 : gbFrameSkip == 1); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 1 : gbFrameSkip == 1);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip2(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip2(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 2 : gbFrameSkip == 2); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 2 : gbFrameSkip == 2);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip3(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip3(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 3 : gbFrameSkip == 3); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 3 : gbFrameSkip == 3);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip4(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip4(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 4 : gbFrameSkip == 4); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 4 : gbFrameSkip == 4);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip5(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip5(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 5 : gbFrameSkip == 5); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 5 : gbFrameSkip == 5);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip6(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip6(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 6 : gbFrameSkip == 6); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 6 : gbFrameSkip == 6);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip7(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip7(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 7 : gbFrameSkip == 7); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 7 : gbFrameSkip == 7);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip8(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip8(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 8 : gbFrameSkip == 8); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 8 : gbFrameSkip == 8);
} }
void MainWnd::OnUpdateOptionsVideoFrameskip9(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFrameskip9(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 9 : gbFrameSkip == 9); pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 9 : gbFrameSkip == 9);
} }
void MainWnd::OnOptionsVideoVsync() void MainWnd::OnOptionsVideoVsync()
{ {
theApp.vsync = !theApp.vsync; theApp.vsync = !theApp.vsync;
theApp.updateRenderMethod(true); if( theApp.display ) {
theApp.display->setOption( _T("vsync"), theApp.vsync );
} }
}
void MainWnd::OnUpdateOptionsVideoVsync(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoVsync(CCmdUI* pCmdUI)
{ {
@ -290,6 +315,7 @@ BOOL MainWnd::OnOptionVideoSize(UINT nID)
return TRUE; return TRUE;
} }
void MainWnd::OnOptionsVideoFullscreen320x240() void MainWnd::OnOptionsVideoFullscreen320x240()
{ {
OnOptionVideoSize(ID_OPTIONS_VIDEO_FULLSCREEN320X240); OnOptionVideoSize(ID_OPTIONS_VIDEO_FULLSCREEN320X240);
@ -332,9 +358,7 @@ void MainWnd::OnOptionsVideoFullscreen()
theApp.fsForceChange = true; theApp.fsForceChange = true;
theApp.fsWidth = width; theApp.fsWidth = width;
theApp.fsHeight = height; theApp.fsHeight = height;
theApp.fsFrequency = (theApp.display->selectFullScreenMode2() & 0xFFFF); theApp.fsFrequency = 60;
theApp.fsAdapter = theApp.display->selectFullScreenMode2();
theApp.fsAdapter = (theApp.fsAdapter & 0xFFFF0000) >> 16;
theApp.fsColorDepth = colorDepth; theApp.fsColorDepth = colorDepth;
theApp.pVideoDriverGUID = pGUID; theApp.pVideoDriverGUID = pGUID;
if(pGUID) { if(pGUID) {
@ -360,22 +384,28 @@ void MainWnd::OnUpdateOptionsVideoFullscreen(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoDisablesfx() void MainWnd::OnOptionsVideoDisablesfx()
{ {
cpuDisableSfx = !cpuDisableSfx; cpuDisableSfx = !cpuDisableSfx;
if(emulating && theApp.cartridgeType == 0) if(emulating && theApp.cartridgeType == IMAGE_GBA)
CPUUpdateRender(); CPUUpdateRender();
} }
void MainWnd::OnUpdateOptionsVideoDisablesfx(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoDisablesfx(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(!cpuDisableSfx); pCmdUI->SetCheck(cpuDisableSfx);
} }
void MainWnd::OnOptionsVideoFullscreenstretchtofit() void MainWnd::OnOptionsVideoFullscreenstretchtofit()
{ {
theApp.fullScreenStretch = !theApp.fullScreenStretch; theApp.fullScreenStretch = !theApp.fullScreenStretch;
theApp.updateWindowSize( theApp.videoOption ); theApp.updateWindowSize( theApp.videoOption );
if(theApp.display) if( theApp.display ) {
if( emulating ) {
theApp.display->clear( ); theApp.display->clear( );
} }
theApp.display->setOption( _T("fullScreenStretch"), theApp.fullScreenStretch );
}
}
void MainWnd::OnUpdateOptionsVideoFullscreenstretchtofit(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoFullscreenstretchtofit(CCmdUI* pCmdUI)
{ {
@ -453,11 +483,15 @@ void MainWnd::OnUpdateOptionsVideoRendermethodOpengl(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.renderMethod == OPENGL); pCmdUI->SetCheck(theApp.renderMethod == OPENGL);
} }
void MainWnd::OnOptionsVideoTriplebuffering() void MainWnd::OnOptionsVideoTriplebuffering()
{ {
theApp.tripleBuffering = !theApp.tripleBuffering; theApp.tripleBuffering = !theApp.tripleBuffering;
theApp.updateRenderMethod(true); if( theApp.display ) {
theApp.display->setOption( _T("tripleBuffering"), theApp.tripleBuffering );
} }
}
void MainWnd::OnUpdateOptionsVideoTriplebuffering(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoTriplebuffering(CCmdUI* pCmdUI)
{ {
@ -467,17 +501,26 @@ void MainWnd::OnUpdateOptionsVideoTriplebuffering(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoDdrawemulationonly() void MainWnd::OnOptionsVideoDdrawemulationonly()
{ {
theApp.ddrawEmulationOnly = !theApp.ddrawEmulationOnly; theApp.ddrawEmulationOnly = !theApp.ddrawEmulationOnly;
if( theApp.display ) {
theApp.display->setOption( _T("ddrawEmulationOnly"), theApp.ddrawEmulationOnly );
} }
}
void MainWnd::OnUpdateOptionsVideoDdrawemulationonly(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoDdrawemulationonly(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.ddrawEmulationOnly); pCmdUI->SetCheck(theApp.ddrawEmulationOnly);
} }
void MainWnd::OnOptionsVideoDdrawusevideomemory() void MainWnd::OnOptionsVideoDdrawusevideomemory()
{ {
theApp.ddrawUseVideoMemory = !theApp.ddrawUseVideoMemory; theApp.ddrawUseVideoMemory = !theApp.ddrawUseVideoMemory;
if( theApp.display ) {
theApp.display->setOption( _T("ddrawUseVideoMemory"), theApp.ddrawUseVideoMemory );
} }
}
void MainWnd::OnUpdateOptionsVideoDdrawusevideomemory(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoDdrawusevideomemory(CCmdUI* pCmdUI)
{ {
@ -487,8 +530,9 @@ void MainWnd::OnUpdateOptionsVideoDdrawusevideomemory(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoRenderoptionsD3dnofilter() void MainWnd::OnOptionsVideoRenderoptionsD3dnofilter()
{ {
theApp.d3dFilter = 0; theApp.d3dFilter = 0;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("d3dFilter", 0); theApp.display->setOption( _T("d3dFilter"), theApp.d3dFilter );
}
} }
void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dnofilter(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dnofilter(CCmdUI* pCmdUI)
@ -496,66 +540,145 @@ void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dnofilter(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.d3dFilter == 0); pCmdUI->SetCheck(theApp.d3dFilter == 0);
} }
void MainWnd::OnOptionsVideoRenderoptionsD3dbilinear() void MainWnd::OnOptionsVideoRenderoptionsD3dbilinear()
{ {
theApp.d3dFilter = 1; theApp.d3dFilter = 1;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("d3dFilter", 1); theApp.display->setOption( _T("d3dFilter"), theApp.d3dFilter );
} }
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dbilinear(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dbilinear(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.d3dFilter == 1); pCmdUI->SetCheck(theApp.d3dFilter == 1);
} }
void MainWnd::OnOptionsVideoRenderoptionsGlnearest() void MainWnd::OnOptionsVideoRenderoptionsGlnearest()
{ {
theApp.glFilter = 0; theApp.glFilter = 0;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("glFilter", 0); theApp.display->setOption( _T("glFilter"), theApp.glFilter );
} }
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlnearest(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsGlnearest(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.glFilter == 0); pCmdUI->SetCheck(theApp.glFilter == 0);
} }
void MainWnd::OnOptionsVideoRenderoptionsGlbilinear() void MainWnd::OnOptionsVideoRenderoptionsGlbilinear()
{ {
theApp.glFilter = 1; theApp.glFilter = 1;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("glFilter", 1); theApp.display->setOption( _T("glFilter"), theApp.glFilter );
} }
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlbilinear(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsGlbilinear(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.glFilter == 1); pCmdUI->SetCheck(theApp.glFilter == 1);
} }
void MainWnd::OnOptionsVideoRenderoptionsGltriangle() void MainWnd::OnOptionsVideoRenderoptionsGltriangle()
{ {
theApp.glType = 0; theApp.glType = 0;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("glType", 0); theApp.display->setOption( _T("glType"), theApp.glType );
} }
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.glType == 0); pCmdUI->SetCheck(theApp.glType == 0);
} }
void MainWnd::OnOptionsVideoRenderoptionsGlquads() void MainWnd::OnOptionsVideoRenderoptionsGlquads()
{ {
theApp.glType = 1; theApp.glType = 1;
if(theApp.display) if( theApp.display ) {
theApp.display->setOption("glType", 1); theApp.display->setOption( _T("glType"), theApp.glType );
} }
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlquads(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsVideoRenderoptionsGlquads(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.glType == 1); pCmdUI->SetCheck(theApp.glType == 1);
} }
void MainWnd::OnOptionsVideoRenderoptionsSelectskin()
{
#ifndef NOSKINS
LPCTSTR exts[] = {".ini" };
CString filter = winLoadFilter(IDS_FILTER_INI);
CString title = winResLoadString(IDS_SELECT_SKIN_FILE);
FileDlg dlg(this,
theApp.skinName,
filter,
0,
"INI",
exts,
"",
title,
false);
if(dlg.DoModal() == IDCANCEL) {
return;
}
bool result = false;
if(!theApp.skinEnabled) {
theApp.skinEnabled = !theApp.skinEnabled;
regSetDwordValue("skinEnabled", theApp.skinEnabled);
}
if(theApp.skin && theApp.skinEnabled) {
delete theApp.skin;
theApp.skin = NULL;
}
theApp.skinName = dlg.GetPathName();
theApp.winUpdateSkin();
theApp.winAccelMgr.UpdateMenu(theApp.menu);
#else
systemMessage( 0, _T("This build of VBA does not support skins!") );
#endif
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsSelectskin(CCmdUI* pCmdUI)
{
pCmdUI->Enable(theApp.display && theApp.display->isSkinSupported() &&
theApp.videoOption <= VIDEO_4X);
}
void MainWnd::OnOptionsVideoRenderoptionsSkin()
{
#ifndef NOSKINS
theApp.skinEnabled = !theApp.skinEnabled;
theApp.updateRenderMethod(true);
theApp.winAccelMgr.UpdateMenu(theApp.menu);
#else
systemMessage( 0, _T("This build of VBA does not support skins!") );
#endif
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsSkin(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.skinEnabled);
pCmdUI->Enable(theApp.display && theApp.display->isSkinSupported() && theApp.videoOption <= VIDEO_4X);
}
void MainWnd::OnOptionsEmulatorAssociate() void MainWnd::OnOptionsEmulatorAssociate()
{ {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
@ -583,6 +706,8 @@ void MainWnd::OnUpdateOptionsEmulatorDisablestatusmessages(CCmdUI* pCmdUI)
void MainWnd::OnOptionsEmulatorSynchronize() void MainWnd::OnOptionsEmulatorSynchronize()
{ {
synchronize = !synchronize; synchronize = !synchronize;
if (synchronize)
theApp.throttle = false;
} }
void MainWnd::OnUpdateOptionsEmulatorSynchronize(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsEmulatorSynchronize(CCmdUI* pCmdUI)
@ -610,17 +735,6 @@ void MainWnd::OnUpdateOptionsEmulatorSpeeduptoggle(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.speedupToggle); pCmdUI->SetCheck(theApp.speedupToggle);
} }
void MainWnd::OnOptionsEmulatorRemoveintrosgba()
{
// theApp.removeIntros = !theApp.removeIntros;
}
void MainWnd::OnUpdateOptionsEmulatorRemoveintrosgba(CCmdUI* pCmdUI)
{
pCmdUI->Enable(false);
// pCmdUI->SetCheck(theApp.removeIntros);
}
void MainWnd::OnOptionsEmulatorAutomaticallyipspatch() void MainWnd::OnOptionsEmulatorAutomaticallyipspatch()
{ {
theApp.autoIPS = !theApp.autoIPS; theApp.autoIPS = !theApp.autoIPS;
@ -656,32 +770,52 @@ void MainWnd::OnOptionsEmulatorAutohidemenu()
theApp.autoHideMenu = !theApp.autoHideMenu; theApp.autoHideMenu = !theApp.autoHideMenu;
} }
void MainWnd::OnOptionsEmulatorGenericflashcard()
{
if(emulating && theApp.cartridgeType == IMAGE_GB)
theApp.winGenericflashcardEnable = !theApp.winGenericflashcardEnable;
}
void MainWnd::OnUpdateOptionsEmulatorGenericflashcard(CCmdUI* pCmdUI)
{
if(emulating && theApp.cartridgeType == IMAGE_GB)
pCmdUI->SetCheck(theApp.winGenericflashcardEnable);
else
pCmdUI->SetCheck(false);
pCmdUI->Enable(emulating && theApp.cartridgeType == IMAGE_GB);
}
void MainWnd::OnUpdateOptionsEmulatorAutohidemenu(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsEmulatorAutohidemenu(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.autoHideMenu); pCmdUI->SetCheck(theApp.autoHideMenu);
} }
void MainWnd::OnOptionsEmulatorRewindinterval() void MainWnd::OnOptionsEmulatorRewindinterval()
{ {
RewindInterval dlg(theApp.rewindTimer/6); RewindInterval dlg(theApp.rewindTimer/6);
int v = dlg.DoModal(); int v = (int)dlg.DoModal();
if( v >= 0 ) { if( v >= 0 ) {
theApp.rewindTimer = v*6; // convert to a multiple of 10 frames theApp.rewindTimer = v*6; // convert to a multiple of 10 frames
regSetDwordValue("rewindTimer", v); regSetDwordValue("rewindTimer", v);
if(v == 0) { if(v == 0) {
if(theApp.rewindMemory) if(theApp.rewindMemory) {
free(theApp.rewindMemory); free(theApp.rewindMemory);
theApp.rewindMemory = NULL; theApp.rewindMemory = NULL;
}
theApp.rewindCount = 0; theApp.rewindCount = 0;
theApp.rewindCounter = 0; theApp.rewindCounter = 0;
theApp.rewindSaveNeeded = false; theApp.rewindSaveNeeded = false;
} else { } else {
if(theApp.rewindMemory == NULL) if(theApp.rewindMemory == NULL) {
theApp.rewindMemory = (char *)malloc(8*REWIND_SIZE); theApp.rewindMemory = (char *)malloc(8*REWIND_SIZE);
} }
} }
} }
}
BOOL MainWnd::OnOptionsEmulatorShowSpeed(UINT nID) BOOL MainWnd::OnOptionsEmulatorShowSpeed(UINT nID)
{ {
@ -791,7 +925,9 @@ void MainWnd::OnOptionsEmulatorSavetypeFlash512k()
void MainWnd::OnUpdateOptionsEmulatorSavetypeFlash512k(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsEmulatorSavetypeFlash512k(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.winFlashSize == 0x10000); // changed theApp.winFlashSize to flashSize to reflect the actual
// flashsize value used by the emu (it can change upon battery loading)
pCmdUI->SetCheck(flashSize == 0x10000);
} }
void MainWnd::OnOptionsEmulatorSavetypeFlash1m() void MainWnd::OnOptionsEmulatorSavetypeFlash1m()
@ -802,7 +938,9 @@ void MainWnd::OnOptionsEmulatorSavetypeFlash1m()
void MainWnd::OnUpdateOptionsEmulatorSavetypeFlash1m(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsEmulatorSavetypeFlash1m(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(theApp.winFlashSize == 0x20000); // changed theApp.winFlashSize to flashSize to reflect the actual
// flashsize value used by the emu (it can change upon battery loading)
pCmdUI->SetCheck(flashSize == 0x20000);
} }
void MainWnd::OnOptionsEmulatorUsebiosfile() void MainWnd::OnOptionsEmulatorUsebiosfile()
@ -873,6 +1011,7 @@ void MainWnd::OnOptionsSoundOff()
{ {
soundOffFlag = true; soundOffFlag = true;
soundShutdown(); soundShutdown();
theApp.soundInitialized = false;
} }
void MainWnd::OnUpdateOptionsSoundOff(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsSoundOff(CCmdUI* pCmdUI)
@ -893,17 +1032,17 @@ void MainWnd::OnUpdateOptionsSoundMute(CCmdUI* pCmdUI)
void MainWnd::OnOptionsSoundOn() void MainWnd::OnOptionsSoundOn()
{ {
//if(soundOffFlag) { if(soundOffFlag) {
soundOffFlag = false; soundOffFlag = false;
//soundInit(!theApp.cartridgeType); // soundInit();
//} }
soundEnable(0x30f); soundEnable(0x30f);
} }
void MainWnd::OnUpdateOptionsSoundOn(CCmdUI* pCmdUI) void MainWnd::OnUpdateOptionsSoundOn(CCmdUI* pCmdUI)
{ {
//int active = soundGetEnable() & 0x30f; int active = soundGetEnable() & 0x30f;
pCmdUI->SetCheck(/*active != 0 &&*/ !soundOffFlag); pCmdUI->SetCheck(active != 0 && !soundOffFlag);
} }
void MainWnd::OnOptionsSoundUseoldsynchronization() void MainWnd::OnOptionsSoundUseoldsynchronization()
@ -1023,8 +1162,6 @@ void MainWnd::updateSoundChannels(UINT id)
{ {
int flag = 0; int flag = 0;
if ( soundOffFlag ) return; // mute hax
if(id == ID_OPTIONS_SOUND_CHANNEL1) if(id == ID_OPTIONS_SOUND_CHANNEL1)
flag = 1; flag = 1;
@ -1520,8 +1657,9 @@ void MainWnd::OnUpdateOptionsFilterDisablemmx(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFilterLcdcolors() void MainWnd::OnOptionsFilterLcdcolors()
{ {
// todo: depreciated
theApp.filterLCD = !theApp.filterLCD; theApp.filterLCD = !theApp.filterLCD;
utilUpdateSystemColorMaps(theApp.filterLCD); utilUpdateSystemColorMaps();
} }
void MainWnd::OnUpdateOptionsFilterLcdcolors(CCmdUI *pCmdUI) void MainWnd::OnUpdateOptionsFilterLcdcolors(CCmdUI *pCmdUI)
@ -1710,7 +1848,7 @@ LRESULT MainWnd::OnConfirmMode(WPARAM, LPARAM)
void MainWnd::winConfirmMode() void MainWnd::winConfirmMode()
{ {
if(theApp.renderMethod == DIRECT_DRAW && theApp.videoOption > VIDEO_4X) { if( theApp.videoOption > VIDEO_4X ) {
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
ModeConfirm dlg(theApp.m_pMainWnd); ModeConfirm dlg(theApp.m_pMainWnd);
@ -1728,6 +1866,10 @@ void MainWnd::OnOptionsVideoFullscreenmaxscale()
theApp.winCheckFullscreen(); theApp.winCheckFullscreen();
dlg.DoModal(); dlg.DoModal();
if( theApp.display ) {
theApp.display->setOption( _T("maxScale"), theApp.fsMaxScale );
}
} }
@ -1768,3 +1910,29 @@ void MainWnd::OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI)
{ {
pCmdUI->SetCheck(adapter); pCmdUI->SetCheck(adapter);
} }
void MainWnd::OnOptionsEmulatorGameoverrides()
{
if(emulating && theApp.cartridgeType == 0) {
GameOverrides dlg(this);
dlg.DoModal();
}
}
void MainWnd::OnUpdateOptionsEmulatorGameoverrides(CCmdUI* pCmdUI)
{
pCmdUI->Enable(emulating && (theApp.cartridgeType == 0));
}
void MainWnd::OnOptionsSoundHardwareacceleration()
{
theApp.dsoundDisableHardwareAcceleration = !theApp.dsoundDisableHardwareAcceleration;
systemSoundShutdown();
systemSoundInit();
}
void MainWnd::OnUpdateOptionsSoundHardwareacceleration(CCmdUI *pCmdUI)
{
pCmdUI->SetCheck(!theApp.dsoundDisableHardwareAcceleration);
}

View File

@ -51,7 +51,7 @@ static char THIS_FILE[] = __FILE__;
extern bool debugger; extern bool debugger;
extern int emulating; extern int emulating;
extern int remoteSocket; extern SOCKET remoteSocket;
extern void remoteCleanUp(); extern void remoteCleanUp();
extern void remoteSetSockets(SOCKET, SOCKET); extern void remoteSetSockets(SOCKET, SOCKET);
@ -205,7 +205,7 @@ void MainWnd::OnToolsDebugGdb()
remoteSetSockets(wait.getListenSocket(), wait.getSocket()); remoteSetSockets(wait.getListenSocket(), wait.getSocket());
debugger = true; debugger = true;
emulating = 1; emulating = 1;
theApp.cartridgeType = 0; theApp.cartridgeType = IMAGE_GBA;
theApp.filename = "\\gnu_stub"; theApp.filename = "\\gnu_stub";
rom = (u8 *)malloc(0x2000000); rom = (u8 *)malloc(0x2000000);
workRAM = (u8 *)calloc(1, 0x40000); workRAM = (u8 *)calloc(1, 0x40000);
@ -214,7 +214,7 @@ void MainWnd::OnToolsDebugGdb()
paletteRAM = (u8 *)calloc(1,0x400); paletteRAM = (u8 *)calloc(1,0x400);
vram = (u8 *)calloc(1, 0x20000); vram = (u8 *)calloc(1, 0x20000);
oam = (u8 *)calloc(1, 0x400); oam = (u8 *)calloc(1, 0x400);
pix = (u8 *)calloc(1, 4 * 240 * 160); pix = (u8 *)calloc(1, 4 * 241 * 162);
ioMem = (u8 *)calloc(1, 0x400); ioMem = (u8 *)calloc(1, 0x400);
theApp.emulator = GBASystem; theApp.emulator = GBASystem;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
@ -465,6 +465,7 @@ void MapView::renderMode5()
bg = 2; bg = 2;
} }
void MapView::OnRefresh() void MapView::OnRefresh()
{ {
paint(); paint();
@ -511,6 +512,12 @@ void MapView::paint()
case 5: case 5:
renderMode5(); renderMode5();
break; break;
case 6:
renderMode5();
break;
case 7:
renderMode5();
break;
} }
enableButtons(mode); enableButtons(mode);
SIZE s; SIZE s;
@ -759,7 +766,7 @@ u32 MapView::GetClickAddress(int x, int y)
u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000; u32 base = ((control >> 8) & 0x1f) * 0x800 + 0x6000000;
// all text bgs (16 bits) // all text bgs (16 bits)
if(mode == 0 ||(mode < 3 && bg < 2)) { if(mode == 0 ||(mode < 3 && bg < 2) || mode == 6 || mode == 7) {
return GetTextClickAddress(base, x, y); return GetTextClickAddress(base, x, y);
} }
// rot bgs (8 bits) // rot bgs (8 bits)
@ -779,8 +786,8 @@ LRESULT MapView::OnMapInfo(WPARAM wParam, LPARAM lParam)
u8 *colors = (u8 *)lParam; u8 *colors = (u8 *)lParam;
mapViewZoom.setColors(colors); mapViewZoom.setColors(colors);
int x = wParam & 0xffff; int x = (int)(wParam & 0xffff);
int y = (wParam >> 16); int y = (int)(wParam >> 16);
CString buffer; CString buffer;
buffer.Format("(%d,%d)", x, y); buffer.Format("(%d,%d)", x, y);
@ -791,7 +798,7 @@ LRESULT MapView::OnMapInfo(WPARAM wParam, LPARAM lParam)
GetDlgItem(IDC_ADDRESS)->SetWindowText(buffer); GetDlgItem(IDC_ADDRESS)->SetWindowText(buffer);
int mode = DISPCNT & 7; int mode = DISPCNT & 7;
if(mode >= 3) { if(mode >= 3 && mode <=5) {
// bitmap modes // bitmap modes
GetDlgItem(IDC_TILE_NUM)->SetWindowText("---"); GetDlgItem(IDC_TILE_NUM)->SetWindowText("---");
GetDlgItem(IDC_FLIP)->SetWindowText("--"); GetDlgItem(IDC_FLIP)->SetWindowText("--");
@ -992,6 +999,8 @@ void MapView::savePNG(const char *name)
} }
void MapView::OnSave() void MapView::OnSave()
{
if(rom != NULL)
{ {
CString filename; CString filename;
@ -1024,3 +1033,4 @@ void MapView::OnSave()
else else
savePNG(dlg.GetPathName()); savePNG(dlg.GetPathName());
} }
}

View File

@ -31,7 +31,7 @@
#include "ZoomControl.h" #include "ZoomControl.h"
#include "ResizeDlg.h" #include "ResizeDlg.h"
#include "IUpdate.h" #include "IUpdate.h"
#include "..\System.h" // Added by ClassView #include "../System.h" // Added by ClassView
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// MapView dialog // MapView dialog

View File

@ -71,10 +71,6 @@ void MaxScale::OnOk()
CString tmp; CString tmp;
m_value.GetWindowText(tmp); m_value.GetWindowText(tmp);
theApp.fsMaxScale = atoi(tmp); theApp.fsMaxScale = atoi(tmp);
theApp.updateWindowSize(theApp.videoOption);
if(theApp.display)
theApp.display->clear();
this->SetFocus();
EndDialog(TRUE); EndDialog(TRUE);
} }

Some files were not shown because too many files have changed in this diff Show More