vrc5 mapper update, prepare to add extra ppu render for it

cheats.cpp int converions warnings fix
change default tool index for vc project. if you have problem with it, feel free to revert. but i can't compile with just "8.1" in there sadly...
This commit is contained in:
g0me3 2019-04-27 21:35:59 +03:00
parent 3270461703
commit 60b314feb3
10 changed files with 201 additions and 120 deletions

View File

@ -1,7 +1,7 @@
/* FCE Ultra - NES/Famicom Emulator /* FCE Ultra - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2005 CaH4e3 * Copyright (C) 2005-2019 CaH4e3
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,19 +23,89 @@
#include "mapinc.h" #include "mapinc.h"
static uint8 QTAINTRAM[2048]; #define CAI_DEBUG
static writefunc old2006wrap;
static writefunc old2007wrap; static writefunc old2007wrap;
static uint8 QTAINTRAM[2048];
static uint16 qtaintramofs;
static uint16 CHRSIZE = 8192; static uint16 CHRSIZE = 8192;
static uint16 WRAMSIZE = 8192 + 4096; static uint16 WRAMSIZE = 8192 + 8192;
static uint8 *CHRRAM = NULL; static uint8 *CHRRAM = NULL;
static uint8 *WRAM = NULL; static uint8 *WRAM = NULL;
static uint8 IRQa, K4IRQ; static uint8 IRQa, K4IRQ;
static uint32 IRQLatch, IRQCount; static uint32 IRQLatch, IRQCount;
static uint8 conv_tbl[128][4] = {
{ 0x40, 0x40, 0x40, 0x40 },
{ 0x41, 0x41, 0x41, 0x41 },
{ 0x42, 0x42, 0x42, 0x42 },
{ 0x43, 0x43, 0x43, 0x43 },
{ 0x44, 0x44, 0x44, 0x44 },
{ 0x45, 0x45, 0x45, 0x45 },
{ 0x46, 0x46, 0x46, 0x46 },
{ 0x47, 0x47, 0x47, 0x47 },
{ 0x40, 0x40, 0x40, 0x40 },
{ 0x41, 0x41, 0x41, 0x41 },
{ 0x42, 0x42, 0x42, 0x42 },
{ 0x43, 0x43, 0x43, 0x43 },
{ 0x44, 0x44, 0x44, 0x44 },
{ 0x45, 0x45, 0x45, 0x45 },
{ 0x46, 0x46, 0x46, 0x46 },
{ 0x47, 0x47, 0x47, 0x47 },
{ 0x40, 0x40, 0x48, 0x44 },
{ 0x41, 0x41, 0x49, 0x45 },
{ 0x42, 0x42, 0x4A, 0x46 },
{ 0x43, 0x43, 0x4B, 0x47 },
{ 0x44, 0x40, 0x48, 0x44 },
{ 0x45, 0x41, 0x49, 0x45 },
{ 0x46, 0x42, 0x4A, 0x46 },
{ 0x47, 0x43, 0x4B, 0x47 },
{ 0x40, 0x50, 0x58, 0x60 },
{ 0x41, 0x51, 0x59, 0x61 },
{ 0x42, 0x52, 0x5A, 0x62 },
{ 0x43, 0x53, 0x5B, 0x63 },
{ 0x44, 0x54, 0x5C, 0x64 },
{ 0x45, 0x55, 0x5D, 0x65 },
{ 0x46, 0x56, 0x5E, 0x66 },
{ 0x47, 0x57, 0x5F, 0x67 },
{ 0x40, 0x68, 0x70, 0x78 },
{ 0x41, 0x69, 0x71, 0x79 },
{ 0x42, 0x6A, 0x72, 0x7A },
{ 0x43, 0x6B, 0x73, 0x7B },
{ 0x44, 0x6C, 0x74, 0x7C },
{ 0x45, 0x6D, 0x75, 0x7D },
{ 0x46, 0x6E, 0x76, 0x7E },
{ 0x47, 0x6F, 0x77, 0x7F },
{ 0x40, 0x40, 0x48, 0x50 },
{ 0x41, 0x41, 0x49, 0x51 },
{ 0x42, 0x42, 0x4A, 0x52 },
{ 0x43, 0x43, 0x4B, 0x53 },
{ 0x44, 0x44, 0x4C, 0x54 },
{ 0x45, 0x45, 0x4D, 0x55 },
{ 0x46, 0x46, 0x4E, 0x56 },
{ 0x47, 0x47, 0x4F, 0x57 },
{ 0x40, 0x58, 0x60, 0x68 },
{ 0x41, 0x59, 0x61, 0x69 },
{ 0x42, 0x5A, 0x62, 0x6A },
{ 0x43, 0x5B, 0x63, 0x6B },
{ 0x44, 0x5C, 0x64, 0x6C },
{ 0x45, 0x5D, 0x65, 0x6D },
{ 0x46, 0x5E, 0x66, 0x6E },
{ 0x47, 0x5F, 0x67, 0x6F },
{ 0x40, 0x70, 0x78, 0x74 },
{ 0x41, 0x71, 0x79, 0x75 },
{ 0x42, 0x72, 0x7A, 0x76 },
{ 0x43, 0x73, 0x7B, 0x77 },
{ 0x44, 0x74, 0x7C, 0x74 },
{ 0x45, 0x75, 0x7D, 0x75 },
{ 0x46, 0x76, 0x7E, 0x76 },
{ 0x47, 0x77, 0x7F, 0x77 },
};
static uint8 regs[16]; static uint8 regs[16];
//static uint8 test[8];
static SFORMAT StateRegs[] = static SFORMAT StateRegs[] =
{ {
{ &IRQCount, 1, "IRQC" }, { &IRQCount, 1, "IRQC" },
@ -48,93 +118,81 @@ static SFORMAT StateRegs[] =
static void chrSync(void) { static void chrSync(void) {
setchr4r(0x10, 0x0000, regs[5] & 1); setchr4r(0x10, 0x0000, regs[5] & 1);
setchr4r(0x10, 0x1000, 0); // one more hack to make visible some screens in common. will be replaced with proper code later
setchr4r(0x10, 0x1000, QTAINTRAM[0] & 1);
// setchr4r(0x10, 0x1000, 1);
} }
static void Sync(void) { static void Sync(void) {
chrSync(); chrSync();
// if(regs[0xA]&0x10) setprg4r(0x10, 0x6000, (regs[0] & 1) | (regs[0] >> 2));
// { setprg4r(0x10, 0x7000, (regs[1] & 1) | (regs[1] >> 2));
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0); #ifdef CAI_DEBUG
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1); setprg8(0x8000, regs[2]);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2); setprg8(0xA000, regs[3]);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3); setprg8(0xC000, regs[4]);
setchr1r(0x10,0x1000,0); setprg8(0xE000, ~0);
setchr1r(0x10,0x1400,1); #else
setchr1r(0x10,0x1800,2); setprg8r((regs[2] >> 6) & 1, 0x8000, (regs[2] & 0x3F));
setchr1r(0x10,0x1c00,3);*/ setprg8r((regs[3] >> 6) & 1, 0xA000, (regs[3] & 0x3F));
/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0); setprg8r((regs[4] >> 6) & 1, 0xC000, (regs[4] & 0x3F));
setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1)^1)<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1)^1)<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1)^1)<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1)^1)<<2)+7);
*/
// }
// else
// {
/*
setchr1r(0x10,0x0000,(((regs[5]&1)^1)<<2)+0);
setchr1r(0x10,0x0400,(((regs[5]&1)^1)<<2)+1);
setchr1r(0x10,0x0800,(((regs[5]&1)^1)<<2)+2);
setchr1r(0x10,0x0c00,(((regs[5]&1)^1)<<2)+3);
setchr1r(0x10,0x1000,(((regs[5]&1))<<2)+4);
setchr1r(0x10,0x1400,(((regs[5]&1))<<2)+5);
setchr1r(0x10,0x1800,(((regs[5]&1))<<2)+6);
setchr1r(0x10,0x1c00,(((regs[5]&1))<<2)+7);
// }
//*/
/* setchr1r(1,0x0000,test[0]);
setchr1r(1,0x0400,test[1]);
setchr1r(1,0x0800,test[2]);
setchr1r(1,0x0c00,test[3]);
setchr1r(1,0x1000,test[4]);
setchr1r(1,0x1400,test[5]);
setchr1r(1,0x1800,test[6]);
setchr1r(1,0x1c00,test[7]);
*/
setprg4r(0x10, 0x6000, regs[0] & 1);
if (regs[2] >= 0x40)
setprg8r(1, 0x8000, (regs[2] - 0x40));
else
setprg8r(0, 0x8000, (regs[2] & 0x3F));
if (regs[3] >= 0x40)
setprg8r(1, 0xA000, (regs[3] - 0x40));
else
setprg8r(0, 0xA000, (regs[3] & 0x3F));
if (regs[4] >= 0x40)
setprg8r(1, 0xC000, (regs[4] - 0x40));
else
setprg8r(0, 0xC000, (regs[4] & 0x3F));
setprg8r(1, 0xE000, ~0); setprg8r(1, 0xE000, ~0);
setmirror(MI_V); #endif
setmirror(((regs[0xA]&2)>>1)^1);
} }
/*static DECLFW(TestWrite) static DECLFW(QTAiWrite) {
{
test[A&7] = V;
Sync();
}*/
static DECLFW(M190Write) {
// FCEU_printf("write %04x:%04x %d, %d\n",A,V,scanline,timestamp);
regs[(A & 0x0F00) >> 8] = V; regs[(A & 0x0F00) >> 8] = V;
switch (A) { switch (A) {
case 0xd600: IRQLatch &= 0xFF00; IRQLatch |= V; break; case 0xd600: {
case 0xd700: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break; IRQLatch &= 0xFF00;
case 0xd900: IRQCount = IRQLatch; IRQa = V & 2; K4IRQ = V & 1; X6502_IRQEnd(FCEU_IQEXT); break; IRQLatch |= V;
case 0xd800: IRQa = K4IRQ; X6502_IRQEnd(FCEU_IQEXT); break; FCEU_printf("irq latch lo=%02x\n", V);
break;
}
case 0xd700: {
IRQLatch &= 0x00FF;
IRQLatch |= V << 8;
FCEU_printf("irq latch hi=%02x\n", V);
break;
}
case 0xd900: {
IRQCount = IRQLatch;
IRQa = V & 2;
K4IRQ = V & 1;
X6502_IRQEnd(FCEU_IQEXT);
FCEU_printf("irq reload\n", V);
break;
}
case 0xd800: {
IRQa = K4IRQ;
X6502_IRQEnd(FCEU_IQEXT);
FCEU_printf("irq stop\n", V);
break;
}
default:
FCEU_printf("write %04x:%04x %d, %d\n", A, V, scanline, timestamp);
} }
Sync(); Sync();
} }
static DECLFR(M190Read) { #ifdef CAI_DEBUG
// FCEU_printf("read %04x:%04x %d, %d\n",A,regs[(A&0x0F00)>>8],scanline,timestamp); static DECLFR(DebugExtNT) {
return regs[(A & 0x0F00) >> 8] + regs[0x0B]; return QTAINTRAM[A & 0x07FF];
} }
#endif
static DECLFR(QTAiRead) {
// OH = conv_tbl[DD00 >> 1][DC00 >> 6]
// OL = ((DC00 & 0x3F) << 2) + DB00
if (A == 0xDD00)
return conv_tbl[regs[0xD] >> 1][regs[0xC] >> 6];
else if (A == 0xDC00)
return ((regs[0xC] & 0x3F) << 2) + regs[0xB];
else
return 0;
}
static void VRC5IRQ(int a) { static void VRC5IRQ(int a) {
if (IRQa) { if (IRQa) {
IRQCount += a; IRQCount += a;
@ -145,50 +203,48 @@ static void VRC5IRQ(int a) {
} }
} }
//static void Mapper190_PPU(uint32 A) // debug hack. mapper does not track ppu address himseld, instead the regular ppu offset is used
//{ // these handlers must be moved in ppu code in order to be emulated properly.
// if(A<0x2000) //
// setchr4r(0x10,0x1000,QTAINTRAM[A&0x1FFF]&1); static DECLFW(QTAi2006Wrap) {
// else
// chrSync();
//}
static DECLFW(M1902007Wrap) {
if (A >= 0x2000) {
if (regs[0xA] & 1) if (regs[0xA] & 1)
QTAINTRAM[A & 0x1FFF] = V; qtaintramofs = (qtaintramofs << 8) | V;
else else
old2007wrap(A, V); old2006wrap(0x2006, V);
}
} }
static DECLFW(QTAi2007Wrap) {
if (regs[0xA] & 1) {
QTAINTRAM[qtaintramofs & 0x07FF] = V;
qtaintramofs++;
} else
old2007wrap(0x2007, V);
}
static void M190Power(void) { static void QTAiPower(void) {
/* test[0]=0;
test[1]=1;
test[2]=2;
test[3]=3;
test[4]=4;
test[5]=5;
test[6]=6;
test[7]=7;
*/
setprg4r(0x10, 0x7000, 2);
QTAIHack = 1;
qtaintramofs = 0;
old2006wrap = GetWriteHandler(0x2006);
old2007wrap = GetWriteHandler(0x2007); old2007wrap = GetWriteHandler(0x2007);
SetWriteHandler(0x2007, 0x2007, M1902007Wrap); SetWriteHandler(0x2006, 0x2006, QTAi2006Wrap);
SetWriteHandler(0x2007, 0x2007, QTAi2007Wrap);
#ifdef CAI_DEBUG
SetReadHandler(0x5000, 0x5FFF, DebugExtNT);
#endif
SetReadHandler(0x6000, 0xFFFF, CartBR); SetReadHandler(0x6000, 0xFFFF, CartBR);
// SetWriteHandler(0x5000,0x5007,TestWrite);
SetWriteHandler(0x6000, 0x7FFF, CartBW); SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, M190Write); SetWriteHandler(0x8000, 0xFFFF, QTAiWrite);
SetReadHandler(0xDC00, 0xDC00, M190Read); SetReadHandler(0xDC00, 0xDC00, QTAiRead);
SetReadHandler(0xDD00, 0xDD00, M190Read); SetReadHandler(0xDD00, 0xDD00, QTAiRead);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
Sync(); Sync();
} }
static void M190Close(void) { static void QTAiClose(void) {
if (CHRRAM) if (CHRRAM)
FCEU_gfree(CHRRAM); FCEU_gfree(CHRRAM);
CHRRAM = NULL; CHRRAM = NULL;
@ -200,3 +256,26 @@ static void M190Close(void) {
static void StateRestore(int version) { static void StateRestore(int version) {
Sync(); Sync();
} }
void QTAi_Init(CartInfo *info) {
info->Power = QTAiPower;
info->Close = QTAiClose;
GameStateRestore = StateRestore;
MapIRQHook = VRC5IRQ;
CHRRAM = (uint8*)FCEU_gmalloc(CHRSIZE);
SetupCartCHRMapping(0x10, CHRRAM, CHRSIZE, 1);
AddExState(CHRRAM, CHRSIZE, 0, "CRAM");
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE - 4096;
}
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@ -61,7 +61,7 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p)
CHEATF_SUBFAST SubCheats[256]; CHEATF_SUBFAST SubCheats[256];
int numsubcheats=0; uint32 numsubcheats=0;
struct CHEATF *cheats=0,*cheatsl=0; struct CHEATF *cheats=0,*cheatsl=0;
@ -98,7 +98,7 @@ static DECLFR(SubCheatsRead)
void RebuildSubCheats(void) void RebuildSubCheats(void)
{ {
int x; uint32 x;
struct CHEATF *c=cheats; struct CHEATF *c=cheats;
for(x=0;x<numsubcheats;x++) for(x=0;x<numsubcheats;x++)
SetReadHandler(SubCheats[x].addr,SubCheats[x].addr,SubCheats[x].PrevRead); SetReadHandler(SubCheats[x].addr,SubCheats[x].addr,SubCheats[x].PrevRead);
@ -137,8 +137,8 @@ void FCEU_PowerCheats()
} }
int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size) { int FCEU_CalcCheatAffectedBytes(uint32 address, uint32 size) {
int count = 0; uint32 count = 0;
for (int i = 0; i < numsubcheats && count < size; ++i) for (uint32 i = 0; i < numsubcheats && count < size; ++i)
if (SubCheats[i].addr >= address && SubCheats[i].addr < address + size) if (SubCheats[i].addr >= address && SubCheats[i].addr < address + size)
++count; ++count;
return count; return count;
@ -945,7 +945,7 @@ void UpdateFrozenList(void)
//and make these accessible to other dialogs that deal with memory addresses such as //and make these accessible to other dialogs that deal with memory addresses such as
//memwatch, hex editor, ramfilter, etc. //memwatch, hex editor, ramfilter, etc.
int x; uint32 x;
FrozenAddresses.clear(); //Clear vector and repopulate FrozenAddresses.clear(); //Clear vector and repopulate
for(x=0;x<numsubcheats;x++) for(x=0;x<numsubcheats;x++)
{ {

View File

@ -394,6 +394,7 @@ void ResetGameLoaded(void) {
MapIRQHook = NULL; MapIRQHook = NULL;
MMC5Hack = 0; MMC5Hack = 0;
PEC586Hack = 0; PEC586Hack = 0;
QTAIHack = 0;
PAL &= 1; PAL &= 1;
default_palette_selection = 0; default_palette_selection = 0;
} }

View File

@ -48,7 +48,7 @@ char *FCEUI_GetAboutString();
extern uint64 timestampbase; extern uint64 timestampbase;
extern uint32 MMC5HackVROMMask; extern uint32 MMC5HackVROMMask;
extern uint8 *MMC5HackExNTARAMPtr; extern uint8 *MMC5HackExNTARAMPtr;
extern int MMC5Hack, PEC586Hack; extern int MMC5Hack, PEC586Hack, QTAIHack;
extern uint8 *MMC5HackVROMPTR; extern uint8 *MMC5HackVROMPTR;
extern uint8 MMC5HackCHRMode; extern uint8 MMC5HackCHRMode;
extern uint8 MMC5HackSPMode; extern uint8 MMC5HackSPMode;

View File

@ -670,7 +670,7 @@ static BMAPPINGLocal bmap[] = {
{"", 217, Mapper217_Init}, // Redefined to a new Discrete BMC mapper {"", 217, Mapper217_Init}, // Redefined to a new Discrete BMC mapper
// {"", 218, Mapper218_Init}, // {"", 218, Mapper218_Init},
{"UNLA9746", 219, UNLA9746_Init}, {"UNLA9746", 219, UNLA9746_Init},
{"Debug Mapper", 220, UNLKS7057_Init}, {"Debug Mapper", 220, QTAi_Init},
{"UNLN625092", 221, UNLN625092_Init}, {"UNLN625092", 221, UNLN625092_Init},
{"", 222, Mapper222_Init}, {"", 222, Mapper222_Init},
// {"", 223, Mapper223_Init}, // {"", 223, Mapper223_Init},

View File

@ -220,6 +220,7 @@ void Mapper186_Init(CartInfo *);
void Mapper187_Init(CartInfo *); void Mapper187_Init(CartInfo *);
void Mapper188_Init(CartInfo *); void Mapper188_Init(CartInfo *);
void Mapper189_Init(CartInfo *); void Mapper189_Init(CartInfo *);
void Mapper190_Init(CartInfo *);
void Mapper191_Init(CartInfo *); void Mapper191_Init(CartInfo *);
void Mapper192_Init(CartInfo *); void Mapper192_Init(CartInfo *);
void Mapper193_Init(CartInfo *); void Mapper193_Init(CartInfo *);

View File

@ -330,7 +330,7 @@ int fceuindbg = 0;
//0xFF shall indicate to use palette[0] //0xFF shall indicate to use palette[0]
uint8 gNoBGFillColor = 0xFF; uint8 gNoBGFillColor = 0xFF;
int MMC5Hack = 0, PEC586Hack = 0;; int MMC5Hack = 0, PEC586Hack = 0, QTAIHack = 0;
uint32 MMC5HackVROMMask = 0; uint32 MMC5HackVROMMask = 0;
uint8 *MMC5HackExNTARAMPtr = 0; uint8 *MMC5HackExNTARAMPtr = 0;
uint8 *MMC5HackVROMPTR = 0; uint8 *MMC5HackVROMPTR = 0;

View File

@ -368,7 +368,7 @@ static BMAPPING bmap[] = {
{ "H2288", UNLH2288_Init, 0 }, { "H2288", UNLH2288_Init, 0 },
{ "HKROM", HKROM_Init, 0 }, { "HKROM", HKROM_Init, 0 },
{ "KOF97", UNLKOF97_Init, 0 }, { "KOF97", UNLKOF97_Init, 0 },
{ "KONAMI-QTAI", Mapper190_Init, 0 }, { "KONAMI-QTAI", QTAi_Init, 0 },
{ "KS7010", UNLKS7010_Init, 0 }, { "KS7010", UNLKS7010_Init, 0 },
{ "KS7012", UNLKS7012_Init, 0 }, { "KS7012", UNLKS7012_Init, 0 },
{ "KS7013B", UNLKS7013B_Init, 0 }, { "KS7013B", UNLKS7013B_Init, 0 },

View File

@ -59,7 +59,7 @@ void LH32_Init(CartInfo *info);
void LH53_Init(CartInfo *info); void LH53_Init(CartInfo *info);
void MALEE_Init(CartInfo *info); void MALEE_Init(CartInfo *info);
void MHROM_Init(CartInfo *info); void MHROM_Init(CartInfo *info);
void Mapper190_Init(CartInfo *info); void QTAi_Init(CartInfo *info);
void NROM_Init(CartInfo *info); void NROM_Init(CartInfo *info);
void Novel_Init(CartInfo *info); void Novel_Init(CartInfo *info);
void S74LS374NA_Init(CartInfo *info); void S74LS374NA_Init(CartInfo *info);

View File

@ -31,7 +31,7 @@
<ProjectGuid>{6893EF44-FEA3-46DF-B236-C4C200F54294}</ProjectGuid> <ProjectGuid>{6893EF44-FEA3-46DF-B236-C4C200F54294}</ProjectGuid>
<RootNamespace>fceux</RootNamespace> <RootNamespace>fceux</RootNamespace>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">