[virtualjaguar] proper mulitwidth support, fixes Doom
This commit is contained in:
parent
a59d66dfdd
commit
98be50057a
Binary file not shown.
|
@ -281,14 +281,8 @@ EXPORT void FrameAdvance(MyFrameInfo* f)
|
||||||
}
|
}
|
||||||
|
|
||||||
lagged = true;
|
lagged = true;
|
||||||
JaguarSetScreenPitch(TOMGetVideoModeWidth());
|
|
||||||
JaguarSetScreenBuffer(f->VideoBuffer);
|
|
||||||
|
|
||||||
JaguarExecuteNew();
|
JaguarExecuteNew();
|
||||||
|
TOMBlit(f->VideoBuffer, f->Width, f->Height);
|
||||||
JaguarSetScreenBuffer(nullptr);
|
|
||||||
f->Width = TOMGetVideoModeWidth();
|
|
||||||
f->Height = TOMGetVideoModeHeight();
|
|
||||||
|
|
||||||
u32 samples = 48000 / (vjs.hardwareTypeNTSC ? 60 : 50);
|
u32 samples = 48000 / (vjs.hardwareTypeNTSC ? 60 : 50);
|
||||||
SoundCallback(soundBuf, samples * 4);
|
SoundCallback(soundBuf, samples * 4);
|
||||||
|
|
|
@ -394,16 +394,6 @@ void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who)
|
||||||
JaguarWriteWord(offset+2, data & 0xFFFF, who);
|
JaguarWriteWord(offset+2, data & 0xFFFF, who);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JaguarSetScreenBuffer(uint32_t * buffer)
|
|
||||||
{
|
|
||||||
screenBuffer = buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JaguarSetScreenPitch(uint32_t pitch)
|
|
||||||
{
|
|
||||||
screenPitch = pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Jaguar console initialization
|
// Jaguar console initialization
|
||||||
//
|
//
|
||||||
|
@ -471,6 +461,7 @@ bool frameDone;
|
||||||
void JaguarExecuteNew(void)
|
void JaguarExecuteNew(void)
|
||||||
{
|
{
|
||||||
frameDone = false;
|
frameDone = false;
|
||||||
|
TOMStartFrame();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "memory.h" // For "UNKNOWN" enum
|
#include "memory.h" // For "UNKNOWN" enum
|
||||||
|
|
||||||
void JaguarSetScreenBuffer(uint32_t * buffer);
|
|
||||||
void JaguarSetScreenPitch(uint32_t pitch);
|
|
||||||
void JaguarInit(void);
|
void JaguarInit(void);
|
||||||
void JaguarReset(void);
|
void JaguarReset(void);
|
||||||
void JaguarDone(void);
|
void JaguarDone(void);
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
// JLH 01/20/2011 Change rendering to RGBA, removed unnecessary code
|
// JLH 01/20/2011 Change rendering to RGBA, removed unnecessary code
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "emulibc.h"
|
||||||
|
|
||||||
#include "tom.h"
|
#include "tom.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -84,8 +86,8 @@ int32_t tomTimerCounter;
|
||||||
uint16_t tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending,
|
uint16_t tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending,
|
||||||
tom_gpu_int_pending, tom_video_int_pending;
|
tom_gpu_int_pending, tom_video_int_pending;
|
||||||
|
|
||||||
uint32_t * screenBuffer;
|
static uint32_t * scanlines[256];
|
||||||
uint32_t screenPitch;
|
static uint32_t scanlineWidths[256];
|
||||||
|
|
||||||
typedef void (render_xxx_scanline_fn)(uint32_t *);
|
typedef void (render_xxx_scanline_fn)(uint32_t *);
|
||||||
|
|
||||||
|
@ -109,9 +111,9 @@ render_xxx_scanline_fn * scanline_render[] =
|
||||||
tom_render_16bpp_rgb_scanline
|
tom_render_16bpp_rgb_scanline
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t RGB16ToRGB32[0x10000];
|
static uint32_t RGB16ToRGB32[0x10000];
|
||||||
uint32_t CRY16ToRGB32[0x10000];
|
static uint32_t CRY16ToRGB32[0x10000];
|
||||||
uint32_t MIX16ToRGB32[0x10000];
|
static uint32_t MIX16ToRGB32[0x10000];
|
||||||
|
|
||||||
void TOMFillLookupTables(void)
|
void TOMFillLookupTables(void)
|
||||||
{
|
{
|
||||||
|
@ -203,6 +205,7 @@ void tom_render_16bpp_cry_rgb_mix_scanline(uint32_t * backbuffer)
|
||||||
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||||
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
||||||
startPos /= pwidth;
|
startPos /= pwidth;
|
||||||
|
if (startPos > width) startPos = width;
|
||||||
|
|
||||||
if (startPos < 0)
|
if (startPos < 0)
|
||||||
current_line_buffer += 2 * -startPos;
|
current_line_buffer += 2 * -startPos;
|
||||||
|
@ -237,6 +240,7 @@ void tom_render_16bpp_cry_scanline(uint32_t * backbuffer)
|
||||||
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||||
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
||||||
startPos /= pwidth;
|
startPos /= pwidth;
|
||||||
|
if (startPos > width) startPos = width;
|
||||||
|
|
||||||
if (startPos < 0)
|
if (startPos < 0)
|
||||||
current_line_buffer += 2 * -startPos;
|
current_line_buffer += 2 * -startPos;
|
||||||
|
@ -271,6 +275,7 @@ void tom_render_24bpp_scanline(uint32_t * backbuffer)
|
||||||
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||||
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
||||||
startPos /= pwidth;
|
startPos /= pwidth;
|
||||||
|
if (startPos > width) startPos = width;
|
||||||
|
|
||||||
if (startPos < 0)
|
if (startPos < 0)
|
||||||
current_line_buffer += 4 * -startPos;
|
current_line_buffer += 4 * -startPos;
|
||||||
|
@ -324,6 +329,7 @@ void tom_render_16bpp_rgb_scanline(uint32_t * backbuffer)
|
||||||
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
uint8_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||||
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
int16_t startPos = GET16(tomRam8, HDB1) - (vjs.hardwareTypeNTSC ? LEFT_VISIBLE_HC : LEFT_VISIBLE_HC_PAL);
|
||||||
startPos /= pwidth;
|
startPos /= pwidth;
|
||||||
|
if (startPos > width) startPos = width;
|
||||||
|
|
||||||
if (startPos < 0)
|
if (startPos < 0)
|
||||||
current_line_buffer += 2 * -startPos;
|
current_line_buffer += 2 * -startPos;
|
||||||
|
@ -384,28 +390,30 @@ void TOMExecHalfline(uint16_t halfline, bool render)
|
||||||
|
|
||||||
uint16_t topVisible = (vjs.hardwareTypeNTSC ? TOP_VISIBLE_VC : TOP_VISIBLE_VC_PAL),
|
uint16_t topVisible = (vjs.hardwareTypeNTSC ? TOP_VISIBLE_VC : TOP_VISIBLE_VC_PAL),
|
||||||
bottomVisible = (vjs.hardwareTypeNTSC ? BOTTOM_VISIBLE_VC : BOTTOM_VISIBLE_VC_PAL);
|
bottomVisible = (vjs.hardwareTypeNTSC ? BOTTOM_VISIBLE_VC : BOTTOM_VISIBLE_VC_PAL);
|
||||||
uint32_t * TOMCurrentLine = 0;
|
uint32_t TOMCurrentLine = 0;
|
||||||
|
|
||||||
if (tomRam8[VP + 1] & 0x01)
|
if (tomRam8[VP + 1] & 0x01)
|
||||||
TOMCurrentLine = &(screenBuffer[((halfline - topVisible) / 2) * screenPitch]);
|
TOMCurrentLine = (halfline - topVisible) / 2;
|
||||||
else
|
else
|
||||||
TOMCurrentLine = &(screenBuffer[(((halfline - topVisible) / 2) * screenPitch * 2) + (field2 ? 0 : screenPitch)]);
|
TOMCurrentLine = (((halfline - topVisible) / 2) * 2) + (field2 ? 0 : 1);
|
||||||
|
|
||||||
if ((halfline >= topVisible) && (halfline < bottomVisible))
|
if ((halfline >= topVisible) && (halfline < bottomVisible) && TOMCurrentLine < (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL))
|
||||||
{
|
{
|
||||||
if (inActiveDisplayArea)
|
if (inActiveDisplayArea)
|
||||||
{
|
{
|
||||||
scanline_render[TOMGetVideoMode()](TOMCurrentLine);
|
scanline_render[TOMGetVideoMode()](scanlines[TOMCurrentLine]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t * currentLineBuffer = TOMCurrentLine;
|
uint32_t * currentLineBuffer = scanlines[TOMCurrentLine];
|
||||||
uint8_t g = tomRam8[BORD1], r = tomRam8[BORD1 + 1], b = tomRam8[BORD2 + 1];
|
uint8_t g = tomRam8[BORD1], r = tomRam8[BORD1 + 1], b = tomRam8[BORD2 + 1];
|
||||||
uint32_t pixel = (r << 16) | (g << 8) | b;
|
uint32_t pixel = (r << 16) | (g << 8) | b;
|
||||||
|
|
||||||
for(uint32_t i=0; i<tomWidth; i++)
|
for(uint32_t i=0; i<tomWidth; i++)
|
||||||
*currentLineBuffer++ = pixel;
|
*currentLineBuffer++ = pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scanlineWidths[TOMCurrentLine] = tomWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +422,11 @@ void TOMExecHalfline(uint16_t halfline, bool render)
|
||||||
//
|
//
|
||||||
void TOMInit(void)
|
void TOMInit(void)
|
||||||
{
|
{
|
||||||
|
for (uint32_t i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
scanlines[i] = alloc_invisible<uint32_t>(LCM_SCREEN_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
TOMFillLookupTables();
|
TOMFillLookupTables();
|
||||||
OPInit();
|
OPInit();
|
||||||
BlitterInit();
|
BlitterInit();
|
||||||
|
@ -426,14 +439,12 @@ void TOMDone(void)
|
||||||
BlitterDone();
|
BlitterDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t TOMGetVideoModeWidth(void)
|
uint32_t TOMGetVideoModeWidth(void)
|
||||||
{
|
{
|
||||||
uint16_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
uint16_t pwidth = ((GET16(tomRam8, VMODE) & PWIDTH) >> 9) + 1;
|
||||||
return (vjs.hardwareTypeNTSC ? RIGHT_VISIBLE_HC - LEFT_VISIBLE_HC : RIGHT_VISIBLE_HC_PAL - LEFT_VISIBLE_HC_PAL) / pwidth;
|
return LCM_SCREEN_WIDTH / pwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t TOMGetVideoModeHeight(void)
|
uint32_t TOMGetVideoModeHeight(void)
|
||||||
{
|
{
|
||||||
return (vjs.hardwareTypeNTSC ? 240 : 256);
|
return (vjs.hardwareTypeNTSC ? 240 : 256);
|
||||||
|
@ -729,3 +740,73 @@ void TOMPITCallback(void)
|
||||||
|
|
||||||
TOMResetPIT();
|
TOMResetPIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TOMStartFrame(void)
|
||||||
|
{
|
||||||
|
memset(scanlineWidths, 0, sizeof(scanlineWidths));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TOMBlit(uint32_t * videoBuffer, int32_t & width, int32_t & height)
|
||||||
|
{
|
||||||
|
uint32_t lines = vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL;
|
||||||
|
uint32_t targetWidth = scanlineWidths[0];
|
||||||
|
bool multiWidth = false;
|
||||||
|
|
||||||
|
for (uint32_t i = 1; i < lines; i++)
|
||||||
|
{
|
||||||
|
if (targetWidth < scanlineWidths[i])
|
||||||
|
{
|
||||||
|
targetWidth = scanlineWidths[i];
|
||||||
|
multiWidth = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetWidth) // skip rendering this I guess?
|
||||||
|
{
|
||||||
|
width = TOMGetVideoModeWidth();
|
||||||
|
height = lines;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect(multiWidth, false))
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < lines; i++)
|
||||||
|
{
|
||||||
|
uint32_t const w = scanlineWidths[i];
|
||||||
|
if (__builtin_expect(LCM_SCREEN_WIDTH == w, false))
|
||||||
|
{
|
||||||
|
memcpy(videoBuffer, scanlines[i], LCM_SCREEN_WIDTH * sizeof(uint32_t));
|
||||||
|
videoBuffer += LCM_SCREEN_WIDTH;
|
||||||
|
}
|
||||||
|
else if (__builtin_expect(w > 0, true))
|
||||||
|
{
|
||||||
|
uint32_t wf = LCM_SCREEN_WIDTH / w;
|
||||||
|
uint32_t * src = scanlines[i];
|
||||||
|
uint32_t * dstNext = videoBuffer + LCM_SCREEN_WIDTH;
|
||||||
|
for (uint32_t x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
for (uint32_t n = 0; n < wf; n++)
|
||||||
|
*videoBuffer++ = *src;
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
while (videoBuffer < dstNext)
|
||||||
|
*videoBuffer++ = src[-1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
videoBuffer += LCM_SCREEN_WIDTH; // skip rendering this line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < lines; i++)
|
||||||
|
{
|
||||||
|
memcpy(videoBuffer, scanlines[i], targetWidth * sizeof(uint32_t));
|
||||||
|
videoBuffer += targetWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width = multiWidth ? LCM_SCREEN_WIDTH : targetWidth;
|
||||||
|
height = lines;
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#define VIRTUAL_SCREEN_HEIGHT_NTSC 240
|
#define VIRTUAL_SCREEN_HEIGHT_NTSC 240
|
||||||
#define VIRTUAL_SCREEN_HEIGHT_PAL 256
|
#define VIRTUAL_SCREEN_HEIGHT_PAL 256
|
||||||
|
|
||||||
|
#define LCM_SCREEN_WIDTH (VIRTUAL_SCREEN_WIDTH * 4)
|
||||||
|
|
||||||
// 68000 Interrupt bit positions (enabled at $F000E0)
|
// 68000 Interrupt bit positions (enabled at $F000E0)
|
||||||
|
|
||||||
enum { IRQ_VIDEO = 0, IRQ_GPU, IRQ_OPFLAG, IRQ_TIMER, IRQ_DSP };
|
enum { IRQ_VIDEO = 0, IRQ_GPU, IRQ_OPFLAG, IRQ_TIMER, IRQ_DSP };
|
||||||
|
@ -53,6 +55,9 @@ void TOMSetPendingGPUInt(void);
|
||||||
void TOMSetPendingVideoInt(void);
|
void TOMSetPendingVideoInt(void);
|
||||||
void TOMResetPIT(void);
|
void TOMResetPIT(void);
|
||||||
|
|
||||||
|
void TOMStartFrame(void);
|
||||||
|
void TOMBlit(uint32_t * framebuffer, int32_t & width, int32_t & height);
|
||||||
|
|
||||||
// Exported variables
|
// Exported variables
|
||||||
|
|
||||||
extern uint32_t tomWidth;
|
extern uint32_t tomWidth;
|
||||||
|
@ -62,7 +67,4 @@ extern uint32_t tomTimerPrescaler;
|
||||||
extern uint32_t tomTimerDivider;
|
extern uint32_t tomTimerDivider;
|
||||||
extern int32_t tomTimerCounter;
|
extern int32_t tomTimerCounter;
|
||||||
|
|
||||||
extern uint32_t screenPitch;
|
|
||||||
extern uint32_t * screenBuffer;
|
|
||||||
|
|
||||||
#endif // __TOM_H__
|
#endif // __TOM_H__
|
||||||
|
|
Loading…
Reference in New Issue