⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stactics.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************

  vidhrdw.c

  Functions to emulate the video hardware of the machine.

---

The Video system used in Space Tactics is unusual.
Here are my notes on how the video system works:

There are 4, 4K pages of Video RAM. (B,D,E & F)

The first 1K of each VRAM page contains the following:
0 0 V V V V V H H H H H   offset value for each 8x8 bitmap
     (v-tile)  (h-tile)

The offset values are used to generate an access into the
last 2K of the VRAM page:
1 D D D D D D D D V V V   here we find 8x8 character data
     (offset)    (line)

In addition, in Page B, the upper nibble of the offset is
also used to select the color palette for the tile.

Page B, D, E, and F all work similarly, except that pages
D, E, and F can be offset from Page B by a given
number of scanlines, based on the contents of the offset
RAM

The offset RAM is addressed in this format:
1 0 0 0 P P P V V V V V V V V V
        (Page)   (scanline)
Page 4=D, 5=E, 6=F

Page D, E, and F are drawn offset from the top of the screen,
starting on the first scanline which contains a 1 in the
appropriate memory location

---

The composited monitor image is seen in a mirror.  It appears
to move when the player moves the handle, due to motors which
tilt the mirror up and down, and the monitor left and right.

---

As if this wasn't enough, there are also "3D" fire beams made
of 120 green LED's which are on a mechanism in front of the mirror.
Along with a single red "sight" LED.  I am reading in the sequence
ROMS and building up a character set to simulate the LEDS with
conventional character graphics.

Finally, there is a score display made of 7-segment LEDS, along
with Credits, Barriers, and Rounds displays made of some other
type of LED bar graphs.  I'm displaying them the best I can on the
bottom line of the screen

***************************************************************************/

#include "driver.h"
#include "vidhrdw/generic.h"

/* These are defined in machine/stactics.c */
extern int stactics_vert_pos;
extern int stactics_horiz_pos;
extern int stactics_motor_on;

/* These are needed by machine/stactics.c  */
int stactics_vblank_count;
int stactics_shot_standby;
int stactics_shot_arrive;
int stactics_display_buffer[16];

/* These are needed by driver/stactics.c   */
unsigned char *stactics_scroll_ram;
unsigned char *stactics_videoram_b;
unsigned char *stactics_chardata_b;
unsigned char *stactics_videoram_d;
unsigned char *stactics_chardata_d;
unsigned char *stactics_videoram_e;
unsigned char *stactics_chardata_e;
unsigned char *stactics_videoram_f;
unsigned char *stactics_chardata_f;

static char dirty_videoram_b[0x400];
static char dirty_chardata_b[0x100];
static char dirty_videoram_d[0x400];
static char dirty_chardata_d[0x100];
static char dirty_videoram_e[0x400];
static char dirty_chardata_e[0x100];
static char dirty_videoram_f[0x400];
static char dirty_chardata_f[0x100];

static int d_offset;
static int e_offset;
static int f_offset;

static int palette_select;

static struct osd_bitmap *tmpbitmap2;
static struct osd_bitmap *bitmap_B;
static struct osd_bitmap *bitmap_D;
static struct osd_bitmap *bitmap_E;
static struct osd_bitmap *bitmap_F;

static unsigned char stactics_beamdata[0x0800];
static int stactics_states_per_frame;

/* The first 16 came from the 7448 BCD to 7-segment decoder data sheet */
/* The rest are made up */

static unsigned char stactics_special_chars[32*8] = {
    0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xf0, 0x00,   /* 0 */
    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,   /* 1 */
    0xf0, 0x10, 0x10, 0xf0, 0x80, 0x80, 0xf0, 0x00,   /* 2 */
    0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x00,   /* 3 */
    0x90, 0x90, 0x90, 0xf0, 0x10, 0x10, 0x10, 0x00,   /* 4 */
    0xf0, 0x80, 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x00,   /* 5 */
    0xf0, 0x80, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x00,   /* 6 */
    0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,   /* 7 */
    0xf0, 0x90, 0x90, 0xf0, 0x90, 0x90, 0xf0, 0x00,   /* 8 */
    0xf0, 0x90, 0x90, 0xf0, 0x10, 0x10, 0xf0, 0x00,   /* 9 */
    0x00, 0x00, 0x00, 0xf0, 0x80, 0x80, 0xf0, 0x00,   /* extras... */
    0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x00,   /* extras... */
    0x90, 0x90, 0x90, 0xf0, 0x00, 0x00, 0x00, 0x00,   /* extras... */
    0xf0, 0x80, 0x80, 0xf0, 0x00, 0x00, 0xf0, 0x00,   /* extras... */
    0x80, 0x80, 0x80, 0xf0, 0x80, 0x80, 0xf0, 0x00,   /* extras... */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space */

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space */
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 1 pip */
    0x60, 0x90, 0x80, 0x60, 0x10, 0x90, 0x60, 0x00,   /* S for Score */
    0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,   /* 2 pips */
    0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00,   /* 3 pips */
    0x60, 0x90, 0x80, 0x80, 0x80, 0x90, 0x60, 0x00,   /* C for Credits */
    0xe0, 0x90, 0x90, 0xe0, 0x90, 0x90, 0xe0, 0x00,   /* B for Barriers */
    0xe0, 0x90, 0x90, 0xe0, 0xc0, 0xa0, 0x90, 0x00,   /* R for Rounds */
    0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00,   /* 4 pips */
    0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, 0x00,   /* Colon */
    0x40, 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Sight */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space (Unused) */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space (Unused) */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space (Unused) */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   /* Space (Unused) */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00    /* Space */
};


