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
Name="VCCLCompilerTool"
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"
StringPooling="false"
MinimalRebuild="true"
@ -83,7 +83,7 @@
/>
<Tool
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"
Version=""
LinkIncremental="2"
@ -165,7 +165,7 @@
OmitFramePointers="true"
EnableFiberSafeOptimizations="false"
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"
IgnoreStandardIncludePath="false"
GeneratePreprocessedFile="0"
@ -216,7 +216,7 @@
Name="VCLinkerTool"
RegisterOutput="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"
OutputFile="$(ProjectDir)VisualBoyAdvance.exe"
Version=""
@ -308,7 +308,7 @@
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
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"
IgnoreStandardIncludePath="false"
GeneratePreprocessedFile="0"
@ -649,14 +649,6 @@
RelativePath=".\src\hq_shared32.cpp"
>
</File>
<File
RelativePath=".\src\lq3x.cpp"
>
</File>
<File
RelativePath=".\src\lq4x.cpp"
>
</File>
<File
RelativePath=".\src\portable.cpp"
>
@ -683,16 +675,40 @@
>
</File>
<File
RelativePath=".\src\getopt.cpp"
RelativePath=".\src\getopt.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\getopt1.cpp"
RelativePath=".\src\getopt1.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\memgzio.cpp"
RelativePath=".\src\memgzio.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\snd_interp.cpp"
@ -890,6 +906,10 @@
RelativePath=".\src\win32\FileDlg.cpp"
>
</File>
<File
RelativePath=".\src\win32\GameOverrides.cpp"
>
</File>
<File
RelativePath=".\src\win32\GBACheats.cpp"
>
@ -1002,6 +1022,14 @@
RelativePath=".\src\win32\RomInfo.cpp"
>
</File>
<File
RelativePath=".\src\win32\skin.cpp"
>
</File>
<File
RelativePath=".\src\win32\skinButton.cpp"
>
</File>
<File
RelativePath=".\src\win32\StringTokenizer.cpp"
>
@ -1014,10 +1042,6 @@
RelativePath=".\src\win32\TileView.cpp"
>
</File>
<File
RelativePath=".\src\win32\UniVideoModeDlg.cpp"
>
</File>
<File
RelativePath=".\src\win32\VideoMode.cpp"
>
@ -1106,6 +1130,10 @@
RelativePath=".\src\win32\DirectSound.cpp"
>
</File>
<File
RelativePath=".\src\win32\display.cpp"
>
</File>
<File
RelativePath=".\src\win32\GDIDisplay.cpp"
>
@ -1155,6 +1183,130 @@
>
</File>
</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
Name="Header"
@ -1624,15 +1776,7 @@
>
</File>
<File
RelativePath=".\res\resource.h"
>
</File>
<File
RelativePath=".\res\VBA.ico"
>
</File>
<File
RelativePath=".\res\VBA.rc"
RelativePath=".\src\win32\VBA.rc"
>
</File>
</Filter>

View File

@ -1,6 +1,8 @@
#include "System.h"
#include "Port.h"
extern int RGB_LOW_BITS_MASK;
extern "C"
{
@ -48,6 +50,7 @@ int Init_2xSaI(u32 BitFormat)
greenMask = 0x7E0;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xF7DEF7DE;
hq2x_init(16);
RGB_LOW_BITS_MASK = 0x0821;
} else if (BitFormat == 555) {
colorMask = 0x7BDE7BDE;
lowPixelMask = 0x04210421;
@ -57,6 +60,7 @@ int Init_2xSaI(u32 BitFormat)
greenMask = 0x3E0;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0x7BDE7BDE;
hq2x_init(15);
RGB_LOW_BITS_MASK = 0x0421;
} else {
return 0;
}
@ -67,6 +71,7 @@ int Init_2xSaI(u32 BitFormat)
qlowpixelMask = 0x030303;
qRGB_COLOR_MASK[0] = qRGB_COLOR_MASK[1] = 0xfefefe;
hq2x_init(32);
RGB_LOW_BITS_MASK = 0x010101;
} else
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.
// 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
// 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_LOWER_OR_EQ_U 110
#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];
int cheatsNumber = 0;
@ -205,6 +208,7 @@ u32 cheatsCBATemporaryValue = 0;
u16 cheatsCBATable[256];
bool cheatsCBATableGenerated = false;
u16 super = 0;
extern u32 mastercode;
u8 cheatsCBACurrentSeed[12] = {
0x00, 0x00, 0x00, 0x00,
@ -317,6 +321,9 @@ u8 v3_deadtable2[256] = {
#define CHEAT_PATCH_ROM_16BIT(a,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)
{
// 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_LOWER_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;
// the codes below have two lines of data
case CBA_SLIDE_CODE:
@ -558,6 +568,10 @@ static int getCodeLength(int num)
case GSA_16_BIT_MIF_FALSE:
case GSA_16_BIT_MIF_LOWER_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;
case CBA_IF_KEYS_PRESSED:
case CBA_SLIDE_CODE:
@ -571,8 +585,10 @@ static int getCodeLength(int num)
int cheatsCheckKeys(u32 keys, u32 extended)
{
bool onoff = true;
int ticks = 1;
int ticks = 0;
int i;
mastercode = 0;
for (i = 0; i<4; i++)
if (rompatch2addr [i] != 0) {
CHEAT_PATCH_ROM_16BIT(rompatch2addr [i],rompatch2oldval [i]);
@ -616,7 +632,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--;
}
}
i++;
break;
case GSA_16_BIT_SLIDE:
i++;
@ -633,7 +648,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--;
}
}
i++;
break;
case GSA_32_BIT_SLIDE:
i++;
@ -650,7 +664,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
count--;
}
}
i++;
break;
case GSA_8_BIT_GS_WRITE2:
i++;
@ -676,41 +689,49 @@ int cheatsCheckKeys(u32 keys, u32 extended)
}
}
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:
i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) {
if(i < cheatsNumber) {
rompatch2addr [0] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [0] = CPUReadHalfWord(rompatch2addr [0]);
rompatch2val [0] = cheatsList[i].rawaddress & 0xFFFF;
}
i++;
break;
case GSA_16_BIT_ROM_PATCH2D:
i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) {
if(i < cheatsNumber) {
rompatch2addr [1] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [1] = CPUReadHalfWord(rompatch2addr [1]);
rompatch2val [1] = cheatsList[i].rawaddress & 0xFFFF;
}
i++;
break;
case GSA_16_BIT_ROM_PATCH2E:
i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) {
if(i < cheatsNumber) {
rompatch2addr [2] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [2] = CPUReadHalfWord(rompatch2addr [2]);
rompatch2val [2] = cheatsList[i].rawaddress & 0xFFFF;
}
i++;
break;
case GSA_16_BIT_ROM_PATCH2F:
i++;
if((i < cheatsNumber) && (cheatsList[i].status & 1) == 0) {
if(i < cheatsNumber) {
rompatch2addr [3] = ((cheatsList[i-1].value & 0x00FFFFFF) << 1) + 0x8000000;
rompatch2oldval [3] = CPUReadHalfWord(rompatch2addr [3]);
rompatch2val [3] = cheatsList[i].rawaddress & 0xFFFF;
}
i++;
break;
case MASTER_CODE:
mastercode = cheatsList[i].address;
break;
}
if (onoff) {
@ -724,15 +745,6 @@ int cheatsCheckKeys(u32 keys, u32 extended)
case INT_32_BIT_WRITE:
CPUWriteMemory(cheatsList[i].address, cheatsList[i].value);
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:
if(extended & 4) {
CPUWriteByte(cheatsList[i].address, cheatsList[i].value);
@ -1289,6 +1301,20 @@ int cheatsCheckKeys(u32 keys, u32 extended)
i+=(cheatsList[i].rawaddress >> 0x10) & 0xFF;
}
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:
cheatsList[x].oldValue = CPUReadMemory(address);
break;
case CHEATS_16_BIT_WRITE:
cheatsList[x].oldValue = CPUReadHalfWord(address);
break;
case CHEATS_32_BIT_WRITE:
cheatsList[x].oldValue = CPUReadMemory(address);
break;
}
cheatsNumber++;
}
@ -1351,6 +1383,19 @@ void cheatsDelete(int number, bool restore)
case INT_32_BIT_WRITE:
CPUWriteMemory(cheatsList[x].address, cheatsList[x].oldValue);
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:
if(cheatsList[x].status & 1) {
cheatsList[x].status &= ~1;
@ -1366,6 +1411,9 @@ void cheatsDelete(int number, bool restore)
cheatsList[x].status &= ~1;
}
break;
case MASTER_CODE:
mastercode=0;
break;
}
}
if((x+1) < cheatsNumber) {
@ -1387,6 +1435,7 @@ void cheatsEnable(int i)
{
if(i >= 0 && i < cheatsNumber) {
cheatsList[i].enabled = true;
mastercode = 0;
}
}
@ -1409,6 +1458,9 @@ void cheatsDisable(int i)
cheatsList[i].status &= ~1;
}
break;
case MASTER_CODE:
mastercode=0;
break;
}
cheatsList[i].enabled = false;
}
@ -1416,7 +1468,7 @@ void cheatsDisable(int i)
bool cheatsVerifyCheatCode(const char *code, const char *desc)
{
int len = strlen(code);
size_t len = strlen(code);
if(len != 11 && len != 13 && len != 17) {
systemMessage(MSG_INVALID_CHEAT_CODE, N_("Invalid cheat code '%s'"), code);
return false;
@ -1427,7 +1479,7 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
return false;
}
int i;
size_t i;
for(i = 0; i < 8; i++) {
if(!CHEAT_IS_HEX(code[i])) {
// wrong cheat
@ -1454,8 +1506,18 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
sscanf(buffer, "%x", &address);
switch(address >> 24) {
case 2:
case 3:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
break;
default:
systemMessage(MSG_INVALID_CHEAT_CODE_ADDRESS,
@ -1468,9 +1530,9 @@ bool cheatsVerifyCheatCode(const char *code, const char *desc)
sscanf(buffer, "%x", &value);
int type = 0;
if(len == 13)
type = 1;
type = 114;
if(len == 17)
type = 2;
type = 115;
cheatsAdd(code, desc, address, address, value, type, type);
return true;
}
@ -1587,6 +1649,15 @@ void cheatsAddGSACode(const char *code, const char *desc, bool v3)
if(v3) {
int type = ((address >> 25) & 127) | ((address >> 17) & 0x80);
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) {
case 0x00:
if(address == 0) {
@ -1997,6 +2068,10 @@ void cheatsAddGSACode(const char *code, const char *desc, bool v3)
break;
}
break;
case 0x0f:
cheatsAdd(code, desc, address, (address & 0xFFFFFFF), value, 256, MASTER_CODE);
mastercode = (address & 0xFFFFFFF);
break;
default:
// unsupported code
cheatsAdd(code, desc, address, address, value, 256,
@ -2466,6 +2541,10 @@ void cheatsAddCBACode(const char *code, const char *desc)
UNKNOWN_CODE);
}
break;
case 0x01:
cheatsAdd(code, desc, address, (address & 0x1FFFFFF) | 0x08000000, value, 512, MASTER_CODE);
mastercode = (address & 0x1FFFFFF) | 0x08000000;
break;
case 0x02:
cheatsAdd(code, desc, address, address & 0x0FFFFFFE, value, 512,
CBA_OR);
@ -2536,17 +2615,33 @@ void cheatsSaveGame(gzFile file)
utilGzWrite(file, cheatsList, sizeof(cheatsList));
}
void cheatsReadGame(gzFile file)
void cheatsReadGame(gzFile file, int version)
{
cheatsNumber = 0;
cheatsNumber = utilReadInt(file);
if (version > 8)
utilGzRead(file, cheatsList, sizeof(cheatsList));
bool firstCodeBreaker = true;
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;
if(!cheatsList[i].codestring[0]) {
switch(cheatsList[i].size) {
@ -2599,7 +2694,7 @@ void cheatsSaveCheatList(const char *file)
return;
int version = 1;
fwrite(&version, 1, sizeof(version), f);
int type = 0;
int type = 1;
fwrite(&type, 1, sizeof(type), f);
fwrite(&cheatsNumber, 1, sizeof(cheatsNumber), f);
fwrite(cheatsList, 1, sizeof(cheatsList), f);
@ -2608,7 +2703,6 @@ void cheatsSaveCheatList(const char *file)
bool cheatsLoadCheatList(const char *file)
{
cheatsNumber = 0;
int count = 0;
@ -2637,7 +2731,8 @@ bool cheatsLoadCheatList(const char *file)
return false;
}
if(type != 0) {
if((type != 0) && (type != 1)) {
systemMessage(MSG_UNSUPPORTED_CHEAT_LIST_TYPE,
N_("Unsupported cheat list type %d"), type);
fclose(f);
@ -2648,11 +2743,32 @@ bool cheatsLoadCheatList(const char *file)
fclose(f);
return false;
}
if (type == 1)
{
if(fread(cheatsList, 1, sizeof(cheatsList), f) != sizeof(cheatsList)) {
fclose(f);
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;
@ -2710,6 +2826,15 @@ static u8 cheatsGetType(u32 address)
return freezeWorkRAM[address & 0x3FFFF];
case 3:
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;
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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 cheatsDisable(int number);
extern void cheatsSaveGame(gzFile file);
extern void cheatsReadGame(gzFile file);
extern void cheatsReadGame(gzFile file, int version);
extern void cheatsSaveCheatList(const char *file);
extern bool cheatsLoadCheatList(const char *file);
extern void cheatsWriteMemory(u32, u32);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <memory.h>
#include "GBA.h"
#include "EEprom.h"
#include "Util.h"
@ -42,6 +43,11 @@ variable_desc eepromSaveData[] = {
{ NULL, 0 }
};
void eepromInit()
{
memset(eepromData, 255, sizeof(eepromData));
}
void eepromReset()
{
eepromMode = EEPROM_IDLE;

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -20,10 +20,11 @@
#ifndef VBA_EEPROM_H
#define VBA_EEPROM_H
extern void eepromSaveGame(gzFile gzFile);
extern void eepromReadGame(gzFile gzFile, int version);
extern void eepromSaveGame(gzFile _gzFile);
extern void eepromReadGame(gzFile _gzFile, int version);
extern int eepromRead(u32 address);
extern void eepromWrite(u32 address, u8 value);
extern void eepromInit();
extern void eepromReset();
extern u8 eepromData[0x2000];
extern bool eepromInUse;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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)
{
// log("Setting flash size to %d\n", size);
flashSize = size;
if(size == 0x10000) {
flashDeviceID = 0x1b;
flashManufacturerID = 0x32;
@ -108,6 +107,11 @@ void flashSetSize(int size)
flashDeviceID = 0x13; //0x09;
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)

View File

@ -20,8 +20,8 @@
#ifndef VBA_FLASH_H
#define VBA_FLASH_H
extern void flashSaveGame(gzFile gzFile);
extern void flashReadGame(gzFile gzFile, int version);
extern void flashSaveGame(gzFile _gzFile);
extern void flashReadGame(gzFile _gzFile, int version);
extern u8 flashRead(u32 address);
extern void flashWrite(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++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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_7 7
#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 {
u8 *address;
@ -85,6 +86,13 @@ extern void (*cpuSaveGameFunc)(u32,u8);
extern u8 freezeWorkRAM[0x40000];
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 CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
extern bool CPUWriteBatteryFile(const char *);
@ -100,17 +108,20 @@ extern bool CPUReadState(const char *);
extern bool CPUWriteMemState(char *, int);
extern bool CPUWriteState(const char *);
extern int CPULoadRom(const char *);
extern void doMirroring(bool);
extern void CPUUpdateRegister(u32, u16);
extern void applyTimer ();
extern void CPUWriteHalfWord(u32, u16);
extern void CPUWriteByte(u32, u8);
extern void CPUInit(const char *,bool);
extern void CPUReset();
extern void CPULoop(int);
extern bool CPUCheckDMA(int,int);
extern void CPUCheckDMA(int,int);
extern bool CPUIsGBAImage(const char *);
extern bool CPUIsZipFile(const char *);
#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);
#endif

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -23,18 +23,26 @@
#include "System.h"
#include "Port.h"
#include "RTC.h"
#include "Sound.h"
extern bool cpuSramEnabled;
extern bool cpuFlashEnabled;
extern bool cpuEEPROMEnabled;
extern bool cpuEEPROMSensorEnabled;
extern bool cpuDmaHack;
extern bool cpuDmaHack2;
extern u32 cpuDmaLast;
extern int lspeed;
extern void LinkSStop(void);
extern bool timer0On;
extern int timer0Ticks;
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) \
map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
@ -45,7 +53,7 @@ extern void LinkSStop(void);
#define CPUReadMemoryQuick(addr) \
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
@ -82,20 +90,26 @@ inline u32 CPUReadMemory(u32 address)
value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
break;
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2])
value = soundRead32(address & 0x3fC);
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
else
value = soundRead16(address & 0x3fc);
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
} else goto unreadable;
break;
case 5:
value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
break;
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;
case 7:
value = READ32LE(((u32 *)&oam[address & 0x3FC]));
@ -126,7 +140,7 @@ inline u32 CPUReadMemory(u32 address)
}
#endif
if(cpuDmaHack || cpuDmaHack2) {
if(cpuDmaHack) {
value = cpuDmaLast;
} else {
if(armState) {
@ -164,7 +178,7 @@ inline u32 CPUReadMemory(u32 address)
extern u32 myROM[];
inline u32 CPUReadHalfWord(u32 address)
static inline u32 CPUReadHalfWord(u32 address)
{
#ifdef DEV_VERSION
if(address & 1) {
@ -199,17 +213,39 @@ inline u32 CPUReadHalfWord(u32 address)
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break;
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[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;
break;
case 5:
value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
break;
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;
case 7:
value = READ16LE(((u16 *)&oam[address & 0x3fe]));
@ -242,7 +278,7 @@ if((address>=0x4000120||address<=0x4000126)&&lspeed)
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack2 || cpuDmaHack) {
if(cpuDmaHack) {
value = cpuDmaLast & 0xFFFF;
} else {
if(armState) {
@ -261,7 +297,7 @@ if((address>=0x4000120||address<=0x4000126)&&lspeed)
return value;
}
inline u16 CPUReadHalfWordSigned(u32 address)
static inline u16 CPUReadHalfWordSigned(u32 address)
{
u16 value = CPUReadHalfWord(address);
if((address & 1))
@ -269,7 +305,7 @@ inline u16 CPUReadHalfWordSigned(u32 address)
return value;
}
inline u8 CPUReadByte(u32 address)
static inline u8 CPUReadByte(u32 address)
{
switch(address >> 24) {
case 0:
@ -290,15 +326,18 @@ inline u8 CPUReadByte(u32 address)
case 3:
return internalRAM[address & 0x7fff];
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return soundRead(address & 0x3ff);
return ioMem[address & 0x3ff];
else goto unreadable;
case 5:
return paletteRAM[address & 0x3ff];
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:
return oam[address & 0x3ff];
case 8:
@ -335,7 +374,7 @@ inline u8 CPUReadByte(u32 address)
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack || cpuDmaHack2) {
if(cpuDmaHack) {
return cpuDmaLast & 0xFF;
} else {
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
if(address & 3) {
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,
address,
armMode ? armNextPC - 4 : armNextPC - 2);
@ -363,7 +403,7 @@ inline void CPUWriteMemory(u32 address, u32 value)
switch(address >> 24) {
case 0x02:
#ifdef SDL
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
cheatsWriteMemory(address & 0x203FFFC,
value);
@ -372,7 +412,7 @@ inline void CPUWriteMemory(u32 address, u32 value)
WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
break;
case 0x03:
#ifdef SDL
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
cheatsWriteMemory(address & 0x3007FFC,
value);
@ -387,15 +427,36 @@ inline void CPUWriteMemory(u32 address, u32 value)
} else goto unwritable;
break;
case 0x05:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezePRAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
break;
case 0x06:
if(address & 0x10000)
WRITE32LE(((u32 *)&vram[address & 0x17ffc]), value);
address = (address & 0x1fffc);
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
WRITE32LE(((u32 *)&vram[address & 0x1fffc]), value);
#endif
WRITE32LE(((u32 *)&vram[address]), value);
break;
case 0x07:
#ifdef BKPT_SUPPORT
if(*((u32 *)&freezeOAM[address & 0x3fc]))
cheatsWriteMemory(address & 0x70003FC,
value);
else
#endif
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
break;
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,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
u32 line0[240];
u32 line1[240];
u32 line2[240];
@ -32,6 +31,7 @@ u32 lineOBJWin[240];
u32 lineMix[240];
bool gfxInWin0[240];
bool gfxInWin1[240];
int lineOBJpixleft[128];
int gfxBG2Changed = 0;
int gfxBG3Changed = 0;

359
src/Gfx.h
View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -28,8 +28,8 @@
//#define SPRITE_DEBUG
void gfxDrawTextScreen(u16, u16, u16, u32 *);
void gfxDrawRotScreen(u16,
static void gfxDrawTextScreen(u16, u16, u16, u32 *);
static void gfxDrawRotScreen(u16,
u16, u16,
u16, u16,
u16, u16,
@ -37,7 +37,7 @@ void gfxDrawRotScreen(u16,
int&, int&,
int,
u32*);
void gfxDrawRotScreen16Bit(u16,
static void gfxDrawRotScreen16Bit(u16,
u16, u16,
u16, u16,
u16, u16,
@ -45,7 +45,7 @@ void gfxDrawRotScreen16Bit(u16,
int&, int&,
int,
u32*);
void gfxDrawRotScreen256(u16,
static void gfxDrawRotScreen256(u16,
u16, u16,
u16, u16,
u16, u16,
@ -53,7 +53,7 @@ void gfxDrawRotScreen256(u16,
int&, int&,
int,
u32*);
void gfxDrawRotScreen16Bit160(u16,
static void gfxDrawRotScreen16Bit160(u16,
u16, u16,
u16, u16,
u16, u16,
@ -61,10 +61,10 @@ void gfxDrawRotScreen16Bit160(u16,
int&, int&,
int,
u32*);
void gfxDrawSprites(u32 *);
void gfxIncreaseBrightness(u32 *line, int coeff);
void gfxDecreaseBrightness(u32 *line, int coeff);
void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
static void gfxDrawSprites(u32 *);
static void gfxIncreaseBrightness(u32 *line, int coeff);
static void gfxDecreaseBrightness(u32 *line, int coeff);
static void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
void mode0RenderLine();
void mode0RenderLineNoWindow();
@ -100,6 +100,7 @@ extern u32 lineOBJWin[240];
extern u32 lineMix[240];
extern bool gfxInWin0[240];
extern bool gfxInWin1[240];
extern int lineOBJpixleft[128];
extern int gfxBG2Changed;
extern int gfxBG3Changed;
@ -114,14 +115,14 @@ extern int gfxBG3LastX;
extern int gfxBG3LastY;
extern int gfxLastVCOUNT;
inline void gfxClearArray(u32 *array)
static inline void gfxClearArray(u32 *array)
{
for(int i = 0; i < 240; i++) {
*array++ = 0x80000000;
}
}
inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
u32 *line)
{
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 y_l, u16 y_h,
u16 pa, u16 pb,
@ -305,7 +306,7 @@ inline void gfxDrawRotScreen(u16 control,
int dy = pc & 0x7FFF;
if(pc & 0x8000)
dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF;
int dmy = pd & 0x7FFF;
if(pd & 0x8000)
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 y_l, u16 y_h,
u16 pa, u16 pb,
@ -462,7 +463,7 @@ inline void gfxDrawRotScreen16Bit(u16 control,
int dy = pc & 0x7FFF;
if(pc & 0x8000)
dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF;
int dmy = pd & 0x7FFF;
if(pd & 0x8000)
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 y_l, u16 y_h,
u16 pa, u16 pb,
@ -560,7 +561,7 @@ inline void gfxDrawRotScreen256(u16 control,
int dy = pc & 0x7FFF;
if(pc & 0x8000)
dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF;
int dmy = pd & 0x7FFF;
if(pd & 0x8000)
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 y_l, u16 y_h,
u16 pa, u16 pb,
@ -661,7 +662,7 @@ inline void gfxDrawRotScreen16Bit160(u16 control,
int dy = pc & 0x7FFF;
if(pc & 0x8000)
dy |= 0xFFFF8000;
int dmy = pd & 0x7FFFF;
int dmy = pd & 0x7FFF;
if(pd & 0x8000)
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;
gfxClearArray(lineOBJ);
if(layerEnable & 0x1000) {
@ -744,55 +749,37 @@ inline void gfxDrawSprites(u32 *lineOBJ)
u16 a2 = READ16LE(sprites++);
sprites++;
// ignore OBJ-WIN
if((a0 & 0x0c00) == 0x0800)
lineOBJpixleft[x]=lineOBJpix;
lineOBJpix-=2;
if (lineOBJpix<=0)
continue;
int sizeY = 8;
int sizeX = 8;
if ((a0 & 0x0c00) == 0x0c00)
a0 &=0xF3FF;
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;
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;
}
#ifdef SPRITE_DEBUG
@ -801,9 +788,45 @@ inline void gfxDrawSprites(u32 *lineOBJ)
#endif
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;
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) {
int fieldX = sizeX;
@ -812,11 +835,18 @@ inline void gfxDrawSprites(u32 *lineOBJ)
fieldX <<= 1;
fieldY <<= 1;
}
if((sy+fieldY) > 256)
sy -= 256;
int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) {
int sx = (a1 & 0x1FF);
if((sx < 240) || (((sx + fieldX) & 511) < 240)) {
int startpix = 0;
if ((sx+fieldX)> 512)
{
startpix=512-sx;
}
if (lineOBJpix>0)
if((sx < 240) || startpix) {
lineOBJpix-=8;
// int t2 = t - (fieldY >> 1);
int rot = (a1 >> 9) & 0x1F;
u16 *OAM = (u16 *)oam;
@ -854,6 +884,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
else
c &= 0x3FE;
for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8;
int yyy = realY >> 8;
@ -885,7 +919,7 @@ inline void gfxDrawSprites(u32 *lineOBJ)
lineOBJ[sx] = 0x001F;
#endif
}
sx = (sx+1)&511;;
sx = (sx+1)&511;
realX += dx;
realY += dy;
}
@ -899,6 +933,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
inc = sizeX >> 3;
int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8;
int yyy = realY >> 8;
if(xxx < 0 || xxx >= sizeX ||
@ -934,7 +972,7 @@ inline void gfxDrawSprites(u32 *lineOBJ)
if(t == 0 || t == maskY || x == 0 || x == maskX)
lineOBJ[sx] = 0x001F;
#endif
sx = (sx+1)&511;;
sx = (sx+1)&511;
realX += dx;
realY += dy;
@ -943,10 +981,17 @@ inline void gfxDrawSprites(u32 *lineOBJ)
}
}
} else {
if(sy+sizeY > 256)
sy -= 256;
int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) {
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(a1 & 0x2000)
t = sizeY - t - 1;
@ -976,6 +1021,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
if ((color==0) && (((prio >> 25)&3) <
@ -1048,6 +1097,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
if(a1 & 0x1000) {
xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
if(xx & 1) {
@ -1088,6 +1141,10 @@ inline void gfxDrawSprites(u32 *lineOBJ)
}
} else {
for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
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);
if(layerEnable & 0x8000) {
if((layerEnable & 0x9000) == 0x9000) {
u16 *sprites = (u16 *)oam;
// u16 *spritePalette = &((u16 *)paletteRAM)[256];
for(int x = 0; x < 128 ; x++) {
int lineOBJpix = lineOBJpixleft[x];
u16 a0 = READ16LE(sprites++);
u16 a1 = READ16LE(sprites++);
u16 a2 = READ16LE(sprites++);
sprites++;
// ignore non OBJ-WIN
if((a0 & 0x0c00) != 0x0800)
if (lineOBJpix<=0)
continue;
int sizeY = 8;
int sizeX = 8;
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:
// ignores non OBJ-WIN and disabled OBJ-WIN
if(((a0 & 0x0c00) != 0x0800) || ((a0 & 0x0300) == 0x0200))
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);
if(sy > 160)
sy -= 256;
if(a0 & 0x0100) {
int fieldX = sizeX;
int fieldY = sizeY;
@ -1211,11 +1249,18 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
fieldX <<= 1;
fieldY <<= 1;
}
if((sy+fieldY) > 256)
sy -= 256;
int t = VCOUNT - sy;
if((t >= 0) && (t < fieldY)) {
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 rot = (a1 >> 9) & 0x1F;
u16 *OAM = (u16 *)oam;
@ -1249,6 +1294,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
else
c &= 0x3FE;
for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8;
int yyy = realY >> 8;
@ -1263,7 +1312,7 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
lineOBJWin[sx] = 1;
}
}
sx = (sx+1)&511;;
sx = (sx+1)&511;
realX += dx;
realY += dy;
}
@ -1277,6 +1326,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
inc = sizeX >> 3;
// int palette = (a2 >> 8) & 0xF0;
for(int x = 0; x < fieldX; x++) {
if (x >= startpix)
lineOBJpix-=2;
if (lineOBJpix<0)
continue;
int xxx = realX >> 8;
int yyy = realY >> 8;
@ -1301,7 +1354,7 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
}
}
// }
sx = (sx+1)&511;;
sx = (sx+1)&511;
realX += dx;
realY += dy;
}
@ -1309,10 +1362,18 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
}
}
} else {
if((sy+sizeY) > 256)
sy -= 256;
int t = VCOUNT - sy;
if((t >= 0) && (t < sizeY)) {
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(a1 & 0x2000)
t = sizeY - t - 1;
@ -1335,6 +1396,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
xxx = 7;
// u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
if(color) {
@ -1384,6 +1449,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
if(a1 & 0x1000) {
xxx = 7;
for(int xx = sizeX - 1; xx >= 0; xx--) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
if(xx & 1) {
@ -1408,6 +1477,10 @@ inline void gfxDrawOBJWin(u32 *lineOBJWin)
}
} else {
for(int xx = 0; xx < sizeX; xx++) {
if (xx >= startpix)
lineOBJpix--;
if (lineOBJpix<0)
continue;
if(sx < 240) {
u8 color = vram[address];
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 g = ((color >> 5) & 0x1F);
@ -1458,7 +1531,7 @@ inline u32 gfxIncreaseBrightness(u32 color, int coeff)
return color;
}
inline void gfxIncreaseBrightness(u32 *line, int coeff)
static inline void gfxIncreaseBrightness(u32 *line, int coeff)
{
for(int x = 0; x < 240; x++) {
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 g = ((color >> 5) & 0x1F);
@ -1499,7 +1572,7 @@ inline u32 gfxDecreaseBrightness(u32 color, int coeff)
return color;
}
inline void gfxDecreaseBrightness(u32 *line, int coeff)
static inline void gfxDecreaseBrightness(u32 *line, int coeff)
{
for(int x = 0; x < 240; x++) {
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) {
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 b0 = ((color2 >> 10) & 0x1F);
r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
r = ((r * ca) + (r0 * cb)) >> 4;
g = ((g * ca) + (g0 * cb)) >> 4;
b = ((b * ca) + (b0 * cb)) >> 4;
if(r > 31)
r = 31;
@ -1546,7 +1619,7 @@ inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
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++) {
u32 color = *ta;
@ -1559,9 +1632,9 @@ inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
int g0 = ((color2 >> 5) & 0x1F);
int b0 = ((color2 >> 10) & 0x1F);
r = ((r * ca) >> 4) + ((r0 * cb) >> 4);
g = ((g * ca) >> 4) + ((g0 * cb) >> 4);
b = ((b * ca) >> 4) + ((b0 * cb) >> 4);
r = ((r * ca) + (r0 * cb)) >> 4;
g = ((g * ca) + (g0 * cb)) >> 4;
b = ((b * ca) + (b0 * cb)) >> 4;
if(r > 31)
r = 31;

View File

@ -16,7 +16,12 @@
// along with this program; if not, write to the Free Software Foundation,
// 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];
memoryMap map[256];
@ -43,8 +48,8 @@ int layerSettings = 0xff00;
int layerEnable = 0xff00;
bool speedHack = false;
int cpuSaveType = 0;
bool cpuEnhancedDetection = true;
bool cheatsEnabled = true;
bool mirroringEnable = false;
u8 *bios = NULL;
u8 *rom = NULL;

View File

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

View File

@ -25,8 +25,8 @@
#define MSG_SAVE_GAME_USING_BIOS 4
#define MSG_UNSUPPORTED_SAVE_TYPE 5
#define MSG_CANNOT_OPEN_FILE 6
#define MSG_BAD_ARCHIVE_FILE 7
#define MSG_NO_IMAGE_ON_ARCHIVE 8
#define MSG_BAD_ZIP_FILE 7
#define MSG_NO_IMAGE_ON_ZIP 8
#define MSG_ERROR_OPENING_IMAGE 9
#define MSG_ERROR_READING_IMAGE 10
#define MSG_UNSUPPORTED_BIOS_FUNCTION 11
@ -60,3 +60,5 @@
#define MSG_INVALID_CBA_CODE 39
#define MSG_CBA_CODE_WARNING 40
#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.
// 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
// 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.state = DATA;
break;
case 0x64:
break;
case 0x65:
{
struct tm *newtime;

View File

@ -659,40 +659,17 @@ void soundChannel4()
{
}
#include <stdio.h>
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;
#endif
}
void soundDirectSoundATimer()
{
if(soundDSAEnabled) {
if(soundDSFifoACount <= 16) {
cpuDmaHack2 = CPUCheckDMA(3, 2);
CPUCheckDMA(3, 2);
if(soundDSFifoACount <= 16) {
soundEvent(FIFOA_L, (u16)0);
soundEvent(FIFOA_H, (u16)0);
@ -714,18 +691,15 @@ void soundDirectSoundATimer()
inline void soundDirectSoundB()
{
#ifdef ENHANCED_RATE
directBuffer[1][soundIndex] = interp_pop(1, calc_rate(soundDSBTimer)); //soundDSBValue;
#else
directBuffer[1][soundIndex] = interp_pop(1); //soundDSBValue;
#endif
}
void soundDirectSoundBTimer()
{
if(soundDSBEnabled) {
if(soundDSFifoBCount <= 16) {
cpuDmaHack2 = CPUCheckDMA(3, 4);
//cpuDmaHack2 =
CPUCheckDMA(3, 4);
if(soundDSFifoBCount <= 16) {
soundEvent(FIFOB_L, (u16)0);
soundEvent(FIFOB_H, (u16)0);

View File

@ -2,6 +2,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// 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
// 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 const BOOST::uint8_t sound_data [Gb_Apu::register_count];
extern void interp_rate();

View File

@ -106,6 +106,12 @@ extern void system10Frames(int);
extern void systemFrame();
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 u16 systemColorMap16[0x10000];
extern u32 systemColorMap32[0x10000];
@ -118,6 +124,7 @@ extern int systemDebug;
extern int systemVerbose;
extern int systemFrameSkip;
extern int systemSaveUpdateCounter;
extern int systemSpeed;
#define SYSTEM_SAVE_UPDATED 30
#define SYSTEM_SAVE_NOT_UPDATED 0

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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]"},
// Format 8
{0xfe00, 0x5200, "strh %r0, [%r3, %r6]"},
{0xfe00, 0x5600, "ldrh %r0, [%r3, %r6]"},
{0xfe00, 0x5a00, "ldsb %r0, [%r3, %r6]"},
{0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]"},
{0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]"},
{0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"},
// Format 9
{0xe800, 0x6000, "str%B %r0, [%r3, %p]"},

View File

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

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -23,6 +23,7 @@
extern void BIOS_ArcTan();
extern void BIOS_ArcTan2();
extern void BIOS_BitUnPack();
extern void BIOS_GetBiosChecksum();
extern void BIOS_BgAffineSet();
extern void BIOS_CpuSet();
extern void BIOS_CpuFastSet();

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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 void gbEmulate(int);
extern void gbWriteMemory(register u16, register u8);
extern void gbDrawLine();
extern bool gbIsGameboyRom(const char *);
extern void gbSoundReset();
extern void gbSoundSetQuality(int);
extern void gbGetHardwareType();
extern void gbReset();
extern void gbCleanUp();
extern void gbCPUInit(const char *,bool);
extern bool gbWriteBatteryFile(const char *);
extern bool gbWriteBatteryFile(const char *, bool);
extern bool gbReadBatteryFile(const char *);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -27,9 +27,11 @@
#include "gbCheats.h"
#include "gbGlobals.h"
#include "GB.h"
gbCheat gbCheatList[100];
int gbCheatNumber = 0;
int gbNextCheat = 0;
bool gbCheatMap[0x10000];
extern bool cheatsEnabled;
@ -50,7 +52,7 @@ void gbCheatUpdateMap()
void gbCheatsSaveGame(gzFile gzFile)
{
utilWriteInt(gzFile, gbCheatNumber);
if(gbCheatNumber)
if(gbCheatNumber>0)
utilGzWrite(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
}
@ -81,7 +83,7 @@ void gbCheatsReadGame(gzFile gzFile, int version)
} else {
gbCheatNumber = utilReadInt(gzFile);
if(gbCheatNumber) {
if(gbCheatNumber>0) {
utilGzRead(gzFile, &gbCheatList[0], sizeof(gbCheat)*gbCheatNumber);
}
}
@ -163,7 +165,7 @@ bool gbCheatsLoadCheatList(const char *file)
bool gbVerifyGsCode(const char *code)
{
int len = strlen(code);
size_t len = strlen(code);
if(len == 0)
return true;
@ -180,10 +182,6 @@ bool gbVerifyGsCode(const char *code)
GBCHEAT_HEX_VALUE(code[4]) << 4 |
GBCHEAT_HEX_VALUE(code[5]);
if(address < 0xa000 ||
address > 0xdfff)
return false;
return true;
}
@ -221,14 +219,22 @@ void gbAddGsCheat(const char *code, const char *desc)
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++;
}
bool gbVerifyGgCode(const char *code)
{
int len = strlen(code);
size_t len = strlen(code);
if(len != 11 &&
len != 7 &&
@ -313,12 +319,12 @@ void gbAddGgCheat(const char *code, const char *desc)
int i = gbCheatNumber;
int len = strlen(code);
size_t len = strlen(code);
strcpy(gbCheatList[i].cheatCode, code);
strcpy(gbCheatList[i].cheatDesc, desc);
gbCheatList[i].code = 1;
gbCheatList[i].code = 0x101;
gbCheatList[i].value = (GBCHEAT_HEX_VALUE(code[0]) << 4) +
GBCHEAT_HEX_VALUE(code[1]);
@ -338,9 +344,12 @@ void gbAddGgCheat(const char *code, const char *desc)
compare ^= 0x45;
gbCheatList[i].compare = compare;
gbCheatList[i].code = 0;
//gbCheatList[i].code = 0;
gbCheatList[i].code = 0x100; // fix for compare value
}
gbCheatList[i].enabled = true;
gbCheatMap[gbCheatList[i].address] = true;
@ -425,6 +434,7 @@ bool gbCheatReadGSCodeFile(const char *fileName)
return true;
}
// Used to emulated GG codes
u8 gbCheatRead(u16 address)
{
if(!cheatsEnabled)
@ -437,10 +447,36 @@ u8 gbCheatRead(u16 address)
if(gbMemoryMap[address>>12][address&0xFFF] == gbCheatList[i].compare)
return gbCheatList[i].value;
break;
case 0x00:
case 0x01:
case 0x80:
case 0x101: // GameGenie 6 digits code support
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 0x91:
case 0x92:
@ -449,14 +485,34 @@ u8 gbCheatRead(u16 address)
case 0x95:
case 0x96:
case 0x97:
if(address >= 0xd000 && address < 0xe000) {
if(((gbMemoryMap[0x0d] - gbWram)/0x1000) ==
(gbCheatList[i].code - 0x90))
return gbCheatList[i].value;
} else
return gbCheatList[i].value;
case 0x98:
case 0x99:
case 0x9A:
case 0x9B:
case 0x9C:
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 gbCheatDisable(int);
extern u8 gbCheatRead(u16);
extern void gbCheatWrite(bool);
extern int gbCheatNumber;
extern gbCheat gbCheatList[100];

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -22,8 +22,8 @@
break;
case 0x01:
// LD BC, NNNN
BC.B.B0=gbReadMemory(PC.W++);
BC.B.B1=gbReadMemory(PC.W++);
BC.B.B0=gbReadOpcode(PC.W++);
BC.B.B1=gbReadOpcode(PC.W++);
break;
case 0x02:
// LD (BC),A
@ -102,7 +102,9 @@
opcode = gbReadOpcode(PC.W++);
if(gbCgbMode) {
if(gbMemory[0xff4d] & 1) {
gbSpeedSwitch();
//clockTicks += 228*144-(gbSpeed ? 62 : 63);
if(gbSpeed == 0)
gbMemory[0xff4d] = 0x00;
@ -113,8 +115,8 @@
break;
case 0x11:
// LD DE, NNNN
DE.B.B0=gbReadMemory(PC.W++);
DE.B.B1=gbReadMemory(PC.W++);
DE.B.B0=gbReadOpcode(PC.W++);
DE.B.B1=gbReadOpcode(PC.W++);
break;
case 0x12:
// LD (DE),A
@ -147,7 +149,7 @@
break;
case 0x18:
// JR NN
PC.W+=(s8)gbReadMemory(PC.W)+1;
PC.W+=(s8)gbReadOpcode(PC.W)+1;
break;
case 0x19:
// ADD HL,DE
@ -190,14 +192,14 @@
if(AF.B.B0&Z_FLAG)
PC.W++;
else {
PC.W+=(s8)gbReadMemory(PC.W)+1;
PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++;
}
break;
case 0x21:
// LD HL,NNNN
HL.B.B0=gbReadMemory(PC.W++);
HL.B.B1=gbReadMemory(PC.W++);
HL.B.B0=gbReadOpcode(PC.W++);
HL.B.B1=gbReadOpcode(PC.W++);
break;
case 0x22:
// LDI (HL),A
@ -233,7 +235,7 @@
case 0x28:
// JR Z,NN
if(AF.B.B0&Z_FLAG) {
PC.W+=(s8)gbReadMemory(PC.W)+1;
PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++;
} else
PC.W++;
@ -278,14 +280,14 @@
if(AF.B.B0&C_FLAG)
PC.W++;
else {
PC.W+=(s8)gbReadMemory(PC.W)+1;
PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks++;
}
break;
case 0x31:
// LD SP,NNNN
SP.B.B0=gbReadMemory(PC.W++);
SP.B.B1=gbReadMemory(PC.W++);
SP.B.B0=gbReadOpcode(PC.W++);
SP.B.B1=gbReadOpcode(PC.W++);
break;
case 0x32:
// LDD (HL),A
@ -318,7 +320,7 @@
case 0x38:
// JR C,NN
if(AF.B.B0&C_FLAG) {
PC.W+=(s8)gbReadMemory(PC.W)+1;
PC.W+=(s8)gbReadOpcode(PC.W)+1;
clockTicks ++;
} else
PC.W++;
@ -575,16 +577,24 @@ case 0x38:
break;
case 0x76:
// 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--;
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;
case 0x77:
@ -1036,16 +1046,16 @@ case 0x38:
if(AF.B.B0&Z_FLAG)
PC.W+=2;
else {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W;
clockTicks++;
}
break;
case 0xc3:
// JP NNNN
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W;
break;
case 0xc4:
@ -1053,8 +1063,8 @@ case 0x38:
if(AF.B.B0&Z_FLAG)
PC.W+=2;
else {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W;
@ -1096,8 +1106,8 @@ case 0x38:
case 0xca:
// JP Z,NNNN
if(AF.B.B0&Z_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W;
clockTicks++;
} else
@ -1107,8 +1117,8 @@ case 0x38:
case 0xcc:
// CALL Z,NNNN
if(AF.B.B0&Z_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W;
@ -1118,8 +1128,8 @@ case 0x38:
break;
case 0xcd:
// CALL NNNN
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W;
@ -1156,20 +1166,24 @@ case 0x38:
if(AF.B.B0&C_FLAG)
PC.W+=2;
else {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W;
clockTicks++;
}
break;
// D3 illegal
case 0xd3:
PC.W--;
IFF = 0;
break;
case 0xd4:
// CALL NC,NNNN
if(AF.B.B0&C_FLAG)
PC.W+=2;
else {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W;
@ -1200,7 +1214,7 @@ case 0x38:
if(AF.B.B0&C_FLAG) {
PC.B.B0=gbReadMemory(SP.W++);
PC.B.B1=gbReadMemory(SP.W++);
clockTicks += 4;
clockTicks += 3;
}
break;
case 0xd9:
@ -1212,19 +1226,23 @@ case 0x38:
case 0xda:
// JP C,NNNN
if(AF.B.B0&C_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W);
PC.W=tempRegister.W;
clockTicks++;
} else
PC.W+=2;
break;
// DB illegal
case 0xdb:
PC.W--;
IFF = 0;
break;
case 0xdc:
// CALL C,NNNN
if(AF.B.B0&C_FLAG) {
tempRegister.B.B0=gbReadMemory(PC.W++);
tempRegister.B.B1=gbReadMemory(PC.W++);
tempRegister.B.B0=gbReadOpcode(PC.W++);
tempRegister.B.B1=gbReadOpcode(PC.W++);
gbWriteMemory(--SP.W,PC.B.B1);
gbWriteMemory(--SP.W,PC.B.B0);
PC.W=tempRegister.W;
@ -1233,6 +1251,10 @@ case 0x38:
PC.W+=2;
break;
// DD illegal
case 0xdd:
PC.W--;
IFF = 0;
break;
case 0xde:
// SBC NN
tempValue=gbReadOpcode(PC.W++);
@ -1262,6 +1284,11 @@ case 0x38:
break;
// E3 illegal
// E4 illegal
case 0xe3:
case 0xe4:
PC.W--;
IFF = 0;
break;
case 0xe5:
// PUSH HL
gbWriteMemory(--SP.W,HL.B.B1);
@ -1308,6 +1335,12 @@ case 0x38:
// EB illegal
// EC illegal
// ED illegal
case 0xeb:
case 0xec:
case 0xed:
PC.W--;
IFF = 0;
break;
case 0xee:
// XOR NN
tempValue=gbReadOpcode(PC.W++);
@ -1336,9 +1369,13 @@ case 0x38:
case 0xf3:
// DI
// IFF&=0xFE;
IFF&=(~0x21);
IFF|=0x08;
break;
// F4 illegal
case 0xf4:
PC.W--;
IFF = 0;
break;
case 0xf5:
// PUSH AF
gbWriteMemory(--SP.W,AF.B.B1);
@ -1383,10 +1420,23 @@ case 0x38:
break;
case 0xfb:
// 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;
// FC illegal
// FD illegal
case 0xfd:
PC.W--;
IFF = 0;
break;
case 0xfe:
// CP NN
tempValue=gbReadOpcode(PC.W++);
@ -1401,7 +1451,10 @@ case 0x38:
PC.W=0x0038;
break;
default:
if (gbSystemMessage == false)
{
systemMessage(0, N_("Unknown opcode %02x at %04x"),
gbReadOpcode(PC.W-1),PC.W-1);
emulating = false;
gbSystemMessage =true;
}
return;

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -1282,7 +1282,10 @@
AF.B.B1|=1<<7;
break;
default:
if (gbSystemMessage == false)
{
systemMessage(0, N_("Unknown opcode %02x at %04x"),
gbReadOpcode(PC.W-1),PC.W-1);
emulating = false;
gbSystemMessage =true;
}
return;

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -58,9 +58,12 @@ u8 gbInvertTab[256] = {
};
u16 gbLineMix[160];
u16 gbWindowColor[160];
extern int inUseRegister_WY;
void gbRenderLine()
{
memset(gbLineMix, 0, sizeof(gbLineMix));
u8 * bank0;
u8 * bank1;
if(gbCgbMode) {
@ -86,10 +89,9 @@ void gbRenderLine()
if(y >= 144)
return;
// int yLine = (y + gbBorderRowSkip) * gbBorderLineSkip;
int sx = register_SCX;
int sy = register_SCY;
int SpritesTicks = gbSpritesTicks[x]*(gbSpeed ? 2 : 4);
int sx = gbSCXLine[(gbSpeed ? 0 : 4)+SpritesTicks];
int sy = gbSCYLine[(gbSpeed ? 11 : 5)+SpritesTicks];
sy+=y;
@ -113,16 +115,17 @@ void gbRenderLine()
tile_map_address++;
if((register_LCDC & 16) == 0) {
if(tile < 128) tile += 128;
else tile -= 128;
}
if(!(register_LCDC & 0x10))
tile ^= 0x80;
int tile_pattern_address = tile_pattern + tile * 16 + by*2;
if(register_LCDC & 0x80) {
if((register_LCDC & 0x01 || gbCgbMode) && (layerSettings & 0x0100)) {
while(x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
@ -155,7 +158,7 @@ void gbRenderLine()
if(gbCgbMode) {
c = c + (attrs & 7)*4;
} else {
c = gbBgp[c];
c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+SpritesTicks]>>(c<<1)) &3;
if(gbSgbMode && !gbCgbMode) {
int dx = x >> 3;
int dy = y >> 3;
@ -168,42 +171,92 @@ void gbRenderLine()
c = c + 4*palette;
}
}
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c]] :
gbPalette[c];
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
x++;
if(x >= 160)
break;
bx >>= 1;
}
tx++;
if(tx == 32)
tx = 0;
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)
attrs = bank1[tile_map_line_y + tx];
tile = bank0[tile_map_line_y + tx];
if((register_LCDC & 16) == 0) {
if(tile < 128) tile += 128;
else tile -= 128;
}
if(!(register_LCDC & 0x10))
tile ^= 0x80;
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
}
} else {
for(int i = 0; i < 160; i++) {
gbLineMix[i] = gbPalette[0];
// Use gbBgp[0] instead of 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;
}
}
// do the window display
if((register_LCDC & 0x20) && (layerSettings & 0x2000)) {
int wy = register_WY;
// LCDC.0 also enables/disables the window in !gbCgbMode ?!?!
// (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 swx = 0;
wx -= 7;
if( wx <= 159 && gbWindowLine <= 143) {
@ -213,9 +266,6 @@ void gbRenderLine()
if((register_LCDC & 0x40) != 0)
tile_map = 0x1c00;
if(gbWindowLine == -1) {
gbWindowLine = 0;
}
tx = 0;
ty = gbWindowLine >> 3;
@ -223,6 +273,25 @@ void gbRenderLine()
bx = 128;
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) {
bx >>= (-wx);
wx = 0;
@ -247,6 +316,10 @@ void gbRenderLine()
tile_pattern_address = tile_pattern + tile * 16 + by*2;
if (wx)
for (i = 0; i<swx; i++)
gbLineMix[i] = gbWindowColor[i];
while(x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
@ -272,6 +345,8 @@ void gbRenderLine()
u8 c = (tile_a & bx) != 0 ? 1 : 0;
c += ((tile_b & bx) != 0 ? 2 : 0);
if (x>=0)
{
if(attrs & 0x80)
gbLineBuffer[x] = 0x300 + c;
else
@ -280,7 +355,7 @@ void gbRenderLine()
if(gbCgbMode) {
c = c + (attrs & 7) * 4;
} else {
c = gbBgp[c];
c = (gbBgpLine[x+(gbSpeed ? 5 : 11)+gbSpritesTicks[x]*(gbSpeed ? 2 : 4)]>>(c<<1)) &3;
if(gbSgbMode && !gbCgbMode) {
int dx = x >> 3;
int dy = y >> 3;
@ -293,8 +368,9 @@ void gbRenderLine()
c = c + 4*palette;
}
}
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c]] :
gbPalette[c];
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
}
x++;
if(x >= 160)
break;
@ -314,13 +390,30 @@ void gbRenderLine()
}
tile_pattern_address = tile_pattern + tile * 16 + by * 2;
}
//for (i = swx; i<160; i++)
// gbLineMix[i] = gbWindowColor[i];
gbWindowLine++;
}
}
}
else if (gbWindowLine == -2)
{
inUseRegister_WY = oldRegister_WY;
if (register_LY>oldRegister_WY)
gbWindowLine = 146;
else
gbWindowLine = 0;
}
} else {
for(int i = 0; i < 160; i++) {
gbLineMix[i] = gbPalette[0];
u16 color = gbColorOption ? gbColorFilter[0x7FFF] :
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;
}
}
@ -346,8 +439,11 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
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;
int flipx = (flags & 0x20);
@ -366,7 +462,7 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int a = 0;
int b = 0;
if(gbCgbMode && flags & 0x08) {
if(gbCgbMode && (flags & 0x08)) {
a = bank1[address++];
b = bank1[address++];
} else {
@ -393,11 +489,13 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
u16 color = gbLineBuffer[xxx];
if(prio) {
// Fixes OAM-BG priority
if(prio && (register_LCDC & 1)) {
if(color < 0x200 && ((color & 0xFF) != 0))
continue;
}
if(color >= 0x300 && color != 0x300)
// Fixes OAM-BG priority for Moorhuhn 2
if(color >= 0x300 && color != 0x300 && (register_LCDC & 1))
continue;
else if(color >= 0x200 && color < 0x300) {
int sprite = color & 0xff;
@ -412,7 +510,9 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
if(sprite < spriteNumber)
continue;
} 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;
}
}
@ -442,12 +542,12 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
}
}
gbLineMix[xxx] = gbColorOption ? gbColorFilter[gbPalette[c]] :
gbPalette[c];
gbLineMix[xxx] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
}
}
void gbDrawSprites()
void gbDrawSprites(bool draw)
{
int x = 0;
int y = 0;
@ -455,6 +555,9 @@ void gbDrawSprites()
int size = (register_LCDC & 4);
if (!draw)
memset (gbSpritesTicks, 0, sizeof(gbSpritesTicks));
if(!(register_LCDC & 0x80))
return;
@ -473,11 +576,19 @@ void gbDrawSprites()
if(x > 0 && y > 0 && x < 168 && y < 160) {
// check if sprite intersects current line
int t = yc -y + 16;
if(size && t >=0 && t < 16) {
gbDrawSpriteTile(tile,x-8,yc,t,flags,size,i);
count++;
} else if(!size && t >= 0 && t < 8) {
if((size && t >=0 && t < 16) || (!size && t >= 0 && t < 8)) {
if (draw)
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++;
}
}
@ -486,5 +597,5 @@ void gbDrawSprites()
break;
}
}
return;
}

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@ int gbRomSizeMask = 0;
int gbRomSize = 0;
int gbRamSizeMask = 0;
int gbRamSize = 0;
int gbTAMA5ramSize = 0;
u8 *gbMemory = NULL;
u8 *gbVram = NULL;
@ -31,6 +32,7 @@ u8 *gbRom = NULL;
u8 *gbRam = NULL;
u8 *gbWram = NULL;
u16 *gbLineBuffer = NULL;
u8 *gbTAMA5ram = NULL;
u16 gbPalette[128];
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};
int gbWindowLine = -1;
bool genericflashcardEnable = false;
int gbCgbMode = 0;
u16 gbColorFilter[32768];

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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 gbRamSize;
extern int gbRamSizeMask;
extern int gbTAMA5ramSize;
extern bool useBios;
extern bool skipBios;
extern u8 *bios;
extern u8 *gbRom;
extern u8 *gbRam;
@ -28,6 +33,7 @@ extern u8 *gbVram;
extern u8 *gbWram;
extern u8 *gbMemory;
extern u16 *gbLineBuffer;
extern u8 *gbTAMA5ram;
extern u8 *gbMemoryMap[16];
@ -46,6 +52,19 @@ extern u8 gbBgp[4];
extern u8 gbObp0[4];
extern u8 gbObp1[4];
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_LY;
@ -54,8 +73,10 @@ extern u8 register_SCX;
extern u8 register_WY;
extern u8 register_WX;
extern u8 register_VBK;
extern u8 oldRegister_WY;
extern int emulating;
extern bool genericflashcardEnable;
extern int gbBorderLineSkip;
extern int gbBorderRowSkip;
@ -63,6 +84,6 @@ extern int gbBorderColumnSkip;
extern int gbDmaTicks;
extern void gbRenderLine();
extern void gbDrawSprites();
extern void gbDrawSprites(bool);
extern u8 (*gbSerialFunction)(u8);

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -20,6 +20,12 @@
#include "../Port.h"
#include "gbGlobals.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 = {
0, // RAM enable
@ -27,7 +33,8 @@ mapperMBC1 gbDataMBC1 = {
0, // RAM bank
0, // memory model
0, // ROM high address
0 // RAM address
0, // RAM address
0 // Rom Bank 0 remapping
};
// MBC1 ROM write registers
@ -41,17 +48,25 @@ void mapperMBC1ROM(u16 address, u8 value)
break;
case 0x2000: // ROM bank select
// value = value & 0x1f;
if(value == 0)
value = 1;
if ((value == 1) && (address == 0x2100))
gbDataMBC1.mapperRomBank0Remapping = 1;
if((value & 0x1f) == 0)
value += 1;
if(value == gbDataMBC1.mapperROMBank)
break;
tmpAddress = value << 14;
// check current model
if (gbDataMBC1.mapperRomBank0Remapping == 3) {
tmpAddress = (value & 0xf) << 14;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 18;
}
else
if(gbDataMBC1.mapperMemoryModel == 0) {
// model is 16/8, so we have a high address in use
tmpAddress |= (gbDataMBC1.mapperROMHighAddress) << 19;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
}
tmpAddress &= gbRomSizeMask;
@ -63,16 +78,39 @@ void mapperMBC1ROM(u16 address, u8 value)
break;
case 0x4000: // RAM bank select
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
value = value & 0x03;
if(value == gbDataMBC1.mapperRAMBank)
break;
tmpAddress = value << 13;
tmpAddress &= gbRamSizeMask;
if(gbRamSize) {
gbMemoryMap[0x0a] = &gbRam[tmpAddress];
gbMemoryMap[0x0b] = &gbRam[tmpAddress + 0x1000];
}
gbDataMBC1.mapperRAMBank = value;
gbDataMBC1.mapperRAMAddress = tmpAddress;
if (gbDataMBC1.mapperRomBank0Remapping != 3)
gbDataMBC1.mapperROMHighAddress = 0;
} else {
// 16/8, set the high address
gbDataMBC1.mapperROMHighAddress = value & 0x03;
@ -83,10 +121,57 @@ void mapperMBC1ROM(u16 address, u8 value)
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];
}
gbDataMBC1.mapperRAMBank = 0;
}
break;
case 0x6000: // memory model select
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;
}
}
@ -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()
{
int tmpAddress = gbDataMBC1.mapperROMBank << 14;
// 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
tmpAddress |= (gbDataMBC1.mapperROMHighAddress) << 19;
tmpAddress |= (gbDataMBC1.mapperROMHighAddress & 3) << 19;
}
tmpAddress &= gbRomSizeMask;
@ -117,8 +250,9 @@ void memoryUpdateMapMBC1()
gbMemoryMap[0x05] = &gbRom[tmpAddress + 0x1000];
gbMemoryMap[0x06] = &gbRom[tmpAddress + 0x2000];
gbMemoryMap[0x07] = &gbRom[tmpAddress + 0x3000];
}
if(gbRamSize) {
if((gbRamSize) && (gbDataMBC1.mapperMemoryModel == 1)){
gbMemoryMap[0x0a] = &gbRam[gbDataMBC1.mapperRAMAddress];
gbMemoryMap[0x0b] = &gbRam[gbDataMBC1.mapperRAMAddress + 0x1000];
}
@ -210,7 +344,7 @@ void memoryUpdateMBC3Clock()
time_t diff = now - gbDataMBC3.mapperLastTime;
if(diff > 0) {
// update the clock according to the last update time
gbDataMBC3.mapperSeconds += diff % 60;
gbDataMBC3.mapperSeconds += (int)(diff % 60);
if(gbDataMBC3.mapperSeconds > 59) {
gbDataMBC3.mapperSeconds -= 60;
gbDataMBC3.mapperMinutes++;
@ -218,22 +352,22 @@ void memoryUpdateMBC3Clock()
diff /= 60;
gbDataMBC3.mapperMinutes += diff % 60;
if(gbDataMBC3.mapperMinutes > 60) {
gbDataMBC3.mapperMinutes += (int)(diff % 60);
if(gbDataMBC3.mapperMinutes > 59) {
gbDataMBC3.mapperMinutes -= 60;
gbDataMBC3.mapperHours++;
}
diff /= 60;
gbDataMBC3.mapperHours += diff % 24;
if(gbDataMBC3.mapperHours > 24) {
gbDataMBC3.mapperHours += (int)(diff % 24);
if(gbDataMBC3.mapperHours > 23) {
gbDataMBC3.mapperHours -= 24;
gbDataMBC3.mapperDays++;
}
diff /= 24;
gbDataMBC3.mapperDays += diff;
gbDataMBC3.mapperDays += (int)(diff & 0xffffffff);
if(gbDataMBC3.mapperDays > 255) {
if(gbDataMBC3.mapperDays > 511) {
gbDataMBC3.mapperDays %= 512;
@ -365,7 +499,30 @@ u8 mapperMBC3ReadRAM(u16 address)
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()
@ -406,6 +563,7 @@ void mapperMBC5ROM(u16 address, u8 value)
gbDataMBC5.mapperRAMEnable = ( ( value & 0x0a) == 0x0a ? 1 : 0);
break;
case 0x2000: // ROM bank select
if(address < 0x3000) {
value = value & 0xff;
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()
{
int tmpAddress = (gbDataMBC5.mapperROMBank << 14) |
@ -568,7 +758,30 @@ u8 mapperMBC7ReadRAM(u16 address)
case 0xa080:
return gbDataMBC7.value;
}
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];
}
// MBC7 RAM write
@ -717,7 +930,7 @@ void mapperMBC7RAM(u16 address, u8 value)
void memoryUpdateMapMBC7()
{
int tmpAddress = (gbDataMBC5.mapperROMBank << 14);
int tmpAddress = (gbDataMBC7.mapperROMBank << 14);
tmpAddress &= gbRomSizeMask;
gbMemoryMap[0x04] = &gbRom[tmpAddress];
@ -965,3 +1178,540 @@ void memoryUpdateMapHuC3()
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++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@ struct mapperMBC1 {
int mapperMemoryModel;
int mapperROMHighAddress;
int mapperRAMAddress;
int mapperRomBank0Remapping;
};
struct mapperMBC2 {
@ -106,15 +107,62 @@ struct mapperHuC3 {
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 mapperMBC2 gbDataMBC2;
extern mapperMBC3 gbDataMBC3;
extern mapperMBC5 gbDataMBC5;
extern mapperHuC1 gbDataHuC1;
extern mapperHuC3 gbDataHuC3;
extern mapperTAMA5 gbDataTAMA5;
extern mapperMMM01 gbDataMMM01;
extern mapperGS3 gbDataGS3;
void mapperMBC1ROM(u16,u8);
void mapperMBC1RAM(u16,u8);
u8 mapperMBC1ReadRAM(u16);
void mapperMBC2ROM(u16,u8);
void mapperMBC2RAM(u16,u8);
void mapperMBC3ROM(u16,u8);
@ -122,6 +170,7 @@ void mapperMBC3RAM(u16,u8);
u8 mapperMBC3ReadRAM(u16);
void mapperMBC5ROM(u16,u8);
void mapperMBC5RAM(u16,u8);
u8 mapperMBC5ReadRAM(u16);
void mapperMBC7ROM(u16,u8);
void mapperMBC7RAM(u16,u8);
u8 mapperMBC7ReadRAM(u16);
@ -130,7 +179,13 @@ void mapperHuC1RAM(u16,u8);
void mapperHuC3ROM(u16,u8);
void mapperHuC3RAM(u16,u8);
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 (*mapperRAM)(u16,u8);
//extern u8 (*mapperReadRAM)(u16);
@ -142,7 +197,9 @@ extern void memoryUpdateMapMBC5();
extern void memoryUpdateMapMBC7();
extern void memoryUpdateMapHuC1();
extern void memoryUpdateMapHuC3();
extern void memoryUpdateMapTAMA5();
extern void memoryUpdateMapMMM01();
extern void memoryUpdateMapGS3();

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -19,8 +19,6 @@
#include <stdlib.h>
#include <memory.h>
#include "../win32/stdafx.h"
#include "../win32/VBA.h"
#include "../System.h"
#include "../Port.h"
#include "../Util.h"
@ -29,6 +27,7 @@
extern u8 *pix;
extern bool speedup;
extern bool gbSgbResetFlag;
#define GBSGB_NONE 0
#define GBSGB_RESET 1
@ -98,7 +97,7 @@ void gbSgbReset()
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+1] = (0x15) | (0x15 << 5) | (0x15 << 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;
u16 c = gbPalette[palette + color];
if(!color)
c = gbPalette[0];
if((yy < 40 || yy >= 184) || (xx < 48 || xx >= 208)) {
// Fix for Super Snaky ???
// (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) {
case 16:
gbSgbDraw16Bit(dest + yyy*(256+2) + xxx, c);
@ -287,7 +289,6 @@ void gbSgbDrawBorderTile(int x, int y, int tile, int attr)
void gbSgbRenderBorder()
{
if(gbBorderOn) {
if (theApp.filterLCD) utilUpdateSystemColorMaps(0);
u8 *fromAddress = gbSgbBorder;
for(u8 y = 0; y < 28; y++) {
@ -298,7 +299,6 @@ void gbSgbRenderBorder()
gbSgbDrawBorderTile(x*8,y*8,tile,attr);
}
}
if (theApp.filterLCD) utilUpdateSystemColorMaps(1);
}
}

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -23,9 +23,6 @@
#include "gbGlobals.h"
#include "gbSound.h"
#include "../Gb_Apu/Multi_Buffer.h"
#include "../Gb_Apu/Gb_Apu.h"
extern u8 soundBuffer[6][735];
extern u16 soundFinalWave[1470];
extern int soundVolume;
@ -35,6 +32,7 @@ extern int soundVolume;
#define NOISE_MAGIC 5
extern int speed;
extern int gbHardware;
extern void soundResume();
@ -58,11 +56,11 @@ extern int soundBufferIndex;
int soundVIN = 0;
extern int soundDebug;
extern Multi_Buffer * apu_out;
extern Gb_Apu * apu;
extern int sound1On;
extern int sound1ATL;
int sound1ATLreload;
int freq1low;
int freq1high;
extern int sound1Skip;
extern int sound1Index;
extern int sound1Continue;
@ -79,6 +77,9 @@ extern u8 *sound1Wave;
extern int sound2On;
extern int sound2ATL;
int sound2ATLreload;
int freq2low;
int freq2high;
extern int sound2Skip;
extern int sound2Index;
extern int sound2Continue;
@ -90,6 +91,9 @@ extern u8 *sound2Wave;
extern int sound3On;
extern int sound3ATL;
int sound3ATLreload;
int freq3low;
int freq3high;
extern int sound3Skip;
extern int sound3Index;
extern int sound3Continue;
@ -99,6 +103,8 @@ extern int sound3Last;
extern int sound4On;
extern int sound4Clock;
extern int sound4ATL;
int sound4ATLreload;
int freq4;
extern int sound4Skip;
extern int sound4Index;
extern int sound4ShiftRight;
@ -126,45 +132,7 @@ extern bool soundLowPass;
extern bool soundReverse;
extern bool soundOffFlag;
u8 gbSoundRead(u16 address)
{
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;
}
bool gbDigitalSound = false;
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);
}
#endif
if (apu && address >= NR10 && address <= 0xFF3F)
{
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
if (address == NR50)
{
apu->write_register(clock, address, data);
switch(address) {
case NR10:
gbMemory[address] = data | 0x80;
sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
sound1SweepSteps = data & 7;
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)
{
soundBalance = data;
apu->write_register(clock, address, data & soundEnableFlag);
break;
case NR21:
gbMemory[address] = data | 0x3f;
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
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()
{
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()
{
// 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()
{
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()
{
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()
{
int res = 0;
blip_sample_t out[2] = {0, 0};
if ( ! apu_out ) return;
while (!apu_out->read_samples(&out[0], 2))
{
int ticks = SOUND_CLOCK_TICKS * 95 / (24 * (gbSpeed ? 2 : 1));
bool was_stereo = apu->end_frame( ticks );
apu_out->end_frame( ticks, was_stereo );
if(soundBalance & 16) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 32) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 64) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 128) {
res += ((s8)soundBuffer[3][soundIndex]);
}
res = out[0];
//res = (res * 7 * 60) >> 8;
if(gbDigitalSound)
res *= soundLevel1*256;
else
res *= soundLevel1*60;
if(soundEcho) {
res *= 2;
@ -273,7 +664,25 @@ void gbSoundMix()
else
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) {
res *= 2;
@ -325,10 +734,10 @@ void gbSoundTick()
{
if(systemSoundOn) {
if(soundMasterOn) {
/*gbSoundChannel1();
gbSoundChannel1();
gbSoundChannel2();
gbSoundChannel3();
gbSoundChannel4();*/
gbSoundChannel4();
gbSoundMix();
} else {
@ -354,7 +763,7 @@ void gbSoundTick()
void gbSoundReset()
{
soundPaused = 1;
soundPaused = true;
soundPlay = 0;
SOUND_CLOCK_TICKS = soundQuality * 24;
soundTicks = SOUND_CLOCK_TICKS;
@ -366,42 +775,99 @@ void gbSoundReset()
soundLevel2 = 7;
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
if(soundDebug) {
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)
{
apu_out->clear();
apu->reset(false);
gbSoundEvent(0xff1a, 0x7f);
gbSoundEvent(0xff1b, 0xff);
gbSoundEvent(0xff1c, 0xbf);
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
if(soundDebug) {
log("*** Sound Init Complete ***\n");
}
if (apu)
{
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
int addr = 0xff30;
while(addr < 0xff40) {
/*gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;*/
gbSoundEvent(addr++, 0x00);
gbSoundEvent(addr++, 0xFF);
}
gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;
}
memset(soundFinalWave, 0x00, soundBufferLen);
@ -411,7 +877,7 @@ void gbSoundReset()
soundEchoIndex = 0;
}
extern bool soundInit(bool gba = true);
extern bool soundInit(bool gb);
extern void soundShutdown();
void gbSoundSetQuality(int quality)
@ -497,6 +963,18 @@ void gbSoundSaveGame(gzFile gzFile)
{
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, soundFinalWave, 2*735);
utilGzWrite(gzFile, &soundQuality, sizeof(int));
@ -506,6 +984,35 @@ void gbSoundReadGame(int version,gzFile gzFile)
{
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;
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 gbSoundSetQuality(int);
extern u8 gbSoundRead(u16 address);
extern int soundTicks;
extern int soundQuality;
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_only ();
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
extern int _getopt_internal ();
#endif /* __STDC__ */
#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 *src3 = (u16 *)frm3;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 2;
for(int i = 0; i < height; i++) {
@ -166,10 +163,10 @@ static void SmartIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms;
}
#endif
src0+= sPitch;
src1+= sPitch;
src2+= sPitch;
src3+= sPitch;
src0+=2;
src1+=2;
src2+=2;
src3+=2;
}
/* Swap buffers around */
@ -200,12 +197,10 @@ void SmartIB(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src3 = (u16 *)frm3;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++)
for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos];
src0[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 */
pos++;
}
pos += sPitch;
}
/* Swap buffers around */
u8 *temp = frm1;
@ -234,9 +227,6 @@ static void SmartIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 *src2 = (u32 *)frm2;
u32 *src3 = (u32 *)frm3;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 1;
for(int i = 0; i < height; i++) {
@ -335,10 +325,10 @@ static void SmartIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
}
#endif
src0 += sPitch;
src1 += sPitch;
src2 += sPitch;
src3 += sPitch;
src0++;
src1++;
src2++;
src3++;
}
/* Swap buffers around */
u8 *temp = frm1;
@ -368,12 +358,10 @@ void SmartIB32(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 colorMask = 0xfefefe;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++)
for (int i = 0; i < sPitch; i++) {
u32 color = src0[pos];
src0[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 */
pos++;
}
pos += sPitch;
}
/* Swap buffers around */
u8 *temp = frm1;
@ -400,9 +386,6 @@ static void MotionBlurIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src0 = (u16 *)srcPtr;
u16 *src1 = (u16 *)frm1;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 2;
for(int i = 0; i < height; i++) {
@ -460,8 +443,8 @@ static void MotionBlurIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms;
}
#endif
src0 += sPitch;
src1 += sPitch;
src0+=2;
src1+=2;
}
}
#endif
@ -485,20 +468,16 @@ void MotionBlurIB(u8 *srcPtr, u32 srcPitch, int width, int height)
u16 *src1 = (u16 *)frm1;
int sPitch = srcPitch >> 1;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++)
for (int i = 0; i < sPitch; i++) {
u16 color = src0[pos];
src0[pos] =
(((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1));
src1[pos] = color;
pos++;
}
pos += sPitch;
}
}
#ifdef MMX
@ -507,9 +486,6 @@ static void MotionBlurIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 *src0 = (u32 *)srcPtr;
u32 *src1 = (u32 *)frm1;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int count = width >> 1;
for(int i = 0; i < height; i++) {
@ -567,8 +543,8 @@ static void MotionBlurIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height)
emms;
}
#endif
src0 += sPitch;
src1 += sPitch;
src0++;
src1++;
}
}
#endif
@ -592,57 +568,14 @@ void MotionBlurIB32(u8 *srcPtr, u32 srcPitch, int width, int height)
u32 colorMask = 0xfefefe;
int sPitch = srcPitch >> 2;
if (width > sPitch) width = sPitch;
sPitch -= width;
int pos = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++)
for (int i = 0; i < sPitch; i++) {
u32 color = src0[pos];
src0[pos] = (((color & colorMask) >> 1) +
((src1[pos] & colorMask) >> 1));
src1[pos] = color;
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_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_2(v) (v & interp_mask[1])

View File

@ -9,7 +9,7 @@
* 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 <stdarg.h>
@ -125,7 +125,7 @@ local size_t memWrite(const void *buffer, size_t size, size_t count,
total = file->available;
}
memcpy(file->next, buffer, total);
file->available -= total;
file->available -= (int)total;
file->next += total;
return total;
}
@ -147,7 +147,7 @@ local size_t memRead(void *buffer, size_t size, size_t count,
total = file->available;
}
memcpy(buffer, file->next, total);
file->available -= total;
file->available -= (int)total;
file->next += total;
return total;
}
@ -170,7 +170,7 @@ local int memPutc(int c, MEMFILE *file)
local long memTell(MEMFILE *f)
{
return (f->next - f->memory) - 8;
return (long)(f->next - f->memory) - 8;
}
local int memError(MEMFILE *f)
@ -197,7 +197,7 @@ local int memPrintf(MEMFILE *f, const char *format, ...)
len = vsprintf(buffer, format, 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
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 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.
*/
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);
}
@ -319,12 +325,13 @@ gzFile ZEXPORT memgzopen (char *memory, int available, const char *mode)
for end of file.
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->stream.avail_in == 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) {
s->z_eof = 1;
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
for concatenated .gz files.
*/
local void check_header(mem_stream *s)
local void check_header(s)
mem_stream *s;
{
int method; /* method 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.
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;
@ -434,7 +443,10 @@ local int destroy (mem_stream *s)
Reads the given number of uncompressed bytes from the compressed 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;
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;
}
if (s->stream.avail_out > 0) {
s->stream.avail_out -= memRead(next_out, 1, s->stream.avail_out,
s->file);
s->stream.avail_out -= (uInt)memRead(next_out, 1, s->stream.avail_out, s->file);
}
len -= s->stream.avail_out;
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) {
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) {
s->z_eof = 1;
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.
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;
@ -558,7 +572,9 @@ int ZEXPORT memgzwrite (gzFile file, const voidp buf, unsigned len)
Flushes all pending output into the compressed file. The parameter
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;
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
*/
local void putLong (MEMFILE *file, uLong x)
local void putLong (file, x)
MEMFILE *file;
uLong x;
{
int 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
of error.
*/
local uLong getLong (mem_stream *s)
local uLong getLong (s)
mem_stream *s;
{
uLong x = (uLong)get_byte(s);
int c;
@ -628,7 +647,8 @@ local uLong getLong (mem_stream *s)
Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state.
*/
int ZEXPORT memgzclose (gzFile file)
int ZEXPORT memgzclose (file)
gzFile file;
{
int err;
mem_stream *s = (mem_stream*)file;
@ -649,7 +669,8 @@ int ZEXPORT memgzclose (gzFile file)
return destroy((mem_stream*)file);
}
long ZEXPORT memtell(gzFile file)
long ZEXPORT memtell(file)
gzFile file;
{
mem_stream *s = (mem_stream*)file;

View File

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

View File

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

View File

@ -19,8 +19,9 @@
// AboutDialog.cpp : implementation file
//
#include "stdafx.h"
#include "AboutDialog.h"
#include "..\..\res\resource.h"
#include "../AutoBuild.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -63,15 +64,13 @@ BOOL AboutDialog::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");
return TRUE; // return TRUE unless you set the focus to a control
// 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 "Hyperlink.h"
#include "..\..\res\resource.h"
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
// AboutDialog dialog
@ -60,7 +60,6 @@ class AboutDialog : public CDialog
// Generated message map functions
//{{AFX_MSG(AboutDialog)
virtual BOOL OnInitDialog();
virtual void OnOK();
//}}AFX_MSG

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@
#if !defined(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
#pragma once
#endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@
#include "BugReport.h"
#include "../agbprint.h"
#include "../AutoBuild.h"
#include "../GBA.h"
#include "../Globals.h"
#include "../Port.h"
@ -215,7 +216,6 @@ CString BugReport::createReport()
AppendFormat(report, "Using BIOS : %d\r\n", theApp.useBiosFile);
AppendFormat(report, "Skip BIOS : %d\r\n", theApp.skipBiosFile);
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, "Rewind : %d\r\n", theApp.rewindTimer);
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, "Blue shift : %08x\r\n", systemBlueShift);
AppendFormat(report, "Layer setting: %04X\r\n", layerSettings);
AppendFormat(report, "Mirroring : %d\r\n", mirroringEnable);
AppendFormat(report, "Save type : %d (%d)\r\n",
theApp.winSaveType, cpuSaveType);
AppendFormat(report, "Flash size : %08X (%08x)\r\n",

View File

@ -264,14 +264,15 @@ void CAccelsOb::GetString(CString& szBuffer)
return;
// 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) {
szBuffer += mapVirtSysKeys[i].szKey;
szBuffer += "+";
}
}
// 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) {
szBuffer += mapVirtKeys[i].szKey;
return;

View File

@ -20,7 +20,7 @@
#if !defined(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
#pragma once
#endif // _MSC_VER > 1000

View File

@ -20,7 +20,7 @@
#if !defined(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
#pragma once
#endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#include "stdafx.h"
#include "AcceleratorManager.h"
#include "..\..\res\resource.h"
#include "resource.h"
#include <afxres.h>
#include <afxtempl.h> // MFC Templates extension
@ -105,6 +105,8 @@ struct {
{ "OptionsVideoRenderDDRAW", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECTDRAW },
{ "OptionsVideoRenderD3D", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECT3D },
{ "OptionsVideoRenderOGL", ID_OPTIONS_VIDEO_RENDERMETHOD_OPENGL },
{ "OptionsVideoRenderSelectSkin", ID_OPTIONS_VIDEO_RENDEROPTIONS_SELECTSKIN },
{ "OptionsVideoRenderSkin", ID_OPTIONS_VIDEO_RENDEROPTIONS_SKIN },
{ "OptionsVideoVsync", ID_OPTIONS_VIDEO_VSYNC },
{ "OptionsVideoX1", ID_OPTIONS_VIDEO_X1 },
{ "OptionsVideoX2", ID_OPTIONS_VIDEO_X2 },
@ -127,13 +129,13 @@ struct {
{ "OptionsEmulatorDirectories", ID_OPTIONS_EMULATOR_DIRECTORIES },
{ "OptionsEmulatorSelectBIOS", ID_OPTIONS_EMULATOR_SELECTBIOSFILE },
{ "OptionsEmulatorUseBIOS", ID_OPTIONS_EMULATOR_USEBIOSFILE },
{ "OptionsEmulatorGameOverrides", ID_OPTIONS_EMULATOR_GAMEOVERRIDES },
{ "OptionsEmulatorSkipBIOS", ID_OPTIONS_EMULATOR_SKIPBIOS },
{ "OptionsEmulatorShowSpeedNone", ID_OPTIONS_EMULATOR_SHOWSPEED_NONE },
{ "OptionsEmulatorShowSpeedPercentage", ID_OPTIONS_EMULATOR_SHOWSPEED_PERCENTAGE },
{ "OptionsEmulatorShowSpeedDetailed", ID_OPTIONS_EMULATOR_SHOWSPEED_DETAILED },
{ "OptionsEmulatorShowSpeedTransparent", ID_OPTIONS_EMULATOR_SHOWSPEED_TRANSPARENT },
{ "OptionsEmulatorSpeedupToggle", ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE },
{ "OptionsEmulatorRemoveIntros", ID_OPTIONS_EMULATOR_REMOVEINTROSGBA },
{ "OptionsEmulatorAutoHideMenu", ID_OPTIONS_EMULATOR_AUTOHIDEMENU },
{ "OptionsEmulatorSaveAuto", ID_OPTIONS_EMULATOR_SAVETYPE_AUTOMATIC },
{ "OptionsEmulatorSaveEEPROM", ID_OPTIONS_EMULATOR_SAVETYPE_EEPROM },
@ -145,9 +147,10 @@ struct {
{ "OptionsEmulatorAutoIPSPatch", ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH },
{ "OptionsEmulatorAGBPrint", ID_OPTIONS_EMULATOR_AGBPRINT },
{ "OptionsEmulatorRTC", ID_OPTIONS_EMULATOR_REALTIMECLOCK },
{ "OptionsEmulatorGenericflashcard", ID_OPTIONS_EMULATOR_GENERICFLASHCARD },
{ "OptionsEmulatorRewindInterval", ID_OPTIONS_EMULATOR_REWINDINTERVAL },
{ "OptionsSoundOff", ID_OPTIONS_SOUND_OFF },
{ "OptionsSoundMute", ID_OPTIONS_SOUND_OFF }, /* mute hax */
{ "OptionsSoundMute", ID_OPTIONS_SOUND_MUTE },
{ "OptionsSoundOn", ID_OPTIONS_SOUND_ON },
{ "OptionsSoundChannel1", ID_OPTIONS_SOUND_CHANNEL1 },
{ "OptionsSoundChannel2", ID_OPTIONS_SOUND_CHANNEL2 },
@ -174,6 +177,7 @@ struct {
{ "OptionsFilterSuper2xSaI", ID_OPTIONS_FILTER_SUPER2XSAI },
{ "OptionsFilterSuperEagle", ID_OPTIONS_FILTER_SUPEREAGLE },
{ "OptionsFilterPixelate", ID_OPTIONS_FILTER16BIT_PIXELATEEXPERIMENTAL },
{ "OptionsFilterMotionBlur", ID_OPTIONS_FILTER16BIT_MOTIONBLUREXPERIMENTAL },
{ "OptionsFilterAdMameScale2x", ID_OPTIONS_FILTER16BIT_ADVANCEMAMESCALE2X },
{ "OptionsFilterSimple2x", ID_OPTIONS_FILTER16BIT_SIMPLE2X },
{ "OptionsFilterBilinear", ID_OPTIONS_FILTER_BILINEAR },
@ -224,7 +228,8 @@ struct {
{ "ToolsCustomize", ID_TOOLS_CUSTOMIZE },
{ "HelpBugReport", ID_HELP_BUGREPORT },
{ "HelpFAQ", ID_HELP_FAQ },
{ "HelpAbout", ID_HELP_ABOUT }
{ "HelpAbout", ID_HELP_ABOUT },
{ "SystemMinimize", ID_SYSTEM_MINIMIZE }
};
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
#include <ddraw.h>
#include <mmsystem.h>
#include "../System.h"
#include "../gb/gbGlobals.h"
#include "../GBA.h"
@ -33,7 +31,9 @@
#include "VBA.h"
#include "MainWnd.h"
#include "Reg.h"
#include "..\..\res\resource.h"
#include "resource.h"
#include "Display.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -58,18 +58,7 @@ private:
int height;
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 StartTimer();
void StopTimer();
static void CALLBACK g_timer_proc( UINT id, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2 );
public:
DirectDrawDisplay();
virtual ~DirectDrawDisplay();
@ -83,9 +72,8 @@ public:
virtual bool changeRenderSize(int w, int h);
virtual DISPLAY_TYPE getType() { return DIRECT_DRAW; };
virtual void setOption(const char *, int) {}
virtual bool isSkinSupported() { return true; }
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)
@ -144,10 +132,6 @@ DirectDrawDisplay::DirectDrawDisplay()
width = 0;
height = 0;
failed = false;
wait_screenheight = 0;
wait_event = 0;
wait_timerres = 0;
wait_timerid = 0;
}
DirectDrawDisplay::~DirectDrawDisplay()
@ -158,15 +142,6 @@ DirectDrawDisplay::~DirectDrawDisplay()
void DirectDrawDisplay::cleanup()
{
if(pDirectDraw != NULL) {
if ( wait_timerid ) {
StopTimer();
}
if ( wait_event ) {
CloseHandle( wait_event );
wait_event = 0;
}
if(ddsClipper != NULL) {
ddsClipper->Release();
ddsClipper = NULL;
@ -192,7 +167,11 @@ void DirectDrawDisplay::cleanup()
}
if(ddrawDLL != NULL) {
#ifdef _AFXDLL
AfxFreeLibrary( ddrawDLL );
#else
FreeLibrary( ddrawDLL );
#endif
ddrawDLL = NULL;
}
width = 0;
@ -228,13 +207,13 @@ bool DirectDrawDisplay::initialize()
case VIDEO_1280x1024:
case VIDEO_OTHER:
{
float scaleX = ((float)theApp.fsWidth / (float)theApp.sizeX);
float scaleY = ((float)theApp.fsHeight / (float)theApp.sizeY);
float min = scaleX < scaleY ? scaleX : scaleY;
int scaleX = (theApp.fsWidth / theApp.sizeX);
int scaleY = (theApp.fsHeight / theApp.sizeY);
int min = scaleX < scaleY ? scaleX : scaleY;
if(theApp.fsMaxScale)
min = min > theApp.fsMaxScale ? theApp.fsMaxScale : min;
theApp.surfaceSizeX = (int)(theApp.sizeX * min);
theApp.surfaceSizeY = (int)(theApp.sizeY * min);
theApp.surfaceSizeX = theApp.sizeX * min;
theApp.surfaceSizeY = theApp.sizeY * min;
if(theApp.fullScreenStretch) {
theApp.surfaceSizeX = theApp.fsWidth;
theApp.surfaceSizeY = theApp.fsHeight;
@ -306,7 +285,12 @@ bool DirectDrawDisplay::initialize()
if(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 *);
if(ddrawDLL != NULL) {
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;
px.dwSize = sizeof(px);
@ -633,7 +611,7 @@ bool DirectDrawDisplay::initializeOffscreen(int w, int h)
winlog("B shift: %d\n", systemBlueShift);
}
utilUpdateSystemColorMaps(theApp.filterLCD);
utilUpdateSystemColorMaps();
width = w;
height = h;
return true;
@ -671,6 +649,7 @@ void DirectDrawDisplay::checkFullScreen()
void DirectDrawDisplay::render()
{
HRESULT hret;
unsigned int nBytesPerPixel = systemColorDepth>>3;
if(pDirectDraw == NULL ||
ddsOffscreen == NULL ||
@ -743,62 +722,9 @@ void DirectDrawDisplay::render()
copyY = 144;
}
}
// MMX doesn't seem to be faster to copy the data
__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:
copyImage( pix, ddsDesc.lpSurface, copyX, copyY, ddsDesc.lPitch, systemColorDepth );
}
}
if(theApp.showSpeed && theApp.videoOption > VIDEO_4X) {
if(theApp.showSpeed && (theApp.videoOption > VIDEO_4X || theApp.skin != NULL)) {
char buffer[30];
if(theApp.showSpeed == 1)
sprintf(buffer, "%3d%%", systemSpeed);
@ -826,8 +752,7 @@ void DirectDrawDisplay::render()
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?
//hret = pDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
WaitForSingleObject( wait_event, 100 );
hret = pDirectDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
}
ddsOffscreen->PageLock(0);
if(theApp.tripleBuffering && theApp.videoOption > VIDEO_4X) {
@ -865,7 +790,7 @@ void DirectDrawDisplay::render()
SetTextColor(hdc, RGB(255,0,0));
SetBkMode(hdc,TRANSPARENT);
TextOut(hdc, theApp.dest.left+10, theApp.dest.bottom - 20, theApp.screenMessageBuffer,
strlen(theApp.screenMessageBuffer));
(int)_tcslen(theApp.screenMessageBuffer));
ddsPrimary->ReleaseDC(hdc);
} else {
theApp.screenMessage = false;
@ -883,74 +808,8 @@ int DirectDrawDisplay::selectFullScreenMode(GUID **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()
{
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
// 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.
/* VisualBoyAdvance S - GB & GBA emulator
Copyright (C) 2006 Spacy
Original VBA Credits:
Copyright (C) 1999-2003 Forgotten
Copyright (C) 2004-2006 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 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "stdafx.h"
#include "VBA.h"
#include "Input.h"
#include "Reg.h"
#include "WinResUtil.h"
#include "Input.h"
#define DIRECTINPUT_VERSION 0x0500
#include <dinput.h>
#define DIRECTINPUT_VERSION 0x0800
#include <Dinput.h>
#pragma comment(lib, "Dinput8")
#ifdef _DEBUG
#define new DEBUG_NEW
@ -39,9 +47,6 @@ extern void winlog(const char *msg,...);
#define POV_LEFT 8
class DirectInput : public Input {
private:
HINSTANCE dinputDLL;
public:
virtual void checkDevices();
DirectInput();
@ -50,7 +55,7 @@ public:
virtual bool initialize();
virtual bool readDevices();
virtual u32 readDevice(int which);
virtual CString getKeyName(int key);
virtual CString getKeyName(LONG_PTR key);
virtual void checkKeys();
virtual void checkMotionKeys();
virtual void activate();
@ -59,7 +64,7 @@ public:
};
struct deviceInfo {
LPDIRECTINPUTDEVICE device;
LPDIRECTINPUTDEVICE8 device;
BOOL isPolled;
int nButtons;
int nAxes;
@ -81,15 +86,13 @@ struct deviceInfo {
static deviceInfo *currentDevice = NULL;
static int numDevices = 1;
static deviceInfo *pDevices = NULL;
static LPDIRECTINPUT pDirectInput = NULL;
static int joyDebug = 0;
static LPDIRECTINPUT8 pDirectInput = NULL;
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_UP, DIK_DOWN,
@ -131,24 +134,24 @@ void winReadKeys()
{
for(int i = 0; i < JOYPADS; i++) {
winReadKey("Left", i, joypad[JOYPAD(i,KEY_LEFT)]);
winReadKey("Right", i, joypad[JOYPAD(i, KEY_RIGHT)]);
winReadKey("Up", i, joypad[JOYPAD(i,KEY_UP)]);
winReadKey("Down", i, joypad[JOYPAD(i,KEY_DOWN)]);
winReadKey("A", i, joypad[JOYPAD(i,KEY_BUTTON_A)]);
winReadKey("B", i, joypad[JOYPAD(i,KEY_BUTTON_B)]);
winReadKey("L", i, joypad[JOYPAD(i,KEY_BUTTON_L)]);
winReadKey("R", i, joypad[JOYPAD(i,KEY_BUTTON_R)]);
winReadKey("Start", i, joypad[JOYPAD(i,KEY_BUTTON_START)]);
winReadKey("Select", i, joypad[JOYPAD(i,KEY_BUTTON_SELECT)]);
winReadKey("Speed", i, joypad[JOYPAD(i,KEY_BUTTON_SPEED)]);
winReadKey("Capture", i, joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winReadKey("GS", i, joypad[JOYPAD(i,KEY_BUTTON_GS)]);
winReadKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
winReadKey("Right", i, theApp.input->joypaddata[JOYPAD(i, KEY_RIGHT)]);
winReadKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
winReadKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
winReadKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
winReadKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
winReadKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
winReadKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
winReadKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
winReadKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
winReadKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
winReadKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winReadKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
}
winReadKey("Motion_Left", joypad[MOTION(KEY_LEFT)]);
winReadKey("Motion_Right", joypad[MOTION(KEY_RIGHT)]);
winReadKey("Motion_Up", joypad[MOTION(KEY_UP)]);
winReadKey("Motion_Down", joypad[MOTION(KEY_DOWN)]);
winReadKey("Motion_Left", theApp.input->joypaddata[MOTION(KEY_LEFT)]);
winReadKey("Motion_Right", theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
winReadKey("Motion_Up", theApp.input->joypaddata[MOTION(KEY_UP)]);
winReadKey("Motion_Down", theApp.input->joypaddata[MOTION(KEY_DOWN)]);
}
void winSaveKey(char *name, KeyList& value)
@ -178,30 +181,30 @@ static void winSaveKey(char *name, int num, KeyList& value)
void winSaveKeys()
{
for(int i = 0; i < JOYPADS; i++) {
winSaveKey("Left", i, joypad[JOYPAD(i,KEY_LEFT)]);
winSaveKey("Right", i, joypad[JOYPAD(i,KEY_RIGHT)]);
winSaveKey("Up", i, joypad[JOYPAD(i,KEY_UP)]);
winSaveKey("Speed", i, joypad[JOYPAD(i,KEY_BUTTON_SPEED)]);
winSaveKey("Capture", i, joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winSaveKey("GS", i, joypad[JOYPAD(i,KEY_BUTTON_GS)]);
winSaveKey("Down", i, joypad[JOYPAD(i,KEY_DOWN)]);
winSaveKey("A", i, joypad[JOYPAD(i,KEY_BUTTON_A)]);
winSaveKey("B", i, joypad[JOYPAD(i,KEY_BUTTON_B)]);
winSaveKey("L", i, joypad[JOYPAD(i,KEY_BUTTON_L)]);
winSaveKey("R", i, joypad[JOYPAD(i,KEY_BUTTON_R)]);
winSaveKey("Start", i, joypad[JOYPAD(i,KEY_BUTTON_START)]);
winSaveKey("Select", i, joypad[JOYPAD(i,KEY_BUTTON_SELECT)]);
winSaveKey("Left", i, theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]);
winSaveKey("Right", i, theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]);
winSaveKey("Up", i, theApp.input->joypaddata[JOYPAD(i,KEY_UP)]);
winSaveKey("Speed", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SPEED)]);
winSaveKey("Capture", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]);
winSaveKey("GS", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]);
winSaveKey("Down", i, theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]);
winSaveKey("A", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]);
winSaveKey("B", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]);
winSaveKey("L", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]);
winSaveKey("R", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]);
winSaveKey("Start", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]);
winSaveKey("Select", i, theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]);
}
regSetDwordValue("joyVersion", 1);
winSaveKey("Motion_Left",
joypad[MOTION(KEY_LEFT)]);
theApp.input->joypaddata[MOTION(KEY_LEFT)]);
winSaveKey("Motion_Right",
joypad[MOTION(KEY_RIGHT)]);
theApp.input->joypaddata[MOTION(KEY_RIGHT)]);
winSaveKey("Motion_Up",
joypad[MOTION(KEY_UP)]);
theApp.input->joypaddata[MOTION(KEY_UP)]);
winSaveKey("Motion_Down",
joypad[MOTION(KEY_DOWN)]);
theApp.input->joypaddata[MOTION(KEY_DOWN)]);
}
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].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++;
@ -327,17 +324,17 @@ static int getPovState(DWORD value)
static void checkKeys()
{
int dev = 0;
LONG_PTR dev = 0;
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])
joypad[i].AddTail(defvalues[i]);
POSITION p = joypad[i].GetHeadPosition();
if (theApp.input->joypaddata[i].IsEmpty() && defvalues[i])
theApp.input->joypaddata[i].AddTail(defvalues[i]);
POSITION p = theApp.input->joypaddata[i].GetHeadPosition();
while(p!=NULL)
{
USHORT k = joypad[i].GetNext(p);
LONG_PTR k = theApp.input->joypaddata[i].GetNext(p);
if (k > 0 && DEVICEOF(k) < numDevices)
pDevices[DEVICEOF(k)].needed = true;
}
@ -349,10 +346,6 @@ static void checkKeys()
static bool readKeyboard()
{
if (pDevices[0].needed) {
if (!theApp.dinputKeyFocus) {
memset(pDevices[0].data, 0, 256);
return true;
}
HRESULT hret = pDevices[0].device->
GetDeviceState(256,
(LPVOID)pDevices[0].data);
@ -401,10 +394,18 @@ static bool readJoystick(int joy)
static void checkKeyboard()
{
// mham fix. Patch #1378104
UCHAR keystate[256];
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->
GetDeviceState(256,
(LPVOID)pDevices[0].data);
GetDeviceState(256, (LPVOID)keystate);
if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) {
return;
@ -412,12 +413,14 @@ static void checkKeyboard()
if (hret == DI_OK) {
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);
break;
}
}
}
memcpy(pDevices[0].data, keystate, sizeof(UCHAR) * 256);
}
static void checkJoypads()
@ -522,16 +525,17 @@ static void checkJoypads()
}
}
BOOL checkKey(int key)
BOOL checkKey(LONG_PTR key)
{
int dev = DEVICEOF(key);
int k = KEYOF(key);
LONG_PTR dev = (key >> 8);
LONG_PTR k = (key & 255);
if (dev == 0) {
return KEYDOWN(pDevices[0].data,k);
} else {
if (k < 16) {
int axis = k >> 1;
LONG_PTR axis = k >> 1;
LONG value = pDevices[dev].axis[axis].center;
switch (pDevices[dev].axis[axis].offset) {
case DIJOFS_X:
@ -564,7 +568,7 @@ BOOL checkKey(int key)
return value > pDevices[dev].axis[axis].positive;
return value < pDevices[dev].axis[axis].negative;
} else if (k < 48) {
int hat = (k >> 2) & 3;
LONG_PTR hat = (k >> 2) & 3;
int state = getPovState(pDevices[dev].state.rgdwPOV[hat]);
BOOL res = FALSE;
switch (k & 3) {
@ -602,9 +606,7 @@ BOOL checkKey(KeyList &k)
}
DirectInput::DirectInput()
{
dinputDLL = NULL;
}
{}
DirectInput::~DirectInput()
{
@ -625,44 +627,29 @@ DirectInput::~DirectInput()
pDirectInput->Release();
pDirectInput = NULL;
}
}
if(dinputDLL) {
FreeLibrary(dinputDLL);
dinputDLL = NULL;
}
}
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) {
directXMessage("DirectInputCreateA");
return false;
}
} else {
directXMessage("DINPUT.DLL");
return false;
}
HRESULT hr;
HRESULT hret = DInputCreate(AfxGetInstanceHandle(),
hr = DirectInput8Create(
AfxGetInstanceHandle(),
DIRECTINPUT_VERSION,
&pDirectInput,
IID_IDirectInput8,
(LPVOID*)&pDirectInput,
NULL );
if(hret != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_CREATE), hret);
if ( hr != DI_OK ) {
return false;
}
hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK,
hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
DIEnumDevicesCallback2,
NULL,
DIEDFL_ATTACHEDONLY);
@ -671,68 +658,49 @@ bool DirectInput::initialize()
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].needed = true;
pDevices[0].first = true;
if(hret != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_CREATEDEVICE), hret);
if (hr != DI_OK) {
return false;
}
numDevices = 1;
hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK,
hr = pDirectInput->EnumDevices(DI8DEVCLASS_GAMECTRL,
DIEnumDevicesCallback,
NULL,
DIEDFL_ATTACHEDONLY);
// hret = pDevices[0].device->SetCooperativeLevel(hWindow,
// DISCL_FOREGROUND|
// DISCL_NONEXCLUSIVE);
if(hret != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_LEVEL), hret);
if (hr != DI_OK) {
return false;
}
hret = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard);
hr = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard);
if(hret != DI_OK) {
// errorMessage(myLoadString(IDS_ERROR_DISP_DATAFORMAT), hret);
if (hr != DI_OK) {
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].needed = false;
pDevices[i].first = true;
currentDevice = &pDevices[i];
axisNumber = 0;
currentDevice->device->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS);
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;
}
if (1) for(int i = 0; i < numDevices; i++)
for (i = 0; i < numDevices; i++)
pDevices[i].device->Acquire();
return true;
@ -759,28 +727,28 @@ u32 DirectInput::readDevice(int which)
if(which >= 0 && which <= 3)
i = which;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_A)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_A)]))
res |= 1;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_B)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_B)]))
res |= 2;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_SELECT)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_SELECT)]))
res |= 4;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_START)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_START)]))
res |= 8;
if(checkKey(joypad[JOYPAD(i,KEY_RIGHT)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_RIGHT)]))
res |= 16;
if(checkKey(joypad[JOYPAD(i,KEY_LEFT)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_LEFT)]))
res |= 32;
if(checkKey(joypad[JOYPAD(i,KEY_UP)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_UP)]))
res |= 64;
if(checkKey(joypad[JOYPAD(i,KEY_DOWN)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_DOWN)]))
res |= 128;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_R)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_R)]))
res |= 256;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_L)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_L)]))
res |= 512;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_GS)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_GS)]))
res |= 4096;
if(theApp.autoFire) {
@ -813,18 +781,18 @@ u32 DirectInput::readDevice(int which)
res = theApp.movieLastJoypad;
}
// 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;
if(checkKey(joypad[JOYPAD(i,KEY_BUTTON_CAPTURE)]))
if(checkKey(theApp.input->joypaddata[JOYPAD(i,KEY_BUTTON_CAPTURE)]))
res |= 2048;
return res;
}
CString DirectInput::getKeyName(int key)
CString DirectInput::getKeyName(LONG_PTR key)
{
int d = (key >> 8);
int k = key & 255;
LONG_PTR d = (key >> 8);
LONG_PTR k = key & 255;
DIDEVICEOBJECTINSTANCE di;
@ -835,7 +803,7 @@ CString DirectInput::getKeyName(int key)
CString winBuffer = winResLoadString(IDS_ERROR);
if (d == 0) {
pDevices[0].device->GetObjectInfo(&di,key,DIPH_BYOFFSET);
pDevices[0].device->GetObjectInfo( &di, (DWORD)key, DIPH_BYOFFSET );
winBuffer = di.tszName;
} else {
if (k < 16) {
@ -864,12 +832,12 @@ CString DirectInput::getKeyName(int key)
winBuffer.Format("Joy %d %s -", d, di.tszName);
}
} else if (k < 48) {
int hat = (k >> 2) & 3;
LONG_PTR hat = (k >> 2) & 3;
pDevices[d].device->GetObjectInfo(&di,
DIJOFS_POV(hat),
(DWORD)DIJOFS_POV(hat),
DIPH_BYOFFSET);
char *dir = "up";
int dd = k & 3;
LONG_PTR dd = k & 3;
if (dd == 1)
dir = "down";
else if (dd == 2)
@ -879,7 +847,7 @@ CString DirectInput::getKeyName(int key)
winBuffer.Format("Joy %d %s %s", d, di.tszName, dir);
} else {
pDevices[d].device->GetObjectInfo(&di,
DIJOFS_BUTTON(k-128),
(DWORD)DIJOFS_BUTTON(k-128),
DIPH_BYOFFSET);
winBuffer.Format(winResLoadString(IDS_JOY_BUTTON),d,di.tszName);
}
@ -895,13 +863,13 @@ void DirectInput::checkKeys()
void DirectInput::checkMotionKeys()
{
if(checkKey(joypad[MOTION(KEY_LEFT)])) {
if(checkKey(theApp.input->joypaddata[MOTION(KEY_LEFT)])) {
theApp.sensorX += 3;
if(theApp.sensorX > 2197)
theApp.sensorX = 2197;
if(theApp.sensorX < 2047)
theApp.sensorX = 2057;
} else if(checkKey(joypad[MOTION(KEY_RIGHT)])) {
} else if(checkKey(theApp.input->joypaddata[MOTION(KEY_RIGHT)])) {
theApp.sensorX -= 3;
if(theApp.sensorX < 1897)
theApp.sensorX = 1897;
@ -917,13 +885,13 @@ void DirectInput::checkMotionKeys()
theApp.sensorX = 2047;
}
if(checkKey(joypad[MOTION(KEY_UP)])) {
if(checkKey(theApp.input->joypaddata[MOTION(KEY_UP)])) {
theApp.sensorY += 3;
if(theApp.sensorY > 2197)
theApp.sensorY = 2197;
if(theApp.sensorY < 2047)
theApp.sensorY = 2057;
} else if(checkKey(joypad[MOTION(KEY_DOWN)])) {
} else if(checkKey(theApp.input->joypaddata[MOTION(KEY_DOWN)])) {
theApp.sensorY -= 3;
if(theApp.sensorY < 1897)
theApp.sensorY = 1897;

View File

@ -1,6 +1,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// MFC
#include "stdafx.h"
#include "VBA.h"
// Tools
#include "AVIWrite.h"
#include "Sound.h"
#include "WavWriter.h"
// Internals
#include "../System.h"
#include "../GBA.h"
#include "../Globals.h"
#include "../Sound.h"
#include <mmreg.h>
#include <Dsound.h> //DirectSound
// DirectSound8
#include <Dsound.h>
#pragma comment( lib, "Dsound" )
#pragma comment( lib, "Dxguid" )
extern bool soundBufferLow;
class DirectSound : public ISound
{
private:
HINSTANCE dsoundDLL;
LPDIRECTSOUND pDirectSound;
LPDIRECTSOUNDBUFFER dsbPrimary;
LPDIRECTSOUNDBUFFER dsbSecondary;
LPDIRECTSOUNDNOTIFY dsbNotify;
LPDIRECTSOUND8 pDirectSound; // DirectSound interface
LPDIRECTSOUNDBUFFER dsbPrimary; // Primary DirectSound buffer
LPDIRECTSOUNDBUFFER dsbSecondary; // Secondary DirectSound buffer
LPDIRECTSOUNDNOTIFY8 dsbNotify;
HANDLE dsbEvent;
WAVEFORMATEX wfx;
WAVEFORMATEX wfx; // Primary buffer wave format
public:
DirectSound();
virtual ~DirectSound();
bool init();
void pause();
void reset();
void resume();
void write();
bool init(); // initialize the primary and secondary sound buffer
void pause(); // pause the secondary sound buffer
void reset(); // stop and reset the secondary sound buffer
void resume(); // resume the secondary sound buffer
void write(); // write the emulated sound to the secondary sound buffer
};
DirectSound::DirectSound()
{
dsoundDLL = NULL;
CoInitialize( NULL );
pDirectSound = NULL;
dsbPrimary = NULL;
dsbSecondary = NULL;
@ -64,39 +70,40 @@ DirectSound::DirectSound()
dsbEvent = NULL;
}
DirectSound::~DirectSound()
{
if(theApp.aviRecorder != NULL) {
if(theApp.aviRecorder) {
delete theApp.aviRecorder;
theApp.aviRecorder = NULL;
theApp.aviFrameNumber = 0;
}
if(theApp.soundRecording) {
if(theApp.soundRecorder != NULL) {
if(theApp.soundRecorder) {
delete theApp.soundRecorder;
theApp.soundRecorder = NULL;
}
theApp.soundRecording = false;
}
if(dsbNotify != NULL) {
if(dsbNotify) {
dsbNotify->Release();
dsbNotify = NULL;
}
if(dsbEvent != NULL) {
if(dsbEvent) {
CloseHandle(dsbEvent);
dsbEvent = NULL;
}
if(pDirectSound != NULL) {
if(dsbPrimary != NULL) {
if(pDirectSound) {
if(dsbPrimary) {
dsbPrimary->Release();
dsbPrimary = NULL;
}
if(dsbSecondary != NULL) {
if(dsbSecondary) {
dsbSecondary->Release();
dsbSecondary = NULL;
}
@ -105,126 +112,106 @@ DirectSound::~DirectSound()
pDirectSound = NULL;
}
if(dsoundDLL != NULL) {
FreeLibrary(dsoundDLL);
dsoundDLL = NULL;
}
CoUninitialize();
}
bool DirectSound::init()
{
HRESULT hr;
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;
}
DWORD freq;
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) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
if( theApp.dsoundDisableHardwareAcceleration ) {
dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
}
if((hr=pDirectSound->CreateSoundBuffer(&dsbdesc,
&dsbPrimary,
NULL) != DS_OK)) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_BUFFER),hr);
systemMessage(IDS_CANNOT_CREATESOUNDBUFFER,
"Cannot CreateSoundBuffer %08x", hr);
if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) {
systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, _T("Cannot CreateSoundBuffer %08x"), hr);
return false;
}
// Set primary buffer format
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;
switch(soundQuality)
{
case 4:
wfx.nSamplesPerSec = 11025;
soundBufferLen = 368*2;
soundBufferTotalLen = 3680*2;
freq = 11025;
break;
case 2:
freq = 22050;
break;
default:
soundQuality = 1;
wfx.nSamplesPerSec = 44100;
soundBufferLen = 1470*2;
soundBufferTotalLen = 14700*2;
case 1:
freq = 44100;
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.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
if((hr = dsbPrimary->SetFormat(&wfx)) != DS_OK) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_PRIMARY),hr);
systemMessage(IDS_CANNOT_SETFORMAT_PRIMARY,
"Cannot SetFormat for primary %08x", hr);
if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) {
systemMessage( IDS_CANNOT_SETFORMAT_PRIMARY, _T("CreateSoundBuffer(primary) failed %08x"), hr );
return false;
}
// Create secondary sound buffer
ZeroMemory( &dsbdesc, 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.lpwfxFormat = &wfx;
if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))
!= DS_OK) {
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
if((hr = pDirectSound->CreateSoundBuffer(&dsbdesc, &dsbSecondary, NULL))
!= DS_OK) {
systemMessage(IDS_CANNOT_CREATESOUNDBUFFER_SEC,
"Cannot CreateSoundBuffer secondary %08x", hr);
if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) {
systemMessage( IDS_CANNOT_CREATESOUNDBUFFER, _T("CreateSoundBuffer(secondary) failed %08x"), hr );
return false;
}
if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) {
systemMessage( 0, _T("dsbSecondary->SetCurrentPosition failed %08x"), hr );
return false;
}
dsbSecondary->SetCurrentPosition(0);
if( !theApp.useOldSync ) {
hr = dsbSecondary->QueryInterface(IID_IDirectSoundNotify,
(void **)&dsbNotify);
if(!FAILED(hr)) {
if( FAILED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) {
dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
DSBPOSITIONNOTIFY notify[10];
for(int i = 0; i < 10; i++) {
for( i = 0; i < 10; i++ ) {
notify[i].dwOffset = i * soundBufferLen;
notify[i].hEventNotify = dsbEvent;
}
if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) {
dsbNotify->Release();
dsbNotify = NULL;
@ -234,94 +221,96 @@ bool DirectSound::init()
}
}
hr = dsbPrimary->Play(0,0,DSBPLAY_LOOPING);
if(hr != DS_OK) {
// errorMessage(myLoadString(IDS_ERROR_SOUND_PLAYPRIM), hr);
systemMessage(IDS_CANNOT_PLAY_PRIMARY, "Cannot Play primary %08x", hr);
// Play primary buffer
if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) {
systemMessage( IDS_CANNOT_PLAY_PRIMARY, _T("Cannot Play primary %08x"), hr );
return false;
}
setsystemSoundOn(true);
systemSoundOn = true;
return true;
}
void DirectSound::pause()
{
if(dsbSecondary != NULL) {
DWORD status = 0;
if( dsbSecondary == NULL ) return;
DWORD status;
dsbSecondary->GetStatus( &status );
if(status & DSBSTATUS_PLAYING) {
dsbSecondary->Stop();
}
}
if( status & DSBSTATUS_PLAYING ) dsbSecondary->Stop();
}
void DirectSound::reset()
{
if(dsbSecondary) {
if( dsbSecondary == NULL ) return;
dsbSecondary->Stop();
dsbSecondary->SetCurrentPosition( 0 );
}
}
void DirectSound::resume()
{
if(dsbSecondary != NULL) {
if( dsbSecondary == NULL ) return;
dsbSecondary->Play( 0, 0, DSBPLAY_LOOPING );
}
}
void DirectSound::write()
{
int len = soundBufferLen;
LPVOID lpvPtr1;
DWORD dwBytes1;
LPVOID lpvPtr2;
DWORD dwBytes2;
if(!pDirectSound) return;
HRESULT hr;
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( dsbSecondary ) {
if(theApp.soundRecorder == NULL) {
if( theApp.soundRecorder ) {
theApp.soundRecorder->AddSound( (u8 *)soundFinalWave, soundBufferLen );
} else {
theApp.soundRecorder = new WavWriter;
WAVEFORMATEX format;
dsbSecondary->GetFormat( &format, sizeof(format), NULL );
if(theApp.soundRecorder->Open(theApp.soundRecordName))
if( theApp.soundRecorder->Open( theApp.soundRecordName ) ) {
theApp.soundRecorder->SetFormat( &format );
}
}
}
}
if(theApp.soundRecorder) {
theApp.soundRecorder->AddSound((u8 *)soundFinalWave, len);
}
}
if( theApp.aviRecording ) {
if( theApp.aviRecorder ) {
if( dsbSecondary ) {
if( !theApp.aviRecorder->IsSoundAdded() ) {
WAVEFORMATEX format;
dsbSecondary->GetFormat( &format, sizeof(format), NULL );
theApp.aviRecorder->SetSoundFormat( &format );
}
}
theApp.aviRecorder->AddSound((const char *)soundFinalWave, len);
theApp.aviRecorder->AddSound( (const char *)soundFinalWave, soundBufferLen );
}
}
HRESULT hr;
if( !speedup && synchronize && !theApp.throttle ) {
DWORD status=0;
hr = dsbSecondary->GetStatus(&status);
if(status && DSBSTATUS_PLAYING) {
if( status & DSBSTATUS_PLAYING ) {
if( !soundPaused ) {
DWORD play;
while( true ) {
dsbSecondary->GetCurrentPosition(&play, NULL);
int BufferLeft = ((soundNextPosition <= play) ?
@ -345,35 +334,49 @@ void DirectSound::write()
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 == hr) {
dsbSecondary->Restore();
hr = dsbSecondary->Lock(soundNextPosition, soundBufferLen,&lpvPtr1,
&dwBytes1, &lpvPtr2, &dwBytes2,
hr = dsbSecondary->Lock(
soundNextPosition,
soundBufferLen,
&lpvPtr1,
&dwBytes1,
&lpvPtr2,
&dwBytes2,
0 );
}
soundNextPosition += soundBufferLen;
soundNextPosition = soundNextPosition % soundBufferTotalLen;
if SUCCEEDED(hr) {
if( SUCCEEDED( hr ) ) {
// Write to pointers.
CopyMemory( lpvPtr1, soundFinalWave, dwBytes1 );
if (NULL != lpvPtr2) {
if ( lpvPtr2 ) {
CopyMemory( lpvPtr2, soundFinalWave + dwBytes1, dwBytes2 );
}
// Release the data back to DirectSound.
hr = dsbSecondary->Unlock(lpvPtr1, dwBytes1, lpvPtr2,
dwBytes2);
hr = dsbSecondary->Unlock( lpvPtr1, dwBytes1, lpvPtr2, dwBytes2 );
} else {
systemMessage( 0, _T("dsbSecondary->Lock() failed: %08x"), hr );
return;
}
}
ISound *newDirectSound()
{
return new DirectSound();

View File

@ -26,6 +26,7 @@
#include "WinResUtil.h"
#include <shlobj.h>
#include <shlwapi.h>
#ifdef _DEBUG
#define new DEBUG_NEW
@ -54,27 +55,21 @@ static int CALLBACK browseCallbackProc(HWND hWnd, UINT msg,
Directories::Directories(CWnd* pParent /*=NULL*/)
: CDialog(Directories::IDD, pParent)
{
//{{AFX_DATA_INIT(Directories)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void Directories::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(Directories)
DDX_Control(pDX, IDC_SAVE_PATH, m_savePath);
DDX_Control(pDX, IDC_ROM_PATH, m_romPath);
DDX_Control(pDX, IDC_GBROM_PATH, m_gbromPath);
DDX_Control(pDX, IDC_CAPTURE_PATH, m_capturePath);
DDX_Control(pDX, IDC_BATTERY_PATH, m_batteryPath);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(Directories, CDialog)
//{{AFX_MSG_MAP(Directories)
ON_BN_CLICKED(IDC_BATTERY_DIR, OnBatteryDir)
ON_BN_CLICKED(IDC_BATTERY_DIR_RESET, OnBatteryDirReset)
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_SAVE_DIR, OnSaveDir)
ON_BN_CLICKED(IDC_SAVE_DIR_RESET, OnSaveDirReset)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
@ -206,22 +200,75 @@ void Directories::OnCancel()
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;
m_romPath.GetWindowText(buffer);
if( !buffer.IsEmpty() )
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);
if( !buffer.IsEmpty() )
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);
if( !buffer.IsEmpty() )
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);
if( !buffer.IsEmpty() )
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);
if( !buffer.IsEmpty() )
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);
}

View File

@ -75,6 +75,23 @@ class Directories : public CDialog
virtual void OnOK();
//}}AFX_MSG
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}}

View File

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

View File

@ -17,6 +17,8 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma once
enum DISPLAY_TYPE {
GDI = 0,
DIRECT_DRAW = 1,
@ -37,8 +39,10 @@ class IDisplay {
virtual void clear() = 0;
virtual bool changeRenderSize(int w, int h) { return true; };
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 bool isSkinSupported() { return false; }
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.
// 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
// it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
// FileDlg.cpp: implementation of the FileDlg class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <commdlg.h>
#include <dlgs.h>
@ -26,7 +26,7 @@
#include "VBA.h"
#include "FileDlg.h"
#include "../System.h"
#include "..\..\res\resource.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -159,15 +159,17 @@ void FileDlg::OnTypeChange(HWND hwnd)
ASSERT(typeControl != NULL);
int sel = ::SendMessage(typeControl, CB_GETCURSEL, 0, 0);
LRESULT sel = ::SendMessage(typeControl, CB_GETCURSEL, 0, 0);
ASSERT(sel != -1);
LPCTSTR typeName = extensions[sel];
if(filename.GetLength() == 0) {
if(strlen(typeName) != 0)
filename.Format("*%s", typeName);
} else {
if(strlen(typeName) != 0) {
int index = filename.Find('.');
if (index == -1) {
filename = filename + typeName;
@ -175,6 +177,7 @@ void FileDlg::OnTypeChange(HWND hwnd)
filename = filename.Left(index) + typeName;
}
}
}
SetWindowText(fileNameControl, filename);
}

View File

@ -772,9 +772,9 @@ void GBACheatList::OnEnable()
if(m_list.GetItem(&item)) {
if(item.state & LVIS_SELECTED) {
if(cheatsList[item.lParam].enabled)
cheatsDisable(item.lParam);
cheatsDisable((int)(item.lParam & 0xFFFFFFFF));
else
cheatsEnable(item.lParam);
cheatsEnable((int)(item.lParam & 0xFFFFFFFF));
}
}
}
@ -796,7 +796,7 @@ void GBACheatList::OnRemove()
item.stateMask = LVIS_SELECTED;
if(m_list.GetItem(&item)) {
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) !=
(((l->uNewState & LVIS_STATEIMAGEMASK)>>12))) {
if(m_list.GetCheck(l->iItem))
cheatsEnable(l->lParam);
cheatsEnable((int)(l->lParam & 0xFFFFFFFF));
else
cheatsDisable(l->lParam);
cheatsDisable((int)(l->lParam & 0xFFFFFFFF));
refresh();
}
}

View File

@ -20,7 +20,7 @@
#if !defined(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
#pragma once
#endif // _MSC_VER > 1000

View File

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

View File

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

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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,
},
{
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*/)
: CDialog(GBColorDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(GBColorDlg)
which = -1;
//}}AFX_DATA_INIT
which = gbPaletteOption;
}
@ -80,10 +80,8 @@ GBColorDlg::GBColorDlg(CWnd* pParent /*=NULL*/)
void GBColorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(GBColorDlg)
DDX_Control(pDX, IDC_PREDEFINED, m_predefined);
DDX_Radio(pDX, IDC_DEFAULT, which);
//}}AFX_DATA_MAP
}
@ -167,10 +165,12 @@ BOOL GBColorDlg::OnInitDialog()
"Green Forest",
"Hot Desert",
"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]);
m_predefined.SetItemData(index, j);
}
@ -222,15 +222,20 @@ void GBColorDlg::OnColorClicked(UINT id)
{
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);
if(dlg.DoModal()) {
if(IDOK == dlg.DoModal())
{
COLORREF c = dlg.GetColor();
colors[which*8+id] = (u16)((c >> 3) & 0x1f | ((c >> 11) & 0x1f) << 5 |
((c >> 19) & 0x1f) << 10);
colors[which*8+id] = (u16)((c >> 3) & 0x1f | ((c >> 11) & 0x1f) << 5 | ((c >> 19) & 0x1f) << 10);
colorControls[id].setColor(colors[which*8+id]);
}
}
@ -246,7 +251,7 @@ void GBColorDlg::OnSelchangePredefined()
int sel = m_predefined.GetCurSel();
if(sel != -1) {
int data = m_predefined.GetItemData(sel);
DWORD_PTR data = m_predefined.GetItemData(sel);
for(int i = 0; i < 8; i++) {
colorControls[i].setColor(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_
#include "ColorButton.h" // Added by ClassView
#include "..\System.h" // Added by ClassView
#include "../System.h" // Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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 SP;
extern gbRegister PC;
extern u8 register_LY;
extern u16 IFF;
extern int gbDis(char *, u16);
@ -114,8 +115,9 @@ void GBDisassemble::OnNext()
void GBDisassemble::OnGo()
{
CString buffer;
m_address.GetWindowText(buffer);
sscanf(buffer, "%x", &address);
sscanf(buffer, "%hx", &address);
refresh();
}
@ -242,6 +244,8 @@ void GBDisassemble::refresh()
GetDlgItem(IDC_R5)->SetWindowText(buffer);
sprintf(buffer, "%04x", IFF);
GetDlgItem(IDC_R6)->SetWindowText(buffer);
sprintf(buffer, "%04x", register_LY);
GetDlgItem(IDC_LY)->SetWindowText(buffer);
m_z = (AF.B.B0 & 0x80) != 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_)
#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
#pragma once
#endif // _MSC_VER > 1000

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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.
#include "stdafx.h"
#include <stdio.h>
#include "Display.h"
#include "../System.h"
#include "../GBA.h"
#include "../Globals.h"
#include "..\gb\gbGlobals.h"
#include "../Text.h"
#include "../Util.h"
#include "UniVideoModeDlg.h"
#include "VBA.h"
#include "MainWnd.h"
#include "Reg.h"
#include "..\..\res\resource.h"
#include "../gbafilter.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
@ -43,20 +41,16 @@ static char THIS_FILE[] = __FILE__;
extern void winlog(const char *,...);
extern int Init_2xSaI(u32);
extern int systemSpeed;
extern int winVideoModeSelect(CWnd *, GUID **);
class GDIDisplay : public IDisplay
{
class GDIDisplay : public IDisplay {
private:
u8 *filterData;
u8 info[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
int SelectedFreq, SelectedAdapter;
public:
GDIDisplay();
virtual ~GDIDisplay();
virtual bool changeRenderSize(int w, int h);
virtual bool initialize();
virtual void cleanup();
virtual void render();
@ -65,11 +59,10 @@ public:
virtual void clear();
virtual DISPLAY_TYPE getType() { return GDI; };
virtual void setOption(const char *, int) {}
virtual bool isSkinSupported() { return true; }
virtual int selectFullScreenMode(GUID **);
virtual int selectFullScreenMode2();
};
static int calculateShift(u32 mask)
{
int m = 0;
@ -84,7 +77,7 @@ static int calculateShift(u32 mask)
GDIDisplay::GDIDisplay()
{
filterData = NULL;
filterData = (u8 *)malloc(4*4*256*240);
}
GDIDisplay::~GDIDisplay()
@ -94,37 +87,17 @@ GDIDisplay::~GDIDisplay()
void GDIDisplay::cleanup()
{
if(filterData)
{
delete [] filterData;
if(filterData) {
free(filterData);
filterData = NULL;
}
}
bool GDIDisplay::initialize()
{
switch(theApp.cartridgeType)
{
case 0:
theApp.sizeX = 240;
theApp.sizeY = 160;
break;
case 1:
if(gbBorderOn)
{
theApp.sizeX = 256;
theApp.sizeY = 224;
}
else
{
theApp.sizeX = 160;
theApp.sizeY = 144;
}
break;
}
switch(theApp.videoOption)
{
switch(theApp.videoOption) {
case VIDEO_1X:
theApp.surfaceSizeX = theApp.sizeX;
theApp.surfaceSizeY = theApp.sizeY;
@ -144,23 +117,19 @@ bool GDIDisplay::initialize()
case VIDEO_320x240:
case VIDEO_640x480:
case VIDEO_800x600:
case VIDEO_1024x768:
case VIDEO_1280x1024:
case VIDEO_OTHER:
float scaleX = ((float)theApp.fsWidth / theApp.sizeX);
float scaleY = ((float)theApp.fsHeight / theApp.sizeY);
float min = scaleX < scaleY ? scaleX : scaleY;
{
int scaleX = (theApp.fsWidth / theApp.sizeX);
int scaleY = (theApp.fsHeight / theApp.sizeY);
int min = scaleX < scaleY ? scaleX : scaleY;
if(theApp.fsMaxScale)
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.surfaceSizeY = theApp.fsHeight;
}
else
{
theApp.surfaceSizeX = (int)(theApp.sizeX * min);
theApp.surfaceSizeY = (int)(theApp.sizeY * min);
}
break;
}
@ -225,61 +194,10 @@ bool GDIDisplay::initialize()
theApp.adjustDestRect();
// Enumerate available display modes
theApp.mode320Available = false;
theApp.mode640Available = 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);
HBITMAP hbm = CreateCompatibleBitmap(dc, 1, 1);
BITMAPINFO *bi = (BITMAPINFO *)info;
@ -313,9 +231,6 @@ bool GDIDisplay::initialize()
Init_2xSaI(32);
}
// Setup system color depth
theApp.fsColorDepth = systemColorDepth;
if(systemColorDepth == 24)
theApp.filterFunction = NULL;
@ -326,7 +241,7 @@ bool GDIDisplay::initialize()
cpu_mmx = 0;
#endif
utilUpdateSystemColorMaps(theApp.filterLCD );
utilUpdateSystemColorMaps();
theApp.updateFilter();
theApp.updateIFB();
@ -335,13 +250,8 @@ bool GDIDisplay::initialize()
return TRUE;
}
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()
@ -356,124 +266,137 @@ void GDIDisplay::checkFullScreen()
void GDIDisplay::render()
{
unsigned int pitch = theApp.filterWidth * (systemColorDepth / 8) + 4;
BITMAPINFO *bi = (BITMAPINFO *)info;
bi->bmiHeader.biWidth = theApp.filterWidth+1;
bi->bmiHeader.biHeight = -theApp.filterHeight;
if(theApp.filterFunction)
{
bi->bmiHeader.biWidth = theApp.rect.right;
bi->bmiHeader.biHeight = -(int)theApp.rect.bottom;
int pitch = theApp.filterWidth * 2 + 4;
if(systemColorDepth == 24)
pitch = theApp.filterWidth * 3;
else if(systemColorDepth == 32)
pitch = theApp.filterWidth * 4 + 4;
(*theApp.filterFunction)(
pix + pitch,
if(theApp.filterFunction) {
bi->bmiHeader.biWidth = theApp.filterWidth * 2;
bi->bmiHeader.biHeight = -theApp.filterHeight * 2;
if(systemColorDepth == 16)
(*theApp.filterFunction)(pix+pitch,
pitch,
(u8*)theApp.delta,
(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.filterHeight);
}
POINT p1, p2;
p1.x = theApp.dest.left;
p1.y = theApp.dest.top;
if(theApp.showSpeed && (theApp.videoOption > VIDEO_4X || theApp.skin != NULL)) {
char buffer[30];
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.y = theApp.dest.bottom;
theApp.m_pMainWnd->ScreenToClient(&p1);
theApp.m_pMainWnd->ScreenToClient(&p2);
pWnd->ScreenToClient(&p2);
CDC *dc = theApp.m_pMainWnd->GetDC();
CDC *dc = pWnd->GetDC();
// Draw bitmap to device
StretchDIBits(
dc->GetSafeHdc(),
p1.x, p1.y,
p2.x - p1.x,
p2.y - p1.y,
theApp.rect.left, theApp.rect.top,
theApp.rect.right - theApp.rect.left,
theApp.rect.bottom - theApp.rect.top,
StretchDIBits((HDC)*dc,
p.x,
p.y,
p2.x - p.x,
p2.y - p.y,
0,
0,
theApp.rect.right,
theApp.rect.bottom,
theApp.filterFunction ? filterData : pix+pitch,
bi,
DIB_RGB_COLORS,
SRCCOPY);
// Draw frame counter
if (theApp.showSpeed && (theApp.videoOption >= VIDEO_320x240))
{
CString speedText;
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)
if(theApp.screenMessage) {
if(((GetTickCount() - theApp.screenMessageTime) < 3000) &&
!theApp.disableStatusMessage) {
dc->SetTextColor(RGB(255,0,0));
dc->SetBkMode(TRANSPARENT);
else
dc->SetBkMode(OPAQUE);
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
dc->TextOut(p.x+10, p2.y - 20, theApp.screenMessageBuffer);
} else {
theApp.screenMessage = false;
}
theApp.m_pMainWnd->ReleaseDC(dc);
}
int GDIDisplay::selectFullScreenMode(GUID **pGUID)
{
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;
}
pWnd->ReleaseDC(dc);
}
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)
{
if (filterData)
{
delete [] filterData;
filterData = NULL;
return (c << 24) | (w << 12) | h;
}
filterData = new u8[w*h*(systemColorDepth>>3)];
return true;
}
IDisplay *newGDIDisplay()
{
return new GDIDisplay();
}

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -26,7 +26,6 @@
#include "../System.h"
#include "../GBA.h"
#include "../Globals.h"
#include "../Sound.h"
#include "IOViewerRegs.h"
@ -68,6 +67,22 @@ BEGIN_MESSAGE_MAP(IOViewer, CDialog)
ON_BN_CLICKED(IDC_AUTO_UPDATE, OnAutoUpdate)
ON_CBN_SELCHANGE(IDC_ADDRESSES, OnSelchangeAddresses)
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
END_MESSAGE_MAP()
@ -81,10 +96,29 @@ void IOViewer::OnClose()
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()
{
// TODO: Add your control notification handler code here
update();
}
void IOViewer::OnAutoUpdate()
@ -165,7 +199,7 @@ void IOViewer::update()
const IOData *sel = &ioViewRegisters[selected];
u16 data = sel->address ? *sel->address :
(ioMem ? soundRead16(sel->offset) : 0);
(ioMem ? *((u16 *)&ioMem[sel->offset]) : 0);
for(int i = 0; i < 16; i++) {
CButton *pWnd = (CButton *)GetDlgItem(IDC_BIT_0 + i);
@ -186,6 +220,8 @@ void IOViewer::update()
}
void IOViewer::OnApply()
{
if(rom != NULL)
{
const IOData *sel = &ioViewRegisters[selected];
u16 res = 0;
@ -200,3 +236,4 @@ void IOViewer::OnApply()
CPUWriteHalfWord(0x4000000+sel->offset, res);
update();
}
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -37,6 +37,7 @@ class IOViewer : public ResizeDlg, IUpdateListener
// Construction
public:
void update();
void bitChange();
bool autoUpdate;
int selected;
IOViewer(CWnd* pParent = NULL); // standard constructor

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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)",

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// 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_dma3 = (systemVerbose & 128) != 0;
m_undefined = (systemVerbose & 256) != 0;
m_agbprint = (systemVerbose & 256) != 0;
m_agbprint = (systemVerbose & 512) != 0;
UpdateData(FALSE);
m_log.LimitText(-1);
@ -237,7 +237,7 @@ BOOL Logging::OnInitDialog()
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.ReplaceSel(s);
}

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -24,12 +24,14 @@
#include "MainWnd.h"
#include <winsock.h>
#include <shlwapi.h>
#include "FileDlg.h"
#include "Reg.h"
#include "WinResUtil.h"
#include "../System.h"
#include "../AutoBuild.h"
#include "../cheatSearch.h"
#include "../GBA.h"
#include "../Globals.h"
@ -41,9 +43,6 @@
#include "../RTC.h"
#include "../Sound.h"
#include "../Util.h"
#include ".\mainwnd.h"
#include "../Link.h" // Link
#ifdef _DEBUG
#define new DEBUG_NEW
@ -54,6 +53,7 @@ static char THIS_FILE[] = __FILE__;
#define VBA_CONFIRM_MODE WM_APP + 100
extern void remoteCleanUp();
extern int gbHardware;
/////////////////////////////////////////////////////////////////////////////
// MainWnd
@ -179,6 +179,10 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLTRIANGLE, OnUpdateOptionsVideoRenderoptionsGltriangle)
ON_COMMAND(ID_OPTIONS_VIDEO_RENDEROPTIONS_GLQUADS, OnOptionsVideoRenderoptionsGlquads)
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_COMMAND(ID_OPTIONS_EMULATOR_ASSOCIATE, OnOptionsEmulatorAssociate)
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_COMMAND(ID_OPTIONS_EMULATOR_SPEEDUPTOGGLE, OnOptionsEmulatorSpeeduptoggle)
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_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOMATICALLYIPSPATCH, OnUpdateOptionsEmulatorAutomaticallyipspatch)
ON_COMMAND(ID_OPTIONS_EMULATOR_AGBPRINT, OnOptionsEmulatorAgbprint)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AGBPRINT, OnUpdateOptionsEmulatorAgbprint)
ON_COMMAND(ID_OPTIONS_EMULATOR_REALTIMECLOCK, OnOptionsEmulatorRealtimeclock)
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_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_AUTOHIDEMENU, OnUpdateOptionsEmulatorAutohidemenu)
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_COMMAND(ID_OPTIONS_EMULATOR_BMPFORMAT, OnOptionsEmulatorBmpformat)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_EMULATOR_BMPFORMAT, OnUpdateOptionsEmulatorBmpformat)
// ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundOff) /* mute hax */
// ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundOff) /* mute hax */
ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundMute) /* mute hax */
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundMute) /* mute hax */
ON_COMMAND(ID_OPTIONS_SOUND_OFF, OnOptionsSoundOff)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_OFF, OnUpdateOptionsSoundOff)
ON_COMMAND(ID_OPTIONS_SOUND_MUTE, OnOptionsSoundMute)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_MUTE, OnUpdateOptionsSoundMute)
ON_COMMAND(ID_OPTIONS_SOUND_ON, OnOptionsSoundOn)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SOUND_ON, OnUpdateOptionsSoundOn)
ON_COMMAND(ID_OPTIONS_SOUND_USEOLDSYNCHRONIZATION, OnOptionsSoundUseoldsynchronization)
@ -374,7 +378,9 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_COMMAND(ID_CHEATS_DISABLECHEATS, OnCheatsDisablecheats)
ON_UPDATE_COMMAND_UI(ID_CHEATS_DISABLECHEATS, OnUpdateCheatsDisablecheats)
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_LOG, OnOptionsLinkLog)
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_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_COMMAND(ID_SYSTEM_MINIMIZE, OnSystemMinimize)
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_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_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(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_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, 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_SIMPLE4X, OnOptionsFilter)
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_FILTER_BILINEAR, ID_OPTIONS_FILTER_BILINEARPLUS, 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_MESSAGE(VBA_CONFIRM_MODE, OnConfirmMode)
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_FULLSCREEN1024X768, OnOptionsVideoFullscreen1024x768)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_VIDEO_FULLSCREEN1024X768, OnUpdateOptionsVideoFullscreen1024x768)
@ -443,6 +452,7 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
void MainWnd::OnClose()
{
emulating = false;
CWnd::OnClose();
delete this;
@ -493,13 +503,40 @@ bool MainWnd::FileRun()
return false;
}
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
theApp.cartridgeType = (int)type;
theApp.cartridgeType = type;
if(type == IMAGE_GB) {
genericflashcardEnable = theApp.winGenericflashcardEnable;
if(!gbLoadRom(theApp.szFile))
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;
gbBorderOn = theApp.winGbBorderOn;
theApp.romSize = gbRomSize;
if(theApp.autoIPS) {
int size = gbRomSize;
utilApplyIPS(ipsname, &gbRom, &size);
@ -521,9 +558,6 @@ bool MainWnd::FileRun()
rtcEnable(theApp.winRtcEnable);
cpuSaveType = theApp.winSaveType;
// if(cpuEnhancedDetection && winSaveType == 0) {
// utilGBAFindSave(rom, size);
// }
GetModuleFileName(NULL, tempName, 2048);
char *p = strrchr(tempName, '\\');
@ -556,6 +590,12 @@ bool MainWnd::FileRun()
tempName);
if(i != (UINT)-1 && (i <= 5))
cpuSaveType = (int)i;
i = GetPrivateProfileInt(buffer,
"mirroringEnabled",
-1,
tempName);
if(i != (UINT)-1)
doMirroring (i == 0 ? false : true);
theApp.emulator = GBASystem;
/* disabled due to problems
@ -579,10 +619,8 @@ bool MainWnd::FileRun()
else
soundReset();
} else {
//if(!soundOffFlag) /* mute hax */
soundInit(!theApp.cartridgeType);
if ( soundOffFlag )
soundDisable(0x30f);
if(!soundOffFlag)
soundInit(!(theApp.cartridgeType==1));
theApp.soundInitialized = true;
}
@ -760,6 +798,16 @@ void MainWnd::winSaveCheatListDefault()
else
name = theApp.filename;
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())
dir = getDirFromFile(filename);
@ -792,6 +840,16 @@ void MainWnd::winLoadCheatListDefault()
else
name = theApp.filename;
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())
dir = getDirFromFile(filename);
@ -854,6 +912,16 @@ void MainWnd::writeBatteryFile()
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -881,6 +949,16 @@ void MainWnd::readBatteryFile()
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -924,39 +1002,128 @@ bool MainWnd::writeSaveGame(const char *name)
void MainWnd::OnContextMenu(CWnd* pWnd, CPoint point)
{
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 = "";
CString initialDir = regQueryStringValue("romdir",".");
if(!initialDir.IsEmpty())
ShowWindow(SW_SHOWMINIMIZED);
}
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;
}
int selectedFilter = regQueryDwordValue("selectedFilter", 0);
if(selectedFilter < 0 || selectedFilter > 2)
int selectedFilter = 0;
if( !gb ) {
selectedFilter = regQueryDwordValue( _T("selectedFilter"), 0);
if( (selectedFilter < 0) || (selectedFilter > 2) ) {
selectedFilter = 0;
}
}
theApp.szFile = "";
theApp.szFile = _T("");
LPCTSTR exts[] = { "" };
CString filter = winLoadFilter(IDS_FILTER_ROM);
CString title = winResLoadString(IDS_SELECT_ROM);
LPCTSTR exts[] = { _T(""), _T(""), _T(""), _T("") };
CString filter;
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 ) {
regSetDwordValue("selectedFilter", dlg.m_ofn.nFilterIndex);
if( !gb ) {
regSetDwordValue( _T("selectedFilter"), dlg.m_ofn.nFilterIndex );
}
theApp.szFile = dlg.GetPathName();
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 );
regSetStringValue("romdir", theApp.dir);
}
SetCurrentDirectory( theApp.dir );
return true;
}
return false;
}
void MainWnd::OnPaint()
{
CPaintDC dc(this); // device context for painting
@ -986,6 +1153,16 @@ void MainWnd::screenCapture(int captureNumber)
CString buffer;
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('\\');
CString name;
@ -1014,6 +1191,15 @@ void MainWnd::screenCapture(int captureNumber)
captureNumber,
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)
theApp.emulator.emuWritePNG(buffer);
else
@ -1126,12 +1312,3 @@ LRESULT MainWnd::OnMySysCommand(WPARAM wParam, LPARAM lParam)
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++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -55,7 +55,7 @@ class MainWnd : public CWnd
void winMouseOn();
void screenCapture(int captureNumber);
HACCEL m_hAccelTable;
bool fileOpenSelect();
bool fileOpenSelect( bool gb = false );
afx_msg LRESULT OnConfirmMode(WPARAM, LPARAM);
afx_msg LRESULT OnMySysCommand(WPARAM, LPARAM);
afx_msg void OnUpdateFileLoadGameSlot(CCmdUI *pCmdUI);
@ -70,9 +70,6 @@ class MainWnd : public CWnd
afx_msg BOOL OnOptionsFilter(UINT nID);
afx_msg void OnUpdateOptionsPriority(CCmdUI *pCmdUI);
afx_msg BOOL OnOptionsPriority(UINT nID);
afx_msg void OnSetFocus(CWnd * pOldWnd);
afx_msg void OnKillFocus(CWnd * pNewWnd);
void updateSoundChannels(UINT nID);
afx_msg void OnUpdateOptionsSoundVolume(CCmdUI *pCmdUI);
afx_msg BOOL OnOptionsSoundVolume(UINT nID);
@ -209,6 +206,10 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoRenderoptionsGlquads();
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 OnOptionsEmulatorAssociate();
afx_msg void OnOptionsEmulatorDirectories();
@ -220,14 +221,14 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsEmulatorPausewheninactive(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorSpeeduptoggle();
afx_msg void OnUpdateOptionsEmulatorSpeeduptoggle(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRemoveintrosgba();
afx_msg void OnUpdateOptionsEmulatorRemoveintrosgba(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAutomaticallyipspatch();
afx_msg void OnUpdateOptionsEmulatorAutomaticallyipspatch(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAgbprint();
afx_msg void OnUpdateOptionsEmulatorAgbprint(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRealtimeclock();
afx_msg void OnUpdateOptionsEmulatorRealtimeclock(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorGenericflashcard();
afx_msg void OnUpdateOptionsEmulatorGenericflashcard(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorAutohidemenu();
afx_msg void OnUpdateOptionsEmulatorAutohidemenu(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorRewindinterval();
@ -256,8 +257,8 @@ class MainWnd : public CWnd
afx_msg void OnUpdateOptionsEmulatorPngformat(CCmdUI* pCmdUI);
afx_msg void OnOptionsEmulatorBmpformat();
afx_msg void OnUpdateOptionsEmulatorBmpformat(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundOff(); /* mute hax */
afx_msg void OnUpdateOptionsSoundOff(CCmdUI* pCmdUI); /* mute hax */
afx_msg void OnOptionsSoundOff();
afx_msg void OnUpdateOptionsSoundOff(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundMute();
afx_msg void OnUpdateOptionsSoundMute(CCmdUI* pCmdUI);
afx_msg void OnOptionsSoundOn();
@ -408,6 +409,9 @@ class MainWnd : public CWnd
afx_msg void OnCheatsDisablecheats();
afx_msg void OnUpdateCheatsDisablecheats(CCmdUI* pCmdUI);
afx_msg void OnOptionsVideoFullscreenmaxscale();
afx_msg void OnOptionsEmulatorGameoverrides();
afx_msg void OnUpdateOptionsEmulatorGameoverrides(CCmdUI* pCmdUI);
afx_msg void OnHelpGnupubliclicense();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
@ -420,6 +424,8 @@ class MainWnd : public CWnd
afx_msg BOOL OnOptionsSoundPcminterpolation(UINT nID);
afx_msg void OnUpdateOptionsSoundPcminterpolation(CCmdUI *pCmdUI);
public:
afx_msg void OnOptionsSoundHardwareacceleration();
afx_msg void OnUpdateOptionsSoundHardwareacceleration(CCmdUI *pCmdUI);
afx_msg void OnOptionsVideoFullscreen1280x1024();
afx_msg void OnOptionsVideoFullscreen1024x768();
afx_msg void OnUpdateOptionsVideoFullscreen1024x768(CCmdUI *pCmdUI);
@ -430,8 +436,6 @@ public:
void OnOptionsLinkRFU() ;
void OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI) ;
};
/////////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,6 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// 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
// it under the terms of the GNU General Public License as published by
@ -19,6 +19,8 @@
#include "stdafx.h"
#include "MainWnd.h"
#include <shlwapi.h>
#include "ExportGSASnapshot.h"
#include "FileDlg.h"
#include "GSACodeSelect.h"
@ -33,20 +35,22 @@
#include "../gb/GB.h"
#include "../gb/gbCheats.h"
#include "../gb/gbGlobals.h"
#include "../Link.h"
extern int emulating;
extern void remoteCleanUp();
extern void InterframeCleanup();
void MainWnd::OnFileOpen()
{
theApp.winCheckFullscreen();
if(fileOpenSelect()) {
if( fileOpenSelect( false ) ) {
FileRun();
}
}
void MainWnd::OnFilePause()
{
theApp.paused = !theApp.paused;
@ -159,32 +163,16 @@ void MainWnd::OnUpdateFileClose(CCmdUI* pCmdUI)
pCmdUI->Enable(emulating);
}
void MainWnd::OnFileOpengameboy()
{
theApp.winCheckFullscreen();
theApp.dir = "";
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);
if( fileOpenSelect( true ) ) {
FileRun();
}
}
void MainWnd::OnFileLoad()
{
theApp.winCheckFullscreen();
@ -199,6 +187,16 @@ void MainWnd::OnFileLoad()
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -246,6 +244,16 @@ BOOL MainWnd::OnFileLoadSlot(UINT nID)
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -255,17 +263,22 @@ BOOL MainWnd::OnFileLoadSlot(UINT nID)
else
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);
buffer.Format(format, nID);
bool res = loadSaveGame(filename);
if (theApp.paused)
InterframeCleanup();
systemScreenMessage(buffer);
systemDrawScreen();
//theApp.rewindCount = 0;
//theApp.rewindCounter = 0;
//theApp.rewindSaveNeeded = false;
return res;
}
@ -283,6 +296,16 @@ void MainWnd::OnFileSave()
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -325,6 +348,16 @@ BOOL MainWnd::OnFileSaveSlot(UINT nID)
buffer = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -341,6 +374,8 @@ BOOL MainWnd::OnFileSaveSlot(UINT nID)
systemScreenMessage(buffer);
systemDrawScreen();
return res;
}
@ -352,6 +387,16 @@ void MainWnd::OnFileImportBatteryfile()
CString title = winResLoadString(IDS_SELECT_BATTERY_FILE);
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())
saveDir = getDirFromFile(theApp.filename);
@ -376,7 +421,8 @@ void MainWnd::OnFileImportBatteryfile()
if(!res)
systemMessage(MSG_CANNOT_OPEN_FILE, "Cannot open file %s", dlg.GetPathName());
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()
{
theApp.winCheckFullscreen();
LPCTSTR exts[] = { "" };
LPCTSTR exts[] = { ".gbs" };
CString filter = theApp.cartridgeType == 1 ? winLoadFilter(IDS_FILTER_GBS) : winLoadFilter(IDS_FILTER_SPS);
CString title = winResLoadString(IDS_SELECT_SNAPSHOT_FILE);
@ -468,6 +514,16 @@ void MainWnd::OnFileExportBatteryfile()
CString title = winResLoadString(IDS_SELECT_BATTERY_FILE);
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())
saveDir = getDirFromFile(theApp.filename);
@ -565,8 +621,18 @@ void MainWnd::OnFileScreencapture()
name = theApp.filename;
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())
capdir = getDirFromFile(name);
capdir = getDirFromFile(theApp.filename);
CString ext = "png";
@ -648,7 +714,6 @@ void MainWnd::OnFileTogglemenu()
theApp.adjustDestRect();
if(theApp.display)
theApp.display->resize(theApp.dest.right-theApp.dest.left, theApp.dest.bottom-theApp.dest.top);
}
void MainWnd::OnUpdateFileTogglemenu(CCmdUI* pCmdUI)
@ -684,7 +749,7 @@ bool MainWnd::fileImportGSACodeFile(CString& fileName)
}
fseek(f, 0x1e, SEEK_SET);
fread(&len, 1, 4, f);
int game = 0;
INT_PTR game = 0;
if(len > 1) {
GSACodeSelect dlg(f);
game = dlg.DoModal();
@ -701,7 +766,7 @@ bool MainWnd::fileImportGSACodeFile(CString& fileName)
}
if(game != -1) {
return cheatsImportGSACodeFile(fileName, game, v3);
return cheatsImportGSACodeFile(fileName, (int)game, v3);
}
return true;
@ -722,6 +787,16 @@ void MainWnd::OnFileSavegameOldestslot()
filename = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -732,15 +807,15 @@ void MainWnd::OnFileSavegameOldestslot()
CString name;
CFileStatus status;
CString str;
unsigned long time = (unsigned long)-1;
time_t time = (time_t)-1;
int found = 0;
for(int i = 0; i < 10; i++) {
name.Format("%s%s%d.sgm", saveDir, filename, i+1);
if(emulating && CFile::GetStatus(name, status)) {
if((unsigned long)status.m_mtime.GetTime() < time) {
time = (time_t)status.m_mtime.GetTime();
if(status.m_mtime.GetTime() < time) {
time = status.m_mtime.GetTime();
found = i;
}
} else {
@ -766,6 +841,16 @@ void MainWnd::OnUpdateFileSavegameOldestslot(CCmdUI* pCmdUI)
filename = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -808,6 +893,16 @@ void MainWnd::OnFileLoadgameMostrecent()
filename = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);
@ -818,15 +913,15 @@ void MainWnd::OnFileLoadgameMostrecent()
CString name;
CFileStatus status;
CString str;
unsigned long time = 0;
time_t time = 0;
int found = -1;
for(int i = 0; i < 10; i++) {
name.Format("%s%s%d.sgm", saveDir, filename, i+1);
if(emulating && CFile::GetStatus(name, status)) {
if((unsigned long)status.m_mtime.GetTime() > time) {
time = (time_t)status.m_mtime.GetTime();
if(status.m_mtime.GetTime() < time) {
time = status.m_mtime.GetTime();
found = i;
}
}
@ -852,6 +947,16 @@ void MainWnd::OnUpdateFileLoadgameMostrecent(CCmdUI* pCmdUI)
filename = theApp.filename;
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())
saveDir = getDirFromFile(theApp.filename);

View File

@ -44,3 +44,9 @@ void MainWnd::OnHelpBugreport()
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 "Directories.h"
#include "FileDlg.h"
#include "GameOverrides.h"
#include "LinkOptions.h"
#include "GBColorDlg.h"
#include "Joypad.h"
#include "MaxScale.h"
#include "ModeConfirm.h"
#include "Reg.h"
#include "RewindInterval.h"
#include "skin.h"
#include "Throttle.h"
#include "WinResUtil.h"
#include "LinkOptions.h"
#include "../System.h"
#include "../agbprint.h"
#include "../GBA.h"
#include "../Globals.h"
#include "../Sound.h"
#include "../Util.h"
#include "../gb/GB.h"
#include "../gb/gbGlobals.h"
#include "../gb/gbPrinter.h"
#include "../Link.h"
#include <tchar.h>
extern int emulating;
@ -52,6 +54,7 @@ extern void CPUUpdateRenderBuffers(bool force);
void MainWnd::OnOptionsFrameskipThrottleNothrottle()
{
theApp.throttle = 0;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
@ -62,6 +65,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottleNothrottle(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle25()
{
theApp.throttle = 25;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
@ -72,6 +76,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle25(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle50()
{
theApp.throttle = 50;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
@ -82,6 +87,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle50(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle100()
{
theApp.throttle = 100;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
@ -92,6 +98,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle100(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle150()
{
theApp.throttle = 150;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
@ -102,6 +109,7 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle150(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFrameskipThrottle200()
{
theApp.throttle = 200;
theApp.autoFrameSkip = false;
}
void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
@ -109,13 +117,18 @@ void MainWnd::OnUpdateOptionsFrameskipThrottle200(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.throttle == 200);
}
void MainWnd::OnOptionsFrameskipThrottleOther()
{
Throttle dlg;
int v = dlg.DoModal();
if(v)
int v = (int)dlg.DoModal();
if( v ) {
theApp.throttle = v;
theApp.autoFrameSkip = false;
}
}
void MainWnd::OnUpdateOptionsFrameskipThrottleOther(CCmdUI* pCmdUI)
{
@ -130,6 +143,12 @@ void MainWnd::OnOptionsFrameskipAutomatic()
theApp.autoFrameSkip = !theApp.autoFrameSkip;
if(!theApp.autoFrameSkip && emulating)
theApp.updateFrameSkip();
else
{
theApp.throttle = false;
frameSkip = 0;
systemFrameSkip = 0;
}
}
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_4:
case ID_OPTIONS_VIDEO_FRAMESKIP_5:
if(theApp.cartridgeType == 0) {
if(theApp.cartridgeType == IMAGE_GBA) {
frameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0;
} else {
gbFrameSkip = nID - ID_OPTIONS_VIDEO_FRAMESKIP_0;
}
if(emulating)
theApp.updateFrameSkip();
theApp.autoFrameSkip = false;
return TRUE;
break;
case ID_OPTIONS_VIDEO_FRAMESKIP_6:
case ID_OPTIONS_VIDEO_FRAMESKIP_7:
case ID_OPTIONS_VIDEO_FRAMESKIP_8:
case ID_OPTIONS_VIDEO_FRAMESKIP_9:
if(theApp.cartridgeType == 0) {
if(theApp.cartridgeType == IMAGE_GBA) {
frameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6;
} else {
gbFrameSkip = 6 + nID - ID_OPTIONS_VIDEO_FRAMESKIP_6;
}
if(emulating)
theApp.updateFrameSkip();
theApp.autoFrameSkip = false;
return TRUE;
break;
}
@ -174,59 +195,63 @@ BOOL MainWnd::OnOptionsFrameskip(UINT nID)
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)
{
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 1 : gbFrameSkip == 1);
pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 1 : gbFrameSkip == 1);
}
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)
{
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 3 : gbFrameSkip == 3);
pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 3 : gbFrameSkip == 3);
}
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)
{
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 5 : gbFrameSkip == 5);
pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 5 : gbFrameSkip == 5);
}
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)
{
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 7 : gbFrameSkip == 7);
pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 7 : gbFrameSkip == 7);
}
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)
{
pCmdUI->SetCheck(theApp.cartridgeType == 0 ? frameSkip == 9 : gbFrameSkip == 9);
pCmdUI->SetCheck(theApp.cartridgeType == IMAGE_GBA ? frameSkip == 9 : gbFrameSkip == 9);
}
void MainWnd::OnOptionsVideoVsync()
{
theApp.vsync = !theApp.vsync;
theApp.updateRenderMethod(true);
if( theApp.display ) {
theApp.display->setOption( _T("vsync"), theApp.vsync );
}
}
void MainWnd::OnUpdateOptionsVideoVsync(CCmdUI* pCmdUI)
{
@ -290,6 +315,7 @@ BOOL MainWnd::OnOptionVideoSize(UINT nID)
return TRUE;
}
void MainWnd::OnOptionsVideoFullscreen320x240()
{
OnOptionVideoSize(ID_OPTIONS_VIDEO_FULLSCREEN320X240);
@ -332,9 +358,7 @@ void MainWnd::OnOptionsVideoFullscreen()
theApp.fsForceChange = true;
theApp.fsWidth = width;
theApp.fsHeight = height;
theApp.fsFrequency = (theApp.display->selectFullScreenMode2() & 0xFFFF);
theApp.fsAdapter = theApp.display->selectFullScreenMode2();
theApp.fsAdapter = (theApp.fsAdapter & 0xFFFF0000) >> 16;
theApp.fsFrequency = 60;
theApp.fsColorDepth = colorDepth;
theApp.pVideoDriverGUID = pGUID;
if(pGUID) {
@ -360,22 +384,28 @@ void MainWnd::OnUpdateOptionsVideoFullscreen(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoDisablesfx()
{
cpuDisableSfx = !cpuDisableSfx;
if(emulating && theApp.cartridgeType == 0)
if(emulating && theApp.cartridgeType == IMAGE_GBA)
CPUUpdateRender();
}
void MainWnd::OnUpdateOptionsVideoDisablesfx(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(!cpuDisableSfx);
pCmdUI->SetCheck(cpuDisableSfx);
}
void MainWnd::OnOptionsVideoFullscreenstretchtofit()
{
theApp.fullScreenStretch = !theApp.fullScreenStretch;
theApp.updateWindowSize( theApp.videoOption );
if(theApp.display)
if( theApp.display ) {
if( emulating ) {
theApp.display->clear( );
}
theApp.display->setOption( _T("fullScreenStretch"), theApp.fullScreenStretch );
}
}
void MainWnd::OnUpdateOptionsVideoFullscreenstretchtofit(CCmdUI* pCmdUI)
{
@ -453,11 +483,15 @@ void MainWnd::OnUpdateOptionsVideoRendermethodOpengl(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.renderMethod == OPENGL);
}
void MainWnd::OnOptionsVideoTriplebuffering()
{
theApp.tripleBuffering = !theApp.tripleBuffering;
theApp.updateRenderMethod(true);
if( theApp.display ) {
theApp.display->setOption( _T("tripleBuffering"), theApp.tripleBuffering );
}
}
void MainWnd::OnUpdateOptionsVideoTriplebuffering(CCmdUI* pCmdUI)
{
@ -467,17 +501,26 @@ void MainWnd::OnUpdateOptionsVideoTriplebuffering(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoDdrawemulationonly()
{
theApp.ddrawEmulationOnly = !theApp.ddrawEmulationOnly;
if( theApp.display ) {
theApp.display->setOption( _T("ddrawEmulationOnly"), theApp.ddrawEmulationOnly );
}
}
void MainWnd::OnUpdateOptionsVideoDdrawemulationonly(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.ddrawEmulationOnly);
}
void MainWnd::OnOptionsVideoDdrawusevideomemory()
{
theApp.ddrawUseVideoMemory = !theApp.ddrawUseVideoMemory;
if( theApp.display ) {
theApp.display->setOption( _T("ddrawUseVideoMemory"), theApp.ddrawUseVideoMemory );
}
}
void MainWnd::OnUpdateOptionsVideoDdrawusevideomemory(CCmdUI* pCmdUI)
{
@ -487,8 +530,9 @@ void MainWnd::OnUpdateOptionsVideoDdrawusevideomemory(CCmdUI* pCmdUI)
void MainWnd::OnOptionsVideoRenderoptionsD3dnofilter()
{
theApp.d3dFilter = 0;
if(theApp.display)
theApp.display->setOption("d3dFilter", 0);
if( theApp.display ) {
theApp.display->setOption( _T("d3dFilter"), theApp.d3dFilter );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dnofilter(CCmdUI* pCmdUI)
@ -496,66 +540,145 @@ void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dnofilter(CCmdUI* pCmdUI)
pCmdUI->SetCheck(theApp.d3dFilter == 0);
}
void MainWnd::OnOptionsVideoRenderoptionsD3dbilinear()
{
theApp.d3dFilter = 1;
if(theApp.display)
theApp.display->setOption("d3dFilter", 1);
if( theApp.display ) {
theApp.display->setOption( _T("d3dFilter"), theApp.d3dFilter );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsD3dbilinear(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.d3dFilter == 1);
}
void MainWnd::OnOptionsVideoRenderoptionsGlnearest()
{
theApp.glFilter = 0;
if(theApp.display)
theApp.display->setOption("glFilter", 0);
if( theApp.display ) {
theApp.display->setOption( _T("glFilter"), theApp.glFilter );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlnearest(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.glFilter == 0);
}
void MainWnd::OnOptionsVideoRenderoptionsGlbilinear()
{
theApp.glFilter = 1;
if(theApp.display)
theApp.display->setOption("glFilter", 1);
if( theApp.display ) {
theApp.display->setOption( _T("glFilter"), theApp.glFilter );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlbilinear(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.glFilter == 1);
}
void MainWnd::OnOptionsVideoRenderoptionsGltriangle()
{
theApp.glType = 0;
if(theApp.display)
theApp.display->setOption("glType", 0);
if( theApp.display ) {
theApp.display->setOption( _T("glType"), theApp.glType );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGltriangle(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.glType == 0);
}
void MainWnd::OnOptionsVideoRenderoptionsGlquads()
{
theApp.glType = 1;
if(theApp.display)
theApp.display->setOption("glType", 1);
if( theApp.display ) {
theApp.display->setOption( _T("glType"), theApp.glType );
}
}
void MainWnd::OnUpdateOptionsVideoRenderoptionsGlquads(CCmdUI* pCmdUI)
{
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()
{
theApp.winCheckFullscreen();
@ -583,6 +706,8 @@ void MainWnd::OnUpdateOptionsEmulatorDisablestatusmessages(CCmdUI* pCmdUI)
void MainWnd::OnOptionsEmulatorSynchronize()
{
synchronize = !synchronize;
if (synchronize)
theApp.throttle = false;
}
void MainWnd::OnUpdateOptionsEmulatorSynchronize(CCmdUI* pCmdUI)
@ -610,17 +735,6 @@ void MainWnd::OnUpdateOptionsEmulatorSpeeduptoggle(CCmdUI* pCmdUI)
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()
{
theApp.autoIPS = !theApp.autoIPS;
@ -656,32 +770,52 @@ void MainWnd::OnOptionsEmulatorAutohidemenu()
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)
{
pCmdUI->SetCheck(theApp.autoHideMenu);
}
void MainWnd::OnOptionsEmulatorRewindinterval()
{
RewindInterval dlg(theApp.rewindTimer/6);
int v = dlg.DoModal();
int v = (int)dlg.DoModal();
if( v >= 0 ) {
theApp.rewindTimer = v*6; // convert to a multiple of 10 frames
regSetDwordValue("rewindTimer", v);
if(v == 0) {
if(theApp.rewindMemory)
if(theApp.rewindMemory) {
free(theApp.rewindMemory);
theApp.rewindMemory = NULL;
}
theApp.rewindCount = 0;
theApp.rewindCounter = 0;
theApp.rewindSaveNeeded = false;
} else {
if(theApp.rewindMemory == NULL)
if(theApp.rewindMemory == NULL) {
theApp.rewindMemory = (char *)malloc(8*REWIND_SIZE);
}
}
}
}
BOOL MainWnd::OnOptionsEmulatorShowSpeed(UINT nID)
{
@ -791,7 +925,9 @@ void MainWnd::OnOptionsEmulatorSavetypeFlash512k()
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()
@ -802,7 +938,9 @@ void MainWnd::OnOptionsEmulatorSavetypeFlash1m()
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()
@ -873,6 +1011,7 @@ void MainWnd::OnOptionsSoundOff()
{
soundOffFlag = true;
soundShutdown();
theApp.soundInitialized = false;
}
void MainWnd::OnUpdateOptionsSoundOff(CCmdUI* pCmdUI)
@ -893,17 +1032,17 @@ void MainWnd::OnUpdateOptionsSoundMute(CCmdUI* pCmdUI)
void MainWnd::OnOptionsSoundOn()
{
//if(soundOffFlag) {
if(soundOffFlag) {
soundOffFlag = false;
//soundInit(!theApp.cartridgeType);
//}
// soundInit();
}
soundEnable(0x30f);
}
void MainWnd::OnUpdateOptionsSoundOn(CCmdUI* pCmdUI)
{
//int active = soundGetEnable() & 0x30f;
pCmdUI->SetCheck(/*active != 0 &&*/ !soundOffFlag);
int active = soundGetEnable() & 0x30f;
pCmdUI->SetCheck(active != 0 && !soundOffFlag);
}
void MainWnd::OnOptionsSoundUseoldsynchronization()
@ -1023,8 +1162,6 @@ void MainWnd::updateSoundChannels(UINT id)
{
int flag = 0;
if ( soundOffFlag ) return; // mute hax
if(id == ID_OPTIONS_SOUND_CHANNEL1)
flag = 1;
@ -1520,8 +1657,9 @@ void MainWnd::OnUpdateOptionsFilterDisablemmx(CCmdUI* pCmdUI)
void MainWnd::OnOptionsFilterLcdcolors()
{
// todo: depreciated
theApp.filterLCD = !theApp.filterLCD;
utilUpdateSystemColorMaps(theApp.filterLCD);
utilUpdateSystemColorMaps();
}
void MainWnd::OnUpdateOptionsFilterLcdcolors(CCmdUI *pCmdUI)
@ -1710,7 +1848,7 @@ LRESULT MainWnd::OnConfirmMode(WPARAM, LPARAM)
void MainWnd::winConfirmMode()
{
if(theApp.renderMethod == DIRECT_DRAW && theApp.videoOption > VIDEO_4X) {
if( theApp.videoOption > VIDEO_4X ) {
theApp.winCheckFullscreen();
ModeConfirm dlg(theApp.m_pMainWnd);
@ -1728,6 +1866,10 @@ void MainWnd::OnOptionsVideoFullscreenmaxscale()
theApp.winCheckFullscreen();
dlg.DoModal();
if( theApp.display ) {
theApp.display->setOption( _T("maxScale"), theApp.fsMaxScale );
}
}
@ -1768,3 +1910,29 @@ void MainWnd::OnUpdateOptionsLinkRFU(CCmdUI* pCmdUI)
{
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 int emulating;
extern int remoteSocket;
extern SOCKET remoteSocket;
extern void remoteCleanUp();
extern void remoteSetSockets(SOCKET, SOCKET);
@ -205,7 +205,7 @@ void MainWnd::OnToolsDebugGdb()
remoteSetSockets(wait.getListenSocket(), wait.getSocket());
debugger = true;
emulating = 1;
theApp.cartridgeType = 0;
theApp.cartridgeType = IMAGE_GBA;
theApp.filename = "\\gnu_stub";
rom = (u8 *)malloc(0x2000000);
workRAM = (u8 *)calloc(1, 0x40000);
@ -214,7 +214,7 @@ void MainWnd::OnToolsDebugGdb()
paletteRAM = (u8 *)calloc(1,0x400);
vram = (u8 *)calloc(1, 0x20000);
oam = (u8 *)calloc(1, 0x400);
pix = (u8 *)calloc(1, 4 * 240 * 160);
pix = (u8 *)calloc(1, 4 * 241 * 162);
ioMem = (u8 *)calloc(1, 0x400);
theApp.emulator = GBASystem;

View File

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

View File

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

View File

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

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