📄 toobin.c
字号:
/***************************************************************************
vidhrdw.c
Functions to emulate the video hardware of the machine.
***************************************************************************/
#include "driver.h"
#include "machine/atarigen.h"
#include "vidhrdw/generic.h"
#define XCHARS 64
#define YCHARS 48
#define XDIM (XCHARS*8)
#define YDIM (YCHARS*8)
struct toobin_mo_data
{
int *redraw_list, *redraw;
};
/*************************************
*
* Globals we own
*
*************************************/
unsigned char *toobin_intensity;
unsigned char *toobin_moslip;
/*************************************
*
* Statics
*
*************************************/
static unsigned char *playfielddirty;
static struct osd_bitmap *playfieldbitmap;
static int xscroll, yscroll;
static int last_intensity;
/*************************************
*
* Prototypes from other modules
*
*************************************/
void toobin_vh_stop (void);
#if 0
static void toobin_dump_video_ram (void);
#endif
/*************************************
*
* Video system start
*
*************************************/
int toobin_vh_start(void)
{
static struct atarigen_modesc toobin_modesc =
{
256, /* maximum number of MO's */
8, /* number of bytes per MO entry */
2, /* number of bytes between MO words */
2, /* ignore an entry if this word == 0xffff */
2, 0, 0xff, /* link = (data[linkword] >> linkshift) & linkmask */
0 /* render in reverse link order */
};
/* allocate dirty buffers */
if (!playfielddirty)
playfielddirty = malloc (atarigen_playfieldram_size / 4);
if (!playfielddirty)
{
toobin_vh_stop ();
return 1;
}
memset (playfielddirty, 1, atarigen_playfieldram_size / 4);
/* allocate bitmaps */
if (!playfieldbitmap)
playfieldbitmap = osd_new_bitmap (128*8, 64*8, Machine->scrbitmap->depth);
if (!playfieldbitmap)
{
toobin_vh_stop ();
return 1;
}
last_intensity = 0;
/* initialize the displaylist system */
return atarigen_init_display_list (&toobin_modesc);
}
/*************************************
*
* Video system shutdown
*
*************************************/
void toobin_vh_stop(void)
{
/* free bitmaps */
if (playfieldbitmap)
osd_free_bitmap (playfieldbitmap);
playfieldbitmap = 0;
/* free dirty buffers */
if (playfielddirty)
free (playfielddirty);
playfielddirty = 0;
}
/*************************************
*
* Playfield RAM read/write handlers
*
*************************************/
int toobin_playfieldram_r (int offset)
{
return READ_WORD (&atarigen_playfieldram[offset]);
}
void toobin_playfieldram_w (int offset, int data)
{
int oldword = READ_WORD (&atarigen_playfieldram[offset]);
int newword = COMBINE_WORD (oldword, data);
if (oldword != newword)
{
WRITE_WORD (&atarigen_playfieldram[offset], newword);
playfielddirty[offset / 4] = 1;
}
}
/*************************************
*
* Palette RAM read/write handlers
*
*************************************/
void toobin_paletteram_w (int offset, int data)
{
int oldword = READ_WORD (&paletteram[offset]);
int newword = COMBINE_WORD (oldword, data);
WRITE_WORD (&paletteram[offset], newword);
{
int red = (((newword >> 10) & 31) * 224) >> 5;
int green = (((newword >> 5) & 31) * 224) >> 5;
int blue = (((newword ) & 31) * 224) >> 5;
if (red) red += 38;
if (green) green += 38;
if (blue) blue += 38;
if (!(newword & 0x8000))
{
red = (red * last_intensity) >> 5;
green = (green * last_intensity) >> 5;
blue = (blue * last_intensity) >> 5;
}
palette_change_color ((offset / 2) & 0x3ff, red, green, blue);
}
}
/*************************************
*
* Motion object list handlers
*
*************************************/
void toobin_update_display_list (int scanline)
{
int link = READ_WORD (&toobin_moslip[0]) & 0xff;
atarigen_update_display_list (atarigen_spriteram, link, scanline);
}
void toobin_moslip_w (int offset, int data)
{
COMBINE_WORD_MEM (&toobin_moslip[offset], data);
toobin_update_display_list (cpu_getscanline ());
}
/*---------------------------------------------------------------------------------
*
* Motion Object encoding
*
* 4 16-bit words are used
*
* Word 1:
*
* Bits 0-2 = width of the sprite / 16 (ranges from 1-8)
* Bits 3-5 = height of the sprite / 16 (ranges from 1-8)
* Bits 6-14 = Y position of the sprite
* Bit 15 = absolute/relative positioning (1 = absolute)
*
* Word 2:
*
* Bits 0-13 = index of the image (0-16383)
* Bit 14 = horizontal flip
* Bit 15 = vertical flip
*
* Word 3:
*
* Bits 0-7 = link to the next image to display
* Bits 12-15 = priority (only upper 2 bits used)
*
* Word 4:
*
* Bits 0-3 = sprite color
* Bits 6-15 = X position of the sprite
*
*---------------------------------------------------------------------------------
*/
void toobin_calc_mo_colors (struct osd_bitmap *bitmap, struct rectangle *clip, unsigned short *data, void *param)
{
unsigned short *colors = param;
int color = data[3] & 0x0f;
int hsize = (data[0] & 7) + 1;
int vsize = ((data[0] >> 3) & 7) + 1;
int pict = data[1] & 0x3fff;
int i;
colors += color;
for (i = hsize * vsize - 1; i >= 0; i--, pict++)
*colors |= Machine->gfx[2]->pen_usage[pict];
}
void toobin_render_mo (struct osd_bitmap *bitmap, struct rectangle *clip, unsigned short *data, void *param)
{
struct toobin_mo_data *modata = param;
int *redraw_list = modata->redraw_list;
int *redraw = modata->redraw;
int *r, redraw_val;
/* extract data from the various words */
int xpos = data[3] >> 6;
int ypos = -(data[0] >> 6);
int hsize = (data[0] & 7) + 1;
int vsize = ((data[0] >> 3) & 7) + 1;
int hflip = data[1] & 0x4000;
int vflip = data[1] & 0x8000;
int pict = data[1] & 0x3fff;
int color = data[3] & 0x0f;
int absolute = data[0] & 0x8000;
int priority = 3;
int x, y, sx, sy, xadv, yadv;
/* adjust position if relative */
if (!absolute)
{
xpos += xscroll;
ypos += yscroll;
}
/* adjust for h flip */
if (hflip)
xpos += (hsize - 1) * 16, xadv = -16;
else
xadv = 16;
/* adjust for vflip */
if (vflip)
ypos -= 16, yadv = -16;
else
ypos -= vsize * 16, yadv = 16;
/* adjust the final coordinates */
xpos &= 0x3ff;
ypos &= 0x1ff;
redraw_val = (xpos << 22) + (ypos << 13) + (priority << 10) + (hsize << 4) + vsize;
if (xpos >= XDIM) xpos -= 0x400;
if (ypos >= YDIM) ypos -= 0x200;
/* see if we already have a redraw entry in the list for this MO */
for (r = redraw_list; r < redraw; )
if (*r++ == redraw_val)
break;
/* if not, add it */
if (r == redraw)
{
*redraw++ = redraw_val;
modata->redraw = redraw;
}
/* loop over the width */
for (x = 0, sx = xpos; x < hsize; x++, sx += xadv)
{
/* clip the X coordinate */
if (sx <= -16)
{
pict += vsize;
continue;
}
else if (sx >= XDIM)
break;
/* loop over the height */
for (y = 0, sy = ypos; y < vsize; y++, sy += yadv, pict++)
{
/* clip the Y coordinate */
if (sy <= clip->min_y - 16 || sy > clip->max_y)
continue;
/* draw the sprite */
drawgfx (bitmap, Machine->gfx[2],
pict, color, hflip, vflip, sx, sy, clip, TRANSPARENCY_PEN, 0);
}
}
}
/***************************************************************************
Draw the game screen in the given osd_bitmap.
Do NOT call osd_update_display() from this function, it will be called by
the main emulation engine.
***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -