trunk/src/mame/video/vsystem_spr.c
| r18480 | r18481 | |
| 1 | 1 | // Video System Sprites |
| 2 | 2 | // todo: |
| 3 | | // unify these functions (secondary stage tile lookup differs between games, use callback) |
| 3 | // unify these functions (secondary stage lookup differs between games, use callback) |
| 4 | 4 | |
| 5 | 5 | // according to gstriker this is probably the Fujitsu CG10103 |
| 6 | 6 | |
| r18480 | r18481 | |
| 38 | 38 | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | void vsystem_spr_device::get_sprite_attributes(UINT16* ram) |
| 42 | { |
| 43 | /* |
| 44 | attr_start + 0x0000 |
| 45 | ---- ---x xxxx xxxx oy |
| 46 | ---- xxx- ---- ---- ysize |
| 47 | xxxx ---- ---- ---- zoomy |
| 41 | 48 | |
| 49 | attr_start + 0x0001 |
| 50 | ---- ---x xxxx xxxx ox |
| 51 | ---- xxx- ---- ---- xsize |
| 52 | xxxx ---- ---- ---- zoomx |
| 42 | 53 | |
| 54 | attr_start + 0x0002 |
| 55 | -x-- ---- ---- ---- flipx |
| 56 | x--- ---- ---- ---- flipy |
| 57 | --xx xxxx ---- ---- color |
| 58 | --xx ---- ---- ---- priority? (upper color bits) |
| 59 | ---- ---- ---- ---x map start (msb) |
| 60 | |
| 61 | attr_start + 0x0003 |
| 62 | xxxx xxxx xxxx xxxx map start (lsb) |
| 63 | */ |
| 64 | |
| 65 | curr_sprite.oy = (ram[0] & 0x01ff); |
| 66 | curr_sprite.ysize = (ram[0] & 0x0e00) >> 9; |
| 67 | curr_sprite.zoomy = (ram[0] & 0xf000) >> 12; |
| 68 | |
| 69 | curr_sprite.ox = (ram[1] & 0x01ff); |
| 70 | curr_sprite.xsize = (ram[1] & 0x0e00) >> 9; |
| 71 | curr_sprite.zoomx = (ram[1] & 0xf000) >> 12; |
| 72 | |
| 73 | curr_sprite.flipx = (ram[2] & 0x4000); |
| 74 | curr_sprite.flipy = (ram[2] & 0x8000); |
| 75 | curr_sprite.color = (ram[2] & 0x3f00) >> 8; |
| 76 | curr_sprite.pri = (ram[2] & 0x3000) >> 12; |
| 77 | curr_sprite.map = (ram[2] & 0x0001) << 16; |
| 78 | |
| 79 | curr_sprite.map |= (ram[3] & 0xffff); |
| 80 | |
| 81 | } |
| 82 | |
| 43 | 83 | // zooming is wrong for 3on3dunk ... suprslam implementation is probably better |
| 44 | 84 | void vsystem_spr_device::draw_sprites_inufuku( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 45 | 85 | { |
| r18480 | r18481 | |
| 57 | 97 | if ((spriteram[offs] & 0x8000) == 0x0000) |
| 58 | 98 | { |
| 59 | 99 | int attr_start; |
| 60 | | int map_start; |
| 61 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; |
| 62 | | int priority, priority_mask; |
| 100 | int x, y; |
| 101 | int priority_mask; |
| 63 | 102 | |
| 64 | 103 | attr_start = 4 * (spriteram[offs] & 0x03ff); |
| 65 | 104 | |
| 66 | | /* |
| 67 | | attr_start + 0x0000 |
| 68 | | ---- ---x xxxx xxxx oy |
| 69 | | ---- xxx- ---- ---- ysize |
| 70 | | xxxx ---- ---- ---- zoomy |
| 105 | get_sprite_attributes(&spriteram[attr_start]); |
| 71 | 106 | |
| 72 | | attr_start + 0x0001 |
| 73 | | ---- ---x xxxx xxxx ox |
| 74 | | ---- xxx- ---- ---- xsize |
| 75 | | xxxx ---- ---- ---- zoomx |
| 107 | curr_sprite.oy += 1; |
| 108 | curr_sprite.map &= 0x7fff; |
| 76 | 109 | |
| 77 | | attr_start + 0x0002 |
| 78 | | -x-- ---- ---- ---- flipx |
| 79 | | x--- ---- ---- ---- flipy |
| 80 | | --xx xxxx ---- ---- color |
| 81 | | --xx ---- ---- ---- priority? |
| 82 | | ---- ---- xxxx xxxx unused? |
| 83 | | |
| 84 | | attr_start + 0x0003 |
| 85 | | -xxx xxxx xxxx xxxx map start |
| 86 | | x--- ---- ---- ---- unused? |
| 87 | | */ |
| 88 | | |
| 89 | | ox = (spriteram[attr_start + 1] & 0x01ff) + 0; |
| 90 | | xsize = (spriteram[attr_start + 1] & 0x0e00) >> 9; |
| 91 | | zoomx = (spriteram[attr_start + 1] & 0xf000) >> 12; |
| 92 | | oy = (spriteram[attr_start + 0] & 0x01ff) + 1; |
| 93 | | ysize = (spriteram[attr_start + 0] & 0x0e00) >> 9; |
| 94 | | zoomy = (spriteram[attr_start + 0] & 0xf000) >> 12; |
| 95 | | flipx = spriteram[attr_start + 2] & 0x4000; |
| 96 | | flipy = spriteram[attr_start + 2] & 0x8000; |
| 97 | | color = (spriteram[attr_start + 2] & 0x3f00) >> 8; |
| 98 | | priority = (spriteram[attr_start + 2] & 0x3000) >> 12; |
| 99 | | map_start = (spriteram[attr_start + 3] & 0x7fff) << 1; |
| 100 | | |
| 101 | | switch (priority) |
| 110 | switch (curr_sprite.pri) |
| 102 | 111 | { |
| 103 | 112 | default: |
| 104 | 113 | case 0: priority_mask = 0x00; break; |
| r18480 | r18481 | |
| 107 | 116 | case 1: priority_mask = 0xf0; break; |
| 108 | 117 | } |
| 109 | 118 | |
| 110 | | ox += (xsize * zoomx + 2) / 4; |
| 111 | | oy += (ysize * zoomy + 2) / 4; |
| 119 | curr_sprite.ox += (curr_sprite.xsize * curr_sprite.zoomx + 2) / 4; |
| 120 | curr_sprite.oy += (curr_sprite.ysize * curr_sprite.zoomy + 2) / 4; |
| 112 | 121 | |
| 113 | | zoomx = 32 - zoomx; |
| 114 | | zoomy = 32 - zoomy; |
| 122 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 123 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 115 | 124 | |
| 116 | | for (y = 0; y <= ysize; y++) |
| 125 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 117 | 126 | { |
| 118 | 127 | int sx, sy; |
| 119 | 128 | |
| 120 | | if (flipy) |
| 121 | | sy = (oy + zoomy * (ysize - y) / 2 + 16) & 0x1ff; |
| 129 | if (curr_sprite.flipy) |
| 130 | sy = (curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y) / 2 + 16) & 0x1ff; |
| 122 | 131 | else |
| 123 | | sy = (oy + zoomy * y / 2 + 16) & 0x1ff; |
| 132 | sy = (curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff; |
| 124 | 133 | |
| 125 | | for (x = 0; x <= xsize; x++) |
| 134 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 126 | 135 | { |
| 127 | 136 | int code; |
| 128 | 137 | |
| 129 | | if (flipx) |
| 130 | | sx = (ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff; |
| 138 | if (curr_sprite.flipx) |
| 139 | sx = (curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff; |
| 131 | 140 | else |
| 132 | | sx = (ox + zoomx * x / 2 + 16) & 0x1ff; |
| 141 | sx = (curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff; |
| 133 | 142 | |
| 134 | | code = ((spriteram2[map_start] & 0x0007) << 16) + spriteram2[map_start + 1]; |
| 143 | code = ((spriteram2[curr_sprite.map*2] & 0x0007) << 16) + spriteram2[(curr_sprite.map*2)+ 1]; |
| 135 | 144 | |
| 136 | 145 | pdrawgfxzoom_transpen(bitmap, cliprect, machine.gfx[2], |
| 137 | 146 | code, |
| 138 | | color, |
| 139 | | flipx, flipy, |
| 147 | curr_sprite.color, |
| 148 | curr_sprite.flipx, curr_sprite.flipy, |
| 140 | 149 | sx - 16, sy - 16, |
| 141 | | zoomx << 11, zoomy << 11, |
| 150 | curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, |
| 142 | 151 | machine.priority_bitmap,priority_mask, 15); |
| 143 | 152 | |
| 144 | | map_start += 2; |
| 153 | curr_sprite.map ++; |
| 145 | 154 | } |
| 146 | 155 | } |
| 147 | 156 | } |
| r18480 | r18481 | |
| 153 | 162 | /* todo, fix zooming correctly, it's _not_ like aerofgt */ |
| 154 | 163 | void vsystem_spr_device::draw_sprites_suprslam( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 155 | 164 | { |
| 156 | | /* SPRITE INFO |
| 157 | | |
| 158 | | Video System hardware, like aerofgt etc. |
| 159 | | |
| 160 | | the sprites use 2 areas of ram, one containing a spritelist + sprite attributes, the other |
| 161 | | contains the sprite tile #'s to use |
| 162 | | |
| 163 | | sprite attribute info (4 words per sprite) |
| 164 | | |
| 165 | | | ZZZZ hhhy yyyy yyyy | zzzz wwwx xxxx xxxx | -fpp pppp ---- ---- | -ooo oooo oooo oooo | |
| 166 | | |
| 167 | | x = x position |
| 168 | | y = y position |
| 169 | | w = width |
| 170 | | h = height |
| 171 | | zZ = y zoom / x zoom |
| 172 | | f = xflip |
| 173 | | p = palette / colour |
| 174 | | o = offset to tile data in other ram area |
| 175 | | |
| 176 | | */ |
| 177 | | |
| 178 | 165 | gfx_element *gfx = machine.gfx[1]; |
| 179 | 166 | UINT16 *source = spriteram; |
| 180 | 167 | UINT16 *source2 = spriteram; |
| r18480 | r18481 | |
| 190 | 177 | source++; |
| 191 | 178 | /* DRAW START */ |
| 192 | 179 | { |
| 193 | | int ypos = source2[sprnum + 0] & 0x1ff; |
| 194 | | int high = (source2[sprnum + 0] & 0x0e00) >> 9; |
| 195 | | int yzoom = (source2[sprnum + 0] & 0xf000) >> 12; |
| 180 | get_sprite_attributes(&source2[sprnum]); |
| 196 | 181 | |
| 197 | | int xpos = source2[sprnum + 1] & 0x1ff; |
| 198 | | int wide = (source2[sprnum + 1] & 0x0e00) >> 9; |
| 199 | | int xzoom = (source2[sprnum + 1] & 0xf000) >> 12; |
| 200 | | |
| 201 | | int col = (source2[sprnum + 2] & 0x3f00) >> 8; |
| 202 | | int flipx = (source2[sprnum + 2] & 0x4000) >> 14; |
| 203 | | // int flipy = (source2[sprnum + 2] & 0x8000) >> 15; |
| 204 | | |
| 205 | | int word_offset = source2[sprnum + 3] & 0x7fff; |
| 182 | curr_sprite.map &= 0x7fff; |
| 183 | |
| 206 | 184 | int xcnt, ycnt; |
| 207 | 185 | |
| 208 | 186 | int loopno = 0; |
| 209 | 187 | |
| 210 | | xzoom = 32 - xzoom; |
| 211 | | yzoom = 32 - yzoom; |
| 188 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 189 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 212 | 190 | |
| 213 | | if (ypos > 0xff) ypos -=0x200; |
| 191 | if (curr_sprite.oy > 0xff) curr_sprite.oy -=0x200; |
| 214 | 192 | |
| 215 | | for (ycnt = 0; ycnt < high+1; ycnt ++) |
| 193 | for (ycnt = 0; ycnt < curr_sprite.ysize+1; ycnt ++) |
| 216 | 194 | { |
| 217 | | if (!flipx) |
| 195 | if (!curr_sprite.flipx) |
| 218 | 196 | { |
| 219 | | for (xcnt = 0; xcnt < wide+1; xcnt ++) |
| 197 | for (xcnt = 0; xcnt < curr_sprite.xsize+1; xcnt ++) |
| 220 | 198 | { |
| 221 | | int tileno = spriteram2[word_offset + loopno]; |
| 222 | | drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 0, 0,xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); |
| 223 | | drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 0, 0,-0x200+xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); |
| 199 | int startno = spriteram2[curr_sprite.map + loopno]; |
| 200 | drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 0, 0,curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15); |
| 201 | drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 0, 0,-0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15); |
| 224 | 202 | loopno ++; |
| 225 | 203 | } |
| 226 | 204 | } |
| 227 | 205 | else |
| 228 | 206 | { |
| 229 | | for (xcnt = wide; xcnt >= 0; xcnt --) |
| 207 | for (xcnt = curr_sprite.xsize; xcnt >= 0; xcnt --) |
| 230 | 208 | { |
| 231 | | int tileno = spriteram2[word_offset + loopno]; |
| 232 | | drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 1, 0,xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); |
| 233 | | drawgfxzoom_transpen(bitmap, cliprect, gfx, tileno, col, 1, 0,-0x200+xpos + xcnt * xzoom/2, ypos + ycnt * yzoom/2,xzoom << 11, yzoom << 11, 15); |
| 209 | int startno = spriteram2[curr_sprite.map + loopno]; |
| 210 | drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 1, 0,curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15); |
| 211 | drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 1, 0,-0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15); |
| 234 | 212 | loopno ++; |
| 235 | 213 | } |
| 236 | 214 | } |
| r18480 | r18481 | |
| 241 | 219 | |
| 242 | 220 | |
| 243 | 221 | |
| 244 | | static void draw_sprite_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, UINT16 spriteno, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 222 | void vsystem_spr_device::draw_sprite_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, UINT16 spriteno, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 245 | 223 | { |
| 246 | 224 | /*- SPR RAM Format -** |
| 247 | 225 | |
| r18480 | r18481 | |
| 249 | 227 | |
| 250 | 228 | zzzz sssp pppp pppp (y zoom, y size, y position) |
| 251 | 229 | zzzz sssp pppp pppp (x zoom, x size, x position) |
| 252 | | yxpc cccc ---- ---- (flipy, flipx, priority?, colour) |
| 253 | | -nnn nnnn nnnn nnnn (tile lookup) |
| 230 | yxpc cccc ---- ---- (flipy, >flipx, priority?, color) |
| 231 | -nnn nnnn nnnn nnnn (map_start lookup) |
| 254 | 232 | |
| 255 | 233 | */ |
| 256 | 234 | |
| r18480 | r18481 | |
| 259 | 237 | UINT16 *source = &spriteram[spriteno*4]; |
| 260 | 238 | gfx_element *gfx = machine.gfx[0]; |
| 261 | 239 | |
| 240 | get_sprite_attributes(&source[0]); |
| 262 | 241 | |
| 263 | | int yzoom = (source[0] & 0xf000) >> 12; |
| 264 | | int xzoom = (source[1] & 0xf000) >> 12; |
| 242 | curr_sprite.map &= 0xffff; |
| 243 | curr_sprite.color &= 0x1f; |
| 265 | 244 | |
| 266 | | int ysize = (source[0] & 0x0e00) >> 9; |
| 267 | | int xsize = (source[1] & 0x0e00) >> 9; |
| 245 | curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4; |
| 246 | curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4; |
| 268 | 247 | |
| 269 | | int ypos = source[0] & 0x01ff; |
| 270 | | int xpos = source[1] & 0x01ff; |
| 248 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 249 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 271 | 250 | |
| 272 | | int yflip = source[2] & 0x8000; |
| 273 | | int xflip = source[2] & 0x4000; |
| 274 | | int color = (source[2] & 0x1f00) >> 8; |
| 275 | 251 | |
| 276 | | int tile = source[3] & 0xffff; |
| 277 | | |
| 278 | | xpos += (xsize*xzoom+2)/4; |
| 279 | | ypos += (ysize*yzoom+2)/4; |
| 280 | | |
| 281 | | xzoom = 32 - xzoom; |
| 282 | | yzoom = 32 - yzoom; |
| 283 | | |
| 284 | | |
| 285 | | for (y = 0;y <= ysize;y++) |
| 252 | for (y = 0;y <= curr_sprite.ysize;y++) |
| 286 | 253 | { |
| 287 | 254 | int sx,sy; |
| 288 | 255 | |
| 289 | | if (yflip) sy = ((ypos + yzoom * (ysize - y)/2 + 16) & 0x1ff) - 16; |
| 290 | | else sy = ((ypos + yzoom * y / 2 + 16) & 0x1ff) - 16; |
| 256 | if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16; |
| 257 | else sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 291 | 258 | |
| 292 | | for (x = 0;x <= xsize;x++) |
| 259 | for (x = 0;x <= curr_sprite.xsize;x++) |
| 293 | 260 | { |
| 294 | 261 | |
| 295 | 262 | /* this indirection is a bit different to the other video system games */ |
| 296 | | int realtile; |
| 263 | int realstart; |
| 297 | 264 | |
| 298 | | realtile = spriteram2[tile&0x7fff]; |
| 265 | realstart = spriteram2[curr_sprite.map&0x7fff]; |
| 299 | 266 | |
| 300 | | if (realtile > 0x3fff) |
| 267 | if (realstart > 0x3fff) |
| 301 | 268 | { |
| 302 | 269 | int block; |
| 303 | 270 | |
| 304 | | block = (realtile & 0x3800)>>11; |
| 271 | block = (realstart & 0x3800)>>11; |
| 305 | 272 | |
| 306 | | realtile &= 0x07ff; |
| 307 | | realtile |= spriteram3[block] * 0x800; |
| 273 | realstart &= 0x07ff; |
| 274 | realstart |= spriteram3[block] * 0x800; |
| 308 | 275 | } |
| 309 | 276 | |
| 310 | | if (xflip) sx = ((xpos + xzoom * (xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 311 | | else sx = ((xpos + xzoom * x / 2 + 16) & 0x1ff) - 16; |
| 277 | if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 278 | else sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 312 | 279 | |
| 313 | 280 | |
| 314 | 281 | drawgfxzoom_transpen(bitmap,cliprect,gfx, |
| 315 | | realtile, |
| 316 | | color, |
| 317 | | xflip,yflip, |
| 282 | realstart, |
| 283 | curr_sprite.color, |
| 284 | curr_sprite.flipx,curr_sprite.flipy, |
| 318 | 285 | sx,sy, |
| 319 | | xzoom << 11, yzoom << 11,15); |
| 286 | curr_sprite.zoomx << 11, curr_sprite.zoomy << 11,15); |
| 320 | 287 | |
| 321 | | tile++; |
| 288 | curr_sprite.map++; |
| 322 | 289 | |
| 323 | 290 | } |
| 324 | 291 | } |
| r18480 | r18481 | |
| 349 | 316 | while (offs < 0x0400 && (spriteram[offs] & 0x4000) == 0) |
| 350 | 317 | { |
| 351 | 318 | int attr_start; |
| 352 | | int map_start; |
| 353 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; |
| 319 | int x, y; |
| 354 | 320 | /* table hand made by looking at the ship explosion in aerofgt attract mode */ |
| 355 | 321 | /* it's almost a logarithmic scale but not exactly */ |
| 356 | 322 | static const int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 }; |
| 357 | 323 | |
| 358 | 324 | attr_start = 4 * (spriteram[offs++] & 0x03ff); |
| 359 | 325 | |
| 360 | | ox = spriteram[attr_start + 1] & 0x01ff; |
| 361 | | xsize = (spriteram[attr_start + 1] & 0x0e00) >> 9; |
| 362 | | zoomx = (spriteram[attr_start + 1] & 0xf000) >> 12; |
| 363 | | oy = spriteram[attr_start + 0] & 0x01ff; |
| 364 | | ysize = (spriteram[attr_start + 0] & 0x0e00) >> 9; |
| 365 | | zoomy = (spriteram[attr_start + 0] & 0xf000) >> 12; |
| 366 | | flipx = spriteram[attr_start + 2] & 0x4000; |
| 367 | | flipy = spriteram[attr_start + 2] & 0x8000; |
| 368 | | color = (spriteram[attr_start + 2] & 0x1f00) >> 8; |
| 369 | | map_start = spriteram[attr_start + 3] & 0x7fff; |
| 326 | get_sprite_attributes(&spriteram[attr_start]); |
| 370 | 327 | |
| 371 | | zoomx = 16 - zoomtable[zoomx] / 8; |
| 372 | | zoomy = 16 - zoomtable[zoomy] / 8; |
| 328 | curr_sprite.color &= 0x1f; |
| 329 | curr_sprite.map &= 0x7fff; |
| 373 | 330 | |
| 374 | | if (spriteram[attr_start + 2] & 0x20ff) color = machine.rand(); |
| 331 | curr_sprite.zoomx = 16 - zoomtable[curr_sprite.zoomx] / 8; |
| 332 | curr_sprite.zoomy = 16 - zoomtable[curr_sprite.zoomy] / 8; |
| 375 | 333 | |
| 376 | | for (y = 0; y <= ysize; y++) |
| 334 | if (spriteram[attr_start + 2] & 0x20ff) curr_sprite.color = machine.rand(); |
| 335 | |
| 336 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 377 | 337 | { |
| 378 | 338 | int sx,sy; |
| 379 | 339 | |
| 380 | | if (flipy) sy = ((oy + zoomy * (ysize - y) + 16) & 0x1ff) - 16; |
| 381 | | else sy = ((oy + zoomy * y + 16) & 0x1ff) - 16; |
| 340 | if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y) + 16) & 0x1ff) - 16; |
| 341 | else sy = ((curr_sprite.oy + curr_sprite.zoomy * y + 16) & 0x1ff) - 16; |
| 382 | 342 | |
| 383 | | for (x = 0; x <= xsize; x++) |
| 343 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 384 | 344 | { |
| 385 | 345 | int code; |
| 386 | 346 | |
| 387 | | if (flipx) sx = ((ox + zoomx * (xsize - x) + 16) & 0x1ff) - 16; |
| 388 | | else sx = ((ox + zoomx * x + 16) & 0x1ff) - 16; |
| 347 | if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) + 16) & 0x1ff) - 16; |
| 348 | else sx = ((curr_sprite.ox + curr_sprite.zoomx * x + 16) & 0x1ff) - 16; |
| 389 | 349 | |
| 390 | | code = spriteram2[map_start & 0x7fff]; |
| 391 | | map_start++; |
| 350 | code = spriteram2[curr_sprite.map & 0x7fff]; |
| 351 | curr_sprite.map++; |
| 392 | 352 | |
| 393 | 353 | if (flipscreen) |
| 394 | 354 | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2], |
| 395 | 355 | code, |
| 396 | | color, |
| 397 | | !flipx,!flipy, |
| 356 | curr_sprite.color, |
| 357 | !curr_sprite.flipx,!curr_sprite.flipy, |
| 398 | 358 | 304-sx,208-sy, |
| 399 | | 0x1000 * zoomx,0x1000 * zoomy,15); |
| 359 | 0x1000 * curr_sprite.zoomx,0x1000 * curr_sprite.zoomy,15); |
| 400 | 360 | else |
| 401 | 361 | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2], |
| 402 | 362 | code, |
| 403 | | color, |
| 404 | | flipx,flipy, |
| 363 | curr_sprite.color, |
| 364 | curr_sprite.flipx,curr_sprite.flipy, |
| 405 | 365 | sx,sy, |
| 406 | | 0x1000 * zoomx,0x1000 * zoomy,15); |
| 366 | 0x1000 * curr_sprite.zoomx,0x1000 * curr_sprite.zoomy,15); |
| 407 | 367 | } |
| 408 | 368 | } |
| 409 | 369 | } |
| r18480 | r18481 | |
| 411 | 371 | |
| 412 | 372 | |
| 413 | 373 | |
| 414 | | void vsystem_spr_device::draw_sprites_aerofght( UINT16* spriteram3, int spriteram_bytes, UINT16* spriteram1, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority ) |
| 374 | void vsystem_spr_device::draw_sprites_aerofght( UINT16* spriteram3, int spriteram_bytes, UINT16* spriteram1, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri ) |
| 415 | 375 | { |
| 416 | 376 | int offs; |
| 417 | | priority <<= 12; |
| 377 | pri <<= 12; |
| 418 | 378 | |
| 419 | 379 | offs = 0; |
| 420 | 380 | while (offs < 0x0400 && (spriteram3[offs] & 0x8000) == 0) |
| 421 | 381 | { |
| 422 | 382 | int attr_start = 4 * (spriteram3[offs] & 0x03ff); |
| 423 | 383 | |
| 424 | | /* is the way I handle priority correct? Or should I just check bit 13? */ |
| 425 | | if ((spriteram3[attr_start + 2] & 0x3000) == priority) |
| 384 | /* is the way I handle pri correct? Or should I just check bit 13? */ |
| 385 | if ((spriteram3[attr_start + 2] & 0x3000) == pri) |
| 426 | 386 | { |
| 427 | | int map_start; |
| 428 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; |
| 387 | int x, y; |
| 429 | 388 | |
| 430 | | ox = spriteram3[attr_start + 1] & 0x01ff; |
| 431 | | xsize = (spriteram3[attr_start + 1] & 0x0e00) >> 9; |
| 432 | | zoomx = (spriteram3[attr_start + 1] & 0xf000) >> 12; |
| 433 | | oy = spriteram3[attr_start + 0] & 0x01ff; |
| 434 | | ysize = (spriteram3[attr_start + 0] & 0x0e00) >> 9; |
| 435 | | zoomy = (spriteram3[attr_start + 0] & 0xf000) >> 12; |
| 436 | | flipx = spriteram3[attr_start + 2] & 0x4000; |
| 437 | | flipy = spriteram3[attr_start + 2] & 0x8000; |
| 438 | | color = (spriteram3[attr_start + 2] & 0x0f00) >> 8; |
| 439 | | map_start = spriteram3[attr_start + 3] & 0x3fff; |
| 389 | get_sprite_attributes(&spriteram3[attr_start]); |
| 440 | 390 | |
| 441 | | ox += (xsize * zoomx + 2) / 4; |
| 442 | | oy += (ysize * zoomy + 2) / 4; |
| 391 | curr_sprite.color &=0xf; |
| 392 | curr_sprite.map &= 0x3fff; |
| 393 | curr_sprite.ox += (curr_sprite.xsize * curr_sprite.zoomx + 2) / 4; |
| 394 | curr_sprite.oy += (curr_sprite.ysize * curr_sprite.zoomy + 2) / 4; |
| 443 | 395 | |
| 444 | | zoomx = 32 - zoomx; |
| 445 | | zoomy = 32 - zoomy; |
| 396 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 397 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 446 | 398 | |
| 447 | | for (y = 0; y <= ysize; y++) |
| 399 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 448 | 400 | { |
| 449 | 401 | int sx, sy; |
| 450 | 402 | |
| 451 | | if (flipy) |
| 452 | | sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; |
| 403 | if (curr_sprite.flipy) |
| 404 | sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16; |
| 453 | 405 | else |
| 454 | | sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 406 | sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 455 | 407 | |
| 456 | | for (x = 0; x <= xsize; x++) |
| 408 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 457 | 409 | { |
| 458 | 410 | int code; |
| 459 | 411 | |
| 460 | | if (flipx) |
| 461 | | sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 412 | if (curr_sprite.flipx) |
| 413 | sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 462 | 414 | else |
| 463 | | sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 415 | sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 464 | 416 | |
| 465 | | if (map_start < 0x2000) |
| 466 | | code = spriteram1[map_start & 0x1fff] & 0x1fff; |
| 417 | if (curr_sprite.map < 0x2000) |
| 418 | code = spriteram1[curr_sprite.map & 0x1fff] & 0x1fff; |
| 467 | 419 | else |
| 468 | | code = spriteram2[map_start & 0x1fff] & 0x1fff; |
| 420 | code = spriteram2[curr_sprite.map & 0x1fff] & 0x1fff; |
| 469 | 421 | |
| 470 | | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2 + (map_start >= 0x2000 ? 1 : 0)], |
| 422 | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2 + (curr_sprite.map >= 0x2000 ? 1 : 0)], |
| 471 | 423 | code, |
| 472 | | color, |
| 473 | | flipx,flipy, |
| 424 | curr_sprite.color, |
| 425 | curr_sprite.flipx,curr_sprite.flipy, |
| 474 | 426 | sx,sy, |
| 475 | | zoomx << 11, zoomy << 11,15); |
| 476 | | map_start++; |
| 427 | curr_sprite.zoomx << 11, curr_sprite.zoomy << 11,15); |
| 428 | curr_sprite.map++; |
| 477 | 429 | } |
| 478 | 430 | } |
| 479 | 431 | } |
| r18480 | r18481 | |
| 490 | 442 | while (offs < 0x0400 && (spritelist[offs] & 0x4000) == 0) |
| 491 | 443 | { |
| 492 | 444 | int attr_start; |
| 493 | | int map_start; |
| 494 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color; |
| 445 | int x, y; |
| 495 | 446 | |
| 496 | 447 | attr_start = 4 * (spritelist[offs++] & 0x01ff); |
| 497 | 448 | |
| 498 | | ox = spritelist[attr_start + 1] & 0x01ff; |
| 499 | | xsize = (spritelist[attr_start + 1] & 0x0e00) >> 9; |
| 500 | | zoomx = (spritelist[attr_start + 1] & 0xf000) >> 12; |
| 501 | | oy = spritelist[attr_start + 0] & 0x01ff; |
| 502 | | ysize = (spritelist[attr_start + 0] & 0x0e00) >> 9; |
| 503 | | zoomy = (spritelist[attr_start + 0] & 0xf000) >> 12; |
| 504 | | flipx = spritelist[attr_start + 2] & 0x4000; |
| 505 | | flipy = spritelist[attr_start + 2] & 0x8000; |
| 506 | | color = (spritelist[attr_start + 2] & 0x1f00) >> 8; |
| 507 | | map_start = spritelist[attr_start + 3] & 0x7fff; |
| 449 | get_sprite_attributes(&spritelist[attr_start]); |
| 508 | 450 | |
| 451 | curr_sprite.color &= 0x1f; |
| 452 | curr_sprite.map &= 0x7fff; |
| 453 | |
| 509 | 454 | // aerofgt has the following adjustment, but doing it here would break the title screen |
| 510 | | // ox += (xsize*zoomx+2)/4; |
| 511 | | // oy += (ysize*zoomy+2)/4; |
| 455 | // curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4; |
| 456 | // curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4; |
| 512 | 457 | |
| 513 | | zoomx = 32 - zoomx; |
| 514 | | zoomy = 32 - zoomy; |
| 458 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 459 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 515 | 460 | |
| 516 | 461 | if (spritelist[attr_start + 2] & 0x20ff) |
| 517 | | color = machine.rand(); |
| 462 | curr_sprite.color = machine.rand(); |
| 518 | 463 | |
| 519 | | for (y = 0; y <= ysize; y++) |
| 464 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 520 | 465 | { |
| 521 | 466 | int sx,sy; |
| 522 | 467 | |
| 523 | | if (flipy) sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; |
| 524 | | else sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 468 | if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16; |
| 469 | else sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 525 | 470 | |
| 526 | | for (x = 0; x <= xsize; x++) |
| 471 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 527 | 472 | { |
| 528 | 473 | int code; |
| 529 | 474 | |
| 530 | | if (flipx) sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 531 | | else sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 475 | if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 476 | else sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 532 | 477 | |
| 533 | | code = sprcgram[map_start & 0x3fff]; |
| 534 | | map_start++; |
| 478 | code = sprcgram[curr_sprite.map & 0x3fff]; |
| 479 | curr_sprite.map++; |
| 535 | 480 | |
| 536 | 481 | if (flipscreen) |
| 537 | 482 | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1], |
| 538 | 483 | code, |
| 539 | | color, |
| 540 | | !flipx,!flipy, |
| 484 | curr_sprite.color, |
| 485 | !curr_sprite.flipx,!curr_sprite.flipy, |
| 541 | 486 | 304-sx,208-sy, |
| 542 | | zoomx << 11,zoomy << 11,15); |
| 487 | curr_sprite.zoomx << 11,curr_sprite.zoomy << 11,15); |
| 543 | 488 | else |
| 544 | 489 | drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1], |
| 545 | 490 | code, |
| 546 | | color, |
| 547 | | flipx,flipy, |
| 491 | curr_sprite.color, |
| 492 | curr_sprite.flipx,curr_sprite.flipy, |
| 548 | 493 | sx,sy, |
| 549 | | zoomx << 11,zoomy << 11,15); |
| 494 | curr_sprite.zoomx << 11,curr_sprite.zoomy << 11,15); |
| 550 | 495 | } |
| 551 | 496 | } |
| 552 | 497 | } |
| r18480 | r18481 | |
| 566 | 511 | - Scaling (x/y) |
| 567 | 512 | - Flipping |
| 568 | 513 | - Indipendent sorting list |
| 569 | | - 1 bit of priority for the mixer |
| 514 | - 1 bit of pri for the mixer |
| 570 | 515 | |
| 571 | 516 | Note that this chip can be connected to a VS9210 which adds a level of indirection for |
| 572 | | tile numbers. Basically, the VS9210 indirects the tile number through a table in its attached |
| 517 | tile numbers. Basically, the VS9210 indirects the tilet number through a table in its attached |
| 573 | 518 | memory, before accessing the ROMs. |
| 574 | 519 | |
| 575 | 520 | |
| 576 | 521 | Sorting list format (VideoRAM offset 0) |
| 577 | 522 | --------------------------------------- |
| 578 | 523 | |
| 579 | | ?e-- ---f ssss ssss |
| 524 | de-- ---f ssss ssss |
| 580 | 525 | |
| 581 | 526 | e=end of list |
| 582 | 527 | f=sprite present in this position |
| 583 | 528 | s=sprite index |
| 584 | | ?=used together with 'e' almost always |
| 529 | d=disable sprite? |
| 585 | 530 | |
| 586 | 531 | |
| 587 | | Sprite format (VideoRAM offset 0x400) |
| 588 | | ------------------------------------- |
| 589 | | |
| 590 | | 0: nnnn jjjy yyyy yyyy |
| 591 | | 1: mmmm iiix xxxx xxxx |
| 592 | | 2: fFpc cccc ---- ---t |
| 593 | | 3: tttt tttt tttt tttt |
| 594 | | |
| 595 | | t=tile, x=posx, y=posy, i=blockx, j=blocky |
| 596 | | c=color, m=zoomx, n=zoomy, p=priority |
| 597 | | |
| 598 | | The zoom (scaling) is probably non-linear, it would require a hand-made table unless we find the correct |
| 599 | | formula. I'd probably try 1/x. I'm almost sure that it scales between full size (value=0) and half size |
| 600 | | (value=0xF) but I couldn't get much more than that from a soccer game. |
| 601 | | |
| 602 | | |
| 603 | 532 | TODO: |
| 604 | 533 | Priorities should be right, but they probably need to be orthogonal with the mixer priorities. |
| 605 | 534 | Zoom factor is not correct, the scale is probably non-linear |
| r18480 | r18481 | |
| 612 | 541 | |
| 613 | 542 | void vsystem_spr_device::CG10103_draw_sprite(running_machine &machine, bitmap_ind16& screen, const rectangle &cliprect, UINT16* spr, int drawpri) |
| 614 | 543 | { |
| 615 | | int ypos = spr[0] & 0x1FF; |
| 616 | | int xpos = (spr[1] & 0x1FF); |
| 617 | | UINT32 tile = (spr[3] & 0xFFFF) | ((spr[2] & 1) << 16); |
| 618 | | int ynum = (spr[0] >> 9) & 0x7; |
| 619 | | int xnum = (spr[1] >> 9) & 0x7; |
| 620 | | int color = (spr[2] >> 8) & 0x1F; |
| 621 | | int flipx = (spr[2] >> 14) & 1; |
| 622 | | int flipy = (spr[2] >> 15) & 1; |
| 623 | | int yzoom = (spr[0] >> 12) & 0xF; |
| 624 | | int xzoom = (spr[1] >> 12) & 0xF; |
| 625 | | int pri = (spr[2] >> 13) & 1; |
| 544 | get_sprite_attributes(&spr[0]); |
| 545 | curr_sprite.color &=0x1f; |
| 546 | curr_sprite.pri >>= 1; |
| 547 | |
| 626 | 548 | int x, y; |
| 627 | 549 | int xstep, ystep; |
| 628 | 550 | int xfact, yfact; |
| 629 | 551 | |
| 552 | |
| 630 | 553 | // Check if we want to draw this sprite now |
| 631 | | if (pri != drawpri) |
| 554 | if (curr_sprite.pri != drawpri) |
| 632 | 555 | return; |
| 633 | 556 | |
| 634 | 557 | // Convert in fixed point to handle the scaling |
| 635 | | xpos <<= 16; |
| 636 | | ypos <<= 16; |
| 558 | curr_sprite.ox <<= 16; |
| 559 | curr_sprite.oy <<= 16; |
| 637 | 560 | |
| 638 | | xnum++; |
| 639 | | ynum++; |
| 561 | curr_sprite.xsize++; |
| 562 | curr_sprite.ysize++; |
| 640 | 563 | xstep = ystep = 16; |
| 641 | 564 | |
| 642 | 565 | // Linear scale, surely wrong |
| 643 | | xfact = 0x10000 - ((0x8000 * xzoom) / 15); |
| 644 | | yfact = 0x10000 - ((0x8000 * yzoom) / 15); |
| 566 | xfact = 0x10000 - ((0x8000 * curr_sprite.zoomx) / 15); |
| 567 | yfact = 0x10000 - ((0x8000 * curr_sprite.zoomy) / 15); |
| 645 | 568 | |
| 646 | 569 | xstep *= xfact; |
| 647 | 570 | ystep *= yfact; |
| 648 | 571 | |
| 649 | 572 | // Handle flipping |
| 650 | | if (flipy) |
| 573 | if (curr_sprite.flipy) |
| 651 | 574 | { |
| 652 | | ypos += (ynum-1) * ystep; |
| 575 | curr_sprite.oy += (curr_sprite.ysize-1) * ystep; |
| 653 | 576 | ystep = -ystep; |
| 654 | 577 | } |
| 655 | 578 | |
| 656 | | if (flipx) |
| 579 | if (curr_sprite.flipx) |
| 657 | 580 | { |
| 658 | | xpos += (xnum-1) * xstep; |
| 581 | curr_sprite.ox += (curr_sprite.xsize-1) * xstep; |
| 659 | 582 | xstep = -xstep; |
| 660 | 583 | } |
| 661 | 584 | |
| 662 | | // @@@ Add here optional connection to the VS9210 for extra level of tile number indirection |
| 663 | | #if 0 |
| 664 | | if (m_CG10103_cur_chip->connected_vs9210) |
| 665 | | { |
| 666 | | // ... |
| 667 | | } |
| 668 | | #endif |
| 669 | | |
| 670 | 585 | // Draw the block |
| 671 | | for (y=0;y<ynum;y++) |
| 586 | for (y=0;y<curr_sprite.ysize;y++) |
| 672 | 587 | { |
| 673 | | int xp = xpos; |
| 588 | int xp = curr_sprite.ox; |
| 674 | 589 | |
| 675 | | for (x=0;x<xnum;x++) |
| 590 | for (x=0;x<curr_sprite.xsize;x++) |
| 676 | 591 | { |
| 677 | 592 | // Hack to handle horizontal wrapping |
| 678 | | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], tile, color+m_CG10103_cur_chip->pal_base, flipx, flipy, xp>>16, ypos>>16, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 679 | | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], tile, color+m_CG10103_cur_chip->pal_base, flipx, flipy, (xp>>16) - 0x200, ypos>>16, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 593 | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, xp>>16, curr_sprite.oy>>16, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 594 | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, (xp>>16) - 0x200, curr_sprite.oy>>16, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 595 | |
| 596 | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, xp>>16, (curr_sprite.oy>>16)-0x200, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 597 | drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, (xp>>16) - 0x200, (curr_sprite.oy>>16)-0x200, xfact, yfact, m_CG10103_cur_chip->transpen); |
| 598 | |
| 680 | 599 | xp += xstep; |
| 681 | | tile++; |
| 600 | curr_sprite.map++; |
| 682 | 601 | } |
| 683 | 602 | |
| 684 | | ypos += ystep; |
| 603 | curr_sprite.oy += ystep; |
| 685 | 604 | } |
| 686 | 605 | } |
| 687 | 606 | |
| 688 | 607 | |
| 689 | | void vsystem_spr_device::CG10103_draw(running_machine &machine, int numchip, bitmap_ind16& screen, const rectangle &cliprect, int priority) |
| 608 | void vsystem_spr_device::CG10103_draw(running_machine &machine, int numchip, bitmap_ind16& screen, const rectangle &cliprect, int pri) |
| 690 | 609 | { |
| 691 | 610 | UINT16* splist; |
| 692 | 611 | int i; |
| r18480 | r18481 | |
| 704 | 623 | if (cmd & 0x4000) |
| 705 | 624 | break; |
| 706 | 625 | |
| 707 | | // Normal sprite here |
| 708 | | if (cmd & 0x100) |
| 626 | if (!(cmd & 0x8000)) |
| 709 | 627 | { |
| 710 | 628 | // Extract sprite index |
| 711 | | int num = cmd & 0xFF; |
| 629 | int num = cmd & 0x3FF; |
| 712 | 630 | |
| 713 | 631 | // Draw the sprite |
| 714 | | CG10103_draw_sprite(machine, screen, cliprect, m_CG10103_cur_chip->vram + 0x400 + num*4, priority); |
| 632 | CG10103_draw_sprite(machine, screen, cliprect, m_CG10103_cur_chip->vram + num*4, pri); |
| 715 | 633 | } |
| 716 | 634 | } |
| 717 | 635 | } |
trunk/src/mame/video/vsystem_spr2.c
| r18480 | r18481 | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | |
| 43 | int vsystem_spr2_device::get_sprite_attributes(UINT16* ram) |
| 44 | { |
| 45 | // sprite is disabled |
| 46 | if (!(ram[2] & 0x0080)) |
| 47 | return 0; |
| 43 | 48 | |
| 49 | curr_sprite.oy = (ram[0] & 0x01ff); |
| 50 | curr_sprite.zoomy = (ram[0] & 0xf000) >> 12; |
| 44 | 51 | |
| 52 | curr_sprite.ox = (ram[1] & 0x01ff); |
| 53 | curr_sprite.zoomx = (ram[1] & 0xf000) >> 12; |
| 54 | |
| 55 | curr_sprite.xsize = (ram[2] & 0x0700) >> 8; |
| 56 | curr_sprite.flipx = (ram[2] & 0x0800); |
| 57 | |
| 58 | curr_sprite.ysize = (ram[2] & 0x7000) >> 12; |
| 59 | curr_sprite.flipy = (ram[2] & 0x8000); |
| 60 | |
| 61 | curr_sprite.color = (ram[2] & 0x000f); |
| 62 | curr_sprite.pri = (ram[2] & 0x0010); |
| 63 | |
| 64 | curr_sprite.map = (ram[3]); |
| 65 | |
| 66 | return 1; |
| 67 | } |
| 68 | |
| 69 | |
| 70 | |
| 45 | 71 | template<class _BitmapClass> |
| 46 | 72 | void vsystem_spr2_device::turbofrc_draw_sprites_common( UINT16* spriteram3, int spriteram3_bytes, UINT16* spriteram1, int spriteram1_bytes, UINT16* spriteram2, int spriteram2_bytes, int sprite_gfx, int spritepalettebank, running_machine &machine, _BitmapClass &bitmap, const rectangle &cliprect, int chip, int chip_disabled_pri ) |
| 47 | 73 | { |
| r18480 | r18481 | |
| 51 | 77 | |
| 52 | 78 | for (attr_start = base + 0x0200 - 8; attr_start >= first + base; attr_start -= 4) |
| 53 | 79 | { |
| 54 | | int map_start; |
| 55 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color, pri; |
| 80 | int x, y; |
| 56 | 81 | // some other drivers still use this wrong table, they have to be upgraded |
| 57 | 82 | // int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 }; |
| 58 | 83 | |
| 59 | | if (!(spriteram3[attr_start + 2] & 0x0080)) |
| 84 | |
| 85 | if (!get_sprite_attributes(&spriteram3[attr_start])) |
| 60 | 86 | continue; |
| 61 | 87 | |
| 62 | | pri = spriteram3[attr_start + 2] & 0x0010; |
| 63 | 88 | |
| 64 | | if ( chip_disabled_pri & !pri) |
| 89 | if ( chip_disabled_pri & !curr_sprite.pri) |
| 65 | 90 | continue; |
| 66 | 91 | |
| 67 | | if ((!chip_disabled_pri) & (pri >> 4)) |
| 92 | if ((!chip_disabled_pri) & (curr_sprite.pri >> 4)) |
| 68 | 93 | continue; |
| 69 | 94 | |
| 70 | | ox = spriteram3[attr_start + 1] & 0x01ff; |
| 71 | | xsize = (spriteram3[attr_start + 2] & 0x0700) >> 8; |
| 72 | | zoomx = (spriteram3[attr_start + 1] & 0xf000) >> 12; |
| 73 | | oy = spriteram3[attr_start + 0] & 0x01ff; |
| 74 | | ysize = (spriteram3[attr_start + 2] & 0x7000) >> 12; |
| 75 | | zoomy = (spriteram3[attr_start + 0] & 0xf000) >> 12; |
| 76 | | flipx = spriteram3[attr_start + 2] & 0x0800; |
| 77 | | flipy = spriteram3[attr_start + 2] & 0x8000; |
| 78 | | color = (spriteram3[attr_start + 2] & 0x000f) + 16 * spritepalettebank; |
| 79 | 95 | |
| 80 | | map_start = spriteram3[attr_start + 3]; |
| 81 | 96 | |
| 97 | curr_sprite.color += 16 * spritepalettebank; |
| 98 | |
| 82 | 99 | // aerofgt has this adjustment, but doing it here would break turbo force title screen |
| 83 | | // ox += (xsize*zoomx+2)/4; |
| 84 | | // oy += (ysize*zoomy+2)/4; |
| 100 | // curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4; |
| 101 | // curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4; |
| 85 | 102 | |
| 86 | | zoomx = 32 - zoomx; |
| 87 | | zoomy = 32 - zoomy; |
| 103 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 104 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 88 | 105 | |
| 89 | | for (y = 0; y <= ysize; y++) |
| 106 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 90 | 107 | { |
| 91 | 108 | int sx, sy; |
| 92 | 109 | |
| 93 | | if (flipy) |
| 94 | | sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; |
| 110 | if (curr_sprite.flipy) |
| 111 | sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16; |
| 95 | 112 | else |
| 96 | | sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 113 | sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 97 | 114 | |
| 98 | | for (x = 0; x <= xsize; x++) |
| 115 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 99 | 116 | { |
| 100 | | int code; |
| 117 | int curr; |
| 101 | 118 | |
| 102 | | if (flipx) |
| 103 | | sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 119 | if (curr_sprite.flipx) |
| 120 | sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 104 | 121 | else |
| 105 | | sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 122 | sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 106 | 123 | |
| 107 | 124 | if (chip == 0) |
| 108 | | code = spriteram1[map_start % (spriteram1_bytes/2)]; |
| 125 | curr = spriteram1[curr_sprite.map % (spriteram1_bytes/2)]; |
| 109 | 126 | else |
| 110 | | code = spriteram2[map_start % (spriteram2_bytes/2)]; |
| 127 | curr = spriteram2[curr_sprite.map % (spriteram2_bytes/2)]; |
| 111 | 128 | |
| 112 | 129 | pdrawgfxzoom_transpen(bitmap,cliprect,machine.gfx[sprite_gfx + chip], |
| 113 | | code, |
| 114 | | color, |
| 115 | | flipx,flipy, |
| 130 | curr, |
| 131 | curr_sprite.color, |
| 132 | curr_sprite.flipx,curr_sprite.flipy, |
| 116 | 133 | sx,sy, |
| 117 | | zoomx << 11, zoomy << 11, |
| 118 | | machine.priority_bitmap,pri ? 0 : 2,15); |
| 119 | | map_start++; |
| 134 | curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, |
| 135 | machine.priority_bitmap,curr_sprite.pri ? 0 : 2,15); |
| 136 | curr_sprite.map++; |
| 120 | 137 | } |
| 121 | 138 | |
| 122 | | if (xsize == 2) map_start += 1; |
| 123 | | if (xsize == 4) map_start += 3; |
| 124 | | if (xsize == 5) map_start += 2; |
| 125 | | if (xsize == 6) map_start += 1; |
| 139 | if (curr_sprite.xsize == 2) curr_sprite.map += 1; |
| 140 | if (curr_sprite.xsize == 4) curr_sprite.map += 3; |
| 141 | if (curr_sprite.xsize == 5) curr_sprite.map += 2; |
| 142 | if (curr_sprite.xsize == 6) curr_sprite.map += 1; |
| 126 | 143 | } |
| 127 | 144 | } |
| 128 | 145 | } |
| r18480 | r18481 | |
| 143 | 160 | |
| 144 | 161 | for (attr_start = base + 0x0200-8; attr_start >= first + base; attr_start -= 4) |
| 145 | 162 | { |
| 146 | | int map_start; |
| 147 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color, pri; |
| 163 | int x, y; |
| 148 | 164 | // some other drivers still use this wrong table, they have to be upgraded |
| 149 | 165 | // int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 }; |
| 150 | 166 | |
| 151 | | if (!(spriteram3[attr_start + 2] & 0x0080)) |
| 167 | |
| 168 | if (!get_sprite_attributes(&spriteram3[attr_start])) |
| 152 | 169 | continue; |
| 153 | 170 | |
| 154 | | pri = spriteram3[attr_start + 2] & 0x0010; |
| 155 | 171 | |
| 156 | | if ( chip_disabled_pri & !pri) |
| 172 | if ( chip_disabled_pri & !curr_sprite.pri) |
| 157 | 173 | continue; |
| 158 | | if ((!chip_disabled_pri) & (pri >> 4)) |
| 174 | if ((!chip_disabled_pri) & (curr_sprite.pri >> 4)) |
| 159 | 175 | continue; |
| 160 | 176 | |
| 161 | | ox = spriteram3[attr_start + 1] & 0x01ff; |
| 162 | | xsize = (spriteram3[attr_start + 2] & 0x0700) >> 8; |
| 163 | | zoomx = (spriteram3[attr_start + 1] & 0xf000) >> 12; |
| 164 | | oy = spriteram3[attr_start + 0] & 0x01ff; |
| 165 | | ysize = (spriteram3[attr_start + 2] & 0x7000) >> 12; |
| 166 | | zoomy = (spriteram3[attr_start + 0] & 0xf000) >> 12; |
| 167 | | flipx = spriteram3[attr_start + 2] & 0x0800; |
| 168 | | flipy = spriteram3[attr_start + 2] & 0x8000; |
| 169 | | color = (spriteram3[attr_start + 2] & 0x000f) + 16 * spritepalettebank; |
| 170 | 177 | |
| 171 | | map_start = spriteram3[attr_start + 3]; |
| 178 | curr_sprite.color += 16 * spritepalettebank; |
| 172 | 179 | |
| 173 | 180 | // aerofgt has this adjustment, but doing it here would break turbo force title screen |
| 174 | | // ox += (xsize*zoomx+2)/4; |
| 175 | | // oy += (ysize*zoomy+2)/4; |
| 181 | // curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4; |
| 182 | // curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4; |
| 176 | 183 | |
| 177 | | zoomx = 32 - zoomx; |
| 178 | | zoomy = 32 - zoomy; |
| 184 | curr_sprite.zoomx = 32 - curr_sprite.zoomx; |
| 185 | curr_sprite.zoomy = 32 - curr_sprite.zoomy; |
| 179 | 186 | |
| 180 | | for (y = 0; y <= ysize; y++) |
| 187 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 181 | 188 | { |
| 182 | 189 | int sx, sy; |
| 183 | 190 | |
| 184 | | if (flipy) |
| 185 | | sy = ((oy + zoomy * (ysize - y)/2 + 16) & 0x1ff) - 16; |
| 191 | if (curr_sprite.flipy) |
| 192 | sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16; |
| 186 | 193 | else |
| 187 | | sy = ((oy + zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 194 | sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16; |
| 188 | 195 | |
| 189 | | for (x = 0; x <= xsize; x++) |
| 196 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 190 | 197 | { |
| 191 | | int code; |
| 198 | int curr; |
| 192 | 199 | |
| 193 | | if (flipx) |
| 194 | | sx = ((ox + zoomx * (xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 200 | if (curr_sprite.flipx) |
| 201 | sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16; |
| 195 | 202 | else |
| 196 | | sx = ((ox + zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 203 | sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16; |
| 197 | 204 | |
| 198 | 205 | if (chip == 0) |
| 199 | | code = spriteram1[map_start % (spriteram1_bytes/2)]; |
| 206 | curr = spriteram1[curr_sprite.map % (spriteram1_bytes/2)]; |
| 200 | 207 | else |
| 201 | | code = spriteram2[map_start % (spriteram2_bytes/2)]; |
| 208 | curr = spriteram2[curr_sprite.map % (spriteram2_bytes/2)]; |
| 202 | 209 | |
| 203 | 210 | pdrawgfxzoom_transpen(bitmap,cliprect,machine.gfx[sprite_gfx + chip], |
| 204 | | code, |
| 205 | | color, |
| 206 | | flipx,flipy, |
| 211 | curr, |
| 212 | curr_sprite.color, |
| 213 | curr_sprite.flipx,curr_sprite.flipy, |
| 207 | 214 | sx,sy, |
| 208 | | zoomx << 11, zoomy << 11, |
| 209 | | machine.priority_bitmap,pri ? 2 : 0,15); |
| 210 | | map_start++; |
| 215 | curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, |
| 216 | machine.priority_bitmap,curr_sprite.pri ? 2 : 0,15); |
| 217 | curr_sprite.map++; |
| 211 | 218 | } |
| 212 | 219 | |
| 213 | | if (xsize == 2) map_start += 1; |
| 214 | | if (xsize == 4) map_start += 3; |
| 215 | | if (xsize == 5) map_start += 2; |
| 216 | | if (xsize == 6) map_start += 1; |
| 220 | if (curr_sprite.xsize == 2) curr_sprite.map += 1; |
| 221 | if (curr_sprite.xsize == 4) curr_sprite.map += 3; |
| 222 | if (curr_sprite.xsize == 5) curr_sprite.map += 2; |
| 223 | if (curr_sprite.xsize == 6) curr_sprite.map += 1; |
| 217 | 224 | } |
| 218 | 225 | } |
| 219 | 226 | } |
| r18480 | r18481 | |
| 234 | 241 | const rectangle &visarea = machine.primary_screen->visible_area(); |
| 235 | 242 | |
| 236 | 243 | /* draw the sprites */ |
| 237 | | for (offs = 0; offs < 0x200 - 4; offs += 4) { |
| 238 | | int data0 = spriteram[offs + 0]; |
| 239 | | int data1 = spriteram[offs + 1]; |
| 240 | | int data2 = spriteram[offs + 2]; |
| 241 | | int data3 = spriteram[offs + 3]; |
| 242 | | int code = data3 & 0x1fff; |
| 243 | | int color = (data2 & 0x0f) + (0x10 * spritepalettebank); |
| 244 | | int y = (data0 & 0x1ff) + 1; |
| 245 | | int x = (data1 & 0x1ff) + 6; |
| 246 | | int yzoom = (data0 >> 12) & 15; |
| 247 | | int xzoom = (data1 >> 12) & 15; |
| 248 | | int zoomed = (xzoom | yzoom); |
| 249 | | int ytiles = ((data2 >> 12) & 7) + 1; |
| 250 | | int xtiles = ((data2 >> 8) & 7) + 1; |
| 251 | | int yflip = (data2 >> 15) & 1; |
| 252 | | int xflip = (data2 >> 11) & 1; |
| 244 | for (offs = 0; offs < 0x200 - 4; offs += 4) |
| 245 | { |
| 246 | if (!get_sprite_attributes(&spriteram[offs])) |
| 247 | continue; |
| 248 | |
| 249 | curr_sprite.map&=0x1fff; |
| 250 | curr_sprite.ysize++; |
| 251 | curr_sprite.xsize++; |
| 252 | curr_sprite.color += (0x10 * spritepalettebank); |
| 253 | |
| 254 | int zoomed = (curr_sprite.zoomx | curr_sprite.zoomy); |
| 253 | 255 | int xt, yt; |
| 254 | 256 | |
| 255 | | if (!(spriteram[offs + 2] & 0x0080)) continue; |
| 256 | 257 | |
| 257 | 258 | /* compute the zoom factor -- stolen from aerofgt.c */ |
| 258 | | xzoom = 16 - zoomtable[xzoom] / 8; |
| 259 | | yzoom = 16 - zoomtable[yzoom] / 8; |
| 259 | curr_sprite.zoomx = 16 - zoomtable[curr_sprite.zoomx] / 8; |
| 260 | curr_sprite.zoomy = 16 - zoomtable[curr_sprite.zoomy] / 8; |
| 260 | 261 | |
| 261 | 262 | /* wrap around */ |
| 262 | | if (x > visarea.max_x) x -= 0x200; |
| 263 | | if (y > visarea.max_y) y -= 0x200; |
| 263 | if (curr_sprite.ox > visarea.max_x) curr_sprite.ox -= 0x200; |
| 264 | if (curr_sprite.oy > visarea.max_y) curr_sprite.oy -= 0x200; |
| 264 | 265 | |
| 265 | 266 | /* normal case */ |
| 266 | | if (!xflip && !yflip) { |
| 267 | | for (yt = 0; yt < ytiles; yt++) { |
| 268 | | for (xt = 0; xt < xtiles; xt++, code++) { |
| 267 | if (!curr_sprite.flipx && !curr_sprite.flipy) { |
| 268 | for (yt = 0; yt < curr_sprite.ysize; yt++) { |
| 269 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) { |
| 269 | 270 | if (!zoomed) |
| 270 | | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], code, color, 0, 0, |
| 271 | | x + xt * 16, y + yt * 16, 15); |
| 271 | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 0, 0, |
| 272 | curr_sprite.ox + xt * 16, curr_sprite.oy + yt * 16, 15); |
| 272 | 273 | else |
| 273 | | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], code, color, 0, 0, |
| 274 | | x + xt * xzoom, y + yt * yzoom, |
| 275 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 274 | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 0, 0, |
| 275 | curr_sprite.ox + xt * curr_sprite.zoomx, curr_sprite.oy + yt * curr_sprite.zoomy, |
| 276 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 276 | 277 | } |
| 277 | | if (xtiles == 3) code += 1; |
| 278 | | if (xtiles == 5) code += 3; |
| 279 | | if (xtiles == 6) code += 2; |
| 280 | | if (xtiles == 7) code += 1; |
| 278 | if (curr_sprite.xsize == 3) curr_sprite.map += 1; |
| 279 | if (curr_sprite.xsize == 5) curr_sprite.map += 3; |
| 280 | if (curr_sprite.xsize == 6) curr_sprite.map += 2; |
| 281 | if (curr_sprite.xsize == 7) curr_sprite.map += 1; |
| 281 | 282 | } |
| 282 | 283 | } |
| 283 | 284 | |
| 284 | | /* xflipped case */ |
| 285 | | else if (xflip && !yflip) { |
| 286 | | for (yt = 0; yt < ytiles; yt++) { |
| 287 | | for (xt = 0; xt < xtiles; xt++, code++) { |
| 285 | /* curr_sprite.flipxped case */ |
| 286 | else if (curr_sprite.flipx && !curr_sprite.flipy) { |
| 287 | for (yt = 0; yt < curr_sprite.ysize; yt++) { |
| 288 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) { |
| 288 | 289 | if (!zoomed) |
| 289 | | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], code, color, 1, 0, |
| 290 | | x + (xtiles - 1 - xt) * 16, y + yt * 16, 15); |
| 290 | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 1, 0, |
| 291 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * 16, curr_sprite.oy + yt * 16, 15); |
| 291 | 292 | else |
| 292 | | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], code, color, 1, 0, |
| 293 | | x + (xtiles - 1 - xt) * xzoom, y + yt * yzoom, |
| 294 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 293 | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 1, 0, |
| 294 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * curr_sprite.zoomx, curr_sprite.oy + yt * curr_sprite.zoomy, |
| 295 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 295 | 296 | } |
| 296 | | if (xtiles == 3) code += 1; |
| 297 | | if (xtiles == 5) code += 3; |
| 298 | | if (xtiles == 6) code += 2; |
| 299 | | if (xtiles == 7) code += 1; |
| 297 | if (curr_sprite.xsize == 3) curr_sprite.map += 1; |
| 298 | if (curr_sprite.xsize == 5) curr_sprite.map += 3; |
| 299 | if (curr_sprite.xsize == 6) curr_sprite.map += 2; |
| 300 | if (curr_sprite.xsize == 7) curr_sprite.map += 1; |
| 300 | 301 | } |
| 301 | 302 | } |
| 302 | 303 | |
| 303 | | /* yflipped case */ |
| 304 | | else if (!xflip && yflip) { |
| 305 | | for (yt = 0; yt < ytiles; yt++) { |
| 306 | | for (xt = 0; xt < xtiles; xt++, code++) { |
| 304 | /* curr_sprite.flipyped case */ |
| 305 | else if (!curr_sprite.flipx && curr_sprite.flipy) { |
| 306 | for (yt = 0; yt < curr_sprite.ysize; yt++) { |
| 307 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) { |
| 307 | 308 | if (!zoomed) |
| 308 | | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], code, color, 0, 1, |
| 309 | | x + xt * 16, y + (ytiles - 1 - yt) * 16, 15); |
| 309 | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 0, 1, |
| 310 | curr_sprite.ox + xt * 16, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * 16, 15); |
| 310 | 311 | else |
| 311 | | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], code, color, 0, 1, |
| 312 | | x + xt * xzoom, y + (ytiles - 1 - yt) * yzoom, |
| 313 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 312 | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 0, 1, |
| 313 | curr_sprite.ox + xt * curr_sprite.zoomx, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * curr_sprite.zoomy, |
| 314 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 314 | 315 | } |
| 315 | | if (xtiles == 3) code += 1; |
| 316 | | if (xtiles == 5) code += 3; |
| 317 | | if (xtiles == 6) code += 2; |
| 318 | | if (xtiles == 7) code += 1; |
| 316 | if (curr_sprite.xsize == 3) curr_sprite.map += 1; |
| 317 | if (curr_sprite.xsize == 5) curr_sprite.map += 3; |
| 318 | if (curr_sprite.xsize == 6) curr_sprite.map += 2; |
| 319 | if (curr_sprite.xsize == 7) curr_sprite.map += 1; |
| 319 | 320 | } |
| 320 | 321 | } |
| 321 | 322 | |
| 322 | | /* x & yflipped case */ |
| 323 | /* x & curr_sprite.flipyped case */ |
| 323 | 324 | else { |
| 324 | | for (yt = 0; yt < ytiles; yt++) { |
| 325 | | for (xt = 0; xt < xtiles; xt++, code++) { |
| 325 | for (yt = 0; yt < curr_sprite.ysize; yt++) { |
| 326 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) { |
| 326 | 327 | if (!zoomed) |
| 327 | | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], code, color, 1, 1, |
| 328 | | x + (xtiles - 1 - xt) * 16, y + (ytiles - 1 - yt) * 16, 15); |
| 328 | drawgfx_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 1, 1, |
| 329 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * 16, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * 16, 15); |
| 329 | 330 | else |
| 330 | | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], code, color, 1, 1, |
| 331 | | x + (xtiles - 1 - xt) * xzoom, y + (ytiles - 1 - yt) * yzoom, |
| 332 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 331 | drawgfxzoom_transpen(bitmap, cliprect, machine.gfx[1], curr_sprite.map, curr_sprite.color, 1, 1, |
| 332 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * curr_sprite.zoomx, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * curr_sprite.zoomy, |
| 333 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 333 | 334 | } |
| 334 | | if (xtiles == 3) code += 1; |
| 335 | | if (xtiles == 5) code += 3; |
| 336 | | if (xtiles == 6) code += 2; |
| 337 | | if (xtiles == 7) code += 1; |
| 335 | if (curr_sprite.xsize == 3) curr_sprite.map += 1; |
| 336 | if (curr_sprite.xsize == 5) curr_sprite.map += 3; |
| 337 | if (curr_sprite.xsize == 6) curr_sprite.map += 2; |
| 338 | if (curr_sprite.xsize == 7) curr_sprite.map += 1; |
| 338 | 339 | } |
| 339 | 340 | } |
| 340 | 341 | } |
| r18480 | r18481 | |
| 351 | 352 | |
| 352 | 353 | for (attr_start = 0x0200 - 8; attr_start >= first; attr_start -= 4) |
| 353 | 354 | { |
| 354 | | int map_start; |
| 355 | | int ox, oy, x, y, xsize, ysize, zoomx, zoomy, flipx, flipy, color/*, pri*/; |
| 355 | int x, y; |
| 356 | 356 | /* table hand made by looking at the ship explosion in attract mode */ |
| 357 | 357 | /* it's almost a logarithmic scale but not exactly */ |
| 358 | 358 | static const int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 }; |
| 359 | 359 | |
| 360 | | if (!(spram[attr_start + 2] & 0x0080)) continue; |
| 361 | 360 | |
| 362 | | ox = spram[attr_start + 1] & 0x01ff; |
| 363 | | xsize = (spram[attr_start + 2] & 0x0700) >> 8; |
| 364 | | zoomx = (spram[attr_start + 1] & 0xf000) >> 12; |
| 365 | | oy = spram[attr_start + 0] & 0x01ff; |
| 366 | | ysize = (spram[attr_start + 2] & 0x7000) >> 12; |
| 367 | | zoomy = (spram[attr_start + 0] & 0xf000) >> 12; |
| 368 | | flipx = spram[attr_start + 2] & 0x0800; |
| 369 | | flipy = spram[attr_start + 2] & 0x8000; |
| 370 | | color = (spram[attr_start + 2] & 0x000f);// + 16 * spritepalettebank; |
| 371 | | //pri = spram[attr_start + 2] & 0x0010; |
| 372 | | map_start = spram[attr_start + 3]; |
| 361 | if (!get_sprite_attributes(&spram[attr_start])) |
| 362 | continue; |
| 373 | 363 | |
| 374 | | zoomx = 16 - zoomtable[zoomx] / 8; |
| 375 | | zoomy = 16 - zoomtable[zoomy] / 8; |
| 364 | curr_sprite.zoomx = 16 - zoomtable[curr_sprite.zoomx] / 8; |
| 365 | curr_sprite.zoomy = 16 - zoomtable[curr_sprite.zoomy] / 8; |
| 376 | 366 | |
| 377 | | for (y = 0; y <= ysize; y++) |
| 367 | for (y = 0; y <= curr_sprite.ysize; y++) |
| 378 | 368 | { |
| 379 | 369 | int sx, sy; |
| 380 | 370 | |
| 381 | | if (flipy) sy = ((oy + zoomy * (ysize - y) + 16) & 0x1ff) - 16; |
| 382 | | else sy = ((oy + zoomy * y + 16) & 0x1ff) - 16; |
| 371 | if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y) + 16) & 0x1ff) - 16; |
| 372 | else sy = ((curr_sprite.oy + curr_sprite.zoomy * y + 16) & 0x1ff) - 16; |
| 383 | 373 | |
| 384 | | for (x = 0; x <= xsize; x++) |
| 374 | for (x = 0; x <= curr_sprite.xsize; x++) |
| 385 | 375 | { |
| 386 | | int code; |
| 376 | int curr; |
| 387 | 377 | |
| 388 | | if (flipx) sx = ((ox + zoomx * (xsize - x) + 16) & 0x1ff) - 16; |
| 389 | | else sx = ((ox + zoomx * x + 16) & 0x1ff) - 16; |
| 378 | if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) + 16) & 0x1ff) - 16; |
| 379 | else sx = ((curr_sprite.ox + curr_sprite.zoomx * x + 16) & 0x1ff) - 16; |
| 390 | 380 | |
| 391 | 381 | if (chip == 0) |
| 392 | | code = spr1cgram[map_start % (spr1cgram_bytes / 2)]; |
| 382 | curr = spr1cgram[curr_sprite.map % (spr1cgram_bytes / 2)]; |
| 393 | 383 | else |
| 394 | | code = spr2cgram[map_start % (spr2cgram_bytes / 2)]; |
| 384 | curr = spr2cgram[curr_sprite.map % (spr2cgram_bytes / 2)]; |
| 395 | 385 | |
| 396 | 386 | pdrawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1 + chip], |
| 397 | | code, |
| 398 | | color, |
| 399 | | flipx,flipy, |
| 387 | curr, |
| 388 | curr_sprite.color, |
| 389 | curr_sprite.flipx,curr_sprite.flipy, |
| 400 | 390 | sx,sy, |
| 401 | | 0x1000 * zoomx,0x1000 * zoomy, |
| 391 | 0x1000 * curr_sprite.zoomx,0x1000 * curr_sprite.zoomy, |
| 402 | 392 | machine.priority_bitmap, |
| 403 | 393 | // pri ? 0 : 0x2); |
| 404 | 394 | primask,15); |
| 405 | | map_start++; |
| 395 | curr_sprite.map++; |
| 406 | 396 | } |
| 407 | 397 | |
| 408 | | if (xsize == 2) map_start += 1; |
| 409 | | if (xsize == 4) map_start += 3; |
| 410 | | if (xsize == 5) map_start += 2; |
| 411 | | if (xsize == 6) map_start += 1; |
| 398 | if (curr_sprite.xsize == 2) curr_sprite.map += 1; |
| 399 | if (curr_sprite.xsize == 4) curr_sprite.map += 3; |
| 400 | if (curr_sprite.xsize == 5) curr_sprite.map += 2; |
| 401 | if (curr_sprite.xsize == 6) curr_sprite.map += 1; |
| 412 | 402 | } |
| 413 | 403 | } |
| 414 | 404 | } |
| r18480 | r18481 | |
| 428 | 418 | int priority = (data2 >> 4) & 1; |
| 429 | 419 | |
| 430 | 420 | /* turns out the sprites are the same as in aerofgt.c */ |
| 431 | | if ((data2 & 0x80) && priority == draw_priority) |
| 421 | if (priority == draw_priority) |
| 432 | 422 | { |
| 433 | | int data0 = spriteram[offs + 0] | (spriteram[offs + 1] << 8); |
| 434 | | int data1 = spriteram[offs + 2] | (spriteram[offs + 3] << 8); |
| 435 | | int data3 = spriteram[offs + 6] | (spriteram[offs + 7] << 8); |
| 436 | | int code = data3 & 0xfff; |
| 437 | | int color = data2 & 0x0f; |
| 438 | | int y = (data0 & 0x1ff) - 6; |
| 439 | | int x = (data1 & 0x1ff) - 13; |
| 440 | | int yzoom = (data0 >> 12) & 15; |
| 441 | | int xzoom = (data1 >> 12) & 15; |
| 442 | | int zoomed = (xzoom | yzoom); |
| 443 | | int ytiles = ((data2 >> 12) & 7) + 1; |
| 444 | | int xtiles = ((data2 >> 8) & 7) + 1; |
| 445 | | int yflip = (data2 >> 15) & 1; |
| 446 | | int xflip = (data2 >> 11) & 1; |
| 423 | if (!get_sprite_attributes((UINT16*)&spriteram[offs])) |
| 424 | continue; |
| 425 | |
| 426 | curr_sprite.ysize++; |
| 427 | curr_sprite.xsize++; |
| 428 | curr_sprite.oy -= 6; |
| 429 | curr_sprite.ox -= 13; |
| 430 | |
| 431 | |
| 432 | |
| 447 | 433 | int xt, yt; |
| 448 | 434 | |
| 435 | |
| 436 | int zoomed = (curr_sprite.zoomx | curr_sprite.zoomy); |
| 437 | |
| 449 | 438 | /* compute the zoom factor -- stolen from aerofgt.c */ |
| 450 | | xzoom = 16 - zoomtable[xzoom] / 8; |
| 451 | | yzoom = 16 - zoomtable[yzoom] / 8; |
| 439 | curr_sprite.zoomx = 16 - zoomtable[curr_sprite.zoomx] / 8; |
| 440 | curr_sprite.zoomy = 16 - zoomtable[curr_sprite.zoomy] / 8; |
| 452 | 441 | |
| 453 | 442 | /* wrap around */ |
| 454 | | if (x > visarea.max_x) |
| 455 | | x -= 0x200; |
| 456 | | if (y > visarea.max_y) |
| 457 | | y -= 0x200; |
| 443 | if (curr_sprite.ox > visarea.max_x) |
| 444 | curr_sprite.ox -= 0x200; |
| 445 | if (curr_sprite.oy > visarea.max_y) |
| 446 | curr_sprite.oy -= 0x200; |
| 458 | 447 | |
| 459 | 448 | /* flip ? */ |
| 460 | 449 | if (flipscreen) |
| 461 | 450 | { |
| 462 | | y = visarea.max_y - y - 16 * ytiles - 4; |
| 463 | | x = visarea.max_x - x - 16 * xtiles - 24; |
| 464 | | xflip=!xflip; |
| 465 | | yflip=!yflip; |
| 451 | curr_sprite.oy = visarea.max_y - curr_sprite.oy - 16 * curr_sprite.ysize - 4; |
| 452 | curr_sprite.ox = visarea.max_x - curr_sprite.ox - 16 * curr_sprite.xsize - 24; |
| 453 | curr_sprite.flipx=!curr_sprite.flipx; |
| 454 | curr_sprite.flipy=!curr_sprite.flipy; |
| 466 | 455 | } |
| 467 | 456 | |
| 468 | 457 | /* normal case */ |
| 469 | | if (!xflip && !yflip) |
| 458 | if (!curr_sprite.flipx && !curr_sprite.flipy) |
| 470 | 459 | { |
| 471 | | for (yt = 0; yt < ytiles; yt++) |
| 472 | | for (xt = 0; xt < xtiles; xt++, code++) |
| 460 | for (yt = 0; yt < curr_sprite.ysize; yt++) |
| 461 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) |
| 473 | 462 | if (!zoomed) |
| 474 | | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 0, 0, |
| 475 | | x + xt * 16, y + yt * 16, 15); |
| 463 | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 0, 0, |
| 464 | curr_sprite.ox + xt * 16, curr_sprite.oy + yt * 16, 15); |
| 476 | 465 | else |
| 477 | | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 0, 0, |
| 478 | | x + xt * xzoom, y + yt * yzoom, |
| 479 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 466 | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 0, 0, |
| 467 | curr_sprite.ox + xt * curr_sprite.zoomx, curr_sprite.oy + yt * curr_sprite.zoomy, |
| 468 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 480 | 469 | } |
| 481 | 470 | |
| 482 | | /* xflipped case */ |
| 483 | | else if (xflip && !yflip) |
| 471 | /* curr_sprite.flipxped case */ |
| 472 | else if (curr_sprite.flipx && !curr_sprite.flipy) |
| 484 | 473 | { |
| 485 | | for (yt = 0; yt < ytiles; yt++) |
| 486 | | for (xt = 0; xt < xtiles; xt++, code++) |
| 474 | for (yt = 0; yt < curr_sprite.ysize; yt++) |
| 475 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) |
| 487 | 476 | if (!zoomed) |
| 488 | | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 1, 0, |
| 489 | | x + (xtiles - 1 - xt) * 16, y + yt * 16, 15); |
| 477 | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 1, 0, |
| 478 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * 16, curr_sprite.oy + yt * 16, 15); |
| 490 | 479 | else |
| 491 | | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 1, 0, |
| 492 | | x + (xtiles - 1 - xt) * xzoom, y + yt * yzoom, |
| 493 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 480 | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 1, 0, |
| 481 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * curr_sprite.zoomx, curr_sprite.oy + yt * curr_sprite.zoomy, |
| 482 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 494 | 483 | } |
| 495 | 484 | |
| 496 | | /* yflipped case */ |
| 497 | | else if (!xflip && yflip) |
| 485 | /* curr_sprite.flipyped case */ |
| 486 | else if (!curr_sprite.flipx && curr_sprite.flipy) |
| 498 | 487 | { |
| 499 | | for (yt = 0; yt < ytiles; yt++) |
| 500 | | for (xt = 0; xt < xtiles; xt++, code++) |
| 488 | for (yt = 0; yt < curr_sprite.ysize; yt++) |
| 489 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) |
| 501 | 490 | if (!zoomed) |
| 502 | | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 0, 1, |
| 503 | | x + xt * 16, y + (ytiles - 1 - yt) * 16, 15); |
| 491 | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 0, 1, |
| 492 | curr_sprite.ox + xt * 16, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * 16, 15); |
| 504 | 493 | else |
| 505 | | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 0, 1, |
| 506 | | x + xt * xzoom, y + (ytiles - 1 - yt) * yzoom, |
| 507 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 494 | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 0, 1, |
| 495 | curr_sprite.ox + xt * curr_sprite.zoomx, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * curr_sprite.zoomy, |
| 496 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 508 | 497 | } |
| 509 | 498 | |
| 510 | | /* x & yflipped case */ |
| 499 | /* x & curr_sprite.flipyped case */ |
| 511 | 500 | else |
| 512 | 501 | { |
| 513 | | for (yt = 0; yt < ytiles; yt++) |
| 514 | | for (xt = 0; xt < xtiles; xt++, code++) |
| 502 | for (yt = 0; yt < curr_sprite.ysize; yt++) |
| 503 | for (xt = 0; xt < curr_sprite.xsize; xt++, curr_sprite.map++) |
| 515 | 504 | if (!zoomed) |
| 516 | | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 1, 1, |
| 517 | | x + (xtiles - 1 - xt) * 16, y + (ytiles - 1 - yt) * 16, 15); |
| 505 | drawgfx_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 1, 1, |
| 506 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * 16, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * 16, 15); |
| 518 | 507 | else |
| 519 | | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], code, color, 1, 1, |
| 520 | | x + (xtiles - 1 - xt) * xzoom, y + (ytiles - 1 - yt) * yzoom, |
| 521 | | 0x1000 * xzoom, 0x1000 * yzoom, 15); |
| 508 | drawgfxzoom_transpen(bitmap, cliprect, screen.machine().gfx[2], curr_sprite.map, curr_sprite.color, 1, 1, |
| 509 | curr_sprite.ox + (curr_sprite.xsize - 1 - xt) * curr_sprite.zoomx, curr_sprite.oy + (curr_sprite.ysize - 1 - yt) * curr_sprite.zoomy, |
| 510 | 0x1000 * curr_sprite.zoomx, 0x1000 * curr_sprite.zoomy, 15); |
| 522 | 511 | } |
| 523 | 512 | } |
| 524 | 513 | } |