SG-1000 progress (try doki doki penguin land)

This commit is contained in:
beirich 2011-01-19 07:06:14 +00:00
parent 8d0ff04b4b
commit 3c019b9e96
4 changed files with 112 additions and 11 deletions

View File

@ -107,7 +107,7 @@ namespace BizHawk.Emulation.Consoles.Sega
{
if (DisplayOn == false) return;
int SpriteBase = SpriteAttributeTableBase;
int SpriteHeight = Enable8x16Sprites ? 16 : 8;
int SpriteHeight = EnableLargeSprites ? 16 : 8;
// Clear the sprite collision buffer for this scanline
Array.Clear(SpriteCollisionBuffer, 0, 256);
@ -136,13 +136,13 @@ namespace BizHawk.Emulation.Consoles.Sega
x -= 8;
int y = VRAM[SpriteBase + i] + 1;
if (y >= (Enable8x16Sprites ? 240 : 248)) y -= 256;
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
if (y + SpriteHeight <= ScanLine || y > ScanLine)
continue;
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
if (Enable8x16Sprites)
if (EnableLargeSprites)
tileNo &= 0xFE;
tileNo += SpriteTileBase;
@ -167,7 +167,7 @@ namespace BizHawk.Emulation.Consoles.Sega
{
if (DisplayOn == false) return;
int SpriteBase = SpriteAttributeTableBase;
int SpriteHeight = Enable8x16Sprites ? 16 : 8;
int SpriteHeight = EnableLargeSprites ? 16 : 8;
// Clear the sprite collision buffer for this scanline
Array.Clear(SpriteCollisionBuffer, 0, 256);
@ -196,13 +196,13 @@ namespace BizHawk.Emulation.Consoles.Sega
x -= 8;
int y = VRAM[SpriteBase + i] + 1;
if (y >= (Enable8x16Sprites ? 240 : 248)) y -= 256;
if (y >= (EnableLargeSprites ? 240 : 248)) y -= 256;
if (y + (SpriteHeight*2) <= ScanLine || y > ScanLine)
continue;
int tileNo = VRAM[SpriteBase + 0x80 + (i * 2) + 1];
if (Enable8x16Sprites)
if (EnableLargeSprites)
tileNo &= 0xFE;
tileNo += SpriteTileBase;

View File

@ -1,5 +1,7 @@
// Contains rendering functions for legacy TMS9918 modes.
using System;
namespace BizHawk.Emulation.Consoles.Sega
{
public partial class VDP
@ -29,8 +31,8 @@ namespace BizHawk.Emulation.Consoles.Sega
int yc = ScanLine/8;
int yofs = ScanLine%8;
int FrameBufferOffset = ScanLine*256;
int PatternNameOffset = mystery_pn + (yc*32);
int PatternNameOffset = TmsPatternNameTableBase + (yc*32);
for (int xc=0; xc<32; xc++)
{
int pn = VRAM[PatternNameOffset++];
@ -49,5 +51,90 @@ namespace BizHawk.Emulation.Consoles.Sega
FrameBuffer[FrameBufferOffset++] = ((pv & 0x01) > 0) ? fgColor : bgColor;
}
}
private void RenderBackgroundM2()
{
int yrow = ScanLine/8;
int yofs = ScanLine%8;
int FrameBufferOffset = ScanLine*256;
int PatternNameOffset = TmsPatternNameTableBase + (yrow*32);
int PatternGeneratorOffset = (((Registers[4] & 4) << 11) & 0x2000);// +((yrow / 8) * 0x100);
int ColorOffset = (ColorTableBase & 0x2000);// +((yrow / 8) * 0x100);
for (int xc=0; xc<32; xc++)
{
int pn = VRAM[PatternNameOffset++];
int pv = VRAM[PatternGeneratorOffset + (pn * 8) + yofs];
int colorEntry = VRAM[ColorOffset + (pn * 8) + yofs];
int fgColor = PaletteTMS9918[(colorEntry >> 4 & 0x0F)];
int bgColor = PaletteTMS9918[(colorEntry & 0x0F)];
FrameBuffer[FrameBufferOffset++] = ((pv & 0x80) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x40) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x20) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x10) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x08) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x04) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x02) > 0) ? fgColor : bgColor;
FrameBuffer[FrameBufferOffset++] = ((pv & 0x01) > 0) ? fgColor : bgColor;
}
}
private void RenderTmsSprites()
{
Array.Clear(ScanlinePriorityBuffer, 0, 256);
Array.Clear(SpriteCollisionBuffer, 0, 256);
bool Double = EnableDoubledSprites;
bool LargeSprites = EnableLargeSprites;
int SpriteSize = 8;
if (LargeSprites) SpriteSize *= 2;
if (Double) SpriteSize *= 2;
int OneCellSize = Double ? 16 : 8;
int NumSpritesOnScanline = 0;
for (int i=0; i<32; i++)
{
int SpriteBase = TmsSpriteAttributeBase + (i*4);
int y = VRAM[SpriteBase++];
int x = VRAM[SpriteBase++];
int Pattern = VRAM[SpriteBase++];
int Color = VRAM[SpriteBase];
if (y == 208) break; // terminator sprite
if (y > 224) y -= 256; // sprite Y wrap
y++; // inexplicably, sprites start on Y+1
if (y > ScanLine || y + SpriteSize <= ScanLine) continue; // sprite is not on this scanline
if ((Color & 0x80) > 0) x -= 32; // Early Clock adjustment
if (++NumSpritesOnScanline == 5)
{
StatusByte |= (byte) i; // set 5th sprite index
StatusByte |= 0x40; // set overflow bit
break;
}
if (LargeSprites) Pattern &= 0xFC; // 16x16 sprites forced to 4-byte alignment
int SpriteLine = ScanLine - y;
if (Double) SpriteLine /= 2;
byte pv = VRAM[SpritePatternGeneratorBase + (Pattern*8) + SpriteLine];
for (int xp = 0; xp < SpriteSize && x + xp < 256; xp++)
{
if (x+xp < 0) continue;
if (LargeSprites && xp == OneCellSize)
pv = VRAM[SpritePatternGeneratorBase + (Pattern * 8) + SpriteLine + 16];
if ((pv & (1 << (7 - (xp & 7)))) > 0)
{
if (Color != 0)
FrameBuffer[(ScanLine * 256) + x + xp] = PaletteTMS9918[Color & 0x0F];
}
}
}
}
}
}

