trunk/src/mame/drivers/popobear.c
| r21822 | r21823 | |
| 85 | 85 | : driver_device(mconfig, type, tag), |
| 86 | 86 | m_maincpu(*this,"maincpu"), |
| 87 | 87 | m_spr(*this, "spr"), |
| 88 | | m_vram(*this, "vram"), |
| 89 | 88 | m_vregs(*this, "vregs"){ } |
| 90 | 89 | |
| 91 | 90 | required_device<cpu_device> m_maincpu; |
| 92 | 91 | required_shared_ptr<UINT16> m_spr; |
| 93 | | required_shared_ptr<UINT16> m_vram; |
| 94 | 92 | required_shared_ptr<UINT16> m_vregs; |
| 93 | |
| 94 | UINT8* m_vram; |
| 95 | UINT8* m_vram_rearranged; |
| 96 | |
| 97 | |
| 95 | 98 | DECLARE_READ8_MEMBER(popo_620000_r); |
| 96 | 99 | DECLARE_WRITE8_MEMBER(popobear_irq_ack_w); |
| 97 | 100 | virtual void video_start(); |
| r21822 | r21823 | |
| 99 | 102 | TIMER_DEVICE_CALLBACK_MEMBER(popobear_irq); |
| 100 | 103 | void draw_layer(bitmap_ind16 &bitmap,const rectangle &cliprect, UINT8 layer_n); |
| 101 | 104 | void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect); |
| 105 | |
| 106 | int m_gfx_index; |
| 107 | |
| 108 | // why are we using 8-bit anyway? |
| 109 | DECLARE_WRITE8_MEMBER(popo_vram_w) |
| 110 | { |
| 111 | m_vram[offset^1] = data; |
| 112 | |
| 113 | // the graphic data for the tiles is in a strange order, rearrange it so that we can use it as tiles.. |
| 114 | int swapped_offset = BITSWAP32(offset, /* unused bits */ 31,30,29,28,27,26,25,24,23,22,21,20, /* end unused bits */ |
| 115 | |
| 116 | 19,18,17,16,15,14,13, |
| 117 | |
| 118 | 9,8,7,6,5,4,3, |
| 119 | |
| 120 | 12,11,10, /* y tile address bits */ |
| 121 | |
| 122 | 2,1,0 /* x tile address bits */); |
| 123 | |
| 124 | |
| 125 | |
| 126 | m_vram_rearranged[swapped_offset] = data; |
| 127 | machine().gfx[m_gfx_index]->mark_dirty((swapped_offset^1)/2); |
| 128 | } |
| 129 | DECLARE_READ8_MEMBER(popo_vram_r) { return m_vram[offset^1]; } |
| 130 | |
| 102 | 131 | }; |
| 103 | 132 | |
| 133 | |
| 134 | static const gfx_layout popobear_char_layout = |
| 135 | { |
| 136 | 8,8, |
| 137 | 0x4000, |
| 138 | 8, |
| 139 | { 0,1,2,3,4,5,6,7 }, |
| 140 | { 0,8,16,24,32,40,48,56 }, |
| 141 | { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 }, |
| 142 | 8*64 |
| 143 | }; |
| 144 | |
| 145 | |
| 146 | |
| 147 | |
| 104 | 148 | void popobear_state::video_start() |
| 105 | 149 | { |
| 150 | /* find first empty slot to decode gfx */ |
| 151 | for (m_gfx_index = 0; m_gfx_index < MAX_GFX_ELEMENTS; m_gfx_index++) |
| 152 | if (machine().gfx[m_gfx_index] == 0) |
| 153 | break; |
| 154 | |
| 155 | assert(m_gfx_index != MAX_GFX_ELEMENTS); |
| 156 | |
| 157 | m_vram = auto_alloc_array_clear(machine(), UINT8, 0x100000); |
| 158 | m_vram_rearranged = auto_alloc_array_clear(machine(), UINT8, 0x100000); |
| 159 | |
| 160 | |
| 161 | /* create the char set (gfx will then be updated dynamically from RAM) */ |
| 162 | machine().gfx[m_gfx_index] = auto_alloc(machine(), gfx_element(machine(), popobear_char_layout, (UINT8 *)m_vram_rearranged, machine().total_colors() / 16, 0)); |
| 106 | 163 | } |
| 107 | 164 | |
| 108 | 165 | void popobear_state::draw_layer(bitmap_ind16 &bitmap,const rectangle &cliprect, UINT8 layer_n) |
| 109 | 166 | { |
| 110 | | // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros! |
| 111 | | UINT8* vram = reinterpret_cast<UINT8 *>(m_vram.target()); |
| 167 | UINT8* vram = m_vram; |
| 112 | 168 | UINT16* vreg = (UINT16 *)m_vregs; |
| 113 | 169 | int count; |
| 114 | 170 | const UINT8 vreg_base[] = { 0x10/2, 0x14/2 }; |
| r21822 | r21823 | |
| 134 | 190 | { |
| 135 | 191 | for(int x=0;x<128;x++) |
| 136 | 192 | { |
| 137 | | int tile,xtile,ytile; |
| 193 | int tile; |
| 138 | 194 | |
| 139 | 195 | tile = vram[count+0]|(vram[count+1]<<8); |
| 140 | | xtile = tile & 0x7f; |
| 141 | | xtile *= 8; |
| 142 | | ytile = tile >> 7; |
| 143 | | ytile *= 1024*8; |
| 196 | |
| 197 | drawgfx_transpen(bitmap,cliprect,machine().gfx[m_gfx_index],tile,0,0,0,(x*8)-xscroll,(y*8)-yscroll, 0); |
| 198 | drawgfx_transpen(bitmap,cliprect,machine().gfx[m_gfx_index],tile,0,0,0,(x*8)-xscroll,512+(y*8)-yscroll, 0); |
| 199 | drawgfx_transpen(bitmap,cliprect,machine().gfx[m_gfx_index],tile,0,0,0,1024+(x*8)-xscroll,(y*8)-yscroll, 0); |
| 200 | drawgfx_transpen(bitmap,cliprect,machine().gfx[m_gfx_index],tile,0,0,0,1024+(x*8)-xscroll,512+(y*8)-yscroll, 0); |
| 144 | 201 | |
| 145 | | for(int yi=0;yi<8;yi++) |
| 146 | | { |
| 147 | | for(int xi=0;xi<8;xi+=2) |
| 148 | | { |
| 149 | | UINT8 color; |
| 150 | | int xoffs,yoffs; |
| 151 | | |
| 152 | | xoffs = x*8+xi - xscroll; |
| 153 | | yoffs = y*8+yi - yscroll; |
| 154 | | |
| 155 | | color = (vram[((xi+yi*1024)+xtile+ytile) & 0xfffff] & 0xff); |
| 156 | | |
| 157 | | if(cliprect.contains(xoffs+1, yoffs) && color) |
| 158 | | bitmap.pix16(yoffs, xoffs+1) = machine().pens[color]; |
| 159 | | |
| 160 | | if(cliprect.contains(xoffs+1, yoffs+512) && color) |
| 161 | | bitmap.pix16(yoffs+512, xoffs+1) = machine().pens[color]; |
| 162 | | |
| 163 | | //if(cliprect.contains(xoffs+1, yoffs+256) && color) |
| 164 | | // bitmap.pix16(yoffs+512, xoffs+1) = machine().pens[color]; |
| 165 | | |
| 166 | | color = (vram[((xi+1+yi*1024)+xtile+ytile) & 0xfffff] & 0xff); |
| 167 | | |
| 168 | | if(cliprect.contains(xoffs, yoffs) && color) |
| 169 | | bitmap.pix16(yoffs, xoffs) = machine().pens[color]; |
| 170 | | |
| 171 | | if(cliprect.contains(xoffs, yoffs+512) && color) |
| 172 | | bitmap.pix16(yoffs+512, xoffs) = machine().pens[color]; |
| 173 | | } |
| 174 | | } |
| 175 | | |
| 176 | 202 | count+=2; |
| 177 | 203 | } |
| 178 | 204 | } |
| 179 | | } |
| 205 | } |
| 180 | 206 | |
| 207 | |
| 181 | 208 | void popobear_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect) |
| 182 | 209 | { |
| 183 | 210 | // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros! |
| r21822 | r21823 | |
| 219 | 246 | |
| 220 | 247 | for(int yi=0;yi<height;yi++) |
| 221 | 248 | { |
| 222 | | for(int xi=0;xi<width;xi+=2) |
| 249 | int y_draw = (y_dir) ? y+(height - yi) : y+yi; |
| 250 | |
| 251 | for(int xi=0;xi<width;xi++) |
| 223 | 252 | { |
| 224 | | UINT8 color; |
| 225 | | int x_res,y_res; |
| 253 | UINT8 pix = (vram[spr_num^1] & 0xff); |
| 254 | int x_draw = (x_dir) ? x+(width - xi) : x+xi; |
| 226 | 255 | |
| 227 | | color = (vram[spr_num] & 0xff); |
| 228 | | x_res = (x_dir) ? x+0+(width - xi) : x+1+xi; |
| 229 | | y_res = (y_dir) ? y+(height - yi) : y+yi; |
| 256 | if(cliprect.contains(x_draw, y_draw) && pix) |
| 257 | bitmap.pix16(y_draw, x_draw) = machine().pens[pix+0x100+color_bank]; |
| 230 | 258 | |
| 231 | | if(cliprect.contains(x_res, y_res) && color) |
| 232 | | bitmap.pix16(y_res, x_res) = machine().pens[color+0x100+color_bank]; |
| 233 | | |
| 234 | | color = (vram[spr_num+1] & 0xff); |
| 235 | | x_res = (x_dir) ? x+1+(width - xi) : x+0+xi; |
| 236 | | y_res = (y_dir) ? y+(height - yi) : y+yi; |
| 237 | | |
| 238 | | if(cliprect.contains(x_res, y_res) && color) |
| 239 | | bitmap.pix16(y_res, x_res) = machine().pens[color+0x100+color_bank]; |
| 240 | | |
| 241 | | spr_num+=2; |
| 259 | spr_num++; |
| 242 | 260 | } |
| 243 | 261 | } |
| 244 | 262 | } |
| r21822 | r21823 | |
| 281 | 299 | AM_RANGE(0x000000, 0x03ffff) AM_ROM |
| 282 | 300 | AM_RANGE(0x210000, 0x21ffff) AM_RAM |
| 283 | 301 | AM_RANGE(0x280000, 0x2fffff) AM_RAM AM_SHARE("spr") // unknown boundaries, 0x2ff800 contains a sprite list |
| 284 | | AM_RANGE(0x300000, 0x3fffff) AM_RAM AM_SHARE("vram") |
| 302 | AM_RANGE(0x300000, 0x3fffff) AM_READWRITE8( popo_vram_r, popo_vram_w, 0xffff ) |
| 303 | |
| 285 | 304 | |
| 286 | 305 | /* Most if not all of these are vregs */ |
| 287 | 306 | AM_RANGE(0x480000, 0x48001f) AM_RAM AM_SHARE("vregs") |