- rewrite all slot2 code, not finished yet;
This commit is contained in:
mtabachenko 2013-11-10 20:20:46 +00:00
parent 0cc53ad207
commit 08c66df12b
27 changed files with 908 additions and 1833 deletions

View File

@ -33,8 +33,8 @@
#include "gfx3d.h"
#include "rtc.h"
#include "mc.h"
#include "addons.h"
#include "slot1.h"
#include "slot2.h"
#include "mic.h"
#include "movie.h"
#include "readwrite.h"
@ -924,14 +924,10 @@ void MMU_Init(void)
MMU.fw.fp = NULL;
MMU.fw.isFirmware = true;
// Init Backup Memory device, this should really be done when the rom is loaded
//mc_init(&MMU.bupmem, MC_TYPE_AUTODETECT);
//mc_alloc(&MMU.bupmem, 1);
//MMU.bupmem.fp = NULL;
rtcInit();
addonsInit();
slot1_Init();
slot2_Init();
if(Mic_Init() == FALSE)
INFO("Microphone init failed.\n");
@ -944,11 +940,9 @@ void MMU_DeInit(void) {
if (MMU.fw.fp)
fclose(MMU.fw.fp);
mc_free(&MMU.fw);
//if (MMU.bupmem.fp)
// fclose(MMU.bupmem.fp);
//mc_free(&MMU.bupmem);
addonsClose();
slot1_Shutdown();
slot2_Shutdown();
Mic_DeInit();
}
@ -1026,8 +1020,8 @@ void MMU_Reset()
rtcInit();
partie = 1;
addonsReset();
slot1_Reset();
slot2_Reset();
Mic_Reset();
MMU.gfx3dCycles = 0;
@ -3205,14 +3199,8 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val)
return;
}
if ((adr >= 0x08000000) && (adr < 0x0A010000))
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
{} //prohibited
else addon.write08(ARMCPU_ARM9, adr, val);
if (slot2_write<ARMCPU_ARM9, u8>(adr, val))
return;
}
//block 8bit writes to OAM and palette memory
if ((adr & 0x0F000000) == 0x07000000) return;
@ -3487,14 +3475,8 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
return;
}
if ((adr >= 0x08000000) && (adr < 0x0A010000))
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
{} //prohibited
else addon.write16(ARMCPU_ARM9, adr, val);
if (slot2_write<ARMCPU_ARM9, u16>(adr, val))
return;
}
// Address is an IO register
if ((adr >> 24) == 4)
@ -3947,14 +3929,8 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
return ;
}
if ((adr >= 0x08000000) && (adr < 0x0A010000))
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
{} //prohibited
else addon.write32(ARMCPU_ARM9, adr, val);
if (slot2_write<ARMCPU_ARM9, u32>(adr, val))
return;
}
#if 0
if ((adr & 0xFF800000) == 0x04800000) {
@ -4380,13 +4356,9 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr)
if(adr<0x02000000)
return T1ReadByte(MMU.ARM9_ITCM, adr&0x7FFF);
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
return 0; //prohibited
else return addon.read08(ARMCPU_ARM9, adr);
}
u8 slot2_val;
if (slot2_read<ARMCPU_ARM9, u8>(adr, slot2_val))
return slot2_val;
// Address is an IO register
if ((adr >> 24) == 4)
@ -4475,13 +4447,9 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
if(adr<0x02000000)
return T1ReadWord_guaranteedAligned(MMU.ARM9_ITCM, adr & 0x7FFE);
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
return 0; //prohibited
else return addon.read16(ARMCPU_ARM9, adr);
}
u16 slot2_val;
if (slot2_read<ARMCPU_ARM9, u16>(adr, slot2_val))
return slot2_val;
// Address is an IO register
if ((adr >> 24) == 4)
@ -4585,13 +4553,9 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr)
if(adr<0x02000000)
return T1ReadLong_guaranteedAligned(MMU.ARM9_ITCM, adr&0x7FFC);
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x204);
if(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7)
return 0; //prohibited
else return addon.read32(ARMCPU_ARM9, adr);
}
u32 slot2_val;
if (slot2_read<ARMCPU_ARM9, u32>(adr, slot2_val))
return slot2_val;
// Address is an IO register
if ((adr >> 24) == 4)
@ -4728,14 +4692,8 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val)
if (adr < 0x02000000) return; //can't write to bios or entire area below main memory
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
{} //prohibited
else addon.write08(ARMCPU_ARM7,adr, val);
if (slot2_write<ARMCPU_ARM7, u8>(adr, val))
return;
}
if ((adr >= 0x04000400) && (adr < 0x04000520))
{
@ -4839,15 +4797,9 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
mmu_log_debug_ARM7(adr, "(write16) 0x%04X", val);
if (adr < 0x02000000) return; //can't write to bios or entire area below main memory
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
{} //prohibited
else addon.write16(ARMCPU_ARM7,adr, val);
if (slot2_write<ARMCPU_ARM7, u16>(adr, val))
return;
}
if ((adr >= 0x04000400) && (adr < 0x04000520))
{
@ -5027,14 +4979,8 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
if (adr < 0x02000000) return; //can't write to bios or entire area below main memory
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
{} //prohibited
else addon.write32(ARMCPU_ARM7,adr, val);
if (slot2_write<ARMCPU_ARM7, u32>(adr, val))
return;
}
if ((adr >= 0x04000400) && (adr < 0x04000520))
{
@ -5153,21 +5099,15 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr)
return WIFI_read16(adr) & 0xFF;
}
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
return 0; //prohibited
else return addon.read08(ARMCPU_ARM7,adr);
}
u8 slot2_val;
if (slot2_read<ARMCPU_ARM7, u8>(adr, slot2_val))
return slot2_val;
if ((adr>=0x04000400)&&(adr<0x04000520))
{
return SPU_ReadByte(adr);
}
if (adr == REG_RTC) return (u8)rtcRead();
// Address is an IO register
if ((adr >> 24) == 4)
{
@ -5177,6 +5117,7 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr)
switch(adr)
{
case REG_RTC: return (u8)rtcRead();
case REG_IF: return MMU.gen_IF<ARMCPU_ARM7>();
case REG_IF+1: return (MMU.gen_IF<ARMCPU_ARM7>()>>8);
case REG_IF+2: return (MMU.gen_IF<ARMCPU_ARM7>()>>16);
@ -5214,13 +5155,9 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr)
if ((adr & 0xFFFF0000) == 0x04800000)
return WIFI_read16(adr) ;
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
return 0; //prohibited
else return addon.read16(ARMCPU_ARM7,adr);
}
u16 slot2_val;
if (slot2_read<ARMCPU_ARM7, u16>(adr, slot2_val))
return slot2_val;
if ((adr>=0x04000400)&&(adr<0x04000520))
{
@ -5318,13 +5255,9 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr)
if ((adr & 0xFFFF0000) == 0x04800000)
return (WIFI_read16(adr) | (WIFI_read16(adr+2) << 16));
if ( (adr >= 0x08000000) && (adr < 0x0A010000) )
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x204);
if(!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7))
return 0; //prohibited
else return addon.read32(ARMCPU_ARM7,adr);
}
u32 slot2_val;
if (slot2_read<ARMCPU_ARM7, u32>(adr, slot2_val))
return slot2_val;
if ((adr>=0x04000400)&&(adr<0x04000520))
{

View File

@ -36,6 +36,7 @@ libdesmume_a_SOURCES = \
rtc.cpp rtc.h \
saves.cpp saves.h \
slot1.cpp slot1.h \
slot2.cpp slot2.h \
SPU.cpp SPU.h \
matrix.cpp matrix.h \
gfx3d.cpp gfx3d.h \
@ -87,7 +88,6 @@ libdesmume_a_SOURCES = \
utils/tinyxml/tinyxml.h \
utils/tinyxml/tinyxmlerror.cpp \
utils/tinyxml/tinyxmlparser.cpp \
addons.cpp addons.h \
addons/slot2_mpcf.cpp addons/slot2_paddle.cpp addons/slot2_gbagame.cpp addons/slot2_none.cpp addons/slot2_rumblepak.cpp addons/slot2_guitarGrip.cpp addons/slot2_expMemory.cpp addons/slot2_piano.cpp addons/slot2_passme.cpp addons/slot1_none.cpp addons/slot1_r4.cpp addons/slot1_retail_nand.cpp addons/slot1_retail_auto.cpp addons/slot1_retail_mcrom.cpp addons/slot1_retail_mcrom_debug.cpp addons/slot1comp_mc.cpp addons/slot1comp_mc.h addons/slot1comp_rom.h addons/slot1comp_rom.cpp addons/slot1comp_protocol.h addons/slot1comp_protocol.cpp \
cheatSystem.cpp cheatSystem.h \
texcache.cpp texcache.h rasterize.cpp rasterize.h \

View File

@ -43,7 +43,7 @@
#include "version.h"
#include "path.h"
#include "slot1.h"
#include "addons.h"
#include "slot2.h"
//int xxctr=0;
//#define LOG_ARM9
@ -340,30 +340,7 @@ void GameInfo::populate()
memset(ROMserial, 0, sizeof(ROMserial));
memset(ROMname, 0, sizeof(ROMname));
//homebrew detection heuristics
//Option Old. - look for this instruction in the game title
//(did this ever work?)
//(header->gameTile[0] == 0x2E) && (header->gameTile[1] == 0x00) && header->gameTile[2] == 0x00) && header->gameTile[3] == 0xEA)
//Option New. - look for gamecode #### (default for ndstool)
//or an invalid gamecode
//this first part may look like a poor heuristic for detecting homebrew, but it is actually pretty good.
//setting your own game code is stupid, so homebrew should just leave it.
//however, non-devkitARM-default makefiles may not have set this.
bool gamecodeHash = !memcmp(header.gameCode,"####",4);
bool gamecodeInvalid = header.gameCode[0] == 0x00;
if((gamecodeHash || gamecodeInvalid)
//TBD - is this check a good idea?
&& header.makerCode == 0x0
)
{
isHomebrew = true;
}
else
isHomebrew = false;
if(isHomebrew)
if(isHomebrew())
{
//we can't really make a serial for a homebrew game that hasnt set a game code
strcpy(ROMserial, "Homebrew");
@ -567,34 +544,37 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
gameInfo.crc = 0;
gameInfo.chipID = 0xC2; // The Manufacturer ID is defined by JEDEC (C2h = Macronix)
gameInfo.chipID |= ((((128 << gameInfo.header.cardSize) / 1024) - 1) << 8); // Chip size in megabytes minus 1
// (07h = 8MB, 0Fh = 16MB, 1Fh = 32MB, 3Fh = 64MB, 7Fh = 128MB)
// flags
// 0: Unknown
// 1: Unknown
// 2: Unknown
// 3: Unknown
// 4: Unknown
// 5: DSi? (if set to 1 then DSi Enhanced games send command D6h to Slot1)
// 6: Unknown
// 7: ROM speed (Secure Area Block transfer mode (trasfer 8x200h or 1000h bytes)
// TODO:
//if (gameInfo.isDSiEnhanced())
// gameInfo.chipID |= (0x40 << 24);
gameInfo.chipID |= (0x00 << 24);
if (gameInfo.romType == ROM_NDS)
if (!gameInfo.isHomebrew())
{
gameInfo.chipID |= ((((128 << gameInfo.header.cardSize) / 1024) - 1) << 8); // Chip size in megabytes minus 1
// (07h = 8MB, 0Fh = 16MB, 1Fh = 32MB, 3Fh = 64MB, 7Fh = 128MB)
// flags
// 0: Unknown
// 1: Unknown
// 2: Unknown
// 3: Unknown
// 4: Unknown
// 5: DSi? (if set to 1 then DSi Enhanced games send command D6h to Slot1)
// 6: Unknown
// 7: ROM speed (Secure Area Block transfer mode (trasfer 8x200h or 1000h bytes)
// TODO:
//if (gameInfo.isDSiEnhanced())
// gameInfo.chipID |= (0x40 << 24);
gameInfo.chipID |= (0x00 << 24);
}
INFO("\nROM game code: %c%c%c%c\n", gameInfo.header.gameCode[0], gameInfo.header.gameCode[1], gameInfo.header.gameCode[2], gameInfo.header.gameCode[3]);
if (gameInfo.crc)
INFO("ROM crc: %08X\n", gameInfo.crc);
if (!gameInfo.isHomebrew())
{
INFO("\nROM game code: %c%c%c%c\n", gameInfo.header.gameCode[0], gameInfo.header.gameCode[1], gameInfo.header.gameCode[2], gameInfo.header.gameCode[3]);
if (gameInfo.crc)
INFO("ROM crc: %08X\n", gameInfo.crc);
INFO("ROM serial: %s\n", gameInfo.ROMserial);
INFO("ROM chipID: %08X\n", gameInfo.chipID);
INFO("ROM internal name: %s\n", gameInfo.ROMname);
if (gameInfo.isDSiEnhanced()) INFO("ROM DSi Enhanced\n");
INFO("ROM developer: %s\n", getDeveloperNameByID(gameInfo.header.makerCode).c_str());
}
INFO("ROM developer: %s\n", ((gameInfo.header.makerCode == 0) && gameInfo.isHomebrew())?"Homebrew":getDeveloperNameByID(gameInfo.header.makerCode).c_str());
memset(buf, 0, MAX_PATH);
strcpy(buf, path.pathToModule);
@ -627,13 +607,14 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
printf("\n");
//for homebrew, try auto-patching DLDI. should be benign if there is no DLDI or if it fails
if(gameInfo.isHomebrew && CommonSettings.loadToMemory)
if(gameInfo.isHomebrew() && CommonSettings.loadToMemory)
{
if (slot1_GetCurrentType() == NDS_SLOT1_R4)
DLDI::tryPatch((void*)gameInfo.romdata, gameInfo.romsize, 1);
else
if (addon_type == NDS_ADDON_CFLASH)
if (slot2_GetCurrentType() == NDS_SLOT2_CFLASH)
DLDI::tryPatch((void*)gameInfo.romdata, gameInfo.romsize, 0);
}
if (cheats != NULL)

View File

@ -341,7 +341,6 @@ struct GameInfo
char ROMserial[20];
char ROMname[20];
bool _isDSiEnhanced;
bool isHomebrew;
NDS_header header;
//a copy of the pristine secure area from the rom
u8 secureArea[0x4000];
@ -372,6 +371,7 @@ struct GameInfo
u32 readROM(u32 pos);
void populate();
bool isDSiEnhanced() { return _isDSiEnhanced; };
bool isHomebrew() { return ((header.ARM9src < 0x4000) && (T1ReadLong(header.logo, 0) != 0x51AEFF24) && (T1ReadLong(header.logo, 4) != 0x699AA221)); }
bool hasRomBanner();
};

View File

@ -1,78 +0,0 @@
/*
Copyright (C) 2009-2012 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "addons.h"
#include <string>
//this is the currently-configured cflash mode
ADDON_CFLASH_MODE CFlash_Mode;
//this is the currently-configured path (directory or filename) for cflash.
//it should be viewed as a parameter for the above.
std::string CFlash_Path;
char GBAgameName[MAX_PATH];
extern ADDONINTERFACE addonNone;
extern ADDONINTERFACE addonCFlash;
extern ADDONINTERFACE addonRumblePak;
extern ADDONINTERFACE addonGBAgame;
extern ADDONINTERFACE addonGuitarGrip;
extern ADDONINTERFACE addonExpMemory;
extern ADDONINTERFACE addonPiano;
extern ADDONINTERFACE addonPaddle;
extern ADDONINTERFACE addonPassME;
//extern ADDONINTERFACE addonExternalMic;
ADDONINTERFACE addonList[NDS_ADDON_COUNT] = {
addonNone,
addonCFlash,
addonRumblePak,
addonGBAgame,
addonGuitarGrip,
addonExpMemory,
addonPiano,
addonPaddle,
addonPassME
};
ADDONINTERFACE addon = addonCFlash; // default cflash pak (why??)
NDS_ADDON_TYPE addon_type = NDS_ADDON_CFLASH;
BOOL addonsInit()
{
return addon.init();
}
void addonsClose()
{
addon.close();
}
void addonsReset()
{
addon.reset();
}
BOOL addonsChangePak(NDS_ADDON_TYPE type)
{
if (type > NDS_ADDON_COUNT) return FALSE;
addon.close();
addon = addonList[type];
addon_type = type;
printf("Slot 2: %s\n", addon.name);
return addon.init();
}

View File

@ -1,95 +0,0 @@
/*
Copyright (C) 2009-2011 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ADDONS_H__
#define __ADDONS_H__
#include "common.h"
#include "types.h"
#include "debug.h"
struct ADDONINTERFACE
{
// The name of the plugin, this name will appear in the plugins list
const char * name;
//called once when the plugin starts up
BOOL (*init)(void);
//called when the emulator resets
void (*reset)(void);
//called when the plugin shuts down
void (*close)(void);
//called when the user configurating plugin
void (*config)(void);
//called when the emulator write to addon
void (*write08)(u32 procnum, u32 adr, u8 val);
void (*write16)(u32 procnum, u32 adr, u16 val);
void (*write32)(u32 procnum, u32 adr, u32 val);
//called when the emulator read from addon
u8 (*read08)(u32 procnum, u32 adr);
u16 (*read16)(u32 procnum, u32 adr);
u32 (*read32)(u32 procnum, u32 adr);
//called when the user get info about addon pak (description)
void (*info)(char *info);
};
enum NDS_ADDON_TYPE
{
NDS_ADDON_NONE,
NDS_ADDON_CFLASH, // compact flash
NDS_ADDON_RUMBLEPAK, // rumble pack
NDS_ADDON_GBAGAME, // gba game in slot
NDS_ADDON_GUITARGRIP, // Guitar Grip
NDS_ADDON_EXPMEMORY, // Memory Expansion
NDS_ADDON_PIANO, // Piano
NDS_ADDON_PADDLE,
//NDS_ADDON_EXTERNALMIC,
NDS_ADDON_PASSME, // PassME
NDS_ADDON_COUNT // use for counter addons - MUST TO BE LAST!!!
};
enum ADDON_CFLASH_MODE
{
ADDON_CFLASH_MODE_Path, ADDON_CFLASH_MODE_File, ADDON_CFLASH_MODE_RomPath
};
extern ADDON_CFLASH_MODE CFlash_Mode;
extern std::string CFlash_Path;
inline bool CFlash_IsUsingPath() { return CFlash_Mode==ADDON_CFLASH_MODE_Path || CFlash_Mode==ADDON_CFLASH_MODE_RomPath; }
extern ADDONINTERFACE addon; // current pak
extern ADDONINTERFACE addonList[NDS_ADDON_COUNT]; // lists pointer on paks
extern NDS_ADDON_TYPE addon_type; // current type pak
extern char GBAgameName[MAX_PATH]; // file name for GBA game (rom)
extern void (*FeedbackON)(BOOL enable); // feedback on/off
extern BOOL addonsInit(); // Init addons
extern void addonsClose(); // Shutdown addons
extern void addonsReset(); // Reset addon
extern BOOL addonsChangePak(NDS_ADDON_TYPE type); // change current adddon
extern void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue); // Guitar grip keys
extern void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic); //piano keys
#endif //__ADDONS_H__

View File

@ -1,30 +1,22 @@
/* Copyright (C) 2009-2013 DeSmuME team
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include "../mem.h"
#include <string.h>
#include "../MMU.h"
static u8 *expMemory = NULL;
static u32 expMemSize = 8 * 1024 * 1024; // 8Mb
static bool ext_ram_lock = true;
#include "../slot2.h"
#if 0
#define EXPINFO(...) INFO(__VA_ARGS__)
@ -32,73 +24,7 @@ static bool ext_ram_lock = true;
#define EXPINFO(...)
#endif
static BOOL ExpMemory_init(void) { return (TRUE); }
static void ExpMemory_reset(void)
{
if (expMemory)
{
delete [] expMemory;
expMemory = NULL;
}
expMemory = new u8 [expMemSize];
memset(expMemory, 0xFF, expMemSize);
ext_ram_lock = true;
}
static void ExpMemory_close(void)
{
if (expMemory)
{
delete [] expMemory;
expMemory = NULL;
}
}
static void ExpMemory_config(void) {}
static void ExpMemory_write08(u32 procnum, u32 adr, u8 val)
{
if (ext_ram_lock) return;
if (adr >= 0x09000000)
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return;
T1WriteByte(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 08 at 0x%08X = 0x%02X\n", adr, val);
}
static void ExpMemory_write16(u32 procnum, u32 adr, u16 val)
{
if (adr == 0x08240000)
{
if (val == 0)
ext_ram_lock = true;
else
if (val == 1)
ext_ram_lock = false;
return;
}
if (ext_ram_lock) return;
if (adr >= 0x09000000)
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return;
T1WriteWord(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 16 at 0x%08X = 0x%04X\n", adr, val);
}
static void ExpMemory_write32(u32 procnum, u32 adr, u32 val)
{
if (ext_ram_lock) return;
if (adr >= 0x09000000)
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return;
T1WriteLong(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 32 at 0x%08X = 0x%08X\n", adr, val);
}
#define EXPANSION_MEMORY_SIZE (8 * 1024 * 1024)
static u8 header_0x00B0[] =
{ 0xFF, 0xFF, 0x96, 0x00, //this 0x96 is strange. it can't be read from the pak when it boots, it must appear later
@ -107,67 +33,135 @@ static u8 header_0x00B0[] =
0xFF, 0xFF, 0xFF, 0x7F
};
static u8 ExpMemory_read08(u32 procnum, u32 adr)
class Slot2_ExpansionPak : public ISlot2Interface
{
EXPINFO("ExpMemory: read 08 at 0x%08X\n", adr);
if(adr>=0x080000B0 && adr<0x080000C0)
return T1ReadByte(header_0x00B0,adr-0x080000B0);
if (adr >= 0x09000000)
private:
u8 *expMemory;
bool ext_ram_lock;
public:
virtual Slot2Info const* info()
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return (0xFF);
return T1ReadByte(expMemory, offs);
static Slot2InfoSimple info("Memory Expansion Pak", "Official RAM expansion for Opera browser");
return &info;
}
return 0xFF;
}
static u16 ExpMemory_read16(u32 procnum, u32 adr)
{
if(adr>=0x080000B0 && adr<0x080000C0)
return T1ReadWord(header_0x00B0,adr-0x080000B0);
if (adr == 0x0801FFFC) return 0x7FFF;
if (adr == 0x08240002) return 0; //this can't be 0xFFFF. dunno why, we just guessed 0
if (adr >= 0x09000000)
virtual void connect()
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return (0xFFFF);
return T1ReadWord(expMemory, offs);
if (expMemory)
{
delete [] expMemory;
expMemory = NULL;
}
expMemory = new u8 [EXPANSION_MEMORY_SIZE];
memset(expMemory, 0xFF, EXPANSION_MEMORY_SIZE);
ext_ram_lock = true;
}
EXPINFO("ExpMemory: read 16 at 0x%08X\n", adr);
return 0xFFFF;
}
static u32 ExpMemory_read32(u32 procnum, u32 adr)
{
if(adr>=0x080000B0 && adr<0x080000C0)
return T1ReadLong(header_0x00B0,adr-0x080000B0);
if (adr >= 0x09000000)
virtual void disconnect()
{
u32 offs = (adr - 0x09000000);
if (offs >= expMemSize) return 0xFFFFFFFF;
return T1ReadLong(expMemory, offs);
delete [] expMemory;
expMemory = NULL;
}
EXPINFO("ExpMemory: read 32 at 0x%08X\n", adr);
return 0xFFFFFFFF;
}
static void ExpMemory_info(char *info) { strcpy(info, "Official RAM expansion for Opera browser"); }
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val)
{
if (ext_ram_lock) return;
ADDONINTERFACE addonExpMemory = {
"Memory Expansion Pak",
ExpMemory_init,
ExpMemory_reset,
ExpMemory_close,
ExpMemory_config,
ExpMemory_write08,
ExpMemory_write16,
ExpMemory_write32,
ExpMemory_read08,
ExpMemory_read16,
ExpMemory_read32,
ExpMemory_info};
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteByte(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 08 at 0x%08X = 0x%02X\n", addr, val);
}
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
{
if (addr == 0x08240000)
{
if (val == 0)
ext_ram_lock = true;
else
if (val == 1)
ext_ram_lock = false;
return;
}
if (ext_ram_lock) return;
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteWord(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 16 at 0x%08X = 0x%04X\n", addr, val);
}
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val)
{
if (ext_ram_lock) return;
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return;
T1WriteLong(expMemory, offs, val);
}
EXPINFO("ExpMemory: write 32 at 0x%08X = 0x%08X\n", addr, val);
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 08 at 0x%08X\n", addr);
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadByte(header_0x00B0, (addr - 0x080000B0));
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFF);
return T1ReadByte(expMemory, offs);
}
return 0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 16 at 0x%08X\n", addr);
if ((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadWord(header_0x00B0, (addr - 0x080000B0));
if (addr == 0x0801FFFC) return 0x7FFF;
if (addr == 0x08240002) return 0; //this can't be 0xFFFF. dunno why, we just guessed 0
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return (0xFFFF);
return T1ReadWord(expMemory, offs);
}
return 0xFFFF;
}
virtual u32 readLong(u8 PROCNUM, u32 addr)
{
EXPINFO("ExpMemory: read 32 at 0x%08X\n", addr);
if((addr >= 0x080000B0) && (addr < 0x080000C0))
return T1ReadLong(header_0x00B0, (addr - 0x080000B0));
if (addr >= 0x09000000)
{
u32 offs = (addr - 0x09000000);
if (offs >= EXPANSION_MEMORY_SIZE) return 0xFFFFFFFF;
return T1ReadLong(expMemory, offs);
}
return 0xFFFFFFFF;
}
};
ISlot2Interface* construct_Slot2_ExpansionPak() { return new Slot2_ExpansionPak(); }

View File

@ -1,473 +1,31 @@
/* Copyright (C) 2009 CrazyMax
Copyright (C) 2009 DeSmuME team
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include "../mem.h"
#include <string.h>
#include "../MMU.h"
#include "../path.h"
#include "../slot2.h"
//SRAM is going to be stored just above the rom.
//that is convenient for us, since it mirrors the nds memory map
#define GBA_ROMSIZE (32 * 1024 * 1024) + 1
#define GBA_SAVESIZE (512 * 1024) + 1
static u8 *GBArom = NULL;
static u8 *saveData = NULL;
static u8 saveType = 0xFF;
//================================================================================== Flash GBA
typedef struct
class Slot2_GbaCart : public ISlot2Interface
{
u8 state;
u8 cmd;
u32 size;
u8 idDevice;
u8 idManufacturer;
u8 bank;
} FLASH_GBA;
FLASH_GBA gbaFlash = {0};
static void gbaWriteFlash(u32 adr, u8 val)
{
switch (gbaFlash.state)
public:
virtual Slot2Info const* info()
{
case 0:
if (adr == 0x0A005555)
{
if (val == 0xF0)
{
//INFO("GBAgame: Flash: reset\n");
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
}
if (val == 0xAA)
{
gbaFlash.state = 1;
return;
}
}
if (adr == 0x0A000000)
{
if (gbaFlash.cmd == 0xB0)
{
gbaFlash.bank = val;
gbaFlash.cmd = 0;
//INFO("GBAgame: Flash: change bank %i\n", val);
return;
}
}
break;
case 1:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 2;
return;
}
gbaFlash.state = 0;
break;
case 2:
if (adr == 0x0A005555)
{
//INFO("GBAgame: Flash: send command flash 0x%02X\n", val);
switch (val)
{
case 0x80: // Erase
gbaFlash.state = 0x80;
break;
case 0x90: // Chip Identification
gbaFlash.state = 0x90;
break;
case 0xA0: // Write
gbaFlash.state = 0;
break;
default:
gbaFlash.state = 0;
break;
}
gbaFlash.cmd = val;
return;
}
gbaFlash.state = 0;
break;
// erase
case 0x80:
if ( (adr == 0x0A005555) && (val == 0xAA) )
{
gbaFlash.state = 0x81;
return;
}
gbaFlash.state = 0;
break;
case 0x81:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 0x82;
return;
}
gbaFlash.state = 0;
break;
case 0x82:
if (val == 0x30)
{
u32 ofs = (adr & 0x0000F000);
//INFO("GBAgame: Flash: erase from 0x%08X to 0x%08X\n", ofs + 0x0A000000, ofs + 0x0A001000);
for (u32 i = ofs; i < (ofs + 0x1000); i++)
saveData[i] = 0xFF;
}
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
// Chip Identification
case 0x90:
if ( (adr == 0x0A005555) && (val == 0xAA) )
{
gbaFlash.state = 0x91;
return;
}
gbaFlash.state = 0;
break;
case 0x91:
if ( (adr == 0x0A002AAA) && (val == 0x55) )
{
gbaFlash.state = 0x92;
return;
}
gbaFlash.state = 0;
break;
case 0x92:
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
static Slot2InfoSimple info("GBA cartridge", "GBA cartridge in slot");
return &info;
}
};
if (gbaFlash.cmd == 0xA0) // write
{
saveData[(adr & 0x1FFFF)+(0x10000*gbaFlash.bank)] = val;
gbaFlash.state = 0;
gbaFlash.cmd = 0;
return;
}
INFO("GBAgame: Flash: write unknown atn 0x%08X = 0x%02X\n", adr, val);
}
static u8 gbaReadFlash(u32 adr)
{
if (gbaFlash.cmd == 0)
{
//INFO("GBAgame: flash read at 0x%08X = 0x%02X\n", adr, saveData[(adr & 0x1FFFF)+(0x10000*gbaFlash.bank)]);
return saveData[(adr & 0x1FFFF)+(0x10000*gbaFlash.bank)];
}
//INFO("GBAgame: flash read at 0x%08X\n", adr);
switch (gbaFlash.cmd)
{
case 0x90: // Chip Identification
if (adr == 0x0A000000) return gbaFlash.idManufacturer;
if (adr == 0x0A000001) return gbaFlash.idDevice;
break;
case 0xF0: //
//INFO("GBAgame: Flash: reset2\n");
gbaFlash.state = 0;
gbaFlash.cmd = 0;
break;
case 0xB0: // Bank switching
break;
default:
INFO("GBAgame: Flash: read - unknown command at 0x%08X = 0x%02X\n", adr, gbaFlash.cmd);
break;
}
return 0xFF;
}
//==================================================================================
static u8 getSaveTypeGBA(const u8 *data, const u32 size)
{
u8 *dat = (u8 *)data;
for (u32 i = 0; i < size; i++)
{
u32 tmp = T1ReadLong(dat, 0);
if (tmp == 0x52504545)
{
if(memcmp(dat, "EEPROM_", 7) == 0)
{
return 1;
}
}
if (tmp == 0x4D415253)
{
if(memcmp(dat, "SRAM_", 5) == 0)
{
return 2;
}
}
if (tmp == 0x53414C46)
{
if(memcmp(dat, "FLASH1M_", 8) == 0)
{
return 3;
}
}
if (tmp == 0x52494953)
{
if(memcmp(dat, "SIIRTC_V", 8) == 0)
{
return 4;
}
}
if(memcmp(dat, "FLASH", 5) == 0)
{
return 5;
}
dat++;
}
return 0xFF; // NONE
}
static BOOL GBAgame_init(void)
{
return (TRUE);
}
static void GBAgame_reset(void)
{
memset(&gbaFlash, 0, sizeof(gbaFlash));
if (GBArom)
{
delete [] GBArom;
GBArom = NULL;
}
GBArom = new u8 [GBA_ROMSIZE];
memset(GBArom, 0xFF, GBA_ROMSIZE);
if (saveData)
{
delete [] saveData;
saveData = NULL;
}
saveData = new u8 [GBA_SAVESIZE];
memset(saveData, 0xFF, GBA_SAVESIZE);
if (!strlen(GBAgameName)) return;
FILE *fgame = 0;
//perk: if the gbagame name is "self" this is a special indicator that we should mount the main rom that we're running as the gba game
if(!strcasecmp(GBAgameName,"self"))
{
strcpy(GBAgameName,path.path.c_str());
}
fgame = fopen(GBAgameName,"rb");
if (!fgame) return;
fseek(fgame, 0, SEEK_END);
u32 size = ftell(fgame);
rewind(fgame);
if (!fread(GBArom, 1, size, fgame))
{
fclose(fgame);
return;
}
fclose(fgame);
saveType = getSaveTypeGBA(GBArom, size);
INFO("Loaded \"%s\" in GBA slot (save type %i)\n", GBAgameName, saveType);
//try loading the sram
char * dot = strrchr(GBAgameName,'.');
if(!dot) return;
std::string sram_fname = GBAgameName;
sram_fname.resize(dot-GBAgameName);
sram_fname += ".sav";
fgame = fopen(sram_fname.c_str(),"rb");
if(!fgame) return;
fseek(fgame, 0, SEEK_END);
size = ftell(fgame);
rewind(fgame);
if (!fread(saveData, 1, size, fgame))
{
fclose(fgame);
return;
}
fclose(fgame);
gbaFlash.size = size;
if (gbaFlash.size <= (64 * 1024))
{
gbaFlash.idDevice = 0x1B;
gbaFlash.idManufacturer = 0x32;
}
else
{
gbaFlash.idDevice = 0x09;
gbaFlash.idManufacturer = 0xC2;
}
INFO("Loaded save \"%s\" in GBA slot\n", sram_fname.c_str());
}
static void GBAgame_close(void)
{
if (GBArom)
{
delete [] GBArom;
GBArom = NULL;
}
if (saveData)
{
delete [] saveData;
saveData = NULL;
}
}
static void GBAgame_config(void) {}
static void GBAgame_write08(u32 procnum, u32 adr, u8 val)
{
//INFO("GBAgame: write08 at 0x%08X val=0x%02X\n", adr, val);
if ( (adr >= 0x0A000000) && (adr < 0x0A010000) )
{
switch (saveType)
{
case 3: // Flash
case 5:
gbaWriteFlash(adr, val);
break;
default:
break;
}
//return (u8)T1ReadByte(saveData, (adr - 0x0A000000));
}
}
static void GBAgame_write16(u32 procnum, u32 adr, u16 val)
{
//INFO("GBAgame: write16 at 0x%08X val=0x%04X\n", adr, val);
}
static void GBAgame_write32(u32 procnum, u32 adr, u32 val)
{
//INFO("GBAgame: write32 at 0x%08X val=0x%08X\n", adr, val);
}
static u8 GBAgame_read08(u32 procnum, u32 adr)
{
//INFO("GBAgame: read08 at 0x%08X value 0x%02X\n", adr, (u8)T1ReadByte(GBArom, (adr - 0x08000000)));
if (adr < 0x0A000000)
return (u8)T1ReadByte(GBArom, (adr - 0x08000000));
if (adr < 0x0A010000)
{
switch (saveType)
{
case 3: // Flash
case 5:
return gbaReadFlash(adr);
default:
break;
}
//INFO("Read08 at 0x%08X val=0x%08X\n", adr, (u8)T1ReadByte(GBArom, (adr - 0x08000000)) );
return (u8)T1ReadByte(saveData, (adr - 0x0A000000));
}
//INFO("Read08 at 0x%08X val=0x%08X\n", adr, (u8)T1ReadByte(GBArom, (adr - 0x08000000)) );
return 0xFF;
}
static u16 GBAgame_read16(u32 procnum, u32 adr)
{
//INFO("GBAgame: read16 at 0x%08X value 0x%04X\n", adr, (u16)T1ReadWord(GBArom, (adr - 0x08000000)));
if (adr < 0x0A000000)
return (u16)T1ReadWord(GBArom, (adr - 0x08000000));
if (adr < 0x0A010000)
{
//INFO("GBAgame: flash read16 at 0x%08X\n", adr);
return (u16)T1ReadWord(saveData, (adr - 0x0A000000));
}
return 0xFFFF;
}
static u32 GBAgame_read32(u32 procnum, u32 adr)
{
//INFO("GBAgame: read32 at 0x%08X value 0x%08X\n", adr, (u32)T1ReadLong(GBArom, (adr - 0x08000000)));
if (adr < 0x0A000000)
return (u32)T1ReadLong(GBArom, (adr - 0x08000000));
if (adr < 0x0A010000)
{
//INFO("GBAgame: flash read32 at 0x%08X\n", adr);
return (u32)T1ReadLong(saveData, (adr - 0x0A000000));
}
return 0xFFFFFFFF;
}
static void GBAgame_info(char *info)
{
strcpy(info, "GBA game in slot");
}
ADDONINTERFACE addonGBAgame = {
"GBA game",
GBAgame_init,
GBAgame_reset,
GBAgame_close,
GBAgame_config,
GBAgame_write08,
GBAgame_write16,
GBAgame_write32,
GBAgame_read08,
GBAgame_read16,
GBAgame_read32,
GBAgame_info};
ISlot2Interface* construct_Slot2_GbaCart() { return new Slot2_GbaCart(); }

View File

@ -1,72 +1,52 @@
/* Copyright (C) 2009-2010 DeSmuME team
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include <string.h>
#include "../slot2.h"
static u8 guitarKeyStatus;
static u8 guitarKeyStatus = 0;
class Slot2_GuitarGrip : public ISlot2Interface
{
private:
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Guitar Grip", "Guitar Grip for Guitar Hero games");
return &info;
}
static BOOL guitarGrip_init(void) { return (TRUE); }
static void guitarGrip_reset(void)
{
//INFO("GuitarGrip: Reset\n");
guitarKeyStatus = 0;
}
static void guitarGrip_close(void) {}
static void guitarGrip_config(void) {}
static void guitarGrip_write08(u32 procnum, u32 adr, u8 val) {}
static void guitarGrip_write16(u32 procnum, u32 adr, u16 val) {}
static void guitarGrip_write32(u32 procnum, u32 adr, u32 val) {}
static u8 guitarGrip_read08(u32 procnum, u32 adr)
{
//INFO("GuitarGrip: read 08 at 0x%08X\n", adr);
if (adr == 0x0A000000) return (~guitarKeyStatus);
else if(adr&1) return 0xF9;
else return 0xFF;
}
static u16 guitarGrip_read16(u32 procnum, u32 adr)
{
//INFO("GuitarGrip: read 16 at 0x%08X\n", adr);
return 0xF9FF;
}
static u32 guitarGrip_read32(u32 procnum, u32 adr)
{
//INFO("GuitarGrip: read 32 at 0x%08X\n", adr);
return (0xF9FFF9FF);
}
static void guitarGrip_info(char *info) { strcpy(info, "Guitar Grip for Guitar Hero games"); }
virtual void connect()
{
guitarKeyStatus = 0;
}
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
if (addr == 0x0A000000) return (~guitarKeyStatus);
return (addr & 1)?0xF9:0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xF9FF; }
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xF9FFF9FF; }
};
ISlot2Interface* construct_Slot2_GuitarGrip() { return new Slot2_GuitarGrip(); }
void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue)
{
guitarKeyStatus = 0 | (green << 6) | (red << 5) | (yellow << 4) | (blue << 3);
}
ADDONINTERFACE addonGuitarGrip = {
"Guitar Grip",
guitarGrip_init,
guitarGrip_reset,
guitarGrip_close,
guitarGrip_config,
guitarGrip_write08,
guitarGrip_write16,
guitarGrip_write32,
guitarGrip_read08,
guitarGrip_read16,
guitarGrip_read32,
guitarGrip_info};

View File

@ -1,338 +1,32 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006 Mic
Copyright (C) 2009-2011 DeSmuME team
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
This file 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
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
This file 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include <string>
#include <string.h>
#include "debug.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "../slot2.h"
#include "types.h"
#include "../utils/vfat.h"
#include "../path.h"
#include "../MMU.h"
#include "NDSSystem.h"
// Set up addresses for GBAMP
#define CF_REG_DATA 0x9000000
#define CF_REG_ERR 0x9020000
#define CF_REG_SEC 0x9040000
#define CF_REG_LBA1 0x9060000
#define CF_REG_LBA2 0x9080000
#define CF_REG_LBA3 0x90A0000
#define CF_REG_LBA4 0x90C0000
#define CF_REG_CMD 0x90E0000
#define CF_REG_STS 0x98C0000
// CF Card commands
#define CF_CMD_LBA 0xE0
#define CF_CMD_READ 0x20
#define CF_CMD_WRITE 0x30
static u16 cf_reg_sts,
cf_reg_lba1,
cf_reg_lba2,
cf_reg_lba3,
cf_reg_lba4,
cf_reg_cmd;
static off_t currLBA;
static const int lfnPos[13] = {1,3,5,7,9,14,16,18,20,22,24,28,30};
static u32 fileStartLBA,fileEndLBA;
static std::string sFlashPath;
static BOOL cflashDeviceEnabled = FALSE;
static EMUFILE* file = NULL;
// ===========================
BOOL inited;
enum EListCallbackArg {
EListCallbackArg_Item, EListCallbackArg_Pop
class Slot2_CFlash : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("MPCF Flash Card Device", "MPCF Flash Card Device");
return &info;
}
};
static BOOL cflash_init()
{
if (inited) return FALSE;
BOOL init_good = FALSE;
CFLASHLOG("CFlash_Mode: %d\n",CFlash_Mode);
if (CFlash_Mode == ADDON_CFLASH_MODE_RomPath)
{
sFlashPath = path.RomDirectory;
INFO("Using CFlash directory of rom: %s\n", sFlashPath.c_str());
}
else if(CFlash_Mode == ADDON_CFLASH_MODE_Path)
{
sFlashPath = CFlash_Path;
INFO("Using CFlash directory: %s\n", sFlashPath.c_str());
}
if(CFlash_IsUsingPath())
{
cflashDeviceEnabled = FALSE;
currLBA = 0;
fileStartLBA = fileEndLBA = 0xFFFFFFFF;
VFAT vfat;
bool ret = vfat.build(sFlashPath.c_str(),16); //allocate 16MB extra for writing. this is probably enough for anyone, but maybe it should be configurable.
//we could always suggest to users to add a big file to their directory to overwrite (that would cause the image to get padded)
if(!ret)
{
CFLASHLOG("FAILED cflash_build_fat\n");
return FALSE;
}
file = vfat.detach();
cf_reg_sts = 0x58; // READY
cflashDeviceEnabled = TRUE;
init_good = TRUE;
}
else
{
sFlashPath = CFlash_Path;
INFO("Using CFlash disk image file %s\n", sFlashPath.c_str());
file = new EMUFILE_FILE(sFlashPath.c_str(),"rb+");
if(file->fail())
{
INFO("Failed to open file %s\n", sFlashPath.c_str());
delete file;
file = NULL;
}
}
// READY
cf_reg_sts = 0x58;
currLBA = 0;
cf_reg_lba1 = cf_reg_lba2 =
cf_reg_lba3 = cf_reg_lba4 = 0;
inited = TRUE;
return init_good;
}
static unsigned int cflash_read(unsigned int address)
{
unsigned int ret_value = 0;
size_t elems_read = 0;
switch (address)
{
case CF_REG_STS:
ret_value = cf_reg_sts;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_READ)
{
if(file)
{
u8 data[2];
file->fseek(currLBA, SEEK_SET);
elems_read += file->fread(data,2);
ret_value = data[1] << 8 | data[0];
}
currLBA += 2;
}
break;
case CF_REG_CMD:
break;
case CF_REG_LBA1:
ret_value = cf_reg_lba1;
break;
}
return ret_value;
}
static void cflash_write(unsigned int address,unsigned int data)
{
static u8 sector_data[512];
static u32 sector_write_index = 0;
switch (address)
{
case CF_REG_STS:
cf_reg_sts = data&0xFFFF;
break;
case CF_REG_DATA:
if (cf_reg_cmd == CF_CMD_WRITE)
{
{
sector_data[sector_write_index] = (data >> 0) & 0xff;
sector_data[sector_write_index + 1] = (data >> 8) & 0xff;
sector_write_index += 2;
if (sector_write_index == 512)
{
CFLASHLOG( "Write sector to %ld\n", currLBA);
size_t written = 0;
if(file)
if(currLBA + 512 < file->size())
{
file->fseek(currLBA,SEEK_SET);
while(written < 512)
{
size_t todo = 512-written;
file->fwrite(&sector_data[written], todo);
size_t cur_write = todo;
written += cur_write;
if ( cur_write == (size_t)-1) break;
}
}
CFLASHLOG("Wrote %u bytes\n", written);
currLBA += 512;
sector_write_index = 0;
}
}
}
break;
case CF_REG_CMD:
cf_reg_cmd = data&0xFF;
cf_reg_sts = 0x58; // READY
break;
case CF_REG_LBA1:
cf_reg_lba1 = data&0xFF;
currLBA = (currLBA&0xFFFFFF00)| cf_reg_lba1;
break;
case CF_REG_LBA2:
cf_reg_lba2 = data&0xFF;
currLBA = (currLBA&0xFFFF00FF)|(cf_reg_lba2<<8);
break;
case CF_REG_LBA3:
cf_reg_lba3 = data&0xFF;
currLBA = (currLBA&0xFF00FFFF)|(cf_reg_lba3<<16);
break;
case CF_REG_LBA4:
cf_reg_lba4 = data&0xFF;
if ((cf_reg_lba4 & 0xf0) == CF_CMD_LBA)
{
currLBA = (currLBA&0x00FFFFFF)|((cf_reg_lba4&0x0F)<<24);
currLBA *= 512;
sector_write_index = 0;
}
break;
}
}
static void cflash_close( void)
{
if (!inited) return;
if(file) delete file;
cflashDeviceEnabled = FALSE;
file = NULL;
inited = FALSE;
}
static BOOL init(void)
{
return TRUE;
}
static void reset(void)
{
cflash_close();
cflash_init();
}
static void close(void)
{
cflash_close();
}
static void config(void)
{
}
static void write08(u32 procnum, u32 adr, u8 val)
{
cflash_write(adr, val);
}
static void write16(u32 procnum, u32 adr, u16 val)
{
cflash_write(adr, val);
}
static void write32(u32 procnum, u32 adr, u32 val)
{
cflash_write(adr, val);
}
static u8 read08(u32 procnum, u32 adr)
{
return (cflash_read(adr));
}
static u16 read16(u32 procnum, u32 adr)
{
return (cflash_read(adr));
}
static u32 read32(u32 procnum, u32 adr)
{
return (cflash_read(adr));
}
static void info(char *info)
{
strcpy(info, "MPCF Flash Card Device");
}
ADDONINTERFACE addonCFlash = {
"MPCF Flash Card Device",
init,
reset,
close,
config,
write08,
write16,
write32,
read08,
read16,
read32,
info};
#undef CFLASHDEBUG
ISlot2Interface* construct_Slot2_CFlash() { return new Slot2_CFlash(); }

View File

@ -1,48 +1,31 @@
/* Copyright (C) 2009 CrazyMax
Copyright (C) 2009 DeSmuME team
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include <string.h>
#include "../slot2.h"
static BOOL None_init(void) { return (TRUE); }
static void None_reset(void) {}
static void None_close(void) {}
static void None_config(void) {}
static void None_write08(u32 procnum, u32 adr, u8 val) {}
static void None_write16(u32 procnum, u32 adr, u16 val) {}
static void None_write32(u32 procnum, u32 adr, u32 val) {}
static u8 None_read08(u32 procnum, u32 adr){ return (0xFF); }
static u16 None_read16(u32 procnum, u32 adr){ return (0xFFFF); }
static u32 None_read32(u32 procnum, u32 adr){ return (0xFFFFFFFF); }
static void None_info(char *info) { strcpy(info, "Nothing in GBA slot"); }
class Slot2_None : public ISlot2Interface
{
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("None", "Slot2 no-device emulation");
return &info;
}
};
ADDONINTERFACE addonNone = {
"NONE",
None_init,
None_reset,
None_close,
None_config,
None_write08,
None_write16,
None_write32,
None_read08,
None_read16,
None_read32,
None_info};
ISlot2Interface* construct_Slot2_None() { return new Slot2_None(); }

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2011 DeSmuME team
/*
Copyright (C) 2011-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -36,109 +37,16 @@ The emulation in all the handling of erroneous cases is not perfect, and some ot
maybe legally configure the paddle differently, which could be rejected here; in which case this code will need finetuning
*/
#include "../addons.h"
#include <string.h>
#include "NDSSystem.h"
#include "../slot2.h"
static BOOL init(void) { return (TRUE); }
static void reset(void)
class Slot2_Paddle : public ISlot2Interface
{
}
static void calibrate()
{
nds.paddle = 0;
}
static void close(void) {}
static void config(void) {}
static void write08(u32 procnum, u32 adr, u8 val)
{
if(adr<0x0A000000) return;
calibrate();
}
static void write16(u32 procnum, u32 adr, u16 val)
{
if(adr<0x0A000000) { calibrate(); return; }
}
static void write32(u32 procnum, u32 adr, u32 val)
{
if(adr<0x0A000000) { calibrate(); return; }
}
extern int currFrameCounter;
static bool Validate(u32 procnum, bool rom) {
if(rom)
return ValidateSlot2Access(procnum,0,0,0,-1);
else
return ValidateSlot2Access(procnum,18,0,0,1);
}
static u8 read08(u32 procnum, u32 adr)
{
//printf("paddle: read 08 at 0x%08X\n", adr);
if(!Validate(procnum,adr<0x0A000000))
return 0xFF;
if(adr<0x0A000000)
public:
virtual Slot2Info const* info()
{
if(adr&1) return 0xFF;
else return 0xEF;
static Slot2InfoSimple info("Paddle", "Paddle");
return &info;
}
};
if(adr==0x0A000000)
{
return nds.paddle&0xFF;
}
if(adr==0x0A000001)
{
return (nds.paddle>>8)&0x0F;
}
return 0x00;
}
static u16 read16(u32 procnum, u32 adr)
{
//printf("paddle : read 16 at 0x%08X\n", adr);
if(!Validate(procnum,adr<0x0A000000))
return 0xFFFF;
if(adr<0x0A000000)
return 0xEFFF;
if(adr==0x0A000000)
{
u8 val = nds.paddle&0xFF;
return val|(val<<8);
}
return 0x0000;
}
static u32 read32(u32 procnum, u32 adr)
{
//printf("paddle: read 32 at 0x%08X\n", adr);
if(!Validate(procnum,adr<0x0A000000))
return 0xFFFFFFFF;
if(adr<0x0A000000)
return 0xEFFFEFFF;
if(adr==0x0A000000)
{
u8 val = nds.paddle&0xFF;
return val|(val<<8)|(val<<16)|(val<<24);
}
return 0x00000000;
}
static void info(char *info) { strcpy(info, "Paddle"); }
ADDONINTERFACE addonPaddle = {
"Paddle",
init,
reset,
close,
config,
write08,
write16,
write32,
read08,
read16,
read32,
info};
ISlot2Interface* construct_Slot2_Paddle() { return new Slot2_Paddle(); }