static int firebeam_state;
static int old_firebeam_state;

void stactics_vh_convert_color_prom(unsigned char *palette,
                                    unsigned short *colortable,
                                    const unsigned char *color_prom)
{
    int i,j;

    #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
    #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs*sizeof(unsigned short)])

    /* Now make the palette */

    for (i=0;i<16;i++)
    {
        int bit0,bit1,bit2, bit3;

        bit0 = i & 1;
        bit1 = (i >> 1) & 1;
        bit2 = (i >> 2) & 1;
        bit3 = (i >> 3) & 1;

        /* red component */
        *(palette++) = 0xff * bit0;

        /* green component */
        *(palette++) = 0xff * bit1 - 0xcc * bit3;

        /* blue component */
        *(palette++) = 0xff * bit2;
    }

    /* The color prom in Space Tactics is used for both   */
    /* color codes, and priority layering of the 4 layers */

    /* Since we are taking care of the layering by our    */
    /* drawing order, we don't need all of the color prom */
    /* entries */

    /* For each of 4 color schemes */
    for(i=0;i<4;i++)
    {
        /* For page B - Alphanumerics and alien shots */
        for(j=0;j<16;j++)
        {
            *(colortable++) = 0;
            *(colortable++) = color_prom[i*0x100+0x01*0x10+j];
        }
        /* For page F - Close Aliens (these are all the same color) */
        for(j=0;j<16;j++)
        {
            *(colortable++) = 0;
            *(colortable++) = color_prom[i*0x100+0x02*0x10];
        }
        /* For page E - Medium Aliens (these are all the same color) */
        for(j=0;j<16;j++)
        {
            *(colortable++) = 0;
            *(colortable++) = color_prom[i*0x100+0x04*0x10+j];
        }
        /* For page D - Far Aliens (these are all the same color) */
        for(j=0;j<16;j++)
        {
            *(colortable++) = 0;
            *(colortable++) = color_prom[i*0x100+0x08*0x10+j];
        }
    }
}

/***************************************************************************

  Start the video hardware emulation.

***************************************************************************/

