summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/volfied.cpp
blob: 70ffc0bfb203788df3fbaa2f45d2c261764b861a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, Nicola Salmoria
#include "emu.h"
#include "includes/volfied.h"

/******************************************************
          INITIALISATION AND CLEAN-UP
******************************************************/

void volfied_state::video_start()
{
	m_video_ram = std::make_unique<uint16_t[]>(0x40000);

	m_video_ctrl = 0;
	m_video_mask = 0;

	save_pointer(NAME(m_video_ram), 0x40000);
	save_item(NAME(m_video_ctrl));
	save_item(NAME(m_video_mask));
}


/*******************************************************
          READ AND WRITE HANDLERS
*******************************************************/

READ16_MEMBER(volfied_state::video_ram_r)
{
	return m_video_ram[offset];
}

WRITE16_MEMBER(volfied_state::video_ram_w)
{
	mem_mask &= m_video_mask;

	COMBINE_DATA(&m_video_ram[offset]);
}

WRITE16_MEMBER(volfied_state::video_ctrl_w)
{
	COMBINE_DATA(&m_video_ctrl);
}

READ16_MEMBER(volfied_state::video_ctrl_r)
{
	/* Could this be some kind of hardware collision detection? If bit 6 is
	   set the game will check for collisions with the large enemy, whereas
	   bit 5 does the same for small enemies. Bit 7 is also used although
	   its purpose is unclear. This register is usually read during a VBI
	   and stored in work RAM for later use. */

	return 0x60;
}

WRITE16_MEMBER(volfied_state::video_mask_w)
{
	COMBINE_DATA(&m_video_mask);
}

WRITE16_MEMBER(volfied_state::sprite_ctrl_w)
{
	m_pc090oj->set_sprite_ctrl((data & 0x3c) >> 2);
}


/*******************************************************
                SCREEN REFRESH
*******************************************************/

void volfied_state::refresh_pixel_layer( bitmap_ind16 &bitmap )
{
	/*********************************************************

	VIDEO RAM has 2 screens x 256 rows x 512 columns x 16 bits

	x---------------  select image
	-x--------------  ?             (used for 3-D corners)
	--x-------------  ?             (used for 3-D walls)
	---xxxx---------  image B
	-------xxx------  palette index bits #8 to #A
	----------x-----  ?
	-----------x----  ?
	------------xxxx  image A

	'3d' corners & walls are made using unknown bits for each
	line the player draws.  However, on the pcb they just
	appear as solid black. Perhaps it was prototype code that
	was turned off at some stage.

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

	uint16_t* p = m_video_ram.get();
	int width = m_screen->width();
	int height = m_screen->height();

	if (m_video_ctrl & 1)
		p += 0x20000;

	for (int y = 0; y < height; y++)
	{
		for (int x = 1; x < width + 1; x++) // Hmm, 1 pixel offset is needed to align properly with sprites
		{
			int color = (p[x] << 2) & 0x700;

			if (p[x] & 0x8000)
			{
				color |= 0x800 | ((p[x] >> 9) & 0xf);

				if (p[x] & 0x2000)
					color &= ~0xf;    /* hack */
			}
			else
				color |= p[x] & 0xf;

			bitmap.pix16(y, x - 1) = color;
		}

		p += 512;
	}
}

uint32_t volfied_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	screen.priority().fill(0, cliprect);
	refresh_pixel_layer(bitmap);
	m_pc090oj->draw_sprites(bitmap, cliprect, screen.priority(), 0);
	return 0;
}