1 #include "driver.h"
2 #include "vidhrdw/generic.h"
3
4
5
6 #define VIDEORAM_SIZE 0x1c00
7 #define SPRITERAM_START 0x1800
8 #define SPRITERAM_SIZE (VIDEORAM_SIZE-SPRITERAM_START)
9
10 static data16_t *vram,*buf_spriteram,*buf_spriteram2;
11
12 #define VREG_SIZE 18
13 static data16_t vreg[VREG_SIZE];
14
15 static struct tilemap *tilemap[3];
16
17
18 /***************************************************************************
19
20 Callbacks for the TileMap code
21
22 ***************************************************************************/
23
get_tile_info(int tile_index,int plane)24 static INLINE void get_tile_info(int tile_index,int plane)
25 {
26 data16_t attr;
27
28 tile_index = 2*tile_index + 0x800*plane;
29 attr = vram[tile_index];
30 SET_TILE_INFO(
31 1,
32 vram[tile_index+1],
33 attr & 0x7f,
34 0)
35 tile_info.priority = (attr & 0x0600) >> 9;
36 }
37
get_tile_info0(int tile_index)38 static void get_tile_info0(int tile_index)
39 {
40 get_tile_info(tile_index,0);
41 }
42
get_tile_info1(int tile_index)43 static void get_tile_info1(int tile_index)
44 {
45 get_tile_info(tile_index,1);
46 }
47
get_tile_info2(int tile_index)48 static void get_tile_info2(int tile_index)
49 {
50 get_tile_info(tile_index,2);
51 }
52
53
54
55 /***************************************************************************
56
57 Start the video hardware emulation.
58
59 ***************************************************************************/
60
VIDEO_START(othldrby)61 VIDEO_START( othldrby )
62 {
63 tilemap[0] = tilemap_create(get_tile_info0,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
64 tilemap[1] = tilemap_create(get_tile_info1,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
65 tilemap[2] = tilemap_create(get_tile_info2,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
66
67 vram = auto_malloc(VIDEORAM_SIZE * sizeof(vram[0]));
68 buf_spriteram = auto_malloc(2*SPRITERAM_SIZE * sizeof(buf_spriteram[0]));
69
70 if (!tilemap[0] || !tilemap[1] || !tilemap[2] || !vram || !buf_spriteram)
71 return 1;
72
73 buf_spriteram2 = buf_spriteram + SPRITERAM_SIZE;
74
75 tilemap_set_transparent_pen(tilemap[0],0);
76 tilemap_set_transparent_pen(tilemap[1],0);
77 tilemap_set_transparent_pen(tilemap[2],0);
78
79 return 0;
80 }
81
82
83
84 /***************************************************************************
85
86 Memory handlers
87
88 ***************************************************************************/
89
90 static unsigned int vram_addr,vreg_addr;
91
WRITE16_HANDLER(othldrby_videoram_addr_w)92 WRITE16_HANDLER( othldrby_videoram_addr_w )
93 {
94 vram_addr = data;
95 }
96
READ16_HANDLER(othldrby_videoram_r)97 READ16_HANDLER( othldrby_videoram_r )
98 {
99 if (vram_addr < VIDEORAM_SIZE)
100 return vram[vram_addr++];
101 else
102 {
103 usrintf_showmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr);
104 return 0;
105 }
106 }
107
WRITE16_HANDLER(othldrby_videoram_w)108 WRITE16_HANDLER( othldrby_videoram_w )
109 {
110 if (vram_addr < VIDEORAM_SIZE)
111 {
112 if (vram_addr < SPRITERAM_START)
113 tilemap_mark_tile_dirty(tilemap[vram_addr/0x800],(vram_addr&0x7ff)/2);
114 vram[vram_addr++] = data;
115 }
116 else
117 usrintf_showmessage("GFXRAM OUT OF BOUNDS %04x",vram_addr);
118 }
119
WRITE16_HANDLER(othldrby_vreg_addr_w)120 WRITE16_HANDLER( othldrby_vreg_addr_w )
121 {
122 vreg_addr = data & 0x7f; /* bit 7 is set when screen is flipped */
123 }
124
WRITE16_HANDLER(othldrby_vreg_w)125 WRITE16_HANDLER( othldrby_vreg_w )
126 {
127 if (vreg_addr < VREG_SIZE)
128 vreg[vreg_addr++] = data;
129 else
130 usrintf_showmessage("%06x: VREG OUT OF BOUNDS %04x",activecpu_get_pc(),vreg_addr);
131 }
132
133
134
135 /***************************************************************************
136
137 Display refresh
138
139 ***************************************************************************/
140
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect,int priority)141 static void draw_sprites(struct mame_bitmap *bitmap,const struct rectangle *cliprect,int priority)
142 {
143 int offs;
144
145 for (offs = 0;offs < SPRITERAM_SIZE;offs += 4)
146 {
147 int x,y,color,code,sx,sy,flipx,flipy,sizex,sizey,pri;
148
149
150 pri = (buf_spriteram[offs] & 0x0600) >> 9;
151 if (pri != priority) continue;
152
153 flipx = buf_spriteram[offs] & 0x1000;
154 flipy = 0;
155 color = (buf_spriteram[offs] & 0x01fc) >> 2;
156 code = buf_spriteram[offs+1] | ((buf_spriteram[offs] & 0x0003) << 16);
157 sx = (buf_spriteram[offs+2] >> 7);
158 sy = (buf_spriteram[offs+3] >> 7);
159 sizex = (buf_spriteram[offs+2] & 0x000f) + 1;
160 sizey = (buf_spriteram[offs+3] & 0x000f) + 1;
161
162 if (flip_screen)
163 {
164 flipx = !flipx;
165 flipy = !flipy;
166 sx = 246 - sx;
167 sy = 16 - sy;
168 }
169
170 for (y = 0;y < sizey;y++)
171 {
172 for (x = 0;x < sizex;x++)
173 {
174 drawgfx(bitmap,Machine->gfx[0],
175 code + x + sizex * y,
176 color,
177 flipx,flipy,
178 (sx + (flipx ? (-8*(x+1)+1) : 8*x) - vreg[6]+44) & 0x1ff,(sy + (flipy ? (-8*(y+1)+1) : 8*y) - vreg[7]-9) & 0x1ff,
179 cliprect,TRANSPARENCY_PEN,0);
180 }
181 }
182 }
183 }
184
VIDEO_UPDATE(othldrby)185 VIDEO_UPDATE( othldrby )
186 {
187 int layer;
188
189
190 flip_screen_set(vreg[0x0f] & 0x80);
191
192 for (layer = 0;layer < 3;layer++)
193 {
194 if (flip_screen)
195 {
196 tilemap_set_scrollx(tilemap[layer],0,vreg[2*layer]+59);
197 tilemap_set_scrolly(tilemap[layer],0,vreg[2*layer+1]+248);
198 }
199 else
200 {
201 tilemap_set_scrollx(tilemap[layer],0,vreg[2*layer]-58);
202 tilemap_set_scrolly(tilemap[layer],0,vreg[2*layer+1]+9);
203 }
204 }
205
206 fillbitmap(priority_bitmap,0,cliprect);
207
208 fillbitmap(bitmap,Machine->pens[0],cliprect);
209
210 for (layer = 0;layer < 3;layer++)
211 tilemap_draw(bitmap,cliprect,tilemap[layer],0,0);
212 draw_sprites(bitmap,cliprect,0);
213 for (layer = 0;layer < 3;layer++)
214 tilemap_draw(bitmap,cliprect,tilemap[layer],1,0);
215 draw_sprites(bitmap,cliprect,1);
216 for (layer = 0;layer < 3;layer++)
217 tilemap_draw(bitmap,cliprect,tilemap[layer],2,0);
218 draw_sprites(bitmap,cliprect,2);
219 for (layer = 0;layer < 3;layer++)
220 tilemap_draw(bitmap,cliprect,tilemap[layer],3,0);
221 draw_sprites(bitmap,cliprect,3);
222 }
223
VIDEO_EOF(othldrby)224 VIDEO_EOF( othldrby )
225 {
226 /* sprites need to be delayed two frames */
227 memcpy(buf_spriteram,buf_spriteram2,SPRITERAM_SIZE*sizeof(buf_spriteram[0]));
228 memcpy(buf_spriteram2,&vram[SPRITERAM_START],SPRITERAM_SIZE*sizeof(buf_spriteram[0]));
229 }
230