View File

@ -1,71 +1,30 @@
/*
Copyright (C) 2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "../addons.h"
#include "../NDSSystem.h"
#include "../slot2.h"
static BOOL PassME_init(void) { return (TRUE); }
static void PassME_reset(void) {}
static void PassME_close(void) {}
static void PassME_config(void) {}
static void PassME_write08(u32 procnum, u32 adr, u8 val) {}
static void PassME_write16(u32 procnum, u32 adr, u16 val) {}
static void PassME_write32(u32 procnum, u32 adr, u32 val) {}
static u8 PassME_read08(u32 procnum, u32 adr)
class Slot2_PassME : public ISlot2Interface
{
u32 tmp_adr = (adr & 0x07FFFFFF);
if (tmp_adr < gameInfo.romsize)
return (u8)gameInfo.readROM(tmp_adr);
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("PassME", "PassME in GBA slot");
return &info;
}
};
return (0xFF);
}
static u16 PassME_read16(u32 procnum, u32 adr)
{
u32 tmp_adr = (adr & 0x07FFFFFF);
if (tmp_adr < gameInfo.romsize)
return (u16)gameInfo.readROM(tmp_adr);
return (0xFFFF);
}
static u32 PassME_read32(u32 procnum, u32 adr)
{
u32 tmp_adr = (adr & 0x07FFFFFF);
if (tmp_adr < gameInfo.romsize)
return gameInfo.readROM(tmp_adr);
return (0xFFFFFFFF);
}
static void PassME_info(char *info) { strcpy(info, "PassME in GBA slot"); }
ADDONINTERFACE addonPassME = {
"PassME",
PassME_init,
PassME_reset,
PassME_close,
PassME_config,
PassME_write08,
PassME_write16,
PassME_write32,
PassME_read08,
PassME_read16,
PassME_read32,
PassME_info};
ISlot2Interface* construct_Slot2_PassME() { return new Slot2_PassME(); }

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2010-2011 DeSmuME team
/*
Copyright (C) 2010-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -14,82 +15,69 @@
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include <string.h>
#include "../slot2.h"
static u16 pianoKeyStatus = 0;
static BOOL piano_init(void) { return (TRUE); }
static void piano_reset(void)
class Slot2_EasyPiano : public ISlot2Interface
{
//INFO("piano: Reset\n");
pianoKeyStatus = 0;
}
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Piano", "Piano for EasyPiano");
return &info;
}
static void piano_close(void) {}
static void piano_config(void) {}
static void piano_write08(u32 procnum, u32 adr, u8 val)
{
//INFO("piano: write 08 at 0x%08X = %02X\n", adr, val);
}
static void piano_write16(u32 procnum, u32 adr, u16 val)
{
//INFO("piano: write 16 at 0x%08X = %04X\n", adr, val);
}
static void piano_write32(u32 procnum, u32 adr, u32 val)
{
//INFO("piano: write 32 at 0x%08X = %08X\n", adr, val);
}
extern int currFrameCounter;
static u8 piano_read08(u32 procnum, u32 adr)
{
//printf("piano: read 08 at 0x%08X\n", adr);
virtual void connect()
{
pianoKeyStatus = 0;
}
//the actual keyboard output
virtual u8 readByte(u8 PROCNUM, u32 addr)
{
//printf("piano: read 08 at 0x%08X\n", adr);
//byte:bit
//0x09FFFFFE:0 = C
//0x09FFFFFE:1 = C#
//0x09FFFFFE:2 = D
//0x09FFFFFE:3 = D#
//0x09FFFFFE:4 = E
//0x09FFFFFE:5 = F
//0x09FFFFFE:6 = F#
//0x09FFFFFE:7 = G
//0x09FFFFFF:0 = G#
//0x09FFFFFF:1 = A
//0x09FFFFFF:2 = A#
//0x09FFFFFF:3 = ?
//0x09FFFFFF:4 = ?
//0x09FFFFFF:5 = B
//0x09FFFFFF:6 = hiC
//0x09FFFFFF:7 = ?
//the actual keyboard output
//deassert bit if key is pressed
//byte:bit
//0x09FFFFFE:0 = C
//0x09FFFFFE:1 = C#
//0x09FFFFFE:2 = D
//0x09FFFFFE:3 = D#
//0x09FFFFFE:4 = E
//0x09FFFFFE:5 = F
//0x09FFFFFE:6 = F#
//0x09FFFFFE:7 = G
//0x09FFFFFF:0 = G#
//0x09FFFFFF:1 = A
//0x09FFFFFF:2 = A#
//0x09FFFFFF:3 = ?
//0x09FFFFFF:4 = ?
//0x09FFFFFF:5 = B
//0x09FFFFFF:6 = hiC
//0x09FFFFFF:7 = ?
//LOG("PIANO: %04X\n",pianoKeyStatus);
//deassert bit if key is pressed
if(adr == 0x09FFFFFE) return (~(pianoKeyStatus&0xFF));
if(adr == 0x09FFFFFF) return (~((pianoKeyStatus>>8)&0xFF))&~(0x18);
//LOG("PIANO: %04X\n",pianoKeyStatus);
if(adr&1) return 0xE7;
else return 0xFF;
}
static u16 piano_read16(u32 procnum, u32 adr)
{
//printf("piano: read 16 at 0x%08X\n", adr);
if(adr != 0x09FFFFFE)
return 0xE7FF;
u16 ret = piano_read08(procnum,0x09FFFFFE)|(piano_read08(procnum,0x09FFFFFF)<<8);
//return ( (PIANO_PAK & 0x1800 ) == 0 );
return ret;
}
static u32 piano_read32(u32 procnum, u32 adr)
{
//printf("piano: read 32 at 0x%08X\n", adr);
return 0xE7FFE7FF;
}
static void piano_info(char *info) { strcpy(info, "Piano for EasyPiano"); }
if(addr == 0x09FFFFFE) return (~(pianoKeyStatus&0xFF));
if(addr == 0x09FFFFFF) return (~((pianoKeyStatus>>8)&0xFF))&~(0x18);
return (addr & 1)?0xE7:0xFF;
}
virtual u16 readWord(u8 PROCNUM, u32 addr)
{
if (addr != 0x09FFFFFE)
return 0xE7FF;
return readByte(PROCNUM, 0x09FFFFFE) | (readByte(PROCNUM,0x09FFFFFF) << 8);
}
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xE7FFE7FF; }
};
ISlot2Interface* construct_Slot2_EasyPiano() { return new Slot2_EasyPiano(); }
void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic)
{
@ -110,35 +98,20 @@ void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, boo
//0x09FFFFFF:6 = hiC
//0x09FFFFFF:7 = ?
#define BIT(N,v) ((v)?(1<<(N)):0)
pianoKeyStatus =
BIT(0,c) |
BIT(1,cs) |
BIT(2,d) |
BIT(3,ds) |
BIT(4,e) |
BIT(5,f) |
BIT(6,fs) |
BIT(7,g) |
BIT(8,gs) |
BIT(9,a) |
BIT(10,as) |
BIT(13,b) |
BIT(14,hic)
;
pianoKeyStatus = pianoKeyStatus;
#define BIT_P(N,v) ((v)?(1<<(N)):0)
pianoKeyStatus =
BIT_P(0,c) |
BIT_P(1,cs) |
BIT_P(2,d) |
BIT_P(3,ds) |
BIT_P(4,e) |
BIT_P(5,f) |
BIT_P(6,fs) |
BIT_P(7,g) |
BIT_P(8,gs) |
BIT_P(9,a) |
BIT_P(10,as) |
BIT_P(13,b) |
BIT_P(14,hic)
;
}
ADDONINTERFACE addonPiano = {
"Piano",
piano_init,
piano_reset,
piano_close,
piano_config,
piano_write08,
piano_write16,
piano_write32,
piano_read08,
piano_read16,
piano_read32,
piano_info};

View File

@ -1,98 +1,57 @@
/* Copyright (C) 2009-2010 DeSmuME team
/*
Copyright (C) 2009 CrazyMax
Copyright (C) 2009-2013 DeSmuME team
This file is part of DeSmuME
This file 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.
DeSmuME 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 file 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.
DeSmuME 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 DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../addons.h"
#include "../mem.h"
#include "../MMU.h"
#include <string.h>
u16 old_val_rumble = 0;
#include "../slot2.h"
void (*FeedbackON)(BOOL enable) = NULL;
static BOOL RumblePak_init(void) { return (TRUE); }
static void RumblePak_reset(void)
class Slot2_RumblePak : public ISlot2Interface
{
old_val_rumble = 0;
if (!FeedbackON) return;
FeedbackON(false);
}
private:
u16 old_val_rumble;
static void RumblePak_close(void) {}
public:
virtual Slot2Info const* info()
{
static Slot2InfoSimple info("Rumble Pak", "NDS Rumble Pak (need joystick with Feedback)");
return &info;
}
static void RumblePak_config(void) {}
virtual void connect()
{
old_val_rumble = 0;
if (!FeedbackON) return;
FeedbackON(false);
}
static void RumblePak_write08(u32 procnum, u32 adr, u8 val)
{
}
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val)
{
if (!FeedbackON) return;
if (old_val_rumble == val) return;
static void RumblePak_write16(u32 procnum, u32 adr, u16 val)
{
if (!FeedbackON) return;
old_val_rumble = val;
if ((addr == 0x08000000) || (addr == 0x08001000))
FeedbackON(val);
}
if (old_val_rumble == val) return;
virtual u8 readByte(u8 PROCNUM, u32 addr) { return (addr & 1)?0xFF:0xFD; };
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFFFD; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFFFDFFFD; };
};
old_val_rumble = val;
// CrazyMax 17/01/2009
// i don't know how send to feedback (PC) impulse with small latency.
if (adr == 0x08000000)
FeedbackON(val);
if (adr == 0x08001000)
FeedbackON(val);
}
static void RumblePak_write32(u32 procnum, u32 adr, u32 val)
{
}
static u8 RumblePak_read08(u32 procnum, u32 adr)
{
if(adr&1) return 0xFF;
else return 0xFD;
}
static u16 RumblePak_read16(u32 procnum, u32 adr)
{
return 0xFFFD;
}
static u32 RumblePak_read32(u32 procnum, u32 adr)
{
return 0xFFFDFFFD;
}
static void RumblePak_info(char *info)
{
strcpy(info, "NDS Rumble Pak (need joystick with Feedback)");
}
ADDONINTERFACE addonRumblePak = {
"Rumble Pak",
RumblePak_init,
RumblePak_reset,
RumblePak_close,
RumblePak_config,
RumblePak_write08,
RumblePak_write16,
RumblePak_write32,
RumblePak_read08,
RumblePak_read16,
RumblePak_read32,
RumblePak_info};
ISlot2Interface* construct_Slot2_RumblePak() { return new Slot2_RumblePak(); }

View File

@ -23,8 +23,8 @@
#include "commandline.h"
#include "types.h"
#include "movie.h"
#include "addons.h"
#include "slot1.h"
#include "slot2.h"
#include "NDSSystem.h"
#include "utils/xstring.h"

194
desmume/src/slot2.cpp Normal file
View File

@ -0,0 +1,194 @@
/*
Copyright (C) 2009-2013 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "slot2.h"
#include "../types.h"
#include "../mem.h"
#include "../MMU.h"
//this is the currently-configured cflash mode
ADDON_CFLASH_MODE CFlash_Mode = ADDON_CFLASH_MODE_RomPath;
//this is the currently-configured path (directory or filename) for cflash.
//it should be viewed as a parameter for the above.
std::string CFlash_Path;
char GBAgameName[MAX_PATH] = {0};
ISlot2Interface* slot2_List[NDS_SLOT2_COUNT] = {0};
ISlot2Interface* slot2_device = NULL;
NDS_SLOT2_TYPE slot2_device_type = NDS_SLOT2_NONE;
void slot2_Init()
{
//due to sloppy initialization code in various untestable desmume ports, we might try this more than once
static bool initialized = false;
if(initialized) return;
initialized = true;
//construct all devices
extern TISlot2InterfaceConstructor construct_Slot2_None;
//extern TISlot2InterfaceConstructor construct_Slot2_Auto;
extern TISlot2InterfaceConstructor construct_Slot2_CFlash;
extern TISlot2InterfaceConstructor construct_Slot2_RumblePak;
extern TISlot2InterfaceConstructor construct_Slot2_GbaCart;
extern TISlot2InterfaceConstructor construct_Slot2_GuitarGrip;
extern TISlot2InterfaceConstructor construct_Slot2_ExpansionPak;
extern TISlot2InterfaceConstructor construct_Slot2_EasyPiano;
extern TISlot2InterfaceConstructor construct_Slot2_Paddle;
extern TISlot2InterfaceConstructor construct_Slot2_PassME;
slot2_List[NDS_SLOT2_NONE] = construct_Slot2_None();
//slot2_List[NDS_SLOT2_AUTO] = construct_Slot2_Auto();
slot2_List[NDS_SLOT2_CFLASH] = construct_Slot2_CFlash();
slot2_List[NDS_SLOT2_RUMBLEPAK] = construct_Slot2_RumblePak();
slot2_List[NDS_SLOT2_GBACART] = construct_Slot2_GbaCart();
slot2_List[NDS_SLOT2_GUITARGRIP] = construct_Slot2_GuitarGrip();
slot2_List[NDS_SLOT2_EXPMEMORY] = construct_Slot2_ExpansionPak();
slot2_List[NDS_SLOT2_EASYPIANO] = construct_Slot2_EasyPiano();
slot2_List[NDS_SLOT2_PADDLE] = construct_Slot2_Paddle();
slot2_List[NDS_SLOT2_PASSME] = construct_Slot2_PassME();
}
void slot2_Shutdown()
{
for(int i=0; i<ARRAY_SIZE(slot2_List); i++)
{
if(slot2_List[i])
slot2_List[i]->shutdown();
delete slot2_List[i];
slot2_List[i] = NULL;
}
}
bool slot2_Connect()
{
slot2_device->connect();
return true;
}
void slot2_Disconnect()
{
slot2_device->disconnect();
}
void slot2_Reset()
{
//disconnect existing device
if(slot2_device != NULL) slot2_device->disconnect();
//connect new device
slot2_device = slot2_List[slot2_device_type];
slot2_device->connect();
}
bool slot2_Change(NDS_SLOT2_TYPE changeToType)
{
if(changeToType == slot2_device_type)
return FALSE; //nothing to do
if (changeToType > NDS_SLOT2_COUNT || changeToType < 0)
return FALSE;
if(slot2_device != NULL)
slot2_device->disconnect();
slot2_device_type = changeToType;
slot2_device = slot2_List[slot2_device_type];
printf("Slot 2: %s\n", slot2_device->info()->name());
slot2_device->connect();
return true;
}
NDS_SLOT2_TYPE slot2_GetCurrentType()
{
return slot2_device_type;
}
void slot2_Savestate(EMUFILE* os)
{
slot2_device->savestate(os);
}
void slot2_Loadstate(EMUFILE* is)
{
slot2_device->loadstate(is);
}
static bool isSlot2(u32 addr)
{
if (addr < 0x08000000) return false;
if (addr >= 0x0A010000) return false;
return true;
}
template <u8 PROCNUM>
static bool skipSlot2Data()
{
u16 exmemcnt = T1ReadWord(MMU.MMU_MEM[PROCNUM][0x40], 0x204);
return (PROCNUM == ARMCPU_ARM9)? (exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7):
!(exmemcnt & EXMEMCNT_MASK_SLOT2_ARM7);
}
template <u8 PROCNUM, typename T>
bool slot2_write(u32 addr, T val)
{
if (!isSlot2(addr)) return false;
if (skipSlot2Data<PROCNUM>()) return true;
switch (sizeof(T))
{
case sizeof(u8) : slot2_device->writeByte(PROCNUM, addr, val); break;
case sizeof(u16): slot2_device->writeWord(PROCNUM, addr, val); break;
case sizeof(u32): slot2_device->writeLong(PROCNUM, addr, val); break;
}
return true;
}
template <u8 PROCNUM, typename T>
bool slot2_read(u32 addr, T &val)
{
if (!isSlot2(addr)) return false;
if (skipSlot2Data<PROCNUM>()) { val = 0; return true; }
switch (sizeof(T))
{
case sizeof(u8) : val = slot2_device->readByte(PROCNUM, addr); break;
case sizeof(u16): val = slot2_device->readWord(PROCNUM, addr); break;
case sizeof(u32): val = slot2_device->readLong(PROCNUM, addr); break;
default: val = 0; break;
}
return true;
}
template bool slot2_write<0, u8> (u32 addr, u8 val);
template bool slot2_write<0, u16>(u32 addr, u16 val);
template bool slot2_write<0, u32>(u32 addr, u32 val);
template bool slot2_write<1, u8> (u32 addr, u8 val);
template bool slot2_write<1, u16>(u32 addr, u16 val);
template bool slot2_write<1, u32>(u32 addr, u32 val);
template bool slot2_read<0, u8> (u32 addr, u8 &val);
template bool slot2_read<0, u16>(u32 addr, u16 &val);
template bool slot2_read<0, u32>(u32 addr, u32 &val);
template bool slot2_read<1, u8> (u32 addr, u8 &val);
template bool slot2_read<1, u16>(u32 addr, u16 &val);
template bool slot2_read<1, u32>(u32 addr, u32 &val);

135
desmume/src/slot2.h Normal file
View File

@ -0,0 +1,135 @@
/*
Copyright (C) 2009-2013 DeSmuME team
This file 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 file 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 the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SLOT2_H__
#define __SLOT_H__
#include "common.h"
#include "types.h"
#include "debug.h"
class Slot2Info
{
public:
virtual const char* name() const = 0;
virtual const char* descr() const = 0;
};
class Slot2InfoSimple : public Slot2Info
{
public:
Slot2InfoSimple(const char* _name, const char* _descr)
: mName(_name)
, mDescr(_descr)
{
}
virtual const char* name() const { return mName; }
virtual const char* descr() const { return mDescr; }
private:
const char* mName, *mDescr;
};
class ISlot2Interface
{
public:
//called to get info about device (description)
virtual Slot2Info const* info() = 0;
//called once when the emulator starts up, or when the device springs into existence
virtual bool init() { return true; }
//called when the emulator connects the device
virtual void connect() { }
//called when the emulator disconnects the device
virtual void disconnect() { }
//called when the emulator shuts down, or when the device disappears from existence
virtual void shutdown() { }
virtual void writeByte(u8 PROCNUM, u32 addr, u8 val) {};
virtual void writeWord(u8 PROCNUM, u32 addr, u16 val) {};
virtual void writeLong(u8 PROCNUM, u32 addr, u32 val) {};
virtual u8 readByte(u8 PROCNUM, u32 addr) { return 0xFF; };
virtual u16 readWord(u8 PROCNUM, u32 addr) { return 0xFFFF; };
virtual u32 readLong(u8 PROCNUM, u32 addr) { return 0xFFFFFFFF; };
virtual void savestate(EMUFILE* os) {}
virtual void loadstate(EMUFILE* is) {}
};
typedef ISlot2Interface* TISlot2InterfaceConstructor();
enum NDS_SLOT2_TYPE
{
NDS_SLOT2_NONE,
//NDS_SLOT2_AUTO,
NDS_SLOT2_CFLASH, // compact flash
NDS_SLOT2_RUMBLEPAK, // rumble pack
NDS_SLOT2_GBACART, // GBA cartrindge in slot
NDS_SLOT2_GUITARGRIP, // Guitar Grip
NDS_SLOT2_EXPMEMORY, // Memory Expansion
NDS_SLOT2_EASYPIANO, // Easy Piano
NDS_SLOT2_PADDLE,
NDS_SLOT2_PASSME, // PassME
NDS_SLOT2_COUNT // use for counter addons - MUST TO BE LAST!!!
};
extern ISlot2Interface* slot2_device; //the current slot2 device instance
extern ISlot2Interface* slot2_List[NDS_SLOT2_COUNT];
void slot2_Init();
bool slot2_Connect();
void slot2_Disconnect();
void slot2_Shutdown();
void slot2_Savestate(EMUFILE* os);
void slot2_Loadstate(EMUFILE* is);
//just disconnects and reconnects the device. ideally, the disconnection and connection would be called with sensible timing
void slot2_Reset();
//change the current device
bool slot2_Change(NDS_SLOT2_TYPE type);
//check on the current device
NDS_SLOT2_TYPE slot2_GetCurrentType();
template <u8 PROCNUM, typename T>
bool slot2_write(u32 addr, T val);
template <u8 PROCNUM, typename T>
bool slot2_read(u32 addr, T &val);
// =================================================================================
extern char GBAgameName[MAX_PATH]; // file name for GBA game (rom)
extern void (*FeedbackON)(BOOL enable); // feedback on/off
enum ADDON_CFLASH_MODE
{
ADDON_CFLASH_MODE_Path, ADDON_CFLASH_MODE_File, ADDON_CFLASH_MODE_RomPath
};
extern ADDON_CFLASH_MODE CFlash_Mode;
extern std::string CFlash_Path;
inline bool CFlash_IsUsingPath() { return CFlash_Mode==ADDON_CFLASH_MODE_Path || CFlash_Mode==ADDON_CFLASH_MODE_RomPath; }
extern void guitarGrip_setKey(bool green, bool red, bool yellow, bool blue); // Guitar grip keys
extern void piano_setKey(bool c, bool cs, bool d, bool ds, bool e, bool f, bool fs, bool g, bool gs, bool a, bool as, bool b, bool hic); //piano keys
#endif //__SLOT_H__

View File

@ -2348,14 +2348,6 @@
>
</File>
</Filter>
<File
RelativePath="..\addons.cpp"
>
</File>
<File
RelativePath="..\addons.h"
>
</File>
<File
RelativePath="..\agg2d.h"
>
@ -2784,6 +2776,14 @@
RelativePath="..\slot1.h"
>
</File>
<File
RelativePath="..\slot2.cpp"
>
</File>
<File
RelativePath="..\slot2.h"
>
</File>
<File
RelativePath="..\SPU.cpp"
>

View File

@ -590,14 +590,6 @@
<Filter
Name="Core"
>
<File
RelativePath="..\addons.cpp"
>
</File>
<File
RelativePath="..\addons.h"
>
</File>
<File
RelativePath="..\aggdraw.cpp"
>
@ -950,6 +942,14 @@
RelativePath="..\slot1.h"
>
</File>
<File
RelativePath="..\slot2.cpp"
>
</File>
<File
RelativePath="..\slot2.h"
>
</File>
<File
RelativePath="..\SPU.cpp"
>

View File

@ -369,7 +369,6 @@
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\addons.cpp" />
<ClCompile Include="..\addons\slot1comp_mc.cpp" />
<ClCompile Include="..\addons\slot1comp_protocol.cpp" />
<ClCompile Include="..\addons\slot1comp_rom.cpp" />
@ -430,6 +429,7 @@
<ClCompile Include="..\rtc.cpp" />
<ClCompile Include="..\saves.cpp" />
<ClCompile Include="..\slot1.cpp" />
<ClCompile Include="..\slot2.cpp" />
<ClCompile Include="..\SPU.cpp" />
<ClCompile Include="..\texcache.cpp" />
<ClCompile Include="..\thumb_instructions.cpp" />
@ -655,7 +655,6 @@
<ClCompile Include="tileView.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\addons.h" />
<ClInclude Include="..\addons\slot1comp_mc.h" />
<ClInclude Include="..\addons\slot1comp_protocol.h" />
<ClInclude Include="..\addons\slot1comp_rom.h" />
@ -708,6 +707,7 @@
<ClInclude Include="..\saves.h" />
<ClInclude Include="..\shaders.h" />
<ClInclude Include="..\slot1.h" />
<ClInclude Include="..\slot2.h" />
<ClInclude Include="..\SPU.h" />
<ClInclude Include="..\texcache.h" />
<ClInclude Include="..\types.h" />

View File

@ -69,9 +69,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\addons.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\aggdraw.cpp">
<Filter>Core</Filter>
</ClCompile>
@ -168,6 +165,9 @@
<ClCompile Include="..\slot1.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\slot2.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\SPU.cpp">
<Filter>Core</Filter>
</ClCompile>
@ -806,9 +806,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\addons.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="..\armcpu.h">
<Filter>Core</Filter>
</ClInclude>
@ -923,6 +920,9 @@
<ClInclude Include="..\slot1.h">
<Filter>Core</Filter>
</ClInclude>
<ClCompile Include="..\slot2.h">
<Filter>Core</Filter>
</ClCompile>
<ClInclude Include="..\SPU.h">
<Filter>Core</Filter>
</ClInclude>

View File

@ -380,7 +380,6 @@
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\addons.cpp" />
<ClCompile Include="..\addons\slot1comp_mc.cpp" />
<ClCompile Include="..\addons\slot1comp_protocol.cpp" />
<ClCompile Include="..\addons\slot1comp_rom.cpp" />
@ -441,6 +440,7 @@
<ClCompile Include="..\rtc.cpp" />
<ClCompile Include="..\saves.cpp" />
<ClCompile Include="..\slot1.cpp" />
<ClCompile Include="..\slot2.cpp" />
<ClCompile Include="..\SPU.cpp" />
<ClCompile Include="..\texcache.cpp" />
<ClCompile Include="..\thumb_instructions.cpp" />
@ -666,7 +666,6 @@
<ClCompile Include="tileView.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\addons.h" />
<ClInclude Include="..\addons\slot1comp_mc.h" />
<ClInclude Include="..\addons\slot1comp_protocol.h" />
<ClInclude Include="..\addons\slot1comp_rom.h" />
@ -719,6 +718,7 @@
<ClInclude Include="..\saves.h" />
<ClInclude Include="..\shaders.h" />
<ClInclude Include="..\slot1.h" />
<ClInclude Include="..\slot2.h" />
<ClInclude Include="..\SPU.h" />
<ClInclude Include="..\texcache.h" />
<ClInclude Include="..\types.h" />

View File

@ -69,9 +69,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\addons.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\aggdraw.cpp">
<Filter>Core</Filter>
</ClCompile>
@ -174,6 +171,9 @@
<ClCompile Include="..\slot1.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\slot2.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="..\SPU.cpp">
<Filter>Core</Filter>
</ClCompile>
@ -798,9 +798,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\addons.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="..\arm_jit.h">
<Filter>Core</Filter>
</ClInclude>
@ -924,6 +921,9 @@
<ClInclude Include="..\slot1.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="..\slot2.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="..\SPU.h">
<Filter>Core</Filter>
</ClInclude>

View File

@ -20,7 +20,7 @@
#include "resource.h"
#include "main.h"
#include "debug.h"
#include "../addons.h"
#include "../slot2.h"
#include "../NDSSystem.h"
#include "inputdx.h"
#include <shlobj.h>
@ -307,7 +307,7 @@ INT_PTR CALLBACK GbaSlotGuitarGrip(HWND dialog, UINT msg,WPARAM wparam,LPARAM lp
SendDlgItemMessage(dialog,IDC_GRED,WM_USER+44,tmp_Guitar.RED,0);
SendDlgItemMessage(dialog,IDC_GYELLOW,WM_USER+44,tmp_Guitar.YELLOW,0);
SendDlgItemMessage(dialog,IDC_GBLUE,WM_USER+44,tmp_Guitar.BLUE,0);
if (temp_type != addon_type)
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
@ -376,7 +376,7 @@ INT_PTR CALLBACK GbaSlotPiano(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
SendDlgItemMessage(dialog,IDC_PIANO_AS,WM_USER+44,tmp_Piano.AS,0);
SendDlgItemMessage(dialog,IDC_PIANO_B,WM_USER+44,tmp_Piano.B,0);
SendDlgItemMessage(dialog,IDC_PIANO_HIC,WM_USER+44,tmp_Piano.HIC,0);
if (temp_type != addon_type)
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
@ -440,7 +440,7 @@ INT_PTR CALLBACK GbaSlotPiano(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
return FALSE;
}
u32 GBAslot_IDDs[NDS_ADDON_COUNT] = {
u32 GBAslot_IDDs[NDS_SLOT2_COUNT] = {
IDD_GBASLOT_NONE,
IDD_GBASLOT_CFLASH,
IDD_GBASLOT_RUMBLEPAK,
@ -452,7 +452,7 @@ u32 GBAslot_IDDs[NDS_ADDON_COUNT] = {
IDD_GBASLOT_NONE, //PassME
};
DLGPROC GBAslot_Procs[NDS_ADDON_COUNT] = {
DLGPROC GBAslot_Procs[NDS_SLOT2_COUNT] = {
GbaSlotNone,
GbaSlotCFlash,
GbaSlotRumblePak,
@ -473,12 +473,10 @@ BOOL CALLBACK GbaSlotBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
case WM_INITDIALOG:
{
OKbutton = GetDlgItem(dialog, IDOK);
for(int i = 0; i < NDS_ADDON_COUNT; i++)
ComboBox_AddString(GetDlgItem(dialog, IDC_ADDONS_LIST), addonList[i].name);
for(int i = 0; i < NDS_SLOT2_COUNT; i++)
ComboBox_AddString(GetDlgItem(dialog, IDC_ADDONS_LIST), slot2_List[i]->info()->name());
ComboBox_SetCurSel(GetDlgItem(dialog, IDC_ADDONS_LIST), temp_type);
u8 tmp_info[512];
addonList[temp_type].info((char *)tmp_info);
SetWindowText(GetDlgItem(dialog, IDC_ADDONS_INFO), (char *)tmp_info);
SetWindowText(GetDlgItem(dialog, IDC_ADDONS_INFO), slot2_List[temp_type]->info()->descr());
_OKbutton = false;
wndConfig=CreateDialogW(hAppInst, MAKEINTRESOURCEW(GBAslot_IDDs[temp_type]),
@ -497,7 +495,7 @@ BOOL CALLBACK GbaSlotBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
case IDOK:
{
int Msg = IDYES;
if (romloaded && (needReset || (temp_type!=addon_type)) )
if (romloaded && (needReset || (temp_type!=slot2_GetCurrentType())) )
{
Msg = MessageBox(dialog,
"After change GBA slot pak game will reset!\nAre you sure to continue?", "DeSmuME",
@ -530,9 +528,7 @@ BOOL CALLBACK GbaSlotBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
EnableWindow(OKbutton, TRUE);
else
EnableWindow(OKbutton, FALSE);
u8 tmp_info[512];
addonList[temp_type].info((char *)tmp_info);
SetWindowText(GetDlgItem(dialog, IDC_ADDONS_INFO), (char *)tmp_info);
SetWindowText(GetDlgItem(dialog, IDC_ADDONS_INFO), slot2_List[temp_type]->info()->descr());
last_type = temp_type;
}
}
@ -546,7 +542,7 @@ BOOL CALLBACK GbaSlotBox_Proc(HWND dialog, UINT msg,WPARAM wparam,LPARAM lparam)
void GBAslotDialog(HWND hwnd)
{
temp_type = addon_type;
temp_type = (u8)slot2_GetCurrentType();
last_type = temp_type;
strcpy(tmp_cflash_filename, win32_CFlash_cfgFileName.c_str());
strcpy(tmp_cflash_path, win32_CFlash_cfgDirectory.c_str());
@ -556,95 +552,96 @@ void GBAslotDialog(HWND hwnd)
tmp_CFlashMode = CFlash_Mode;
_OKbutton = false;
needReset = true;
u32 res=DialogBoxW(hAppInst, MAKEINTRESOURCEW(IDD_GBASLOT), hwnd, (DLGPROC) GbaSlotBox_Proc);
if (res)
{
switch (temp_type)
{
case NDS_ADDON_NONE:
if (temp_type != addon_type)
case NDS_SLOT2_NONE:
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
break;
case NDS_ADDON_CFLASH:
case NDS_SLOT2_CFLASH:
//save current values for win32 configuration
win32_CFlash_cfgMode = tmp_CFlashMode;
win32_CFlash_cfgDirectory = tmp_cflash_path;
win32_CFlash_cfgFileName = tmp_cflash_filename;
WritePrivateProfileInt("GBAslot.CFlash","fileMode",tmp_CFlashMode,IniName);
WritePrivateProfileString("GBAslot.CFlash","path",tmp_cflash_path,IniName);
WritePrivateProfileString("GBAslot.CFlash","filename",tmp_cflash_filename,IniName);
WritePrivateProfileInt("Slot2.CFlash","fileMode",tmp_CFlashMode,IniName);
WritePrivateProfileString("Slot2.CFlash","path",tmp_cflash_path,IniName);
WritePrivateProfileString("Slot2.CFlash","filename",tmp_cflash_filename,IniName);
WIN_InstallCFlash();
needReset = true;
break;
case NDS_ADDON_RUMBLEPAK:
if (temp_type != addon_type)
case NDS_SLOT2_RUMBLEPAK:
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
break;
case NDS_ADDON_PADDLE:
if (temp_type != addon_type)
case NDS_SLOT2_PADDLE:
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
break;
case NDS_ADDON_GBAGAME:
case NDS_SLOT2_GBACART:
strcpy(GBAgameName, tmp_gbagame_filename);
WritePrivateProfileString("GBAslot.GBAgame","filename",GBAgameName,IniName);
WritePrivateProfileString("Slot2.GBAgame","filename",GBAgameName,IniName);
needReset = true;
break;
case NDS_ADDON_GUITARGRIP:
case NDS_SLOT2_GUITARGRIP:
memcpy(&Guitar, &tmp_Guitar, sizeof(tmp_Guitar));
Guitar.Enabled = true;
WritePrivateProfileInt("GBAslot.GuitarGrip","green",Guitar.GREEN,IniName);
WritePrivateProfileInt("GBAslot.GuitarGrip","red",Guitar.RED,IniName);
WritePrivateProfileInt("GBAslot.GuitarGrip","yellow",Guitar.YELLOW,IniName);
WritePrivateProfileInt("GBAslot.GuitarGrip","blue",Guitar.BLUE,IniName);
if (temp_type != addon_type)
WritePrivateProfileInt("Slot2.GuitarGrip","green",Guitar.GREEN,IniName);
WritePrivateProfileInt("Slot2.GuitarGrip","red",Guitar.RED,IniName);
WritePrivateProfileInt("Slot2.GuitarGrip","yellow",Guitar.YELLOW,IniName);
WritePrivateProfileInt("Slot2.GuitarGrip","blue",Guitar.BLUE,IniName);
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
break;
case NDS_ADDON_PIANO:
case NDS_SLOT2_EASYPIANO:
memcpy(&Piano, &tmp_Piano, sizeof(tmp_Piano));
Piano.Enabled = true;
WritePrivateProfileInt("GBAslot.Piano","C",Piano.C,IniName);
WritePrivateProfileInt("GBAslot.Piano","CS",Piano.CS,IniName);
WritePrivateProfileInt("GBAslot.Piano","D",Piano.D,IniName);
WritePrivateProfileInt("GBAslot.Piano","DS",Piano.DS,IniName);
WritePrivateProfileInt("GBAslot.Piano","E",Piano.E,IniName);
WritePrivateProfileInt("GBAslot.Piano","F",Piano.F,IniName);
WritePrivateProfileInt("GBAslot.Piano","FS",Piano.FS,IniName);
WritePrivateProfileInt("GBAslot.Piano","G",Piano.G,IniName);
WritePrivateProfileInt("GBAslot.Piano","GS",Piano.GS,IniName);
WritePrivateProfileInt("GBAslot.Piano","A",Piano.A,IniName);
WritePrivateProfileInt("GBAslot.Piano","AS",Piano.AS,IniName);
WritePrivateProfileInt("GBAslot.Piano","B",Piano.B,IniName);
WritePrivateProfileInt("GBAslot.Piano","HIC",Piano.HIC,IniName);
if (temp_type != addon_type)
WritePrivateProfileInt("Slot2.Piano","C",Piano.C,IniName);
WritePrivateProfileInt("Slot2.Piano","CS",Piano.CS,IniName);
WritePrivateProfileInt("Slot2.Piano","D",Piano.D,IniName);
WritePrivateProfileInt("Slot2.Piano","DS",Piano.DS,IniName);
WritePrivateProfileInt("Slot2.Piano","E",Piano.E,IniName);
WritePrivateProfileInt("Slot2.Piano","F",Piano.F,IniName);
WritePrivateProfileInt("Slot2.Piano","FS",Piano.FS,IniName);
WritePrivateProfileInt("Slot2.Piano","G",Piano.G,IniName);
WritePrivateProfileInt("Slot2.Piano","GS",Piano.GS,IniName);
WritePrivateProfileInt("Slot2.Piano","A",Piano.A,IniName);
WritePrivateProfileInt("Slot2.Piano","AS",Piano.AS,IniName);
WritePrivateProfileInt("Slot2.Piano","B",Piano.B,IniName);
WritePrivateProfileInt("Slot2.Piano","HIC",Piano.HIC,IniName);
if (temp_type != slot2_GetCurrentType())
needReset = true;
else
needReset = false;
break;
case NDS_ADDON_EXPMEMORY:
case NDS_SLOT2_EXPMEMORY:
break;
case NDS_ADDON_PASSME:
case NDS_SLOT2_PASSME:
break;
default:
return;
}
if (temp_type!=NDS_ADDON_GUITARGRIP)
if (temp_type!=NDS_SLOT2_GUITARGRIP)
Guitar.Enabled = false;
WritePrivateProfileInt("GBAslot","type",temp_type,IniName);
WritePrivateProfileInt("Slot2","type",temp_type,IniName);
addon_type = (NDS_ADDON_TYPE)temp_type;
addonsChangePak(addon_type);
slot2_Change((NDS_SLOT2_TYPE)temp_type);
if (romloaded && needReset)
NDS_Reset();
return;
}
}
}

View File

@ -49,7 +49,7 @@
#include "main.h"
#include "resource.h"
#include "common.h"
#include "../addons.h"
#include "../slot2.h"
#include "../NDSSystem.h"
#define DIRECTINPUT_VERSION 0x0800
@ -365,7 +365,7 @@ static void ReadHotkey(const char* name, WORD& output)
static void ReadGuitarControl(const char* name, WORD& output)
{
UINT temp;
temp = GetPrivateProfileInt("GBAslot.GuitarGrip",name,-1,IniName);
temp = GetPrivateProfileInt("Slot2.GuitarGrip",name,-1,IniName);
if(temp != -1) {
output = temp;
}
@ -374,7 +374,7 @@ static void ReadGuitarControl(const char* name, WORD& output)
static void ReadPianoControl(const char* name, WORD& output)
{
UINT temp;
temp = GetPrivateProfileInt("GBAslot.Piano",name,-1,IniName);
temp = GetPrivateProfileInt("Slot2.Piano",name,-1,IniName);
if(temp != -1) {
output = temp;
}

View File

@ -45,7 +45,7 @@
#include "../debug.h"
#include "../saves.h"
#include "../slot1.h"
#include "../addons.h"
#include "../slot2.h"
#include "../GPU_osd.h"
#include "../OGLRender.h"
#include "../OGLRender_3_2.h"
@ -3132,8 +3132,8 @@ int _main()
input_init();
if (addon_type == NDS_ADDON_GUITARGRIP) Guitar.Enabled = true;
if (addon_type == NDS_ADDON_PIANO) Piano.Enabled = true;
if (slot2_GetCurrentType() == NDS_SLOT2_GUITARGRIP) Guitar.Enabled = true;
if (slot2_GetCurrentType() == NDS_SLOT2_EASYPIANO) Piano.Enabled = true;
LOG("Init NDS\n");
@ -3158,11 +3158,11 @@ int _main()
cmdline._slot1_fat_dir_type = 0;
slot1_R4_path_type = cmdline._slot1_fat_dir_type;
addon_type = (NDS_ADDON_TYPE)GetPrivateProfileInt("GBAslot", "type", NDS_ADDON_NONE, IniName);
win32_CFlash_cfgMode = GetPrivateProfileInt("GBAslot.CFlash", "fileMode", 2, IniName);
win32_CFlash_cfgDirectory = GetPrivateProfileStdString("GBAslot.CFlash", "path", "");
win32_CFlash_cfgFileName = GetPrivateProfileStdString("GBAslot.CFlash", "filename", "");
GetPrivateProfileString("GBAslot.GBAgame", "filename", "", GBAgameName, MAX_PATH, IniName);
int slot2_device_type = (NDS_SLOT2_TYPE)GetPrivateProfileInt("Slot2", "type", NDS_SLOT1_NONE, IniName);
win32_CFlash_cfgMode = GetPrivateProfileInt("Slot2.CFlash", "fileMode", 2, IniName);
win32_CFlash_cfgDirectory = GetPrivateProfileStdString("Slot2.CFlash", "path", "");
win32_CFlash_cfgFileName = GetPrivateProfileStdString("Slot2.CFlash", "filename", "");
GetPrivateProfileString("Slot2.GBAgame", "filename", "", GBAgameName, MAX_PATH, IniName);
cmdline.process_addonCommands();
WIN_InstallCFlash();
@ -3171,7 +3171,7 @@ int _main()
if(cmdline.is_cflash_configured)
{
addon_type = NDS_ADDON_CFLASH;
slot2_device_type = NDS_SLOT2_CFLASH;
//push the commandline-provided options into the current config slots
if(CFlash_Mode == ADDON_CFLASH_MODE_Path)
win32_CFlash_cfgDirectory = CFlash_Path;
@ -3179,47 +3179,7 @@ int _main()
win32_CFlash_cfgFileName = CFlash_Path;
}
if(cmdline.gbaslot_rom != "")
{
addon_type = NDS_ADDON_GBAGAME;
strcpy(GBAgameName, cmdline.gbaslot_rom.c_str());
}
switch (addon_type)
{
case NDS_ADDON_NONE:
break;
case NDS_ADDON_CFLASH:
break;
case NDS_ADDON_RUMBLEPAK:
break;
case NDS_ADDON_GBAGAME:
if (!strlen(GBAgameName))
{
addon_type = NDS_ADDON_NONE;
break;
}
// TODO: check for file exist
break;
case NDS_ADDON_GUITARGRIP:
break;
case NDS_ADDON_EXPMEMORY:
break;
case NDS_ADDON_PIANO:
break;
case NDS_ADDON_PADDLE:
break;
case NDS_ADDON_PASSME:
break;
default:
addon_type = NDS_ADDON_NONE;
break;
}
addonsChangePak(addon_type);
slot1_Init();
//override slot1 type with commandline, if present
int slot1_device_type = (NDS_SLOT1_TYPE)GetPrivateProfileInt("Slot1", "type", NDS_SLOT1_RETAIL_AUTO, IniName);
if(cmdline.slot1 != "")
@ -3227,6 +3187,47 @@ int _main()
else
slot1_Change((NDS_SLOT1_TYPE)slot1_device_type);
//slot2_device_type = NDS_SLOT2_GBACART; // ====================================
slot2_Init();
if(cmdline.gbaslot_rom != "")
{
slot2_device_type = NDS_SLOT2_GBACART;
strcpy(GBAgameName, cmdline.gbaslot_rom.c_str());
}
switch (slot2_device_type)
{
case NDS_SLOT2_NONE:
break;
case NDS_SLOT2_CFLASH:
break;
case NDS_SLOT2_RUMBLEPAK:
break;
case NDS_SLOT2_GBACART:
if (!strlen(GBAgameName))
{
slot2_device_type = NDS_SLOT2_NONE;
break;
}
// TODO: check for file exist
break;
case NDS_SLOT2_GUITARGRIP:
break;
case NDS_SLOT2_EXPMEMORY:
break;
case NDS_SLOT2_EASYPIANO:
break;
case NDS_SLOT2_PADDLE:
break;
case NDS_SLOT2_PASSME:
break;
default:
slot2_device_type = NDS_SLOT2_NONE;
break;
}
slot2_Change((NDS_SLOT2_TYPE)slot2_device_type);
CommonSettings.wifi.mode = GetPrivateProfileInt("Wifi", "Mode", 0, IniName);
CommonSettings.wifi.infraBridgeAdapter = GetPrivateProfileInt("Wifi", "BridgeAdapter", 0, IniName);
@ -7157,7 +7158,6 @@ void WIN_InstallCFlash()
CFlash_Path = "";
CFlash_Mode = ADDON_CFLASH_MODE_RomPath;
}
}
// ================================================================= DDraw