diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index 0c1bdf73a3..6a5a924e10 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -139,7 +139,7 @@ namespace BizHawk.Client.Common using (var file = new HawkFile()) { - var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64" }; + var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64", "WS", "WSC" }; // lets not use this unless we need to // file.NonArchiveExtensions = romExtensions; diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs index 8de62ee32e..21a1a86e38 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs @@ -41,8 +41,9 @@ namespace BizHawk.Emulation.Cores.WonderSwan /// uint32 video output buffer /// int16 sound output buffer /// [In] max hold size of soundbuff [Out] number of samples actually deposited + /// true if lagged [DllImport(dd, CallingConvention = cc)] - public static extern void bizswan_advance(IntPtr core, Buttons buttons, bool novideo, int[] surface, short[] soundbuff, ref int soundbuffsize); + public static extern bool bizswan_advance(IntPtr core, Buttons buttons, bool novideo, int[] surface, short[] soundbuff, ref int soundbuffsize); /// /// load rom @@ -51,9 +52,10 @@ namespace BizHawk.Emulation.Cores.WonderSwan /// /// /// + /// (out) true if screen is rotated left 90 /// [DllImport(dd, CallingConvention = cc)] - public static extern bool bizswan_load(IntPtr core, byte[] data, int length, [In] ref SyncSettings settings); + public static extern bool bizswan_load(IntPtr core, byte[] data, int length, [In] ref SyncSettings settings, ref bool IsRotated); /// /// get size of saveram @@ -95,8 +97,8 @@ namespace BizHawk.Emulation.Cores.WonderSwan DownY = 0x0040, LeftY = 0x0080, Start = 0x0100, - B = 0x0200, - A = 0x0400, + A = 0x0200, + B = 0x0400, } public enum Language : byte @@ -131,8 +133,6 @@ namespace BizHawk.Emulation.Cores.WonderSwan public Gender sex; public Bloodtype blood; [MarshalAs(UnmanagedType.U1)] - public bool rotateinput; - [MarshalAs(UnmanagedType.U1)] public bool color; // true for color system [MarshalAs(UnmanagedType.U1)] public bool userealtime; // true for use real real RTC instead of emulation pegged time diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs index ce15e8f2eb..9dc4a6c279 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs @@ -54,20 +54,23 @@ namespace BizHawk.Emulation.Cores.WonderSwan sex = BizSwan.Gender.Male, blood = BizSwan.Bloodtype.A, language = BizSwan.Language.Japanese, - rotateinput = false, // TODO bday = 5, bmonth = 12, byear = 1968 }; ss.SetName("LaForge"); - if (!BizSwan.bizswan_load(Core, rom, rom.Length, ref ss)) + bool rotate = false; + + if (!BizSwan.bizswan_load(Core, rom, rom.Length, ref ss, ref rotate)) throw new InvalidOperationException("bizswan_load() returned FALSE!"); CoreComm.VsyncNum = 3072000; // master CPU clock, also pixel clock CoreComm.VsyncDen = (144 + 15) * (224 + 32); // 144 vislines, 15 vblank lines; 224 vispixels, 32 hblank pixels saverambuff = new byte[BizSwan.bizswan_saveramsize(Core)]; + + InitVideo(rotate); } catch { @@ -94,12 +97,11 @@ namespace BizHawk.Emulation.Cores.WonderSwan BizSwan.bizswan_reset(Core); int soundbuffsize = sbuff.Length; - BizSwan.bizswan_advance(Core, GetButtons(), !render, vbuff, sbuff, ref soundbuffsize); + IsLagFrame = BizSwan.bizswan_advance(Core, GetButtons(), !render, vbuff, sbuff, ref soundbuffsize); if (soundbuffsize == sbuff.Length) throw new Exception(); sbuffcontains = soundbuffsize; - IsLagFrame = false; // TODO if (IsLagFrame) LagCount++; } @@ -226,6 +228,20 @@ namespace BizHawk.Emulation.Cores.WonderSwan public IVideoProvider VideoProvider { get { return this; } } + void InitVideo(bool rotate) + { + if (rotate) + { + BufferWidth = 144; + BufferHeight = 224; + } + else + { + BufferWidth = 224; + BufferHeight = 144; + } + } + private int[] vbuff = new int[224 * 144]; public int[] GetVideoBuffer() @@ -233,10 +249,10 @@ namespace BizHawk.Emulation.Cores.WonderSwan return vbuff; } - public int VirtualWidth { get { return 224; } } - public int VirtualHeight { get { return 144; } } - public int BufferWidth { get { return 224; } } - public int BufferHeight { get { return 144; } } + public int VirtualWidth { get { return BufferWidth; } } + public int VirtualHeight { get { return BufferHeight; } } + public int BufferWidth { get; private set; } + public int BufferHeight { get; private set; } public int BackgroundColor { get { return unchecked((int)0xff000000); } } #endregion diff --git a/output/dll/bizswan.dll b/output/dll/bizswan.dll index 97f73d2a6e..654c4169c0 100644 Binary files a/output/dll/bizswan.dll and b/output/dll/bizswan.dll differ diff --git a/wonderswan/gfx.cpp b/wonderswan/gfx.cpp index 43603ebf40..0b8fc5cc0a 100644 --- a/wonderswan/gfx.cpp +++ b/wonderswan/gfx.cpp @@ -154,18 +154,17 @@ namespace MDFN_IEN_WSWAN bool GFX::ExecuteLine(uint32 *surface, bool skip) { - //static const void* const WEP_Tab[3] = { &&WEP0, &&WEP1, &&WEP2 }; // The things we do for debugger step mode save states! If we ever add more entries, remember to change the mask stuff in StateAction - bool ret; - -// weppy = 0; -//WEP0: ; - - ret = FALSE; + bool ret = false; // true if we finish frame here if(wsLine < 144) { if(!skip) - Scanline(surface + wsLine * 224); + { + if (sys->rotate) + Scanline(surface + 223 * 144 + wsLine); + else + Scanline(surface + wsLine * 224); + } } sys->memory.CheckSoundDMA(); @@ -183,7 +182,7 @@ namespace MDFN_IEN_WSWAN if(wsLine == 144) { - ret = TRUE; + ret = true; sys->interrupt.DoInterrupt(WSINT_VBLANK); //printf("VBlank: %d\n", wsLine); } @@ -201,10 +200,9 @@ namespace MDFN_IEN_WSWAN } } -// weppy = 1; + // CPU ========================== sys->cpu.execute(224); -// goto *WEP_Tab[weppy]; -//WEP1: ; + // CPU ========================== wsLine = (wsLine + 1) % 159; if(wsLine == LineCompare) @@ -213,10 +211,9 @@ namespace MDFN_IEN_WSWAN //printf("Line hit: %d\n", wsLine); } -// weppy = 2; + // CPU ========================== sys->cpu.execute(32); -// goto *WEP_Tab[weppy]; -//WEP2: ; + // CPU ========================== sys->rtc.Clock(256); @@ -236,8 +233,7 @@ namespace MDFN_IEN_WSWAN wsLine = 0; } -// weppy = 0; - return(ret); + return ret; } void GFX::SetLayerEnableMask(uint32 mask) @@ -248,7 +244,9 @@ namespace MDFN_IEN_WSWAN void GFX::SetPixelFormat() { for(int r = 0; r < 16; r++) + { for(int g = 0; g < 16; g++) + { for(int b = 0; b < 16; b++) { uint32 neo_r, neo_g, neo_b; @@ -270,6 +268,8 @@ namespace MDFN_IEN_WSWAN ColorMapG[i] = 0xff000000 | neo_r << 16 | neo_g << 8 | neo_b << 0; } + } + } } void GFX::Scanline(uint32 *target) @@ -537,15 +537,23 @@ namespace MDFN_IEN_WSWAN } // End sprite drawing + const int hinc = sys->rotate ? -144 : 1; + if(wsVMode) { for(l=0;l<224;l++) - target[l] = ColorMap[wsCols[b_bg_pal[l+7]][b_bg[(l+7)]&0xf]]; + { + target[0] = ColorMap[wsCols[b_bg_pal[l+7]][b_bg[(l+7)]&0xf]]; + target += hinc; + } } else { for(l=0;l<224;l++) - target[l] = ColorMapG[(b_bg[l+7])&15]; + { + target[0] = ColorMapG[(b_bg[l+7])&15]; + target += hinc; + } } } @@ -556,11 +564,10 @@ namespace MDFN_IEN_WSWAN void GFX::Reset() { - //weppy = 0; - wsLine=145; // all frames same length - SetVideo(0,TRUE); + wsLine = 145; // all frames same length + SetVideo(0, true); - memset(SpriteTable, 0, sizeof(SpriteTable)); + std::memset(SpriteTable, 0, sizeof(SpriteTable)); SpriteCountCache = 0; DispControl = 0; BGColor = 0; @@ -592,11 +599,7 @@ namespace MDFN_IEN_WSWAN HBCounter = 0; VBCounter = 0; - - for(int u0=0;u0<16;u0++) - for(int u1=0;u1<16;u1++) - wsCols[u0][u1]=0; - + std::memset(wsCols, 0, sizeof(wsCols)); } } diff --git a/wonderswan/mednafen/types.h b/wonderswan/mednafen/types.h index 4e2b24f631..570f96aa90 100644 --- a/wonderswan/mednafen/types.h +++ b/wonderswan/mednafen/types.h @@ -195,6 +195,6 @@ typedef unsigned char Boolean; /* 0 or 1 */ #error "Define MSB_FIRST or LSB_FIRST!" #endif -#include "error.h" +//#include "error.h" #endif diff --git a/wonderswan/memory.cpp b/wonderswan/memory.cpp index 1f76c4c576..5389f90209 100644 --- a/wonderswan/memory.cpp +++ b/wonderswan/memory.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include namespace MDFN_IEN_WSWAN @@ -256,6 +256,7 @@ namespace MDFN_IEN_WSWAN case 0xB3: CommControl = V & 0xF0; break; case 0xb5: ButtonWhich = V >> 4; + Lagged = false; ButtonReadLatch = 0; if(ButtonWhich & 0x4) /*buttons*/ diff --git a/wonderswan/memory.h b/wonderswan/memory.h index d2e94761b5..e9d938a316 100644 --- a/wonderswan/memory.h +++ b/wonderswan/memory.h @@ -30,6 +30,7 @@ public: uint8 *wsSRAM; // = NULL; uint16 WSButtonStatus; // bitfield of buttons, indeed + bool Lagged; private: diff --git a/wonderswan/rtc.cpp b/wonderswan/rtc.cpp index b621ba0a93..4423bce87a 100644 --- a/wonderswan/rtc.cpp +++ b/wonderswan/rtc.cpp @@ -26,10 +26,13 @@ namespace MDFN_IEN_WSWAN static void GMTime(uint64 ticks, tm &time) { time_t t = ticks; - #ifdef __GNUC__ - gmtime_r(&t, &time); - #elif defined _MSC_VER + #if defined _MSC_VER gmtime_s(&time, &t); + #elif defined __MINGW32__ + tm *tmp = gmtime(&t); + time = *tmp; + #elif defined __GNUC__ + gmtime_r(&t, &time); #endif } @@ -58,7 +61,7 @@ namespace MDFN_IEN_WSWAN { tm newtime; uint64 now = userealtime ? time(0) : CurrentTime; - GMTime(CurrentTime, newtime); + GMTime(now, newtime); switch(wsCA15) { diff --git a/wonderswan/sound.cpp b/wonderswan/sound.cpp index f484d8f1e5..a94a63ee11 100644 --- a/wonderswan/sound.cpp +++ b/wonderswan/sound.cpp @@ -260,9 +260,9 @@ namespace MDFN_IEN_WSWAN int ch = (A - 0x80) >> 1; if(A & 1) - return(period[ch] >> 8); + return period[ch] >> 8; else - return(period[ch]); + return (uint8)period[ch]; } else if(A >= 0x88 && A <= 0x8B) return(volume[A - 0x88]); @@ -320,7 +320,7 @@ namespace MDFN_IEN_WSWAN sbuf[i]->bass_freq(20); } - double eff_volume = 1.0 / 4; + double eff_volume = 0.1; //TOOLOUD 1.0 / 4; WaveSynth.volume(eff_volume); NoiseSynth.volume(eff_volume); diff --git a/wonderswan/system.cpp b/wonderswan/system.cpp index b94ded841c..549a666b05 100644 --- a/wonderswan/system.cpp +++ b/wonderswan/system.cpp @@ -65,10 +65,23 @@ namespace MDFN_IEN_WSWAN cpu.set_reg(NEC_SP,0x2000); } - - void System::Advance(uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize) + static uint16 RotateButtons(uint16 input) { - memory.WSButtonStatus = buttons; + int groupx = input & 0xf; + groupx <<= 1; + groupx |= groupx >> 4; + groupx &= 0x0f; + int groupy = input & 0xf0; + groupy <<= 1; + groupy |= groupy >> 4; + groupy &= 0xf0; + return input & 0xff00 | groupx | groupy; + } + + bool System::Advance(uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize) + { + memory.WSButtonStatus = rotate ? RotateButtons(buttons) : buttons; + memory.Lagged = true; while (!gfx.ExecuteLine(surface, novideo)) { } @@ -79,11 +92,12 @@ namespace MDFN_IEN_WSWAN // how is this OK to reset? it's only used by the sound code, so once the sound for the frame has // been collected, it's OK to zero. indeed, it should be done as there's no rollover protection cpu.timestamp = 0; + return memory.Lagged; } // Source: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 // Rounds up to the nearest power of 2. - static INLINE uint64 round_up_pow2(uint64 v) + static INLINE uint32 round_up_pow2(uint32 v) { v--; v |= v >> 1; @@ -91,7 +105,6 @@ namespace MDFN_IEN_WSWAN v |= v >> 4; v |= v >> 8; v |= v >> 16; - v |= v >> 32; v++; v += (v == 0); @@ -115,7 +128,6 @@ namespace MDFN_IEN_WSWAN return false; } - real_rom_size = (length + 0xFFFF) & ~0xFFFF; memory.rom_size = round_up_pow2(real_rom_size); @@ -186,14 +198,7 @@ namespace MDFN_IEN_WSWAN memory.wsCartROM[0xfffec]=0x20; } - - if(header[6] & 0x1) - { - //MDFNGameInfo->rotated = MDFN_ROTATE90; - } - - - //MDFNMP_Init(16384, (1 << 20) / 1024); + rotate = header[6] & 1; memory.Init(settings); @@ -229,7 +234,7 @@ namespace MDFN_IEN_WSWAN { } - int System::SaveRamSize() + int System::SaveRamSize() const { return eeprom.ieeprom_size + eeprom.eeprom_size + memory.sram_size; } @@ -249,7 +254,7 @@ namespace MDFN_IEN_WSWAN return true; } - bool System::SaveRamSave(uint8 *dest, int maxsize) + bool System::SaveRamSave(uint8 *dest, int maxsize) const { if (maxsize != SaveRamSize()) return false; @@ -280,14 +285,16 @@ namespace MDFN_IEN_WSWAN s->Reset(); } - EXPORT void bizswan_advance(System *s, uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int *soundbuffsize) + EXPORT int bizswan_advance(System *s, uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int *soundbuffsize) { - s->Advance(buttons, novideo, surface, soundbuff, *soundbuffsize); + return s->Advance(buttons, novideo, surface, soundbuff, *soundbuffsize); } - EXPORT int bizswan_load(System *s, const uint8 *data, int length, const SyncSettings *settings) + EXPORT int bizswan_load(System *s, const uint8 *data, int length, const SyncSettings *settings, int *IsRotated) { - return s->Load(data, length, *settings); + bool ret = s->Load(data, length, *settings); + *IsRotated = s->rotate; + return ret; } EXPORT int bizswan_saveramsize(System *s) diff --git a/wonderswan/system.h b/wonderswan/system.h index fad4f6cb40..69d13b048a 100644 --- a/wonderswan/system.h +++ b/wonderswan/system.h @@ -30,12 +30,12 @@ public: static void* operator new(std::size_t size); void Reset(); - void Advance(uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize); + bool Advance(uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize); bool Load(const uint8 *data, int length, const SyncSettings &s); - int SaveRamSize(); + int SaveRamSize() const; bool SaveRamLoad(const uint8 *data, int size); - bool SaveRamSave(uint8 *dest, int maxsize); + bool SaveRamSave(uint8 *dest, int maxsize) const; public: GFX gfx; @@ -45,6 +45,8 @@ public: Sound sound; V30MZ cpu; Interrupt interrupt; + + bool rotate; // rotate screen and controls left 90 }; struct SyncSettings @@ -56,7 +58,6 @@ struct SyncSettings uint8 language; // 0 = J, 1 = E; only affects "Digimon Tamers - Battle Spirit" uint8 sex; // sex, 1 = male, 2 = female uint8 blood; // 1 = a, 2 = b, 3 = o, 4 = ab - bool rotateinput; // true to rotate input and dpads, sync setting because of this bool color; // true if wonderswan is in color mode bool userealtime; // true to use the system's actual clock; false to use an emulation pegged clock uint64 initialtime; // when userealtime is false, the initial time in unix format