This commit is contained in:
Ville Linde 2006-07-12 18:56:25 +00:00
parent b4f2c7d9fe
commit 83f2c2259c
7 changed files with 428 additions and 103 deletions

View file

@ -2383,6 +2383,11 @@ BOOL model3_init(void)
tilegen_init(vram);
r3d_init(culling_ram_8e, culling_ram_8c, polygon_ram, texture_ram, vrom);
render_init(culling_ram_8e, culling_ram_8c, polygon_ram, texture_ram, vrom);
#ifndef RENDERER_D3D
osd_renderer_set_memory(polygon_ram, texture_ram, vrom);
#endif
// scsp_init();
// if(m3_config.flags & GAME_OWN_DSB1) dsb_reset();
controls_init();

View file

@ -652,82 +652,114 @@ static void set_color_offset(UINT32 reg)
void render_frame(void)
{
UINT32 renderer_features;
int i, j;
UINT32 color_offset;
LONGLONG counter_start, counter_end, counter_frequency;
LOG("model3.log", "RENDER START\n");
QueryPerformanceFrequency((LARGE_INTEGER*)&counter_frequency);
tilegen_update();
renderer_features = osd_renderer_get_features();
if (renderer_features & RENDERER_FEATURE_PRIORITY)
{
UINT32 *priority = tilegen_get_priority_buffer();
for (i=0; i < 4; i++)
// this is codepath for new-style renderers that support priorities
{
int pitch;
UINT8 *buffer;
osd_renderer_get_priority_buffer(i, &buffer, &pitch);
UINT32 *priority = tilegen_get_priority_buffer();
for (j=0; j < 512; j++)
for (i=0; i < 4; i++)
{
if (tilegen_is_priority_enabled())
int pitch;
UINT8 *buffer;
osd_renderer_get_priority_buffer(i, &buffer, &pitch);
for (j=0; j < 512; j++)
{
buffer[j*pitch] = (priority[j] >> ((3-i) * 8)) & 0xff;
}
else
{
if (i < 2) buffer[j*pitch] = 0xff;
else buffer[j*pitch] = 0x00;
if (tilegen_is_priority_enabled())
{
buffer[j*pitch] = (priority[j] >> ((3-i) * 8)) & 0xff;
}
else
{
if (i < 2) buffer[j*pitch] = 0xff;
else buffer[j*pitch] = 0x00;
}
}
osd_renderer_free_priority_buffer(i);
}
}
osd_renderer_free_priority_buffer(i);
osd_renderer_clear(1, 1); // clear both the frame and Z-buffer
// set_color_offset(tilegen_read_32(0x44));
/*if (tilegen_is_layer_enabled(3))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(3);
color_offset = tilegen_get_layer_color_offset(3);
osd_renderer_draw_layer(3, color_offset, scroll & 0xffff, scroll >> 16);
}
if (tilegen_is_layer_enabled(2))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(2);
color_offset = tilegen_get_layer_color_offset(2);
osd_renderer_draw_layer(2, color_offset, scroll & 0xffff, scroll >> 16);
}*/
for (i=3; i >= 0; i--)
{
if (tilegen_is_layer_enabled(i))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(i);
color_offset = tilegen_get_layer_color_offset(i);
osd_renderer_draw_layer(i, color_offset, scroll & 0xffff, scroll >> 16, FALSE);
}
}
do_3d();
for (i=3; i >= 0; i--)
{
if (tilegen_is_layer_enabled(i))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(i);
color_offset = tilegen_get_layer_color_offset(i);
osd_renderer_draw_layer(i, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
}
}
}
osd_renderer_clear(1, 1); // clear both the frame and Z-buffer
// set_color_offset(tilegen_read_32(0x44));
/*if (tilegen_is_layer_enabled(3))
else
{
UINT32 scroll = tilegen_get_layer_scroll_pos(3);
color_offset = tilegen_get_layer_color_offset(3);
osd_renderer_draw_layer(3, color_offset, scroll & 0xffff, scroll >> 16);
}
if (tilegen_is_layer_enabled(2))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(2);
color_offset = tilegen_get_layer_color_offset(2);
osd_renderer_draw_layer(2, color_offset, scroll & 0xffff, scroll >> 16);
}*/
// this codepath is for the old-style renderers
osd_renderer_clear(1, 1); // clear both the frame and Z-buffer
for (i=3; i >= 0; i--)
{
if (tilegen_is_layer_enabled(i))
if (tilegen_is_layer_enabled(3))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(i);
color_offset = tilegen_get_layer_color_offset(i);
osd_renderer_draw_layer(i, color_offset, scroll & 0xffff, scroll >> 16, FALSE);
UINT32 scroll = tilegen_get_layer_scroll_pos(3);
color_offset = tilegen_get_layer_color_offset(3);
osd_renderer_draw_layer(3, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
}
}
QueryPerformanceCounter((LARGE_INTEGER*)&counter_start);
do_3d();
QueryPerformanceCounter((LARGE_INTEGER*)&counter_end);
for (i=3; i >= 0; i--)
{
if (tilegen_is_layer_enabled(i))
if (tilegen_is_layer_enabled(2))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(i);
color_offset = tilegen_get_layer_color_offset(i);
osd_renderer_draw_layer(i, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
UINT32 scroll = tilegen_get_layer_scroll_pos(2);
color_offset = tilegen_get_layer_color_offset(2);
osd_renderer_draw_layer(2, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
}
do_3d();
if (tilegen_is_layer_enabled(1))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(1);
color_offset = tilegen_get_layer_color_offset(1);
osd_renderer_draw_layer(1, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
}
if (tilegen_is_layer_enabled(0))
{
UINT32 scroll = tilegen_get_layer_scroll_pos(0);
color_offset = tilegen_get_layer_color_offset(0);
osd_renderer_draw_layer(0, color_offset, scroll & 0xffff, scroll >> 16, TRUE);
}
}

View file

@ -105,18 +105,18 @@ static int tilemap_redraw[4];
* and advance the buffer pointer.
*/
/*#define PUTPIXEL8_32(bp) \
do { \
pixel = pal[((pattern >> bp) & 0xFF) | pal_bits]; \
*buf++ = pixel; \
#define PUTPIXEL8_NP(bp) \
do \
{ \
*buf++ = pal[((pattern >> bp) & 0xFF) | pal_bits]; \
} while (0)
#define PUTPIXEL4_32(bp) \
do { \
pixel = pal[((pattern >> bp) & 0xF) | pal_bits]; \
*buf++ = pixel; \
#define PUTPIXEL4_NP(bp) \
do \
{ \
*buf++ = pal[((pattern >> bp) & 0xF) | pal_bits]; \
} while (0)
*/
#define PUTPIXEL8(bp) \
do \
@ -130,12 +130,6 @@ static int tilemap_redraw[4];
*buf++ = ((pattern >> bp) & 0xf) | pal_bits; \
} while(0)
/*
* draw_tile_8bit_32():
*
* Draws an 8-bit tile to a 32-bit layer buffer.
*/
static void draw_tile_8bit(UINT tile, UINT16 *buf)
{
UINT tile_offs; // offset of tile within VRAM
@ -195,12 +189,6 @@ static void draw_tile_8bit(UINT tile, UINT16 *buf)
}
}
/*
* draw_tile_4bit_32():
*
* Draws a 4-bit tile to a 32-bit layer buffer.
*/
static void draw_tile_4bit(UINT tile, UINT16 *buf)
{
UINT tile_offs; // offset of tile within VRAM
@ -252,6 +240,120 @@ static void draw_tile_4bit(UINT tile, UINT16 *buf)
}
}
/*****************************************************************************/
static void draw_tile_8bit_np(UINT tile, UINT32 *buf)
{
UINT tile_offs; // offset of tile within VRAM
UINT pal_bits; // color palette bits obtained from tile
UINT y;
UINT32 pattern; // 4 pattern pixels fetched at once
/*
* Calculate tile offset; each tile occupies 64 bytes when using 8-bit
* pixels
*/
//tile_offs = tile & 0x3fff;
//tile_offs *= 64;
tile_offs = ((tile & 0x3fff) << 1) | ((tile >> 15) & 1);
tile_offs *= 32;
/*
* Obtain upper color bits; the lower 8 bits come from the tile pattern
*/
pal_bits = tile & 0x7F00;
/*
* Draw!
*/
for (y = 0; y < 8; y++)
{
/*
* Fetch first 4 pixels and draw them
*/
pattern = *((UINT32 *) &vram[tile_offs]);
tile_offs += 4;
PUTPIXEL8_NP(24);
PUTPIXEL8_NP(16);
PUTPIXEL8_NP(8);
PUTPIXEL8_NP(0);
/*
* Next 4
*/
pattern = *((UINT32 *) &vram[tile_offs]);
tile_offs += 4;
PUTPIXEL8_NP(24);
PUTPIXEL8_NP(16);
PUTPIXEL8_NP(8);
PUTPIXEL8_NP(0);
/*
* Move to the next line
*/
buf += (pitch - 8); // next line in layer buffer
}
}
static void draw_tile_4bit_np(UINT tile, UINT32 *buf)
{
UINT tile_offs; // offset of tile within VRAM
UINT pal_bits; // color palette bits obtained from tile
UINT y;
UINT32 pattern; // 8 pattern pixels fetched at once
/*
* Calculate tile offset; each tile occupies 32 bytes when using 4-bit
* pixels
*/
tile_offs = ((tile & 0x3fff) << 1) | ((tile >> 15) & 1);
tile_offs *= 32;
/*
* Obtain upper color bits; the lower 4 bits come from the tile pattern
*/
pal_bits = tile & 0x7FF0;
/*
* Draw!
*/
for (y = 0; y < 8; y++)
{
pattern = *((UINT32 *) &vram[tile_offs]);
/*
* Draw the 8 pixels we've fetched
*/
PUTPIXEL4_NP(28);
PUTPIXEL4_NP(24);
PUTPIXEL4_NP(20);
PUTPIXEL4_NP(16);
PUTPIXEL4_NP(12);
PUTPIXEL4_NP(8);
PUTPIXEL4_NP(4);
PUTPIXEL4_NP(0);
/*
* Move to the next line
*/
tile_offs += 4; // next tile pattern line
buf += (pitch - 8); // next line in layer buffer
}
}
/*****************************************************************************/
/*
* draw_layer_8bit_32():
*
@ -360,6 +462,118 @@ static void draw_layer_4bit(UINT16 *layer, int layer_num)
tilemap_redraw[layer_num] = 0;
}
/*****************************************************************************/
/*
* draw_layer_8bit_32():
*
* Draws an entire layer of 8-bit tiles to a 32-bit layer buffer.
*/
static void draw_layer_8bit_np(UINT32 *layer, int layer_num)
{
int ty, tx;
int tilenum;
UINT32 tile;
UINT32 addr = 0xf8000 + (layer_num * 0x2000);
if (tilemap_is_dirty[layer_num] == 0)
{
return;
}
tilemap_is_dirty[layer_num] = 0;
tilenum = 0;
for (ty = 0; ty < 64; ty++)
{
for (tx = 0; tx < 64; tx+=2)
{
if (tilemap_redraw[layer_num] || tilemap_dirty[layer_num][tilenum+0])
{
tilemap_depth[layer_num][tilenum+0] = 0;
tilemap_dirty[layer_num][tilenum+0] = 0;
tile = *((UINT32 *) &vram[addr]) >> 16;
draw_tile_8bit_np(tile & 0xffff, layer);
}
if (tilemap_redraw[layer_num] || tilemap_dirty[layer_num][tilenum+1])
{
tilemap_depth[layer_num][tilenum+1] = 0;
tilemap_dirty[layer_num][tilenum+1] = 0;
tile = *((UINT32 *) &vram[addr]) >> 0;
draw_tile_8bit_np(tile & 0xffff, layer+8);
}
addr += 4;
layer += 16;
tilenum+=2;
}
//addr += (64 - 62) * 2;
layer += (7 * pitch) + (pitch - 512); // next tile row
}
tilemap_redraw[layer_num] = 0;
}
/*
* draw_layer_4bit_32():
*
* Draws an entire layer of 4-bit tiles to a 32-bit layer buffer.
*/
static void draw_layer_4bit_np(UINT32 *layer, int layer_num)
{
int ty, tx;
int tilenum;
UINT32 tile;
UINT32 addr = 0xf8000 + (layer_num * 0x2000);
if (tilemap_is_dirty[layer_num] == 0)
{
return;
}
tilemap_is_dirty[layer_num] = 0;
tilenum = 0;
for (ty = 0; ty < 64; ty++)
{
for (tx = 0; tx < 64; tx+=2)
{
if (tilemap_redraw[layer_num] || tilemap_dirty[layer_num][tilenum+0])
{
tilemap_depth[layer_num][tilenum+0] = 1;
tilemap_dirty[layer_num][tilenum+0] = 0;
tile = *((UINT32 *) &vram[addr]) >> 16;
draw_tile_4bit_np(tile & 0xffff, layer);
}
if (tilemap_redraw[layer_num] || tilemap_dirty[layer_num][tilenum+1])
{
tilemap_depth[layer_num][tilenum+0] = 1;
tilemap_dirty[layer_num][tilenum+1] = 0;
tile = *((UINT32 *) &vram[addr]) >> 0;
draw_tile_4bit_np(tile & 0xffff, layer+8);
}
addr += 4;
layer += 16;
tilenum+=2;
}
//addr += (64 - 62) * 2;
layer += (7 * pitch) + (pitch - 512); // next tile row
}
tilemap_redraw[layer_num] = 0;
}
/*****************************************************************************/
/*
* void tilegen_update(void);
*
@ -372,6 +586,7 @@ void tilegen_update(void)
UINT layer_colors, layer_color_mask;
FLAGS layer_enable_mask;
int i, j;
UINT32 renderer_features;
/*
* Render layers
@ -379,12 +594,16 @@ void tilegen_update(void)
PROFILE_SECT_ENTRY("tilegen");
renderer_features = osd_renderer_get_features();
layer_colors = BSWAP32(*(UINT32 *) &reg[REG_LAYER_COLORS]);
layer_color_mask = 0x00100000; // first layer color bit (moves left)
layer_enable_mask = 1;
// layer_colors = 0; // enable this to force 8-bit mode for VF3
// update palette if the renderer supports paletting
if (renderer_features & RENDERER_FEATURE_PALETTE)
{
UINT32 *palette;
int pwidth;
@ -434,14 +653,28 @@ void tilegen_update(void)
{
osd_renderer_get_layer_buffer(i, &layer, &pitch);
if ((layer_colors & layer_color_mask))
if (renderer_features & RENDERER_FEATURE_PALETTE)
{
draw_layer_4bit((UINT16 *) layer, i);
if ((layer_colors & layer_color_mask))
{
draw_layer_4bit((UINT16 *) layer, i);
}
else
{
draw_layer_8bit((UINT16 *) layer, i);
}
}
else
{
draw_layer_8bit((UINT16 *) layer, i);
}
if ((layer_colors & layer_color_mask))
{
draw_layer_4bit_np((UINT16 *) layer, i);
}
else
{
draw_layer_8bit_np((UINT16 *) layer, i);
}
}
osd_renderer_free_layer_buffer(i);
}
@ -542,10 +775,26 @@ void tilegen_vram_write_32(UINT32 addr, UINT32 data)
}
else if (addr >= 0x100000 && addr < 0x120000) // palette
{
UINT32 renderer_features = osd_renderer_get_features();
*(UINT32 *)&vram[addr] = data;
color = (addr - 0x100000) / 4; // color number
pal[color] = data;
if (renderer_features & RENDERER_FEATURE_PALETTE)
{
pal[color] = data;
}
else
{
int a = (data & 0x8000) ? 0 : 0xff;
int r = (data >> 10) & 0x1f;
int g = (data >> 5) & 0x1f;
int b = (data >> 0) & 0x1f;
r = (r << 3) | (r >> 2);
g = (g << 3) | (g >> 2);
b = (b << 3) | (b >> 2);
pal[color] = (a << 24) | (r << 16) | (g << 8) | (b);
}
}
}

View file

@ -62,8 +62,6 @@
* These will be passed to us before rendering begins.
*/
static UINT8 *culling_ram_8e; // pointer to Real3D culling RAM
static UINT8 *culling_ram_8c; // pointer to Real3D culling RAM
static UINT8 *polygon_ram; // pointer to Real3D polygon RAM
static UINT8 *texture_ram; // pointer to Real3D texture RAM
static UINT8 *vrom; // pointer to VROM
@ -196,7 +194,7 @@ PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
* h = Height.
*/
void osd_renderer_invalidate_textures(UINT x, UINT y, UINT w, UINT h)
void osd_renderer_invalidate_textures(UINT x, UINT y, int u, int v, UINT w, UINT h, UINT8 *texture, int miplevel)
{
UINT yi;
@ -1162,7 +1160,7 @@ void osd_renderer_pop_matrix(void)
* Called just before rendering begins for the current frame. Does nothing.
*/
void osd_renderer_begin(void)
void osd_renderer_begin_3d_scene(void)
{
}
@ -1172,7 +1170,7 @@ void osd_renderer_begin(void)
* Called just after rendering ends for the current frame. Does nothing.
*/
void osd_renderer_end(void)
void osd_renderer_end_3d_scene(void)
{
}
@ -1369,6 +1367,24 @@ void osd_renderer_free_layer_buffer(UINT layer_num)
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, layer[layer_num]);
}
/*
* void osd_renderer_draw_text(int x, int y, const char* string, DWORD color, BOOL shadow);
*
* Draws text on screen
*
* Parameters:
* x = Left X-coordinate of the text
* y = Top Y-coordinate of the text
* string = Text string
* color = Packed 24-bit RGBA color of the text
* shadow = if TRUE, draws a shadow behind the text
*/
void osd_renderer_draw_text(int x, int y, const char* string, DWORD color, BOOL shadow)
{
// TODO: needs to be implemented
}
/******************************************************************/
/* Initialization and Set Up */
/******************************************************************/
@ -1393,13 +1409,9 @@ void osd_renderer_free_layer_buffer(UINT layer_num)
* vrom_ptr = Pointer to VROM.
*/
void osd_renderer_set_memory(UINT8 *culling_ram_8e_ptr,
UINT8 *culling_ram_8c_ptr,
UINT8 *polygon_ram_ptr, UINT8 *texture_ram_ptr,
void osd_renderer_set_memory(UINT8 *polygon_ram_ptr, UINT8 *texture_ram_ptr,
UINT8 *vrom_ptr)
{
culling_ram_8e = culling_ram_8e_ptr;
culling_ram_8c = culling_ram_8c_ptr;
polygon_ram = polygon_ram_ptr;
texture_ram = texture_ram_ptr;
vrom = vrom_ptr;
@ -1466,7 +1478,7 @@ void osd_gl_set_mode(UINT new_xres, UINT new_yres)
const GLfloat zero[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
INT i;
osd_renderer_invalidate_textures(0, 0, 2048, 2048);
osd_renderer_invalidate_textures(0, 0, 0, 0, 2048, 2048, NULL, 0);
xres = new_xres;
yres = new_yres;
@ -1525,12 +1537,6 @@ void osd_gl_set_mode(UINT new_xres, UINT new_yres)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, layer[i]);
}
/*
* Configure the tile generator
*/
tilegen_set_layer_format(32, 0, 8, 16, 24);
/*
* Set vertex format
*/
@ -1566,6 +1572,17 @@ void osd_gl_set_mode(UINT new_xres, UINT new_yres)
void osd_gl_unset_mode(void)
{
osd_renderer_invalidate_textures(0, 0, 2048, 2048);
osd_renderer_invalidate_textures(0, 0, 0, 0, 2048, 2048, NULL, 0);
glDeleteTextures(4, layer_texture);
}
UINT32 osd_renderer_get_features(void)
{
return 0;
}
// Not supported but the interface requires them
void osd_renderer_get_palette_buffer(UINT32 **buffer, int *width, int *pitch) { };
void osd_renderer_free_palette_buffer(void) { };
void osd_renderer_get_priority_buffer(int layer_num, UINT8 **buffer, int *pitch) { };
void osd_renderer_free_priority_buffer(int layer_num) { };

View file

@ -108,7 +108,10 @@ extern void osd_renderer_blit(void);
extern void osd_renderer_begin_3d_scene(void);
extern void osd_renderer_end_3d_scene(void);
extern void osd_renderer_draw_text(int x, int y, const char* string, DWORD color, BOOL shadow);
extern UINT32 osd_renderer_get_features(void);
#define RENDERER_FEATURE_PALETTE 0x00000001
#define RENDERER_FEATURE_PRIORITY 0x00000002
/******************************************************************/

View file

@ -1710,3 +1710,8 @@ void osd_renderer_invalidate_textures(UINT x, UINT y, int u, int v, UINT w, UINT
{
renderer_upload_texture(x, y, u, v, w, h, texture_sheet, miplevel);
}
UINT32 osd_renderer_get_features(void)
{
return RENDERER_FEATURE_PALETTE | RENDERER_FEATURE_PRIORITY;
}

View file

@ -219,11 +219,13 @@ int main(int argc, char *argv[])
exit(1);
}
#if RENDERER_D3D
if (d3d_pre_init() == FALSE)
{
message(0, "The video card doesn't meet the requirements, the program will not run further.");
exit(1);
}
#endif
message(0, "");
@ -266,11 +268,15 @@ int main(int argc, char *argv[])
model3_init();
model3_reset();
#if RENDERER_D3D
if (!d3d_init(main_window))
{
message(0, "d3d_init failed.");
exit(1);
}
#else
win_gl_init(XRES, YRES);
#endif
if (osd_input_init() == FALSE)
{
@ -298,6 +304,9 @@ int main(int argc, char *argv[])
else
do_fps = FALSE;
QueryPerformanceCounter((LARGE_INTEGER *)&time_start);
QueryPerformanceCounter((LARGE_INTEGER *)&time_end);
memset(&msg, 0, sizeof(MSG));
while (quit == FALSE)
{
@ -329,12 +338,17 @@ int main(int argc, char *argv[])
time_start = time_end;
}
#if RENDERER_D3D
if (m3_config.show_fps)
{
//fps = 1.0 / ((double)(time_end - time_start) / freq);
sprintf(title, "FPS: %.3f", fps);
osd_renderer_draw_text(2, 2, title, 0xffff0000, TRUE);
}
#else
sprintf(title, "%s: %s, FPS: %.3f", app_title, m3_config.game_name, fps);
SetWindowText(main_window, title);
#endif
//osd_renderer_draw_text(2, 2, title, 0x00ff0000, TRUE);