trunk/src/mame/drivers/popobear.c
| r241892 | r241893 | |
| 89 | 89 | : driver_device(mconfig, type, tag), |
| 90 | 90 | m_maincpu(*this,"maincpu"), |
| 91 | 91 | m_spr(*this, "spr"), |
| 92 | m_vram(*this, "vram"), |
| 92 | 93 | m_vregs(*this, "vregs"), |
| 93 | 94 | m_gfxdecode(*this, "gfxdecode"), |
| 94 | 95 | m_palette(*this, "palette") |
| r241892 | r241893 | |
| 98 | 99 | tilemap_base[1] = 0xf4000; |
| 99 | 100 | tilemap_base[2] = 0xf8000; |
| 100 | 101 | tilemap_base[3] = 0xfc000; |
| 101 | | |
| 102 | | tilemap_size[0] = 0x04000; |
| 103 | | tilemap_size[1] = 0x04000; |
| 104 | | tilemap_size[2] = 0x04000; |
| 105 | | tilemap_size[3] = 0x04000; |
| 106 | 102 | } |
| 107 | 103 | |
| 108 | 104 | required_device<cpu_device> m_maincpu; |
| 109 | 105 | required_shared_ptr<UINT16> m_spr; |
| 106 | required_shared_ptr<UINT16> m_vram; |
| 110 | 107 | required_shared_ptr<UINT16> m_vregs; |
| 111 | 108 | optional_device<gfxdecode_device> m_gfxdecode; |
| 112 | 109 | required_device<palette_device> m_palette; |
| 113 | 110 | |
| 114 | | UINT16* m_vram; |
| 115 | | UINT16* m_vram_rearranged; |
| 111 | dynamic_array<UINT16> m_vram_rearranged; |
| 116 | 112 | |
| 117 | 113 | int tilemap_base[4]; |
| 118 | | int tilemap_size[4]; |
| 119 | 114 | |
| 120 | 115 | DECLARE_READ8_MEMBER(popo_620000_r); |
| 121 | 116 | DECLARE_WRITE8_MEMBER(popobear_irq_ack_w); |
| r241892 | r241893 | |
| 124 | 119 | TIMER_DEVICE_CALLBACK_MEMBER(popobear_irq); |
| 125 | 120 | void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect); |
| 126 | 121 | |
| 127 | | int m_gfx_index; |
| 128 | 122 | tilemap_t *m_bg_tilemap[4]; |
| 129 | 123 | TILE_GET_INFO_MEMBER(get_popobear_bg0_tile_info); |
| 130 | 124 | TILE_GET_INFO_MEMBER(get_popobear_bg1_tile_info); |
| r241892 | r241893 | |
| 149 | 143 | |
| 150 | 144 | |
| 151 | 145 | COMBINE_DATA(&m_vram_rearranged[swapped_offset]); |
| 152 | | m_gfxdecode->gfx(m_gfx_index)->mark_dirty((swapped_offset)/32); |
| 146 | m_gfxdecode->gfx(0)->mark_dirty((swapped_offset)/32); |
| 153 | 147 | |
| 154 | 148 | // unfortunately tilemaps and tilegfx share the same ram so we're always dirty if we write to RAM |
| 155 | 149 | m_bg_tilemap[0]->mark_all_dirty(); |
| r241892 | r241893 | |
| 158 | 152 | m_bg_tilemap[3]->mark_all_dirty(); |
| 159 | 153 | |
| 160 | 154 | } |
| 161 | | DECLARE_READ16_MEMBER(popo_vram_r) { return m_vram[offset]; } |
| 162 | 155 | |
| 163 | 156 | }; |
| 164 | 157 | |
| r241892 | r241893 | |
| 166 | 159 | static const gfx_layout popobear_char_layout = |
| 167 | 160 | { |
| 168 | 161 | 8,8, |
| 169 | | 0x4000, |
| 162 | RGN_FRAC(1,1), |
| 170 | 163 | 8, |
| 171 | 164 | { 0,1,2,3,4,5,6,7 }, |
| 172 | 165 | { STEP8(0, 8) }, |
| r241892 | r241893 | |
| 174 | 167 | 8*64 |
| 175 | 168 | }; |
| 176 | 169 | |
| 170 | GFXDECODE_START(popobear) |
| 171 | GFXDECODE_RAM( "vram", 0, popobear_char_layout, 0, 1 ) |
| 172 | GFXDECODE_END |
| 177 | 173 | |
| 178 | 174 | TILE_GET_INFO_MEMBER(popobear_state::get_popobear_bg0_tile_info) |
| 179 | 175 | { |
| r241892 | r241893 | |
| 212 | 208 | |
| 213 | 209 | void popobear_state::video_start() |
| 214 | 210 | { |
| 215 | | /* find first empty slot to decode gfx */ |
| 216 | | for (m_gfx_index = 0; m_gfx_index < MAX_GFX_ELEMENTS; m_gfx_index++) |
| 217 | | if (m_gfxdecode->gfx(m_gfx_index) == 0) |
| 218 | | break; |
| 211 | m_vram_rearranged.resize(0x100000 / 2); |
| 219 | 212 | |
| 220 | | assert(m_gfx_index != MAX_GFX_ELEMENTS); |
| 213 | m_gfxdecode->gfx(0)->set_source(reinterpret_cast<UINT8 *>(&m_vram_rearranged[0])); |
| 221 | 214 | |
| 222 | | m_vram = auto_alloc_array_clear(machine(), UINT16, 0x100000/2); |
| 223 | | m_vram_rearranged = auto_alloc_array_clear(machine(), UINT16, 0x100000/2); |
| 224 | | |
| 225 | | |
| 226 | | /* create the char set (gfx will then be updated dynamically from RAM) */ |
| 227 | | m_gfxdecode->set_gfx(m_gfx_index, global_alloc(gfx_element(m_palette, popobear_char_layout, (UINT8 *)m_vram_rearranged, NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0))); |
| 228 | | |
| 229 | 215 | m_bg_tilemap[0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 230 | 216 | m_bg_tilemap[1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 231 | 217 | m_bg_tilemap[2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| r241892 | r241893 | |
| 243 | 229 | |
| 244 | 230 | void popobear_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect) |
| 245 | 231 | { |
| 246 | | // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros! |
| 247 | 232 | UINT8* vram = reinterpret_cast<UINT8 *>(m_spr.target()); |
| 248 | 233 | int i; |
| 249 | 234 | |
| r241892 | r241893 | |
| 264 | 249 | /* 0x*29 = 32 x 32 */ |
| 265 | 250 | for(i = 0x800-8;i >= 0; i-=8) |
| 266 | 251 | { |
| 267 | | int y = vram[i+0x7f800+2]|(vram[i+0x7f800+3]<<8); |
| 268 | | int x = vram[i+0x7f800+4]|(vram[i+0x7f800+5]<<8); |
| 269 | | int spr_num = vram[i+0x7f800+6]|(vram[i+0x7f800+7]<<8); |
| 270 | | int param = vram[i+0x7f800+0]|(vram[i+0x7f800+1]<<8); |
| 252 | UINT16 *sprdata = &m_spr[(0x7f800 + i) / 2]; |
| 271 | 253 | |
| 254 | int param = sprdata[0]; |
| 272 | 255 | int pri = (param & 0x0f00)>>8; |
| 273 | 256 | |
| 274 | 257 | // we do this because it's sprite<->sprite priority, |
| 275 | 258 | if (pri!=drawpri) |
| 276 | 259 | continue; |
| 277 | 260 | |
| 261 | int y = sprdata[1]; |
| 262 | int x = sprdata[2]; |
| 263 | int spr_num = sprdata[3]; |
| 264 | |
| 278 | 265 | int width = 8 << ((param & 0x30)>>4); |
| 279 | 266 | int height = width; // sprites are always square? |
| 280 | 267 | |
| r241892 | r241893 | |
| 327 | 314 | |
| 328 | 315 | for(int xi=0;xi<width;xi++) |
| 329 | 316 | { |
| 330 | | UINT8 pix = (vram[spr_num^1] & 0xff); |
| 317 | UINT8 pix = vram[BYTE_XOR_BE(spr_num)]; |
| 331 | 318 | int x_draw = (x_dir) ? x+((width-1) - xi) : x+xi; |
| 332 | 319 | |
| 333 | 320 | if(cliprect.contains(x_draw, y_draw)) |
| r241892 | r241893 | |
| 479 | 466 | AM_RANGE(0x000000, 0x03ffff) AM_ROM |
| 480 | 467 | AM_RANGE(0x210000, 0x21ffff) AM_RAM |
| 481 | 468 | AM_RANGE(0x280000, 0x2fffff) AM_RAM AM_SHARE("spr") // unknown boundaries, 0x2ff800 contains a sprite list, lower area = sprite gfx |
| 482 | | AM_RANGE(0x300000, 0x3fffff) AM_READWRITE( popo_vram_r, popo_vram_w ) // tile definitions + tilemaps |
| 469 | AM_RANGE(0x300000, 0x3fffff) AM_RAM_WRITE( popo_vram_w ) AM_SHARE("vram") // tile definitions + tilemaps |
| 483 | 470 | |
| 484 | 471 | |
| 485 | 472 | /* Most if not all of these are vregs */ |
| r241892 | r241893 | |
| 660 | 647 | |
| 661 | 648 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 662 | 649 | |
| 663 | | MCFG_GFXDECODE_ADD("gfxdecode", "palette", empty) |
| 650 | MCFG_GFXDECODE_ADD("gfxdecode", "palette", popobear) |
| 664 | 651 | |
| 665 | 652 | MCFG_SOUND_ADD("ymsnd", YM2413, XTAL_42MHz/16) // XTAL CORRECT, DIVISOR GUESSED |
| 666 | 653 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) |