trunk/src/mame/drivers/popobear.c
| r21823 | r21824 | |
| 6 | 6 | |
| 7 | 7 | TODO: |
| 8 | 8 | - auto-animation speed is erratic (way too fast); |
| 9 | | - sprites; |
| 10 | 9 | - tilemap effects (scrolling, colscroll, linescroll); |
| 10 | (high score table?) |
| 11 | - BMC logo isn't copied correctly after an attract loop, RAM not cleared on a reset either? |
| 11 | 12 | - BGM seems quite off, YM2413 core bug? |
| 12 | 13 | - I/Os; |
| 13 | 14 | - IRQ generation; |
| r21823 | r21824 | |
| 73 | 74 | *******************************************************************************************/ |
| 74 | 75 | |
| 75 | 76 | |
| 77 | |
| 76 | 78 | #include "emu.h" |
| 77 | 79 | #include "cpu/m68000/m68000.h" |
| 78 | 80 | #include "sound/okim6295.h" |
| r21823 | r21824 | |
| 85 | 87 | : driver_device(mconfig, type, tag), |
| 86 | 88 | m_maincpu(*this,"maincpu"), |
| 87 | 89 | m_spr(*this, "spr"), |
| 88 | | m_vregs(*this, "vregs"){ } |
| 90 | m_vregs(*this, "vregs") |
| 91 | |
| 92 | { |
| 93 | tilemap_base[0] = 0xf0000; |
| 94 | tilemap_base[1] = 0xf4000; |
| 95 | tilemap_base[2] = 0xf8000; |
| 96 | tilemap_base[3] = 0xfc000; |
| 89 | 97 | |
| 98 | tilemap_size[0] = 0x04000; |
| 99 | tilemap_size[1] = 0x04000; |
| 100 | tilemap_size[2] = 0x04000; |
| 101 | tilemap_size[3] = 0x04000; |
| 102 | } |
| 103 | |
| 90 | 104 | required_device<cpu_device> m_maincpu; |
| 91 | 105 | required_shared_ptr<UINT16> m_spr; |
| 92 | 106 | required_shared_ptr<UINT16> m_vregs; |
| r21823 | r21824 | |
| 94 | 108 | UINT8* m_vram; |
| 95 | 109 | UINT8* m_vram_rearranged; |
| 96 | 110 | |
| 111 | int tilemap_base[4]; |
| 112 | int tilemap_size[4]; |
| 97 | 113 | |
| 98 | 114 | DECLARE_READ8_MEMBER(popo_620000_r); |
| 99 | 115 | DECLARE_WRITE8_MEMBER(popobear_irq_ack_w); |
| r21823 | r21824 | |
| 104 | 120 | void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect); |
| 105 | 121 | |
| 106 | 122 | int m_gfx_index; |
| 123 | tilemap_t *m_bg_tilemap[4]; |
| 124 | TILE_GET_INFO_MEMBER(get_popobear_bg0_tile_info); |
| 125 | TILE_GET_INFO_MEMBER(get_popobear_bg1_tile_info); |
| 126 | TILE_GET_INFO_MEMBER(get_popobear_bg2_tile_info); |
| 127 | TILE_GET_INFO_MEMBER(get_popobear_bg3_tile_info); |
| 107 | 128 | |
| 108 | 129 | // why are we using 8-bit anyway? |
| 109 | 130 | DECLARE_WRITE8_MEMBER(popo_vram_w) |
| r21823 | r21824 | |
| 125 | 146 | |
| 126 | 147 | m_vram_rearranged[swapped_offset] = data; |
| 127 | 148 | machine().gfx[m_gfx_index]->mark_dirty((swapped_offset^1)/2); |
| 149 | |
| 150 | // unfortunately tilemaps and tilegfx share the same ram so we're always dirty if we write to RAM |
| 151 | m_bg_tilemap[0]->mark_all_dirty(); |
| 152 | m_bg_tilemap[1]->mark_all_dirty(); |
| 153 | m_bg_tilemap[2]->mark_all_dirty(); |
| 154 | m_bg_tilemap[3]->mark_all_dirty(); |
| 155 | |
| 128 | 156 | } |
| 129 | 157 | DECLARE_READ8_MEMBER(popo_vram_r) { return m_vram[offset^1]; } |
| 130 | 158 | |
| r21823 | r21824 | |
| 143 | 171 | }; |
| 144 | 172 | |
| 145 | 173 | |
| 174 | TILE_GET_INFO_MEMBER(popobear_state::get_popobear_bg0_tile_info) |
| 175 | { |
| 176 | int base = tilemap_base[0]; |
| 177 | int tileno = (m_vram[base + tile_index*2 + 1]<<8) | m_vram[base + tile_index*2 + 0]; |
| 178 | SET_TILE_INFO_MEMBER(0, tileno, 0, 0); |
| 179 | } |
| 146 | 180 | |
| 181 | TILE_GET_INFO_MEMBER(popobear_state::get_popobear_bg1_tile_info) |
| 182 | { |
| 183 | int base = tilemap_base[1]; |
| 184 | int tileno = (m_vram[base + tile_index*2 + 1]<<8) | m_vram[base + tile_index*2 + 0]; |
| 185 | SET_TILE_INFO_MEMBER(0, tileno, 0, 0); |
| 186 | } |
| 147 | 187 | |
| 188 | TILE_GET_INFO_MEMBER(popobear_state::get_popobear_bg2_tile_info) |
| 189 | { |
| 190 | int base = tilemap_base[2]; |
| 191 | int tileno = (m_vram[base + tile_index*2 + 1]<<8) | m_vram[base + tile_index*2 + 0]; |
| 192 | SET_TILE_INFO_MEMBER(0, tileno, 0, 0); |
| 193 | } |
| 194 | |
| 195 | TILE_GET_INFO_MEMBER(popobear_state::get_popobear_bg3_tile_info) |
| 196 | { |
| 197 | int base = tilemap_base[3]; |
| 198 | int tileno = (m_vram[base + tile_index*2 + 1]<<8) | m_vram[base + tile_index*2 + 0]; |
| 199 | SET_TILE_INFO_MEMBER(0, tileno, 0, 0); |
| 200 | } |
| 201 | |
| 202 | |
| 203 | |
| 204 | |
| 148 | 205 | void popobear_state::video_start() |
| 149 | 206 | { |
| 150 | 207 | /* find first empty slot to decode gfx */ |
| r21823 | r21824 | |
| 160 | 217 | |
| 161 | 218 | /* create the char set (gfx will then be updated dynamically from RAM) */ |
| 162 | 219 | machine().gfx[m_gfx_index] = auto_alloc(machine(), gfx_element(machine(), popobear_char_layout, (UINT8 *)m_vram_rearranged, machine().total_colors() / 16, 0)); |
| 220 | |
| 221 | m_bg_tilemap[0] = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 222 | m_bg_tilemap[1] = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 223 | m_bg_tilemap[2] = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 224 | m_bg_tilemap[3] = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(popobear_state::get_popobear_bg3_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 64); |
| 225 | |
| 226 | m_bg_tilemap[0]->set_transparent_pen(0); |
| 227 | m_bg_tilemap[1]->set_transparent_pen(0); |
| 228 | m_bg_tilemap[2]->set_transparent_pen(0); |
| 229 | m_bg_tilemap[3]->set_transparent_pen(0); |
| 230 | |
| 163 | 231 | } |
| 164 | 232 | |
| 233 | |
| 165 | 234 | void popobear_state::draw_layer(bitmap_ind16 &bitmap,const rectangle &cliprect, UINT8 layer_n) |
| 166 | 235 | { |
| 167 | | UINT8* vram = m_vram; |
| 168 | 236 | UINT16* vreg = (UINT16 *)m_vregs; |
| 169 | | int count; |
| 170 | 237 | const UINT8 vreg_base[] = { 0x10/2, 0x14/2 }; |
| 171 | 238 | int xscroll,yscroll; |
| 172 | 239 | |
| 173 | | // count = (m_vregs[vreg_base[layer_n]]<<5); |
| 174 | | // count &= 0xfc000; |
| 175 | | count = (0xf0000+layer_n*0x4000); |
| 176 | 240 | if(layer_n & 2) |
| 177 | 241 | { |
| 178 | 242 | xscroll = vreg[vreg_base[(layer_n & 1) ^ 1]+2/2] & 0x1ff; |
| r21823 | r21824 | |
| 183 | 247 | xscroll = 0; |
| 184 | 248 | yscroll = 0; |
| 185 | 249 | } |
| 186 | | |
| 187 | 250 | popmessage("%04x %04x",vreg[vreg_base[0]+0/2],vreg[vreg_base[1]+0/2]); |
| 188 | 251 | |
| 189 | | for(int y=0;y<64;y++) |
| 190 | | { |
| 191 | | for(int x=0;x<128;x++) |
| 192 | | { |
| 193 | | int tile; |
| 194 | 252 | |
| 195 | | tile = vram[count+0]|(vram[count+1]<<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); |
| 253 | m_bg_tilemap[layer_n]->set_scrolly(0, yscroll); |
| 254 | m_bg_tilemap[layer_n]->set_scrollx(0, xscroll); |
| 201 | 255 | |
| 202 | | count+=2; |
| 203 | | } |
| 204 | | } |
| 205 | | } |
| 206 | 256 | |
| 207 | 257 | |
| 258 | m_bg_tilemap[layer_n]->draw(bitmap, cliprect, 0, 0); |
| 259 | |
| 260 | } |
| 261 | |
| 262 | |
| 208 | 263 | void popobear_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect) |
| 209 | 264 | { |
| 210 | 265 | // ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros! |