1 /***************************************************************************
2 
3 	vidhrdw.c
4 
5 	Functions to emulate the video hardware of the machine.
6 
7 	There are only a few differences between the video hardware of Mysterious
8 	Stones and Mat Mania. The tile bank select bit is different and the sprite
9 	selection seems to be different as well. Additionally, the palette is stored
10 	differently. I'm also not sure that the 2nd tile page is really used in
11 	Mysterious Stones.
12 
13 ***************************************************************************/
14 
15 #include "driver.h"
16 #include "vidhrdw/generic.h"
17 
18 
19 
20 unsigned char *mystston_videoram2,*mystston_colorram2;
21 size_t mystston_videoram2_size;
22 unsigned char *mystston_scroll;
23 static int textcolor;
24 static int flipscreen;
25 
26 /***************************************************************************
27 
28   Convert the color PROMs into a more useable format.
29 
30   Mysterious Stones has both palette RAM and a PROM. The PROM is used for
31   text.
32 
33 ***************************************************************************/
mystston_vh_convert_color_prom(unsigned char * palette,unsigned short * colortable,const unsigned char * color_prom)34 void mystston_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
35 {
36 	int i;
37 	#define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
38 	#define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
39 
40 
41 	palette += 3*24;	/* first 24 colors are RAM */
42 
43 	for (i = 0;i < 32;i++)
44 	{
45 		int bit0,bit1,bit2;
46 
47 
48 		/* red component */
49 		bit0 = (*color_prom >> 0) & 0x01;
50 		bit1 = (*color_prom >> 1) & 0x01;
51 		bit2 = (*color_prom >> 2) & 0x01;
52 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
53 		/* green component */
54 		bit0 = (*color_prom >> 3) & 0x01;
55 		bit1 = (*color_prom >> 4) & 0x01;
56 		bit2 = (*color_prom >> 5) & 0x01;
57 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
58 		/* blue component */
59 		bit0 = 0;
60 		bit1 = (*color_prom >> 6) & 0x01;
61 		bit2 = (*color_prom >> 7) & 0x01;
62 		*(palette++) = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
63 
64 		color_prom++;
65 	}
66 }
67 
68 
69 /***************************************************************************
70 
71   Start the video hardware emulation.
72 
73 ***************************************************************************/
mystston_vh_start(void)74 int mystston_vh_start(void)
75 {
76 	if ((dirtybuffer = (unsigned char*)malloc(videoram_size)) == 0)
77 		return 1;
78 	memset(dirtybuffer,1,videoram_size);
79 
80 	/* Mysterious Stones has a virtual screen twice as large as the visible screen */
81 	if ((tmpbitmap = bitmap_alloc(Machine->drv->screen_width,2*Machine->drv->screen_height)) == 0)
82 	{
83 		free(dirtybuffer);
84 		return 1;
85 	}
86 
87 	return 0;
88 }
89 
90 
91 
92 /***************************************************************************
93 
94   Stop the video hardware emulation.
95 
96 ***************************************************************************/
mystston_vh_stop(void)97 void mystston_vh_stop(void)
98 {
99 	free(dirtybuffer);
100 	bitmap_free(tmpbitmap);
101 }
102 
103 
104 
WRITE_HANDLER(mystston_2000_w)105 WRITE_HANDLER( mystston_2000_w )
106 {
107 	/* bits 0 and 1 are text color */
108 	textcolor = ((data & 0x01) << 1) | ((data & 0x02) >> 1);
109 
110 	/* bits 4 and 5 are coin counters */
111 	coin_counter_w(0,data & 0x10);
112 	coin_counter_w(1,data & 0x20);
113 
114 	/* bit 7 is screen flip */
115 	if (flipscreen != (data & 0x80))
116 	{
117 		flipscreen = data & 0x80;
118 		memset(dirtybuffer,1,videoram_size);
119 	}
120 
121 	/* other bits unused? */
122 //logerror("PC %04x: 2000 = %02x\n",cpu_get_pc(),data);
123 }
124 
125 
126 
127 /***************************************************************************
128 
129   Draw the game screen in the given osd_bitmap.
130   Do NOT call osd_update_display() from this function, it will be called by
131   the main emulation engine.
132 
133 ***************************************************************************/
mystston_vh_screenrefresh(struct osd_bitmap * bitmap,int full_refresh)134 void mystston_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
135 {
136 	int offs;
137 
138 
139 	if (palette_recalc())
140 		memset(dirtybuffer,1,videoram_size);
141 
142 	/* for every character in the Video RAM, check if it has been modified */
143 	/* since last time and update it accordingly. */
144 	for (offs = videoram_size - 1;offs >= 0;offs--)
145 	{
146 		if (dirtybuffer[offs])
147 		{
148 			int sx,sy,flipy;
149 
150 
151 			dirtybuffer[offs] = 0;
152 
153 			sx = 15 - offs / 32;
154 			sy = offs % 32;
155 			flipy = (sy >= 16) ? 1 : 0;	/* flip horizontally tiles on the right half of the bitmap */
156 			if (flipscreen)
157 			{
158 				sx = 15 - sx;
159 				sy = 31 - sy;
160 				flipy = !flipy;
161 			}
162 			drawgfx(tmpbitmap,Machine->gfx[1],
163 					videoram[offs] + 256 * (colorram[offs] & 0x01),
164 					0,
165 					flipscreen,flipy,
166 					16*sx,16*sy,
167 					0,TRANSPARENCY_NONE,0);
168 		}
169 	}
170 
171 
172 	/* copy the temporary bitmap to the screen */
173 	{
174 		int scrolly;
175 
176 
177 		scrolly = -*mystston_scroll;
178 		if (flipscreen) scrolly = 256 - scrolly;
179 
180 		copyscrollbitmap(bitmap,tmpbitmap,0,0,1,&scrolly,&Machine->visible_area,TRANSPARENCY_NONE,0);
181 	}
182 
183 
184 	/* Draw the sprites */
185 	for (offs = 0;offs < spriteram_size;offs += 4)
186 	{
187 		if (spriteram[offs] & 0x01)
188 		{
189 			int sx,sy,flipx,flipy;
190 
191 
192 			sx = 240 - spriteram[offs+3];
193 			sy = (240 - spriteram[offs+2]) & 0xff;
194 			flipx = spriteram[offs] & 0x04;
195 			flipy = spriteram[offs] & 0x02;
196 			if (flipscreen)
197 			{
198 				sx = 240 - sx;
199 				sy = 240 - sy;
200 				flipx = !flipx;
201 				flipy = !flipy;
202 			}
203 
204 			drawgfx(bitmap,Machine->gfx[2],
205 					spriteram[offs+1] + ((spriteram[offs] & 0x10) << 4),
206 					(spriteram[offs] & 0x08) >> 3,
207 					flipx,flipy,
208 					sx,sy,
209 					&Machine->visible_area,TRANSPARENCY_PEN,0);
210 		}
211 	}
212 
213 
214 	/* draw the frontmost playfield. They are characters, but draw them as sprites */
215 	for (offs = mystston_videoram2_size - 1;offs >= 0;offs--)
216 	{
217 		int sx,sy;
218 
219 
220 		sx = 31 - offs / 32;
221 		sy = offs % 32;
222 		if (flipscreen)
223 		{
224 			sx = 31 - sx;
225 			sy = 31 - sy;
226 		}
227 
228 		drawgfx(bitmap,Machine->gfx[0],
229 				mystston_videoram2[offs] + 256 * (mystston_colorram2[offs] & 0x07),
230 				textcolor,
231 				flipscreen,flipscreen,
232 				8*sx,8*sy,
233 				&Machine->visible_area,TRANSPARENCY_PEN,0);
234 	}
235 }
236