int stactics_vh_start(void)
{
    int i,j;
    const unsigned char *firebeam_data;
    unsigned char firechar[256*8*9];

    if ((tmpbitmap = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;
    if ((tmpbitmap2 = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;
    if ((bitmap_B = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;
    if ((bitmap_D = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;
    if ((bitmap_E = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;
    if ((bitmap_F = osd_create_bitmap(Machine->drv->screen_width,Machine->drv->screen_height)) == 0)
        return 1;

    memset(dirty_videoram_b,1,sizeof(dirty_videoram_b));
    memset(dirty_chardata_b,1,sizeof(dirty_chardata_b));
    memset(dirty_videoram_d,1,sizeof(dirty_videoram_d));
    memset(dirty_chardata_d,1,sizeof(dirty_chardata_d));
    memset(dirty_videoram_e,1,sizeof(dirty_videoram_e));
    memset(dirty_chardata_e,1,sizeof(dirty_chardata_e));
    memset(dirty_videoram_f,1,sizeof(dirty_videoram_f));
    memset(dirty_chardata_f,1,sizeof(dirty_chardata_f));

    d_offset = 0;
    e_offset = 0;
    f_offset = 0;

    palette_select = 0;
    stactics_vblank_count = 0;
    stactics_shot_standby = 1;
    stactics_shot_arrive = 0;
    firebeam_state = 0;
    old_firebeam_state = 0;

    /* Create a fake character set for LED fire beam */

    memset(firechar,0,sizeof(firechar));
    for(i=0;i<256;i++)
    {
        for(j=0;j<8;j++)
        {
            if ((i>>j)&0x01)
            {
                firechar[i*9+(7-j)]   |= (0x01<<(7-j));
                firechar[i*9+(7-j)+1] |= (0x01<<(7-j));
            }
        }
    }

    for(i=0;i<256;i++)
    {
        decodechar(Machine->gfx[4],
                   i,
                   firechar,
                   Machine->drv->gfxdecodeinfo[4].gfxlayout);
    }

    /* Decode the Fire Beam ROM for later      */
    /* (I am basically just juggling the bytes */
    /* and storing it again to make it easier) */

    firebeam_data = Machine->memory_region[1];

    for(i=0;i<256;i++)
    {
        stactics_beamdata[i*8]   = firebeam_data[i                   ];
        stactics_beamdata[i*8+1] = firebeam_data[i + 1024            ];
        stactics_beamdata[i*8+2] = firebeam_data[i              + 256];
        stactics_beamdata[i*8+3] = firebeam_data[i + 1024       + 256];
        stactics_beamdata[i*8+4] = firebeam_data[i        + 512      ];
        stactics_beamdata[i*8+5] = firebeam_data[i + 1024 + 512      ];
        stactics_beamdata[i*8+6] = firebeam_data[i        + 512 + 256];
        stactics_beamdata[i*8+7] = firebeam_data[i + 1024 + 512 + 256];
    }

    /* Build some characters for simulating the LED displays */

    for(i=0;i<32;i++)
    {
        decodechar(Machine->gfx[5],
                   i,
                   stactics_special_chars,
                   Machine->drv->gfxdecodeinfo[5].gfxlayout);
    }

    stactics_vblank_count = 0;
    stactics_vert_pos = 0;
    stactics_horiz_pos = 0;
    stactics_motor_on = 0;

    return 0;
}


/***************************************************************************

  Stop the video hardware emulation.

***************************************************************************/
void stactics_vh_stop(void)
{
    osd_free_bitmap(tmpbitmap);
    osd_free_bitmap(tmpbitmap2);
    osd_free_bitmap(bitmap_B);
    osd_free_bitmap(bitmap_D);
    osd_free_bitmap(bitmap_E);
    osd_free_bitmap(bitmap_F);
}

int stactics_videoram_b_r(int offset)
{
    return stactics_videoram_b[offset];
}

int stactics_chardata_b_r(int offset)
{
    return stactics_chardata_b[offset];
}

int stactics_videoram_d_r(int offset)
{
    return stactics_videoram_d[offset];
}

int stactics_chardata_d_r(int offset)
{
    return stactics_chardata_d[offset];
}

int stactics_videoram_e_r(int offset)
{
    return stactics_videoram_e[offset];
}

int stactics_chardata_e_r(int offset)
{
    return stactics_chardata_e[offset];
}

int stactics_videoram_f_r(int offset)
{
    return stactics_videoram_f[offset];
}

int stactics_chardata_f_r(int offset)
{
    return stactics_chardata_f[offset];
}

void stactics_palette_w(int offset,int data)
{
    int old_palette_select = palette_select;

    switch (offset)
    {
        case 0:
            palette_select = (palette_select & 0x02) | (data&0x01);
            break;
        case 1:
            palette_select = (palette_select & 0x01) | ((data&0x01)<<1);
            break;
        default:
            return;
    }

    if (old_palette_select != palette_select)
    {
        memset(dirty_videoram_b,1,sizeof(dirty_videoram_b));
        memset(dirty_videoram_d,1,sizeof(dirty_videoram_d));
        memset(dirty_videoram_e,1,sizeof(dirty_videoram_e));
        memset(dirty_videoram_f,1,sizeof(dirty_videoram_f));
    }
    return;
}


void stactics_score_w(int offset, int data)
{
    if (offset < 16)
    {
        stactics_display_buffer[offset] = (data&0x0f)^0x0f;
    }
}

void stactics_scroll_ram_w(int offset,int data)
{
    int temp;

    if (stactics_scroll_ram[offset] != data)
    {
        stactics_scroll_ram[offset] = data;
        temp = (offset&0x700)>>8;
        switch(temp)
        {
            case 4:  
            {
                if (data&0x01)
                    d_offset = offset&0xff;
                break;
            }
            case 5:  
            {
                if (data&0x01)
                    e_offset = offset&0xff;
                break;
            }
            case 6:  
            {
                if (data&0x01)
                    f_offset = offset&0xff;
                break;
            }
        }
    }
}

void stactics_speed_latch_w(int offset, int data)
{
    /* This writes to a shift register which is clocked by   */
    /* a 555 oscillator.  This value determines the speed of */
    /* the LED fire beams as follows:                        */

    /*   555_freq / bits_in_SR * edges_in_SR / states_in_PR67 / frame_rate */
    /*      = num_led_states_per_frame  */
    /*   36439 / 8 * x / 32 / 60 ~= 19/8*x */

    /* Here, we will count the number of rising edges in the shift register */

    int i;
    int num_rising_edges = 0;

    for(i=0;i<8;i++)
    {
        if ( (((data>>i)&0x01) == 1) && (((data>>((i+1)%8))&0x01) == 0))
            num_rising_edges++;
    }

    stactics_states_per_frame = num_rising_edges*19/8;
}

void stactics_shot_trigger_w(int offset, int data)
{
    stactics_shot_standby = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -