Previous 199869 Revisions Next

r17604 Sunday 2nd September, 2012 at 23:32:35 UTC by Angelo Salese
New WORKING game
--------------------
Little Robin [David Haywood]
[src/mame/drivers]littlerb.c

trunk/src/mame/drivers/littlerb.c
r17603r17604
1111
1212/*
1313
14strange vdp/memory access chip..
15at the moment gfx / palettes etc. get drawn then erased, I think it's a blitter, with multiple layers
16some of the 'sprite entries' seem a different size, or alignment, hence the bad sprites on the title
17screen.  no idea how layers are seleced / cleared right now either
14Notes:
1815
16VDP (Blitter) handling is not 100% correct
17A brief original video (recorded by Dox) can be seen at https://www.youtube.com/watch?v=8THpeogarUk
1918
20maybe it needs read commands working so it knows how many sprites are in
21the list?
19Overall addressing / auto-increment etc. of the VDP device is not fully understood, but for now
20appears to be good enough for the game.
2221
23maybe the vdp 'commands' can be used to store and get back
24write addresses?
22How we distinguish between mode setting (clear, copy, cliprect etc.) VDP commands and actual sprite
23commands is not yet understood.  All 'sprite' sections of the blit list seem to be terminated with
24a 0x0000 word, but it isn't clear how the blocks are started, the current method relies on some bits
25of the sprite data offset to determine if we're sprite data, or a command.  Maybe this is just a
26quirk of the hardware, and you can't have sprites at those offsets?
2527
26most graphics are stored as packed 4bpp in RAM, expanded before
27writing to the vdp device.  actual gfx are 8bpp.
28Copy / Scroll are not yet implemented, see the Smileys between scenes in the original video.
29 (Clipping is implemented, but might be per layer, so you do see the sprites vanish, but no
30   smileys are drawn)
2831
32How big are the actual framebuffers?  Are both also double buffered?
33
2934Sound pitch is directly correlated with irqs, scanline timings and pixel clock,
3035so it's surely not 100% correct. Sound sample playbacks looks fine at current time tho.
3136
37------
3238
39
40
3341Dip sw.1
3442--------
3543             | Coin 1 | Coin 2  |
r17603r17604
8896        m_dacl(*this, "dacl"),
8997         m_dacr(*this, "dacr"),
9098      m_region4(*this, "region4")
91   {
99   {
92100      m_1ff80804 = -1;
93101   }
94102
r17603r17604
111119   UINT32 m_lasttype2pc;
112120   UINT8 m_sound_index_l,m_sound_index_r;
113121   UINT16 m_sound_pointer_l,m_sound_pointer_r;
122   
123   bitmap_ind16 *m_temp_bitmap_sprites;
124   bitmap_ind16 *m_temp_bitmap_sprites_back;
114125
115   bitmap_ind16 m_temp_bitmap_sprites;
116   bitmap_ind16 m_temp_bitmap_sprites_back; // not currently used
117126
118
119127   DECLARE_WRITE16_MEMBER(spritelist_w);
120128   DECLARE_WRITE16_MEMBER(region4_w);
121129   DECLARE_READ16_MEMBER(buffer_status_r);
r17603r17604
155163   {
156164      littlerb_printf("littlerb_1ff80804_w %04x\n", data);
157165
158      if ((!(m_spritelist[2] & 0x1000)) && (!(m_spritelist[1] & 0x1000)))
166      if ((!(m_spritelist[2] & 0x1000)) && (!(m_spritelist[1] & 0x1000)))
159167      {
160168
161169      }
162      else
170      else
163171      {
164172         if (!(m_spritelist[2] & 0x1000))
165            m_temp_bitmap_sprites_back.fill(0, m_temp_bitmap_sprites_back.cliprect());
173            m_temp_bitmap_sprites_back->fill(0, m_temp_bitmap_sprites_back->cliprect());
166174
167175      }
168
176     
169177      littlerb_draw_sprites(space.machine());
170178
171179
r17603r17604
507515   PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
508516   PORT_DIPSETTING(      0x2000, DEF_STR( Off ) )
509517   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
510   PORT_DIPNAME( 0x4000, 0x4000, "GAME/TEST??" ) // changes what gets uploaded
511   PORT_DIPSETTING(      0x4000, DEF_STR( Off ) )
512   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
518   PORT_SERVICE( 0x4000, IP_ACTIVE_LOW )
513519   PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
514520   PORT_DIPSETTING(      0x8000, DEF_STR( Off ) )
515521   PORT_DIPSETTING(      0x0000, DEF_STR( On ) )
r17603r17604
552558   littlerb_state *state = screen.machine().driver_data<littlerb_state>();
553559   bitmap.fill(0, cliprect);
554560
555   copybitmap_trans(bitmap, state->m_temp_bitmap_sprites_back, 0, 0, 0, 0, cliprect, 0);
556   copybitmap_trans(bitmap, state->m_temp_bitmap_sprites, 0, 0, 0, 0, cliprect, 0);
561   copybitmap_trans(bitmap, *state->m_temp_bitmap_sprites_back, 0, 0, 0, 0, cliprect, 0);
562   copybitmap_trans(bitmap, *state->m_temp_bitmap_sprites, 0, 0, 0, 0, cliprect, 0);
557563
558564   return 0;
559565}
r17603r17604
588594VIDEO_START( littlerb )
589595{
590596   littlerb_state *state = machine.driver_data<littlerb_state>();
597//   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites_back);
598//   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites);
591599
600   state->m_temp_bitmap_sprites_back = auto_bitmap_ind16_alloc(machine,512,512);
601   state->m_temp_bitmap_sprites = auto_bitmap_ind16_alloc(machine,512,512);
592602
593   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites_back);
594   machine.primary_screen->register_screen_bitmap(state->m_temp_bitmap_sprites);
603
595604   state->m_spritelist = (UINT16*)auto_alloc_array_clear(machine, UINT16, 0x20000);
596605
597606}
r17603r17604
616625         drawxpos = xpos+x;
617626         drawypos = ypos+y;
618627
628         // odd clipping behavior, count is only increased for visible lines?
629         // I suspect the sprite corruption if you're near the top of the screen
630         // between level changes is related to this too, data offset values are
631         // probably being adjusted as layer is scrolled (and the cliprect is changed)
632         // even if they don't move.
633         if(drawypos>=cliprect.min_y)
634         {
635            fulloffs++;
636         }
637
619638         if(cliprect.contains(drawxpos, drawypos))
620639         {
621640            if(pix&0xff) bitmap.pix16(drawypos, drawxpos) = pix;
622641         }
623642
624643         drawxpos++;
625         fulloffs++;
626644      }
627645   }
628646}
r17603r17604
634652   int xsize,ysize;
635653   UINT16* spriteregion = state->m_spritelist;
636654   //littlerb_printf("frame\n");
637   /* the spriteram format is something like this .. */
638//   for (offs=2;offs<0xc00;offs+=6) // this will draw different hud gfx.. meaning not ALL entries are 6 words(?!) command based blitter rather than RAM? (but MODE is 3800 when both the sprite 'list' is written, and gfx data?,
639655
640656   int layer = 0;
657   int yoffset = 0;
641658
642
643659   littlerb_printf("m_listoffset %04x\n", state->m_listoffset );
644660
645661   littlerb_printf("%04x %04x %04x %04x\n", spriteregion[0], spriteregion[1], spriteregion[2], spriteregion[3]);
646662
647663   littlerb_alt_printf("start\n");
648664
665   int minx = 0 , maxx = 0x14f;
666   int miny = 0 , maxy = 0x11f;
667
649668   for (offs=0;offs<(state->m_listoffset);)
650669   {
651670
r17603r17604
664683      else if (spriteregion[offs+0] == 0x0040)
665684      {
666685         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x ---- ---- ---- ----\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
667
686         
668687         // some scroll stuff is here (title -> high score transition)
669688         // maybe also copy area operations?
670689
671         // probably wrong
672         if ((spriteregion[offs+4]==0x6000) && (spriteregion[offs+3] & 0x1000))
673            state->m_temp_bitmap_sprites_back.fill(0, state->m_temp_bitmap_sprites_back.cliprect());
690
691         // this isn't understood ... note, we still have a hack before draw_sprites is called too
692
693         // usual start of frame
694         // Control Word 0040 0090 6000 0026 0000 0012 ---- ---- ---- ----
695
696         // happens in the middle of list during boss death, causes sprites to vanish atm
697         // Control Word 0040 ffd6 00aa 00f8 0088 0018 ---- ---- ---- ----
698         if (spriteregion[offs+4]==0x6000)
699         {
700            if (spriteregion[offs+3] & 0x1000)
701               state->m_temp_bitmap_sprites_back->fill(0, state->m_temp_bitmap_sprites_back->cliprect());
702         }
674703         else
675            state->m_temp_bitmap_sprites.fill(0, state->m_temp_bitmap_sprites.cliprect());
704         {
705            if (spriteregion[offs+1] != 0xffd6) state->m_temp_bitmap_sprites->fill(0, state->m_temp_bitmap_sprites->cliprect());
706         }
707           
676708
677709
710         // this is some kind of scroll or copy area..
711         // also some of the other values change
712         // this is set AFTER the graphics which need to be scrolled are sent and causes the credit text to bounce up and down instead of
713         // anything scrolling
714         //yoffset = spriteregion[offs+1] - 0x90;
715         
716
678717         offs += 6;
679718      }
680719      else if (read_dword == 0x00e40020)
681720      {
682721         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
683
722     
684723         if (spriteregion[offs+4]==0x6000)
685724            layer = 1;
686725         else
687726            layer = 0;
688727
689728
729         minx = spriteregion[offs+6];
730         maxx = spriteregion[offs+8];
731
732         miny = spriteregion[offs+7];
733         maxy = spriteregion[offs+9];
734
735
690736         offs += 10;
691737      }
692738      else if (read_dword == 0x00e40000)
693739      {
740         // same as above?
694741         littlerb_alt_printf("Control Word %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5], spriteregion[offs+6], spriteregion[offs+7], spriteregion[offs+8], spriteregion[offs+9]);
695
742   
696743         if (spriteregion[offs+4]==0x6000)
697744            layer = 1;
698745         else
699746            layer = 0;
700747
748         minx = spriteregion[offs+6];
749         maxx = spriteregion[offs+8];
750
751         miny = spriteregion[offs+7];
752         maxy = spriteregion[offs+9];
753
754
701755         offs += 10;
702756      }
703757      else if (read_dword == 0x00000000)
r17603r17604
714768         if (x&0x400) x-=0x800;
715769         if (y&0x200) y-=0x400;
716770
771         y+= yoffset;
772
717773         xsize = (spriteregion[offs+4] & 0x01ff); // background gfx for many places at 0x1ff wide
718774         ysize = (spriteregion[offs+5] & 0x00ff); // player1/player2 texts in service mode sides are 0xff high
719775
720776
777         rectangle clip;
778
779         clip.min_x = minx;
780         clip.max_x = maxx;
781
782         clip.min_y = miny;
783         clip.max_y = maxy;
784
785         // used between levels, and on boss death to clip sprite at the ground for sinking effect
786
787
788         if (clip.min_x > state->m_temp_bitmap_sprites->cliprect().max_x)
789            clip.min_x =  state->m_temp_bitmap_sprites->cliprect().max_x;
790
791         if (clip.min_x < state->m_temp_bitmap_sprites->cliprect().min_x)
792            clip.min_x =  state->m_temp_bitmap_sprites->cliprect().min_x;
793
794         if (clip.max_x > state->m_temp_bitmap_sprites->cliprect().max_x)
795            clip.max_x =  state->m_temp_bitmap_sprites->cliprect().max_x;
796
797         if (clip.max_x < state->m_temp_bitmap_sprites->cliprect().min_x)
798            clip.max_x =  state->m_temp_bitmap_sprites->cliprect().min_x;
799
800
801         if (clip.min_y > state->m_temp_bitmap_sprites->cliprect().max_y)
802            clip.min_y =  state->m_temp_bitmap_sprites->cliprect().max_y;
803
804         if (clip.min_y < state->m_temp_bitmap_sprites->cliprect().min_y)
805            clip.min_y =  state->m_temp_bitmap_sprites->cliprect().min_y;
806
807         if (clip.max_y > state->m_temp_bitmap_sprites->cliprect().max_y)
808            clip.max_y =  state->m_temp_bitmap_sprites->cliprect().max_y;
809
810         if (clip.max_y < state->m_temp_bitmap_sprites->cliprect().min_y)
811            clip.max_y =  state->m_temp_bitmap_sprites->cliprect().min_y;
812
813
721814         littlerb_alt_printf("%04x %04x %04x %04x %04x %04x\n", spriteregion[offs+0], spriteregion[offs+1], spriteregion[offs+2], spriteregion[offs+3], spriteregion[offs+4], spriteregion[offs+5]);
722815
723         if (layer==0) draw_sprite(machine, state->m_temp_bitmap_sprites, state->m_temp_bitmap_sprites.cliprect(),xsize,ysize,fullcode,x,y);
724         else draw_sprite(machine, state->m_temp_bitmap_sprites_back, state->m_temp_bitmap_sprites_back.cliprect(),xsize,ysize,fullcode,x,y);
816         if (layer==0) draw_sprite(machine, *state->m_temp_bitmap_sprites, clip,xsize,ysize,fullcode,x,y);
817         else draw_sprite(machine, *state->m_temp_bitmap_sprites_back, clip,xsize,ysize,fullcode,x,y);
725818
726
819           
727820         offs += 6;
728821      }
729822   }
r17603r17604
771864ROM_END
772865
773866
774GAME( 1993, littlerb, 0, littlerb, littlerb, driver_device, 0, ROT0, "TCH", "Little Robin", GAME_NOT_WORKING|GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )
867GAME( 1994, littlerb, 0, littlerb, littlerb, driver_device, 0, ROT0, "TCH", "Little Robin", GAME_IMPERFECT_GRAPHICS|GAME_IMPERFECT_SOUND )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team