trunk/src/mess/video/arcadia.c
| r20655 | r20656 | |
| 314 | 314 | UINT8 data=0; |
| 315 | 315 | switch (offset) |
| 316 | 316 | { |
| 317 | | case 0xff: data=m_charline|0xf0;break; |
| 318 | | case 0x100: data=ioport("controller1_col1")->read();break; |
| 319 | | case 0x101: data=ioport("controller1_col2")->read();break; |
| 320 | | case 0x102: data=ioport("controller1_col3")->read();break; |
| 321 | | case 0x103: data=ioport("controller1_extra")->read();break; |
| 322 | | case 0x104: data=ioport("controller2_col1")->read();break; |
| 323 | | case 0x105: data=ioport("controller2_col2")->read();break; |
| 324 | | case 0x106: data=ioport("controller2_col3")->read();break; |
| 325 | | case 0x107: data=ioport("controller2_extra")->read();break; |
| 326 | | case 0x108: data=ioport("panel")->read();break; |
| 317 | case 0xff: data = m_charline|0xf0;break; |
| 318 | case 0x100: data = m_controller1_col1->read();break; |
| 319 | case 0x101: data = m_controller1_col2->read();break; |
| 320 | case 0x102: data = m_controller1_col3->read();break; |
| 321 | case 0x103: data = m_controller1_extra->read();break; |
| 322 | case 0x104: data = m_controller2_col1->read();break; |
| 323 | case 0x105: data = m_controller2_col2->read();break; |
| 324 | case 0x106: data = m_controller2_col3->read();break; |
| 325 | case 0x107: data = m_controller2_extra->read();break; |
| 326 | case 0x108: data = m_panel->read();break; |
| 327 | 327 | #if 0 |
| 328 | 328 | case 0x1fe: |
| 329 | 329 | if (m_ad_select) |
| r20655 | r20656 | |
| 342 | 342 | data = 0x80; |
| 343 | 343 | if (m_ad_select) |
| 344 | 344 | { |
| 345 | | if (ioport("joysticks")->read()&0x10) data=0; |
| 346 | | if (ioport("joysticks")->read()&0x20) data=0xff; |
| 345 | if (m_joysticks->read()&0x10) data=0; |
| 346 | if (m_joysticks->read()&0x20) data=0xff; |
| 347 | 347 | } |
| 348 | 348 | else |
| 349 | 349 | { |
| 350 | | if (ioport("joysticks")->read()&0x40) data=0xff; |
| 351 | | if (ioport("joysticks")->read()&0x80) data=0; |
| 350 | if (m_joysticks->read()&0x40) data=0xff; |
| 351 | if (m_joysticks->read()&0x80) data=0; |
| 352 | 352 | } |
| 353 | 353 | break; |
| 354 | 354 | case 0x1ff: |
| 355 | 355 | data = 0x6f; // 0x7f too big for alien invaders (move right) |
| 356 | 356 | if (m_ad_select) |
| 357 | 357 | { |
| 358 | | if (ioport("joysticks")->read()&0x1) data=0; |
| 359 | | if (ioport("joysticks")->read()&0x2) data=0xff; |
| 358 | if (m_joysticks->read()&0x1) data=0; |
| 359 | if (m_joysticks->read()&0x2) data=0xff; |
| 360 | 360 | } |
| 361 | 361 | else |
| 362 | 362 | { |
| 363 | | if (ioport("joysticks")->read()&0x4) data=0xff; |
| 364 | | if (ioport("joysticks")->read()&0x8) data=0; |
| 363 | if (m_joysticks->read()&0x4) data=0xff; |
| 364 | if (m_joysticks->read()&0x8) data=0; |
| 365 | 365 | } |
| 366 | 366 | break; |
| 367 | 367 | #endif |
| r20655 | r20656 | |
| 373 | 373 | |
| 374 | 374 | WRITE8_MEMBER( arcadia_state::arcadia_video_w ) |
| 375 | 375 | { |
| 376 | | arcadia_sound_device *sound = machine().device<arcadia_sound_device>("custom"); |
| 377 | 376 | m_reg.data[offset]=data; |
| 378 | 377 | switch (offset) |
| 379 | 378 | { |
| r20655 | r20656 | |
| 381 | 380 | m_ypos=255-data+YPOS; |
| 382 | 381 | break; |
| 383 | 382 | case 0xfd: |
| 384 | | sound->write(space, offset&3, data); |
| 383 | m_custom->write(space, offset&3, data); |
| 385 | 384 | m_multicolor = data & 0x80; |
| 386 | 385 | break; |
| 387 | 386 | case 0xfe: |
| 388 | | sound->write(space, offset&3, data); |
| 387 | m_custom->write(space, offset&3, data); |
| 389 | 388 | m_shift = (data>>5); |
| 390 | 389 | break; |
| 391 | 390 | case 0xf0: |
| r20655 | r20656 | |
| 421 | 420 | } |
| 422 | 421 | } |
| 423 | 422 | |
| 424 | | INLINE void arcadia_draw_char(running_machine &machine, bitmap_ind16 &bitmap, UINT8 *ch, int charcode, int y, int x) |
| 423 | void arcadia_state::arcadia_draw_char(UINT8 *ch, int charcode, int y, int x) |
| 425 | 424 | { |
| 426 | | arcadia_state *state = machine.driver_data<arcadia_state>(); |
| 427 | 425 | int k,b,cc,sc, colour; |
| 428 | | if (state->m_multicolor) |
| 426 | if (m_multicolor) |
| 429 | 427 | { |
| 430 | 428 | if (charcode&0x40) |
| 431 | | cc=((state->m_reg.d.pal[1]>>3)&7); |
| 429 | cc=((m_reg.d.pal[1]>>3)&7); |
| 432 | 430 | else |
| 433 | | cc=((state->m_reg.d.pal[0]>>3)&7); |
| 431 | cc=((m_reg.d.pal[0]>>3)&7); |
| 434 | 432 | |
| 435 | 433 | if (charcode&0x80) |
| 436 | | sc=(state->m_reg.d.pal[1]&7); |
| 434 | sc=(m_reg.d.pal[1]&7); |
| 437 | 435 | else |
| 438 | | sc=(state->m_reg.d.pal[0]&7); |
| 436 | sc=(m_reg.d.pal[0]&7); |
| 439 | 437 | } |
| 440 | 438 | else |
| 441 | 439 | { |
| 442 | | cc=((state->m_reg.d.pal[1]>>3)&1)|((charcode>>5)&6); |
| 443 | | sc=(state->m_reg.d.pal[1]&7); |
| 440 | cc=((m_reg.d.pal[1]>>3)&1)|((charcode>>5)&6); |
| 441 | sc=(m_reg.d.pal[1]&7); |
| 444 | 442 | } |
| 445 | 443 | colour = (((sc << 3) | cc) + 4); |
| 446 | 444 | |
| 447 | | if (state->m_doublescan) |
| 445 | if (m_doublescan) |
| 448 | 446 | { |
| 449 | | for (k=0; (k<8)&&(y<bitmap.height()); k++, y+=2) |
| 447 | for (k=0; (k<8)&&(y<m_bitmap->height()); k++, y+=2) |
| 450 | 448 | { |
| 451 | 449 | b=ch[k]; |
| 452 | | state->m_bg[y][x>>3]|=b>>(x&7); |
| 453 | | state->m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); |
| 450 | m_bg[y][x>>3]|=b>>(x&7); |
| 451 | m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); |
| 454 | 452 | |
| 455 | | if (y+1<bitmap.height()) |
| 453 | if (y+1<m_bitmap->height()) |
| 456 | 454 | { |
| 457 | | state->m_bg[y+1][x>>3]|=b>>(x&7); |
| 458 | | state->m_bg[y+1][(x>>3)+1]|=b<<(8-(x&7)); |
| 459 | | drawgfx_opaque(bitmap, bitmap.cliprect(), machine.gfx[0], b,colour, 0,0,x,y); |
| 460 | | drawgfx_opaque(bitmap, bitmap.cliprect(), machine.gfx[0], b,colour, 0,0,x,y+1); |
| 455 | m_bg[y+1][x>>3]|=b>>(x&7); |
| 456 | m_bg[y+1][(x>>3)+1]|=b<<(8-(x&7)); |
| 457 | drawgfx_opaque(*m_bitmap, m_bitmap->cliprect(), machine().gfx[0], b,colour, 0,0,x,y); |
| 458 | drawgfx_opaque(*m_bitmap, m_bitmap->cliprect(), machine().gfx[0], b,colour, 0,0,x,y+1); |
| 461 | 459 | } |
| 462 | 460 | } |
| 463 | 461 | } |
| 464 | 462 | else |
| 465 | 463 | { |
| 466 | | for (k=0; (k<8)&&(y<bitmap.height()); k++, y++) |
| 464 | for (k=0; (k<8)&&(y<m_bitmap->height()); k++, y++) |
| 467 | 465 | { |
| 468 | 466 | b=ch[k]; |
| 469 | | state->m_bg[y][x>>3]|=b>>(x&7); |
| 470 | | state->m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); |
| 467 | m_bg[y][x>>3]|=b>>(x&7); |
| 468 | m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); |
| 471 | 469 | |
| 472 | | drawgfx_opaque(bitmap, bitmap.cliprect(), machine.gfx[0], b,colour, 0,0,x,y); |
| 470 | drawgfx_opaque(*m_bitmap, m_bitmap->cliprect(), machine().gfx[0], b,colour, 0,0,x,y); |
| 473 | 471 | } |
| 474 | 472 | } |
| 475 | 473 | } |
| 476 | 474 | |
| 477 | | INLINE void arcadia_vh_draw_line(running_machine &machine, bitmap_ind16 &bitmap, int y, UINT8 chars1[16]) |
| 475 | |
| 476 | void arcadia_state::arcadia_vh_draw_line(int y, UINT8 chars1[16]) |
| 478 | 477 | { |
| 479 | | arcadia_state *state = machine.driver_data<arcadia_state>(); |
| 480 | 478 | int x, ch, j, h; |
| 481 | | int graphics=state->m_graphics; |
| 482 | | h=state->m_doublescan ? 16 : 8 ; |
| 479 | int graphics = m_graphics; |
| 480 | h = m_doublescan ? 16 : 8 ; |
| 483 | 481 | |
| 484 | | if (bitmap.height()-state->m_line<h) |
| 485 | | h=bitmap.height()-state->m_line; |
| 482 | if (m_bitmap->height() - m_line < h) |
| 483 | h = m_bitmap->height() - m_line; |
| 486 | 484 | |
| 487 | | bitmap.plot_box(0, y, bitmap.width(), h, (state->m_reg.d.pal[1]&7)); |
| 488 | | memset(state->m_bg[y], 0, sizeof(state->m_bg[0])*h); |
| 485 | m_bitmap->plot_box(0, y, m_bitmap->width(), h, (m_reg.d.pal[1]&7)); |
| 486 | memset(m_bg[y], 0, sizeof(m_bg[0])*h); |
| 489 | 487 | |
| 490 | | for (x=XPOS+state->m_shift, j=0; j<16;j++,x+=8) |
| 488 | for (x=XPOS+m_shift, j=0; j<16;j++,x+=8) |
| 491 | 489 | { |
| 492 | 490 | ch=chars1[j]; |
| 493 | 491 | // hangman switches with 0x40 |
| r20655 | r20656 | |
| 504 | 502 | } |
| 505 | 503 | } |
| 506 | 504 | if (graphics) |
| 507 | | arcadia_draw_char(machine, bitmap, state->m_rectangle[ch&0x3f], ch, y, x); |
| 505 | arcadia_draw_char(m_rectangle[ch&0x3f], ch, y, x); |
| 508 | 506 | else |
| 509 | | arcadia_draw_char(machine, bitmap, state->m_chars[ch&0x3f], ch, y, x); |
| 507 | arcadia_draw_char(m_chars[ch&0x3f], ch, y, x); |
| 510 | 508 | } |
| 511 | 509 | } |
| 512 | 510 | |
| 513 | | static int arcadia_sprite_collision(arcadia_state *state, int n1, int n2) |
| 511 | |
| 512 | int arcadia_state::arcadia_sprite_collision(int n1, int n2) |
| 514 | 513 | { |
| 515 | 514 | int k, b1, b2, x; |
| 516 | | if (state->m_pos[n1].x+8<=state->m_pos[n2].x) |
| 515 | if (m_pos[n1].x+8<=m_pos[n2].x) |
| 517 | 516 | return FALSE; |
| 518 | | if (state->m_pos[n1].x>=state->m_pos[n2].x+8) |
| 517 | if (m_pos[n1].x>=m_pos[n2].x+8) |
| 519 | 518 | return FALSE; |
| 520 | 519 | |
| 521 | 520 | for (k=0; k<8; k++) |
| 522 | 521 | { |
| 523 | | if (state->m_pos[n1].y+k<state->m_pos[n2].y) |
| 522 | if (m_pos[n1].y+k<m_pos[n2].y) |
| 524 | 523 | continue; |
| 525 | | if (state->m_pos[n1].y+k>=state->m_pos[n2].y+8) |
| 524 | if (m_pos[n1].y+k>=m_pos[n2].y+8) |
| 526 | 525 | break; |
| 527 | | x=state->m_pos[n1].x-state->m_pos[n2].x; |
| 528 | | b1=state->m_reg.d.chars[n1][k]; |
| 529 | | b2=state->m_reg.d.chars[n2][state->m_pos[n1].y+k-state->m_pos[n2].y]; |
| 526 | x=m_pos[n1].x-m_pos[n2].x; |
| 527 | b1=m_reg.d.chars[n1][k]; |
| 528 | b2=m_reg.d.chars[n2][m_pos[n1].y+k-m_pos[n2].y]; |
| 530 | 529 | if (x<0) |
| 531 | 530 | b2>>=-x; |
| 532 | 531 | if (x>0) |
| r20655 | r20656 | |
| 537 | 536 | return FALSE; |
| 538 | 537 | } |
| 539 | 538 | |
| 540 | | static void arcadia_draw_sprites(running_machine &machine, bitmap_ind16 &bitmap) |
| 539 | |
| 540 | void arcadia_state::arcadia_draw_sprites() |
| 541 | 541 | { |
| 542 | | arcadia_state *state = machine.driver_data<arcadia_state>(); |
| 543 | 542 | int i, k, x, y, color=0; |
| 544 | 543 | UINT8 b; |
| 545 | 544 | |
| 546 | | state->m_reg.d.collision_bg|=0xf; |
| 547 | | state->m_reg.d.collision_sprite|=0x3f; |
| 545 | m_reg.d.collision_bg|=0xf; |
| 546 | m_reg.d.collision_sprite|=0x3f; |
| 548 | 547 | for (i=0; i<4; i++) |
| 549 | 548 | { |
| 550 | 549 | int doublescan = FALSE; |
| 551 | | if (state->m_pos[i].y<=-YPOS) continue; |
| 552 | | if (state->m_pos[i].y>=bitmap.height()-YPOS-8) continue; |
| 553 | | if (state->m_pos[i].x<=-XPOS) continue; |
| 554 | | if (state->m_pos[i].x>=128+XPOS-8) continue; |
| 550 | if (m_pos[i].y<=-YPOS) continue; |
| 551 | if (m_pos[i].y>=m_bitmap->height()-YPOS-8) continue; |
| 552 | if (m_pos[i].x<=-XPOS) continue; |
| 553 | if (m_pos[i].x>=128+XPOS-8) continue; |
| 555 | 554 | |
| 556 | 555 | switch (i) |
| 557 | 556 | { |
| 558 | 557 | case 0: |
| 559 | | color=(state->m_reg.d.pal[3]>>3)&7; |
| 560 | | doublescan=state->m_reg.d.pal[3]&0x80?FALSE:TRUE; |
| 558 | color=(m_reg.d.pal[3]>>3)&7; |
| 559 | doublescan=m_reg.d.pal[3]&0x80?FALSE:TRUE; |
| 561 | 560 | break; |
| 562 | 561 | case 1: |
| 563 | | color=state->m_reg.d.pal[3]&7; |
| 564 | | doublescan=state->m_reg.d.pal[3]&0x40?FALSE:TRUE; |
| 562 | color=m_reg.d.pal[3]&7; |
| 563 | doublescan=m_reg.d.pal[3]&0x40?FALSE:TRUE; |
| 565 | 564 | break; |
| 566 | 565 | case 2: |
| 567 | | color=(state->m_reg.d.pal[2]>>3)&7; |
| 568 | | doublescan=state->m_reg.d.pal[2]&0x80?FALSE:TRUE; |
| 566 | color=(m_reg.d.pal[2]>>3)&7; |
| 567 | doublescan=m_reg.d.pal[2]&0x80?FALSE:TRUE; |
| 569 | 568 | break; |
| 570 | 569 | case 3: |
| 571 | | color=state->m_reg.d.pal[2]&7; |
| 572 | | doublescan=state->m_reg.d.pal[2]&0x40?FALSE:TRUE; |
| 570 | color=m_reg.d.pal[2]&7; |
| 571 | doublescan=m_reg.d.pal[2]&0x40?FALSE:TRUE; |
| 573 | 572 | break; |
| 574 | 573 | } |
| 575 | 574 | for (k=0; k<8; k++) |
| 576 | 575 | { |
| 577 | 576 | int j, m; |
| 578 | | b=state->m_reg.d.chars[i][k]; |
| 579 | | x=state->m_pos[i].x+XPOS; |
| 577 | b=m_reg.d.chars[i][k]; |
| 578 | x=m_pos[i].x+XPOS; |
| 580 | 579 | if (!doublescan) |
| 581 | 580 | { |
| 582 | | y=state->m_pos[i].y+YPOS+k; |
| 581 | y=m_pos[i].y+YPOS+k; |
| 583 | 582 | for (j=0,m=0x80; j<8; j++, m>>=1) |
| 584 | 583 | { |
| 585 | 584 | if (b & m) |
| 586 | | bitmap.pix16(y, x + j) = color; |
| 585 | m_bitmap->pix16(y, x + j) = color; |
| 587 | 586 | } |
| 588 | 587 | } |
| 589 | 588 | else |
| 590 | 589 | { |
| 591 | | y=state->m_pos[i].y+YPOS+k*2; |
| 590 | y=m_pos[i].y+YPOS+k*2; |
| 592 | 591 | for (j=0,m=0x80; j<8; j++, m>>=1) |
| 593 | 592 | { |
| 594 | 593 | if (b & m) |
| 595 | 594 | { |
| 596 | | bitmap.pix16(y, x + j) = color; |
| 597 | | bitmap.pix16(y+1, x + j) = color; |
| 595 | m_bitmap->pix16(y, x + j) = color; |
| 596 | m_bitmap->pix16(y+1, x + j) = color; |
| 598 | 597 | } |
| 599 | 598 | } |
| 600 | 599 | } |
| 601 | | if (state->m_reg.d.collision_bg&(1<<i)) |
| 600 | if (m_reg.d.collision_bg&(1<<i)) |
| 602 | 601 | { |
| 603 | | if ( (b<<(8-(x&7))) & ((state->m_bg[y][x>>3]<<8) | state->m_bg[y][(x>>3)+1]) ) |
| 604 | | state->m_reg.d.collision_bg&=~(1<<i); |
| 602 | if ( (b<<(8-(x&7))) & ((m_bg[y][x>>3]<<8) | m_bg[y][(x>>3)+1]) ) |
| 603 | m_reg.d.collision_bg&=~(1<<i); |
| 605 | 604 | } |
| 606 | 605 | } |
| 607 | 606 | } |
| 608 | | if (arcadia_sprite_collision(state,0,1)) state->m_reg.d.collision_sprite&=~1; |
| 609 | | if (arcadia_sprite_collision(state,0,2)) state->m_reg.d.collision_sprite&=~2; |
| 610 | | if (arcadia_sprite_collision(state,0,3)) state->m_reg.d.collision_sprite&=~4; |
| 611 | | if (arcadia_sprite_collision(state,1,2)) state->m_reg.d.collision_sprite&=~8; |
| 612 | | if (arcadia_sprite_collision(state,1,3)) state->m_reg.d.collision_sprite&=~0x10; //guess |
| 613 | | if (arcadia_sprite_collision(state,2,3)) state->m_reg.d.collision_sprite&=~0x20; //guess |
| 607 | if (arcadia_sprite_collision(0,1)) m_reg.d.collision_sprite&=~1; |
| 608 | if (arcadia_sprite_collision(0,2)) m_reg.d.collision_sprite&=~2; |
| 609 | if (arcadia_sprite_collision(0,3)) m_reg.d.collision_sprite&=~4; |
| 610 | if (arcadia_sprite_collision(1,2)) m_reg.d.collision_sprite&=~8; |
| 611 | if (arcadia_sprite_collision(1,3)) m_reg.d.collision_sprite&=~0x10; //guess |
| 612 | if (arcadia_sprite_collision(2,3)) m_reg.d.collision_sprite&=~0x20; //guess |
| 614 | 613 | } |
| 615 | 614 | |
| 616 | 615 | INTERRUPT_GEN_MEMBER(arcadia_state::arcadia_video_line) |
| r20655 | r20656 | |
| 642 | 641 | { |
| 643 | 642 | if (((m_line-m_ypos)&(h-1))==0) |
| 644 | 643 | { |
| 645 | | arcadia_vh_draw_line(machine(), *m_bitmap, m_charline*h+m_ypos, |
| 646 | | m_reg.d.chars1[m_charline]); |
| 644 | arcadia_vh_draw_line(m_charline*h+m_ypos, m_reg.d.chars1[m_charline]); |
| 647 | 645 | } |
| 648 | 646 | } |
| 649 | 647 | else |
| r20655 | r20656 | |
| 651 | 649 | { |
| 652 | 650 | if (((m_line-m_ypos)&(h-1))==0) |
| 653 | 651 | { |
| 654 | | arcadia_vh_draw_line(machine(), *m_bitmap, m_charline*h+m_ypos, |
| 655 | | m_reg.d.chars2[m_charline-13]); |
| 652 | arcadia_vh_draw_line(m_charline*h+m_ypos, m_reg.d.chars2[m_charline-13]); |
| 656 | 653 | } |
| 657 | 654 | m_charline-=13; |
| 658 | 655 | } |
| r20655 | r20656 | |
| 664 | 661 | } |
| 665 | 662 | } |
| 666 | 663 | if (m_line==261) |
| 667 | | arcadia_draw_sprites(machine(), *m_bitmap); |
| 664 | arcadia_draw_sprites(); |
| 668 | 665 | } |
| 669 | 666 | |
| 670 | 667 | READ8_MEMBER( arcadia_state::arcadia_vsync_r ) |