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