bizswan: rotated display, lag frames, stuff
This commit is contained in:
parent
cc4df67923
commit
14f0faf7ff
|
@ -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;
|
||||
|
|
|
@ -41,8 +41,9 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
|||
/// <param name="surface">uint32 video output buffer</param>
|
||||
/// <param name="soundbuff">int16 sound output buffer</param>
|
||||
/// <param name="soundbuffsize">[In] max hold size of soundbuff [Out] number of samples actually deposited</param>
|
||||
/// <returns>true if lagged</returns>
|
||||
[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);
|
||||
|
||||
/// <summary>
|
||||
/// load rom
|
||||
|
@ -51,9 +52,10 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
|||
/// <param name="data"></param>
|
||||
/// <param name="length"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="IsRotated">(out) true if screen is rotated left 90</param>
|
||||
/// <returns></returns>
|
||||
[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);
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
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*/
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
uint8 *wsSRAM; // = NULL;
|
||||
|
||||
uint16 WSButtonStatus; // bitfield of buttons, indeed
|
||||
bool Lagged;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue