1 // license:BSD-3-Clause
2 // copyright-holders:Bryan McPhail, Nicola Salmoria
3 #include "emu.h"
4 #include "includes/volfied.h"
5 
6 /******************************************************
7           INITIALISATION AND CLEAN-UP
8 ******************************************************/
9 
video_start()10 void volfied_state::video_start()
11 {
12 	m_video_ram = std::make_unique<uint16_t[]>(0x40000);
13 
14 	m_video_ctrl = 0;
15 	m_video_mask = 0;
16 
17 	save_pointer(NAME(m_video_ram), 0x40000);
18 	save_item(NAME(m_video_ctrl));
19 	save_item(NAME(m_video_mask));
20 }
21 
22 
23 /*******************************************************
24           READ AND WRITE HANDLERS
25 *******************************************************/
26 
video_ram_r(offs_t offset)27 uint16_t volfied_state::video_ram_r(offs_t offset)
28 {
29 	return m_video_ram[offset];
30 }
31 
video_ram_w(offs_t offset,uint16_t data,uint16_t mem_mask)32 void volfied_state::video_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
33 {
34 	mem_mask &= m_video_mask;
35 
36 	COMBINE_DATA(&m_video_ram[offset]);
37 }
38 
video_ctrl_w(offs_t offset,uint16_t data,uint16_t mem_mask)39 void volfied_state::video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
40 {
41 	COMBINE_DATA(&m_video_ctrl);
42 }
43 
video_ctrl_r()44 uint16_t volfied_state::video_ctrl_r()
45 {
46 	/* Could this be some kind of hardware collision detection? If bit 6 is
47 	   set the game will check for collisions with the large enemy, whereas
48 	   bit 5 does the same for small enemies. Bit 7 is also used although
49 	   its purpose is unclear. This register is usually read during a VBI
50 	   and stored in work RAM for later use. */
51 
52 	return 0x60;
53 }
54 
video_mask_w(offs_t offset,uint16_t data,uint16_t mem_mask)55 void volfied_state::video_mask_w(offs_t offset, uint16_t data, uint16_t mem_mask)
56 {
57 	COMBINE_DATA(&m_video_mask);
58 }
59 
volfied_colpri_cb(u32 & sprite_colbank,u32 & pri_mask,u16 sprite_ctrl)60 void volfied_state::volfied_colpri_cb(u32 &sprite_colbank, u32 &pri_mask, u16 sprite_ctrl)
61 {
62 	sprite_colbank = 0x100 | ((sprite_ctrl & 0x3c) << 2);
63 	pri_mask = 0; /* sprites over everything */
64 }
65 
66 
67 /*******************************************************
68                 SCREEN REFRESH
69 *******************************************************/
70 
refresh_pixel_layer(bitmap_ind16 & bitmap)71 void volfied_state::refresh_pixel_layer( bitmap_ind16 &bitmap )
72 {
73 	/*********************************************************
74 
75 	VIDEO RAM has 2 screens x 256 rows x 512 columns x 16 bits
76 
77 	x---------------  select image
78 	-x--------------  ?             (used for 3-D corners)
79 	--x-------------  ?             (used for 3-D walls)
80 	---xxxx---------  image B
81 	-------xxx------  palette index bits #8 to #A
82 	----------x-----  ?
83 	-----------x----  ?
84 	------------xxxx  image A
85 
86 	'3d' corners & walls are made using unknown bits for each
87 	line the player draws.  However, on the pcb they just
88 	appear as solid black. Perhaps it was prototype code that
89 	was turned off at some stage.
90 
91 	*********************************************************/
92 
93 	uint16_t* p = m_video_ram.get();
94 	int width = m_screen->width();
95 	int height = m_screen->height();
96 
97 	if (m_video_ctrl & 1)
98 		p += 0x20000;
99 
100 	for (int y = 0; y < height; y++)
101 	{
102 		for (int x = 1; x < width + 1; x++) // Hmm, 1 pixel offset is needed to align properly with sprites
103 		{
104 			int color = (p[x] << 2) & 0x700;
105 
106 			if (p[x] & 0x8000)
107 			{
108 				color |= 0x800 | ((p[x] >> 9) & 0xf);
109 
110 				if (p[x] & 0x2000)
111 					color &= ~0xf;    /* hack */
112 			}
113 			else
114 				color |= p[x] & 0xf;
115 
116 			bitmap.pix(y, x - 1) = color;
117 		}
118 
119 		p += 512;
120 	}
121 }
122 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)123 uint32_t volfied_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
124 {
125 	screen.priority().fill(0, cliprect);
126 	refresh_pixel_layer(bitmap);
127 	m_pc090oj->draw_sprites(screen, bitmap, cliprect);
128 	return 0;
129 }
130