summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/appoooh.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/appoooh.c')
-rw-r--r--src/mame/video/appoooh.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/mame/video/appoooh.c b/src/mame/video/appoooh.c
new file mode 100644
index 00000000000..e1c56bf6a3f
--- /dev/null
+++ b/src/mame/video/appoooh.c
@@ -0,0 +1,339 @@
+/***************************************************************************
+
+ video.c
+
+ Functions to emulate the video hardware of the machine.
+
+***************************************************************************/
+
+#include "driver.h"
+#include "appoooh.h"
+
+UINT8 *appoooh_fg_videoram,*appoooh_fg_colorram;
+UINT8 *appoooh_bg_videoram,*appoooh_bg_colorram;
+
+#define CHR1_OFST 0x00 /* palette page of char set #1 */
+#define CHR2_OFST 0x10 /* palette page of char set #2 */
+
+static tilemap *fg_tilemap,*bg_tilemap;
+
+static int scroll_x;
+static int priority;
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ Palette information of appoooh is not known.
+
+ The palette decoder of Bank Panic was used for this driver.
+ Because these hardware is similar.
+
+***************************************************************************/
+PALETTE_INIT( appoooh )
+{
+ int i;
+ #define TOTAL_COLORS(gfxn) (machine->gfx[gfxn]->total_colors * machine->gfx[gfxn]->color_granularity)
+ #define COLOR(gfxn,offs) (colortable[machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
+
+ for (i = 0;i < machine->drv->total_colors;i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = (*color_prom >> 0) & 0x01;
+ bit1 = (*color_prom >> 1) & 0x01;
+ bit2 = (*color_prom >> 2) & 0x01;
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ bit0 = (*color_prom >> 3) & 0x01;
+ bit1 = (*color_prom >> 4) & 0x01;
+ bit2 = (*color_prom >> 5) & 0x01;
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* blue component */
+ bit0 = 0;
+ bit1 = (*color_prom >> 6) & 0x01;
+ bit2 = (*color_prom >> 7) & 0x01;
+ b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette_set_color(machine,i,MAKE_RGB(r,g,b));
+ color_prom++;
+ }
+
+ /* color_prom now points to the beginning of the lookup table */
+
+ /* charset #1 lookup table */
+ for (i = 0;i < TOTAL_COLORS(0);i++)
+ COLOR(0,i) = (*(color_prom++) & 0x0f)|CHR1_OFST;
+
+ /* charset #2 lookup table */
+ for (i = 0;i < TOTAL_COLORS(1);i++)
+ COLOR(1,i) = (*(color_prom++) & 0x0f)|CHR2_OFST;
+
+ /* TODO: the driver currently uses only 16 of the 32 color codes. */
+ /* 16-31 might be unused, but there might be a palette bank selector */
+ /* to use them somewhere in the game. */
+}
+
+PALETTE_INIT( robowres )
+{
+ int i;
+ #define TOTAL_COLORS(gfxn) (machine->gfx[gfxn]->total_colors * machine->gfx[gfxn]->color_granularity)
+ #define COLOR(gfxn,offs) (colortable[machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
+
+ for (i = 0;i < machine->drv->total_colors;i++)
+ {
+ int bit0,bit1,bit2,r,g,b;
+
+ /* red component */
+ bit0 = (*color_prom >> 0) & 0x01;
+ bit1 = (*color_prom >> 1) & 0x01;
+ bit2 = (*color_prom >> 2) & 0x01;
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* green component */
+ bit0 = (*color_prom >> 3) & 0x01;
+ bit1 = (*color_prom >> 4) & 0x01;
+ bit2 = (*color_prom >> 5) & 0x01;
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+ /* blue component */
+ bit0 = 0;
+ bit1 = (*color_prom >> 6) & 0x01;
+ bit2 = (*color_prom >> 7) & 0x01;
+ b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette_set_color(machine,i,MAKE_RGB(r,g,b));
+ color_prom++;
+ }
+
+ /* color_prom now points to the beginning of the lookup table */
+
+ for (i = 0;i < 32*8;i++)
+ colortable[i]=(*(color_prom++) & 0x0f);
+
+}
+
+
+
+/***************************************************************************
+
+ Callbacks for the TileMap code
+
+***************************************************************************/
+
+static TILE_GET_INFO( get_fg_tile_info )
+{
+ int code = appoooh_fg_videoram[tile_index] + 256 * ((appoooh_fg_colorram[tile_index]>>5) & 7);
+
+ SET_TILE_INFO(
+ 0,
+ code,
+ appoooh_fg_colorram[tile_index]&0x0f,
+ (appoooh_fg_colorram[tile_index] & 0x10 ) ? TILEMAP_FLIPX : 0
+ );
+}
+
+static TILE_GET_INFO( get_bg_tile_info )
+{
+ int code = appoooh_bg_videoram[tile_index] + 256 * ((appoooh_bg_colorram[tile_index]>>5) & 7);
+
+ SET_TILE_INFO(
+ 1,
+ code,
+ appoooh_bg_colorram[tile_index]&0x0f,
+ (appoooh_bg_colorram[tile_index] & 0x10 ) ? TILEMAP_FLIPX : 0
+ );
+}
+
+/***************************************************************************
+
+ Start the video hardware emulation.
+
+***************************************************************************/
+VIDEO_START( appoooh )
+{
+ fg_tilemap = tilemap_create(get_fg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN,8,8,32,32);
+ bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_TYPE_PEN, 8,8,32,32);
+
+ tilemap_set_transparent_pen(fg_tilemap,0);
+ tilemap_set_scrolldy(fg_tilemap,8,8);
+ tilemap_set_scrolldy(bg_tilemap,8,8);
+}
+
+WRITE8_HANDLER( appoooh_scroll_w )
+{
+ scroll_x = data;
+}
+
+
+WRITE8_HANDLER( appoooh_fg_videoram_w )
+{
+ appoooh_fg_videoram[offset] = data;
+ tilemap_mark_tile_dirty(fg_tilemap,offset);
+}
+
+WRITE8_HANDLER( appoooh_fg_colorram_w )
+{
+ appoooh_fg_colorram[offset] = data;
+ tilemap_mark_tile_dirty(fg_tilemap,offset);
+}
+
+WRITE8_HANDLER( appoooh_bg_videoram_w )
+{
+ appoooh_bg_videoram[offset] = data;
+ tilemap_mark_tile_dirty(bg_tilemap,offset);
+}
+
+WRITE8_HANDLER( appoooh_bg_colorram_w )
+{
+ appoooh_bg_colorram[offset] = data;
+ tilemap_mark_tile_dirty(bg_tilemap,offset);
+}
+
+WRITE8_HANDLER( appoooh_out_w )
+{
+ /* bit 0 controls NMI */
+ interrupt_enable_w(0,data & 0x01);
+
+ /* bit 1 flip screen */
+ flip_screen_set(data & 0x02);
+
+ /* bits 2-3 unknown */
+
+ /* bits 4-5 are playfield/sprite priority */
+ /* TODO: understand how this works, currently the only thing I do is draw */
+ /* the front layer behind sprites when priority == 0, and invert the sprite */
+ /* order when priority == 1 */
+ priority = (data & 0x30) >> 4;
+
+ /* bit 6 ROM bank select */
+ {
+ UINT8 *RAM = memory_region(REGION_CPU1);
+
+ memory_set_bankptr(1,&RAM[data&0x40 ? 0x10000 : 0x0a000]);
+ }
+
+ /* bit 7 unknown (used) */
+}
+
+static void appoooh_draw_sprites(mame_bitmap *dest_bmp,
+ const rectangle *cliprect,
+ const gfx_element *gfx,
+ UINT8 *sprite)
+{
+ int offs;
+
+ for (offs = 0x20 - 4;offs >= 0;offs -= 4)
+ {
+ int sy = 240 - sprite[offs+0];
+ int code = (sprite[offs+1]>>2) + ((sprite[offs+2]>>5) & 0x07)*0x40;
+ int color = sprite[offs+2]&0x0f; /* TODO: bit 4 toggles continuously, what is it? */
+ int sx = sprite[offs+3];
+ int flipx = sprite[offs+1]&0x01;
+
+ if(sx>=248) sx -= 256;
+
+ if (flip_screen)
+ {
+ sx = 239 - sx;
+ sy = 239 - sy;
+ flipx = !flipx;
+ }
+ drawgfx( dest_bmp, gfx,
+ code,
+ color,
+ flipx,flip_screen,
+ sx, sy,
+ cliprect,
+ TRANSPARENCY_PEN , 0);
+ }
+}
+
+static void robowres_draw_sprites(mame_bitmap *dest_bmp,
+ const rectangle *cliprect,
+ const gfx_element *gfx,
+ UINT8 *sprite)
+{
+ int offs;
+
+ for (offs = 0x20 - 4;offs >= 0;offs -= 4)
+ {
+ int sy = 240 - sprite[offs+0];
+ int code = 0x200 + (sprite[offs+1]>>2) + ((sprite[offs+2]>>5) & 0x07)*0x40;
+ int color = sprite[offs+2]&0x0f; /* TODO: bit 4 toggles continuously, what is it? */
+ int sx = sprite[offs+3];
+ int flipx = sprite[offs+1]&0x01;
+
+ if(sx>=248) sx -= 256;
+
+ if (flip_screen)
+ {
+ sx = 239 - sx;
+ sy = 239 - sy;
+ flipx = !flipx;
+ }
+ drawgfx( dest_bmp, gfx,
+ code,
+ color,
+ flipx,flip_screen,
+ sx, sy,
+ cliprect,
+ TRANSPARENCY_PEN , 0);
+ }
+}
+
+
+VIDEO_UPDATE( appoooh )
+{
+ tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
+
+ if (priority == 0) /* fg behind sprites */
+ tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
+
+ /* draw sprites */
+ if (priority == 1)
+ {
+ /* sprite set #1 */
+ appoooh_draw_sprites( bitmap, cliprect, machine->gfx[2],spriteram);
+ /* sprite set #2 */
+ appoooh_draw_sprites( bitmap, cliprect, machine->gfx[3],spriteram_2);
+ }
+ else
+ {
+ /* sprite set #2 */
+ appoooh_draw_sprites( bitmap, cliprect, machine->gfx[3],spriteram_2);
+ /* sprite set #1 */
+ appoooh_draw_sprites( bitmap, cliprect, machine->gfx[2],spriteram);
+ }
+
+ if (priority != 0) /* fg in front of sprites */
+ tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
+ return 0;
+}
+
+VIDEO_UPDATE( robowres )
+{
+ tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
+
+ if (priority == 0) /* fg behind sprites */
+ tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
+
+ /* draw sprites */
+ if (priority == 1)
+ {
+ /* sprite set #1 */
+ robowres_draw_sprites( bitmap, cliprect, machine->gfx[2],spriteram);
+ /* sprite set #2 */
+ robowres_draw_sprites( bitmap, cliprect, machine->gfx[3],spriteram_2);
+ }
+ else
+ {
+ /* sprite set #2 */
+ robowres_draw_sprites( bitmap, cliprect, machine->gfx[3],spriteram_2);
+ /* sprite set #1 */
+ robowres_draw_sprites( bitmap, cliprect, machine->gfx[2],spriteram);
+ }
+
+ if (priority != 0) /* fg in front of sprites */
+ tilemap_draw(bitmap,cliprect,fg_tilemap,0,0);
+ return 0;
+}