View File

@ -48,7 +48,7 @@ namespace BizHawk.Emulation.Consoles.Sega
public bool HorizScrollLock { get { return (Registers[0] & 64) > 0; } }
public bool VerticalScrollLock { get { return (Registers[0] & 128) > 0; } }
public bool EnableDoubledSprites { get { return (Registers[1] & 1) > 0; } }
public bool Enable8x16Sprites { get { return (Registers[1] & 2) > 0; } }
public bool EnableLargeSprites { get { return (Registers[1] & 2) > 0; } }
public bool EnableFrameInterrupts { get { return (Registers[1] & 32) > 0; } }
public bool DisplayOn { get { return (Registers[1] & 64) > 0; } }
public int SpriteAttributeTableBase { get { return ((Registers[5] >> 1) << 8) & 0x3FFF; } }
@ -59,7 +59,8 @@ namespace BizHawk.Emulation.Consoles.Sega
private int ColorTableBase;
private int PatternGeneratorBase;
private int SpritePatternGeneratorBase;
private int mystery_pn;
private int TmsPatternNameTableBase;
private int TmsSpriteAttributeBase;
// preprocessed state assist stuff.
public int[] Palette = new int[32];
@ -288,7 +289,7 @@ namespace BizHawk.Emulation.Consoles.Sega
break;
case 2: // Name Table Base Address
NameTableBase = CalcNameTableBase();
mystery_pn = (Registers[2] << 10) & 0x3C00;
TmsPatternNameTableBase = (Registers[2] << 10) & 0x3C00;
break;
case 3: // Color Table Base Address
ColorTableBase = (Registers[3] << 6) & 0x3FC0;
@ -298,6 +299,7 @@ namespace BizHawk.Emulation.Consoles.Sega
break;
case 5: // Sprite Attribute Table Base Address
// ??? should I move from my property to precalculated?
TmsSpriteAttributeBase = (Registers[5] << 7) & 0x3F80;
break;
case 6: // Sprite Pattern Generator Base Adderss
SpritePatternGeneratorBase = (Registers[6] << 11) & 0x3800;
@ -369,6 +371,7 @@ namespace BizHawk.Emulation.Consoles.Sega
RenderBlankingRegions();
}
}
internal void RenderCurrentScanline(bool render)
{
if (ScanLine >= FrameHeight)
@ -383,6 +386,9 @@ namespace BizHawk.Emulation.Consoles.Sega
RenderSpritesCurrentLineDoubleSize();
else
RenderSpritesCurrentLine();
} else if (TmsMode == 2) {
RenderBackgroundM2();
RenderTmsSprites();
} else if (TmsMode == 0) {
RenderBackgroundM0();
}

View File

@ -80,6 +80,8 @@ namespace BizHawk.MultiClient
{
case "SMS": return "SMS/SaveRAM/" + Name + ".SaveRAM";
case "GG": return "Game Gear/SaveRAM/" + Name + ".SaveRAM";
case "SG": return "SG-1000/SaveRAM/" + Name + ".SaveRAM";
case "SGX": return "TurboGrafx/SaveRAM/" + Name + ".SaveRAM";
case "PCE": return "TurboGrafx/SaveRAM/" + Name + ".SaveRAM";
case "GB": return "Gameboy/SaveRAM/" + Name + ".SaveRAM";
case "GEN": return "Genesis/SaveRAM/" + Name + ".SaveRAM";
@ -97,7 +99,9 @@ namespace BizHawk.MultiClient
{
case "SMS": return "SMS/State/" + Name;
case "GG": return "Game Gear/State/" + Name;
case "SG": return "SG-1000/State/" + Name;
case "PCE": return "TurboGrafx/State/" + Name;
case "SGX": return "TurboGrafx/State/" + Name;
case "GB": return "Gameboy/State/" + Name;
case "GEN": return "Genesis/State/" + Name;
case "NES": return "NES/State/" + Name;
@ -115,7 +119,9 @@ namespace BizHawk.MultiClient
{
case "SMS": return "SMS/Movie/" + Name;
case "GG": return "Game Gear/Movie/" + Name;
case "SG": return "SG-1000/Movie/" + Name;
case "PCE": return "TurboGrafx/Movie/" + Name;
case "SGX": return "TurboGrafx/Movie/" + Name;
case "GB": return "Gameboy/Movie/" + Name;
case "GEN": return "Genesis/Movie/" + Name;
case "NES": return "NES/Movie/" + Name;
@ -132,7 +138,9 @@ namespace BizHawk.MultiClient
{
case "SMS": return "SMS/Screenshot/" + Name;
case "GG": return "Game Gear/Screenshot/" + Name;
case "SG": return "SG-1000/Screenshot/" + Name;
case "PCE": return "TurboGrafx/Screenshot/" + Name;
case "SGX": return "TurboGrafx/Screenshot/" + Name;
case "GB": return "Gameboy/Screenshot/" + Name;
case "GEN": return "Genesis/Screenshot/" + Name;
case "NES": return "NES/Screenshot/" + Name;