diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/makefile mame-firefox/makefile *** mame/makefile Wed Jan 28 18:59:16 2004 --- mame-firefox/makefile Sun Feb 15 11:27:25 2004 *************** *** 95,111 **** DEFS = -DX86_ASM -DLSB_FIRST -DINLINE="static __inline__" -Dasm=__asm__ ! CFLAGS = -std=gnu99 -Isrc -Isrc/includes -Isrc/$(MAMEOS) -I$(OBJ)/cpu/m68000 -Isrc/cpu/m68000 ifdef SYMBOLS ! CFLAGS += -O0 -Werror -Wall -Wno-unused -g else CFLAGS += -DNDEBUG \ ! $(ARCH) -O3 -fomit-frame-pointer -fstrict-aliasing \ ! -Werror -Wall -Wno-sign-compare -Wunused \ -Wpointer-arith -Wbad-function-cast -Wcast-align -Waggregate-return \ -Wshadow -Wstrict-prototypes -Wundef \ ! -Wformat-security -Wwrite-strings \ -Wdisabled-optimization \ # -Wredundant-decls # -Wfloat-equal --- 95,111 ---- DEFS = -DX86_ASM -DLSB_FIRST -DINLINE="static __inline__" -Dasm=__asm__ ! CFLAGS = -std=gnu99 -Isrc -Isrc/includes -Isrc/$(MAMEOS) -I$(OBJ)/cpu/m68000 -Isrc/cpu/m68000 -I/usr/local/include/mpeg2dec -I/usr/local/include ifdef SYMBOLS ! CFLAGS += -O0 -Wno-unused -g else CFLAGS += -DNDEBUG \ ! $(ARCH) -O2 -fomit-frame-pointer -fstrict-aliasing \ ! -Wno-sign-compare -Wunused \ -Wpointer-arith -Wbad-function-cast -Wcast-align -Waggregate-return \ -Wshadow -Wstrict-prototypes -Wundef \ ! -Wformat -Wformat-security -Wwrite-strings \ -Wdisabled-optimization \ # -Wredundant-decls # -Wfloat-equal *************** *** 139,145 **** endif # platform .mak files will want to add to this ! LIBS = -lz OBJDIRS = obj $(OBJ) $(OBJ)/cpu $(OBJ)/sound $(OBJ)/$(MAMEOS) \ $(OBJ)/drivers $(OBJ)/machine $(OBJ)/vidhrdw $(OBJ)/sndhrdw --- 139,145 ---- endif # platform .mak files will want to add to this ! LIBS = -L/usr/local/lib -lz -lmpeg2 -lvo -lFLAC -lmpeg2convert OBJDIRS = obj $(OBJ) $(OBJ)/cpu $(OBJ)/sound $(OBJ)/$(MAMEOS) \ $(OBJ)/drivers $(OBJ)/machine $(OBJ)/vidhrdw $(OBJ)/sndhrdw *************** *** 182,196 **** # always recompile the version string $(CC) $(CDEFS) $(CFLAGSPEDANTIC) -c src/version.c -o $(OBJ)/version.o @echo Linking $@... ! $(LD) $(LDFLAGS) $(OBJS) $(COREOBJS) $(OSOBJS) $(LIBS) $(DRVLIBS) -o $@ $(MAPFLAGS) romcmp$(EXE): $(OBJ)/romcmp.o $(OBJ)/unzip.o @echo Linking $@... ! $(LD) $(LDFLAGS) $^ -lz -o $@ chdman$(EXE): $(OBJ)/chdman.o $(OBJ)/chd.o $(OBJ)/md5.o $(OBJ)/sha1.o $(OBJ)/version.o @echo Linking $@... ! $(LD) $(LDFLAGS) $^ -lz -o $@ xml2info$(EXE): src/xml2info/xml2info.c @echo Compiling $@... --- 182,196 ---- # always recompile the version string $(CC) $(CDEFS) $(CFLAGSPEDANTIC) -c src/version.c -o $(OBJ)/version.o @echo Linking $@... ! $(LD) $(LDFLAGS) $(OBJS) $(COREOBJS) $(OSOBJS) $(LIBS) $(DRVLIBS) -lmpeg2convert -lmpeg2 -lFLAC -lvo -o $@ $(MAPFLAGS) romcmp$(EXE): $(OBJ)/romcmp.o $(OBJ)/unzip.o @echo Linking $@... ! $(LD) $(LDFLAGS) -L/usr/local/lib $^ -lz -o $@ chdman$(EXE): $(OBJ)/chdman.o $(OBJ)/chd.o $(OBJ)/md5.o $(OBJ)/sha1.o $(OBJ)/version.o @echo Linking $@... ! $(LD) $(LDFLAGS) $^ -L/usr/local/lib -lz -lFLAC -o $@ xml2info$(EXE): src/xml2info/xml2info.c @echo Compiling $@... diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/artwork.c mame-firefox/src/artwork.c *** mame/src/artwork.c Sun Oct 12 20:56:02 2003 --- mame-firefox/src/artwork.c Sun Feb 15 11:29:47 2004 *************** *** 306,311 **** --- 306,312 ---- #include "vidhrdw/vector.h" #include #include + #include "vidhrdw/laserdsk.h" /*************************************************************************** *************** *** 334,340 **** LAYER_MARQUEE, LAYER_PANEL, LAYER_SIDE, ! LAYER_FLYER }; /* UI transparency hack */ --- 335,342 ---- LAYER_MARQUEE, LAYER_PANEL, LAYER_SIDE, ! LAYER_FLYER, ! LAYER_VIDEO }; /* UI transparency hack */ *************** *** 352,390 **** ***************************************************************************/ - struct artwork_piece - { - /* linkage */ - struct artwork_piece * next; - - /* raw data from the .art file */ - UINT8 layer; - UINT8 has_alpha; - int priority; - float alpha; - float brightness; - float top; - float left; - float bottom; - float right; - char * tag; - char * filename; - char * alpha_filename; - - /* bitmaps */ - struct mame_bitmap * rawbitmap; - struct mame_bitmap * prebitmap; - struct mame_bitmap * yrgbbitmap; - UINT32 * scanlinehint; - UINT8 blendflags; - - /* derived/dynamic data */ - int intersects_game; - int visible; - struct rectangle bounds; - }; - - /*************************************************************************** --- 354,359 ---- *************** *** 397,407 **** static UINT32 transparent_color; static struct artwork_piece *artwork_list; ! static int num_underlays, num_overlays, num_bezels; static int num_pieces; ! static struct mame_bitmap *underlay, *overlay, *overlay_yrgb, *bezel, *final; ! static struct rectangle underlay_invalid, overlay_invalid, bezel_invalid; static struct rectangle gamerect, screenrect; static int gamescale; --- 366,376 ---- static UINT32 transparent_color; static struct artwork_piece *artwork_list; ! static int num_underlays, num_overlays, num_bezels, num_videos; static int num_pieces; ! static struct mame_bitmap *underlay, *overlay, *overlay_yrgb, *bezel, *final, *video; ! static struct rectangle underlay_invalid, overlay_invalid, bezel_invalid, video_invalid; static struct rectangle gamerect, screenrect; static int gamescale; *************** *** 416,421 **** --- 385,393 ---- static const struct overlay_piece *overlay_list; + /* laserdisk tag */ + static const char *TAG_LASERDISK = "[laserdiscvideo]"; + static struct artwork_piece *video_piece; /*************************************************************************** *************** *** 429,435 **** static int compute_rgb_components(int depth, UINT32 rgb_components[3], UINT32 rgb32_components[3]); static int load_bitmap(const char *gamename, struct artwork_piece *piece); static int load_alpha_bitmap(const char *gamename, struct artwork_piece *piece, const struct png_info *original); - static int scale_bitmap(struct artwork_piece *piece, int newwidth, int newheight); static void trim_bitmap(struct artwork_piece *piece); static int parse_art_file(mame_file *file); static int validate_pieces(void); --- 401,406 ---- *************** *** 437,442 **** --- 408,414 ---- static void update_palette_lookup(struct mame_display *display); static int update_layers(void); static void render_game_bitmap(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display); + static void render_game_bitmap_video(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display); static void render_game_bitmap_underlay(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display); static void render_game_bitmap_overlay(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display); static void render_game_bitmap_underlay_overlay(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display); *************** *** 558,563 **** --- 530,598 ---- } + /*------------------------------------------------- + blend the video with the game using the bottom 2 bits of blue as the blend + TODO: This is for firefox but should be made generic + -------------------------------------------------*/ + + INLINE UINT32 video_blend_and_clamp_firefox(UINT32 game, UINT32 underpix) + { + UINT8 r,g,b; + UINT8 blend = RGB_BLUE(game) & 0x3; + + switch(blend) + { + case 0: return underpix; + case 1: + r = ((RGB_RED(game) << 1) + RGB_RED(underpix)) >> 1; + g = ((RGB_GREEN(game) << 1) + RGB_GREEN(underpix)) >> 1; + b = ((RGB_BLUE(game) << 1) + RGB_BLUE(underpix)) >> 1; + return MAKE_ARGB(0xff, r, g, b); + case 2: + r = ((RGB_RED(underpix) << 1) + RGB_RED(game)) >> 1; + g = ((RGB_GREEN(underpix) << 1) + RGB_GREEN(game)) >> 1; + b = ((RGB_BLUE(underpix) << 1) + RGB_BLUE(game)) >> 1; + return MAKE_ARGB(0xff, r, g, b); + default: + return game; + } + } + + + /*------------------------------------------------- + blend the video with the game any black area of the game is replaced with + the video + -------------------------------------------------*/ + + INLINE UINT32 video_blend_and_clamp_mach3(UINT32 game, UINT32 underpix) + { + if(game) + return game; + else + return underpix; + } + struct rectangle *get_video_invalid() + { + return(&video_invalid); + } + + struct rectangle *get_underlay_invalid() + { + return(&underlay_invalid); + } + + struct artwork_piece * get_laser_disc_artwork_piece() + { + struct artwork_piece *p = artwork_list; + while(p) + { + if(!strcmp(p->tag, TAG_LASERDISK)) + return(p); + else + p = p->next; + } + return(NULL); + } /*------------------------------------------------- blend_over - blend two pixels with overlay *************** *** 670,675 **** --- 705,711 ---- params->depth = 32; /* allocate memory for the bitmaps */ + video = auto_bitmap_alloc_depth(params->width, params->height, 32); underlay = auto_bitmap_alloc_depth(params->width, params->height, 32); overlay = auto_bitmap_alloc_depth(params->width, params->height, 32); overlay_yrgb = auto_bitmap_alloc_depth(params->width, params->height, 32); *************** *** 771,776 **** --- 807,813 ---- if (ui_changed) { union_rect(&underlay_invalid, &ui_changed_bounds); + union_rect(&video_invalid, &ui_changed_bounds); union_rect(&overlay_invalid, &ui_changed_bounds); union_rect(&bezel_invalid, &ui_changed_bounds); ui_changed--; *************** *** 780,785 **** --- 817,823 ---- if (!global_artwork_enable) { fillbitmap(final, MAKE_ARGB(0,0,0,0), NULL); + union_rect(&video_invalid, &screenrect); union_rect(&underlay_invalid, &screenrect); union_rect(&overlay_invalid, &screenrect); union_rect(&bezel_invalid, &screenrect); *************** *** 799,804 **** --- 837,846 ---- render_game_bitmap_underlay(display->game_bitmap, palette_lookup, display); else if (num_overlays) render_game_bitmap_overlay(display->game_bitmap, palette_lookup, display); + else if (num_videos) /* can only cope with video on its own */ + { + render_game_bitmap_video(display->game_bitmap, palette_lookup, display); + } else render_game_bitmap(display->game_bitmap, palette_lookup, display); *************** *** 985,990 **** --- 1027,1036 ---- /* bezel */ else if (piece->layer >= LAYER_BEZEL) union_rect(&bezel_invalid, &piece->bounds); + + /* bezel */ + else if (piece->layer >= LAYER_VIDEO) + union_rect(&video_invalid, &piece->bounds); } } } *************** *** 1007,1012 **** --- 1053,1073 ---- struct rectangle combined; int changed = 0; + + /* update the video */ + /* assume only one video and just change the pointer */ + if (video_invalid.max_x != 0) + { + video = piece->prebitmap; + /* + sect_rect(&video_invalid, &screenrect); + erase_rect(video, &video_invalid, 0); + for (piece = artwork_list; piece; piece = piece->next) + if (piece->layer == LAYER_VIDEO && piece->visible && piece->prebitmap) + alpha_blend_intersecting_rect(video, &video_invalid, piece->prebitmap, &piece->bounds, piece->scanlinehint); + */ + } + /* update the underlays */ if (underlay_invalid.max_x != 0) { *************** *** 1040,1045 **** --- 1101,1107 ---- /* combine the invalid rects */ combined = underlay_invalid; + union_rect(&combined, &video_invalid); union_rect(&combined, &overlay_invalid); union_rect(&combined, &bezel_invalid); if (combined.max_x != 0) *************** *** 1056,1061 **** --- 1118,1125 ---- underlay_invalid.max_x = 0; overlay_invalid.max_x = 0; bezel_invalid.max_x = 0; + video_invalid.max_x = 0; + return changed; } *************** *** 1597,1602 **** --- 1661,1822 ---- /*------------------------------------------------- + render_game_bitmap_video - render the game over the video + -------------------------------------------------*/ + + static void render_game_bitmap_video(struct mame_bitmap *bitmap, const rgb_t *palette, struct mame_display *display) + { + int srcrowpixels = bitmap->rowpixels; + int dstrowpixels = final->rowpixels; + void *srcbase, *dstbase, *undbase; + int width, height; + int x, y; + + /* compute common parameters */ + width = Machine->absolute_visible_area.max_x - Machine->absolute_visible_area.min_x + 1; + height = Machine->absolute_visible_area.max_y - Machine->absolute_visible_area.min_y + 1; + srcbase = (UINT8 *)bitmap->base + Machine->absolute_visible_area.min_y * bitmap->rowbytes; + dstbase = (UINT8 *)final->base + gamerect.min_y * final->rowbytes + gamerect.min_x * sizeof(UINT32); + undbase = (UINT8 *)video->base + gamerect.min_y * video->rowbytes + gamerect.min_x * sizeof(UINT32); + + /* vector case */ + if (display->changed_flags & VECTOR_PIXELS_CHANGED) + { + vector_pixel_t offset = VECTOR_PIXEL(gamerect.min_x, gamerect.min_y); + vector_pixel_t *list = display->vector_dirty_pixels; + + /* 16/15bpp case */ + if (bitmap->depth != 32) + { + while (*list != VECTOR_PIXEL_END) + { + vector_pixel_t coords = *list; + x = VECTOR_PIXEL_X(coords); + y = VECTOR_PIXEL_Y(coords); + *list++ = coords + offset; + logerror("VECTOR_PIXELS_CHANGED not implemented in render_game_bitmap_video\n"); + PIXEL(x,y,dst,dst,32) = add_and_clamp(palette[PIXEL(x,y,src,src,16)], PIXEL(x,y,und,dst,32)); + } + } + + /* 32bpp case */ + else + { + while (*list != VECTOR_PIXEL_END) + { + vector_pixel_t coords = *list; + x = VECTOR_PIXEL_X(coords); + y = VECTOR_PIXEL_Y(coords); + *list++ = coords + offset; + PIXEL(x,y,dst,dst,32) = add_and_clamp(PIXEL(x,y,src,src,32), PIXEL(x,y,und,dst,32)); + } + } + } + + /* 1x scale */ + else if (gamescale == 1) + { + /* 16/15bpp case, this is enough for MACH3 and Firefox */ + /* Do this with an if not a function pointer so it can remain INLINE */ + if (bitmap->depth != 32) + { + if(!video_piece->alpha_filename) + { + logerror("blending style not set in art file"); + return; + } + if(!strcmp(video_piece->alpha_filename, "mach3")) + { + for (y = 0; y < height; y++) + { + UINT16 *src = (UINT16 *)srcbase + y * srcrowpixels + Machine->absolute_visible_area.min_x; + UINT32 *dst = (UINT32 *)dstbase + y * dstrowpixels; + UINT32 *und = (UINT32 *)undbase + y * dstrowpixels; + for (x = 0; x < width; x++) + { + *dst++ = video_blend_and_clamp_mach3(palette[*src++], *und++); + } + } + } + else + { + for (y = 0; y < height; y++) + { + UINT16 *src = (UINT16 *)srcbase + y * srcrowpixels + Machine->absolute_visible_area.min_x; + UINT32 *dst = (UINT32 *)dstbase + y * dstrowpixels; + UINT32 *und = (UINT32 *)undbase + y * dstrowpixels; + for (x = 0; x < width; x++) + { + *dst++ = video_blend_and_clamp_firefox(palette[*src++], *und++); + } + } + } + } + + /* 32bpp case */ + else + { + for (y = 0; y < height; y++) + { + UINT32 *src = (UINT32 *)srcbase + y * srcrowpixels + Machine->absolute_visible_area.min_x; + UINT32 *dst = (UINT32 *)dstbase + y * dstrowpixels; + UINT32 *und = (UINT32 *)undbase + y * dstrowpixels; + for (x = 0; x < width; x++) + *dst++ = add_and_clamp(*src++, *und++); + } + } + } + + /* 2x scale */ + else if (gamescale == 2) + { + /* 16/15bpp case */ + if (bitmap->depth != 32) + { + for (y = 0; y < height; y++) + { + UINT16 *src = (UINT16 *)srcbase + y * srcrowpixels + Machine->absolute_visible_area.min_x; + UINT32 *dst = (UINT32 *)dstbase + y * 2 * dstrowpixels; + UINT32 *und = (UINT32 *)undbase + y * 2 * dstrowpixels; + for (x = 0; x < width; x++) + { + UINT32 val = palette[*src++]; + dst[0] = add_and_clamp(val, und[0]); + dst[1] = add_and_clamp(val, und[1]); + dst[dstrowpixels] = add_and_clamp(val, und[dstrowpixels]); + dst[dstrowpixels + 1] = add_and_clamp(val, und[dstrowpixels + 1]); + dst += 2; + und += 2; + } + } + } + + /* 32bpp case */ + else + { + for (y = 0; y < height; y++) + { + UINT32 *src = (UINT32 *)srcbase + y * srcrowpixels + Machine->absolute_visible_area.min_x; + UINT32 *dst = (UINT32 *)dstbase + y * 2 * dstrowpixels; + UINT32 *und = (UINT32 *)undbase + y * 2 * dstrowpixels; + for (x = 0; x < width; x++) + { + UINT32 val = *src++; + dst[0] = add_and_clamp(val, und[0]); + dst[1] = add_and_clamp(val, und[1]); + dst[dstrowpixels] = add_and_clamp(val, und[dstrowpixels]); + dst[dstrowpixels + 1] = add_and_clamp(val, und[dstrowpixels + 1]); + dst += 2; + und += 2; + } + } + } + } + } + + + + /*------------------------------------------------- render_game_bitmap_overlay - render the game bitmap blended with an overlay -------------------------------------------------*/ *************** *** 2005,2010 **** --- 2225,2231 ---- num_underlays = 0; num_overlays = 0; num_bezels = 0; + num_videos = 0; overlay_list = NULL; /* if the user turned artwork off, bail */ *************** *** 2050,2061 **** num_underlays++; else if (piece->layer == LAYER_OVERLAY) num_overlays++; ! else if (piece->layer >= LAYER_BEZEL) num_bezels++; /* load the graphics */ if (driver) load_bitmap(driver->name, piece); } // debugging // fprintf(stderr, "backdrops=%d overlays=%d bezels=%d\n", num_underlays, num_overlays, num_bezels); --- 2271,2291 ---- num_underlays++; else if (piece->layer == LAYER_OVERLAY) num_overlays++; ! else if (piece->layer == LAYER_BEZEL) num_bezels++; + else if (piece->layer >= LAYER_VIDEO) + { + video_piece = piece; + num_videos++; + } /* load the graphics */ if (driver) load_bitmap(driver->name, piece); + + /* if its an mpeg piece then init it */ + if(!strcmp(piece->tag, TAG_LASERDISK)) + init_mpeg(driver->name); } // debugging // fprintf(stderr, "backdrops=%d overlays=%d bezels=%d\n", num_underlays, num_overlays, num_bezels); *************** *** 2309,2314 **** --- 2539,2545 ---- underlay_invalid = screenrect; overlay_invalid = screenrect; bezel_invalid = screenrect; + video_invalid = screenrect; /* loop through all the pieces, generating the scaled bitmaps */ for (piece = artwork_list; piece; piece = piece->next) *************** *** 2336,2351 **** given piece of artwork -------------------------------------------------*/ ! static int scale_bitmap(struct artwork_piece *piece, int newwidth, int newheight) { UINT32 sx, sxfrac, sxstep, sy, syfrac, systep; UINT32 global_brightness, global_alpha; int x, y; /* skip if no bitmap */ if (!piece->rawbitmap) return 1; /* allocate two new bitmaps */ piece->prebitmap = auto_bitmap_alloc_depth(newwidth, newheight, -32); piece->yrgbbitmap = auto_bitmap_alloc_depth(newwidth, newheight, -32); --- 2567,2595 ---- given piece of artwork -------------------------------------------------*/ ! /* TODO is this ok non-static? */ ! int scale_bitmap(struct artwork_piece *piece, int newwidth, int newheight) { UINT32 sx, sxfrac, sxstep, sy, syfrac, systep; UINT32 global_brightness, global_alpha; + int sxadx, syady; int x, y; + int xweight, dx; + int yweight, dy; + int xwbyw; + int wc2, wc3, wc4; + int prevstate = 0, statex = 0; + rgb_t pix1, pix2, pix3, pix4; + int r, g, b, a; + int newstate; /* skip if no bitmap */ if (!piece->rawbitmap) return 1; + /* no need to do this memory stuff all the time */ + if(!piece->prebitmap) + { /* allocate two new bitmaps */ piece->prebitmap = auto_bitmap_alloc_depth(newwidth, newheight, -32); piece->yrgbbitmap = auto_bitmap_alloc_depth(newwidth, newheight, -32); *************** *** 2357,2362 **** --- 2601,2607 ---- if (!piece->scanlinehint) return 0; memset(piece->scanlinehint, 0, newheight * MAX_HINTS_PER_SCANLINE * sizeof(piece->scanlinehint[0])); + } /* convert global brightness and alpha to fixed point */ global_brightness = (int)(piece->brightness * 65536.0); *************** *** 2373,2379 **** /* now do the scaling, using 4-point sampling */ for (y = 0; y < newheight; y++) { - int prevstate = 0, statex = 0; sxfrac = (sxstep / 2) & FRAC_MASK; sx = (sxstep / 2) >> FRAC_BITS; --- 2618,2623 ---- *************** *** 2381,2391 **** /* loop over columns */ for (x = 0; x < newwidth; x++) { - rgb_t pix1, pix2, pix3, pix4; - int xweight, dx; - int yweight, dy; - int r, g, b, a; - int newstate; /* determine the weights and which pixels to fetch */ if (sxfrac <= FRAC_HALF) --- 2625,2630 ---- *************** *** 2414,2460 **** xweight >>= FRAC_BITS - 8; yweight >>= FRAC_BITS - 8; /* fetch the pixels */ ! pix1 = *((UINT32 *)piece->rawbitmap->base + (sy + dy + 0) * piece->rawbitmap->rowpixels + (sx + dx + 0)); ! pix2 = *((UINT32 *)piece->rawbitmap->base + (sy + dy + 0) * piece->rawbitmap->rowpixels + (sx + dx + 1)); ! pix3 = *((UINT32 *)piece->rawbitmap->base + (sy + dy + 1) * piece->rawbitmap->rowpixels + (sx + dx + 0)); ! pix4 = *((UINT32 *)piece->rawbitmap->base + (sy + dy + 1) * piece->rawbitmap->rowpixels + (sx + dx + 1)); /* blend red */ ! r = xweight * yweight * RGB_RED(pix1); ! r += (0x100 - xweight) * yweight * RGB_RED(pix2); ! r += xweight * (0x100 - yweight) * RGB_RED(pix3); ! r += (0x100 - xweight) * (0x100 - yweight) * RGB_RED(pix4); r >>= 16; r = (r * global_brightness) >> 16; if (r > 0xff) r = 0xff; /* blend green */ ! g = xweight * yweight * RGB_GREEN(pix1); ! g += (0x100 - xweight) * yweight * RGB_GREEN(pix2); ! g += xweight * (0x100 - yweight) * RGB_GREEN(pix3); ! g += (0x100 - xweight) * (0x100 - yweight) * RGB_GREEN(pix4); g >>= 16; g = (g * global_brightness) >> 16; if (g > 0xff) g = 0xff; /* blend blue */ ! b = xweight * yweight * RGB_BLUE(pix1); ! b += (0x100 - xweight) * yweight * RGB_BLUE(pix2); ! b += xweight * (0x100 - yweight) * RGB_BLUE(pix3); ! b += (0x100 - xweight) * (0x100 - yweight) * RGB_BLUE(pix4); b >>= 16; b = (b * global_brightness) >> 16; if (b > 0xff) b = 0xff; /* blend alpha */ ! a = xweight * yweight * RGB_ALPHA(pix1); ! a += (0x100 - xweight) * yweight * RGB_ALPHA(pix2); ! a += xweight * (0x100 - yweight) * RGB_ALPHA(pix3); ! a += (0x100 - xweight) * (0x100 - yweight) * RGB_ALPHA(pix4); a >>= 16; a = (a * global_alpha) >> 16; if (a > 0xff) a = 0xff; /* compute the two pixel types */ *((UINT32 *)piece->prebitmap->base + y * piece->prebitmap->rowpixels + x) = compute_pre_pixel(a,r,g,b); --- 2653,2716 ---- xweight >>= FRAC_BITS - 8; yweight >>= FRAC_BITS - 8; + sxadx = sx + dx; + syady = sy + dy; /* fetch the pixels */ ! if(syady == -1) ! { ! syady = 0; ! } ! ! pix1 = *((UINT32 *)piece->rawbitmap->base + (syady + 0) * piece->rawbitmap->rowpixels + (sxadx + 0)); ! pix2 = *((UINT32 *)piece->rawbitmap->base + (syady + 0) * piece->rawbitmap->rowpixels + (sxadx + 1)); ! pix3 = *((UINT32 *)piece->rawbitmap->base + (syady + 1) * piece->rawbitmap->rowpixels + (sxadx + 0)); ! pix4 = *((UINT32 *)piece->rawbitmap->base + (syady + 1) * piece->rawbitmap->rowpixels + (sxadx + 1)); ! ! xwbyw = xweight * yweight; ! wc2 = (0x100 - xweight) * yweight; ! wc3 = xweight * (0x100 - yweight); ! wc4 = (0x100 - xweight) * (0x100 - yweight); /* blend red */ ! r = xwbyw * RGB_RED(pix1); ! r += wc2 * RGB_RED(pix2); ! r += wc3 * RGB_RED(pix3); ! r += wc4 * RGB_RED(pix4); r >>= 16; r = (r * global_brightness) >> 16; if (r > 0xff) r = 0xff; /* blend green */ ! g = xwbyw * RGB_GREEN(pix1); ! g += wc2 * RGB_GREEN(pix2); ! g += wc3 * RGB_GREEN(pix3); ! g += wc4 * RGB_GREEN(pix4); g >>= 16; g = (g * global_brightness) >> 16; if (g > 0xff) g = 0xff; /* blend blue */ ! b = xwbyw * RGB_BLUE(pix1); ! b += wc2 * RGB_BLUE(pix2); ! b += wc3 * RGB_BLUE(pix3); ! b += wc4 * RGB_BLUE(pix4); b >>= 16; b = (b * global_brightness) >> 16; if (b > 0xff) b = 0xff; /* blend alpha */ ! if(strcmp(piece->tag, TAG_LASERDISK)) ! { ! a = xwbyw * RGB_ALPHA(pix1); ! a += wc2 * RGB_ALPHA(pix2); ! a += wc3 * RGB_ALPHA(pix3); ! a += wc4 * RGB_ALPHA(pix4); a >>= 16; a = (a * global_alpha) >> 16; if (a > 0xff) a = 0xff; + } + else + a = 0xff; /* compute the two pixel types */ *((UINT32 *)piece->prebitmap->base + y * piece->prebitmap->rowpixels + x) = compute_pre_pixel(a,r,g,b); *************** *** 2615,2620 **** --- 2871,2877 ---- newpiece->alpha_filename = NULL; newpiece->intersects_game = 0; newpiece->visible = 1; + newpiece->prebitmap = NULL; /* force alloc of memory */ /* allocate space for the filename */ newpiece->tag = auto_malloc(strlen(tag) + 1); *************** *** 2668,2673 **** --- 2925,2931 ---- { switch (piece->layer) { + case LAYER_VIDEO: case LAYER_BACKDROP: if (options.use_artwork & ARTWORK_USE_BACKDROPS) array[i++] = piece; *************** *** 2975,2980 **** --- 3233,3240 ---- piece->layer = LAYER_SIDE; else if (!strcmp(value, "flyer")) piece->layer = LAYER_FLYER; + else if (!strcmp(value, "video")) + piece->layer = LAYER_VIDEO; else return 0; return 1; diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/artwork.h mame-firefox/src/artwork.h *** mame/src/artwork.h Sun Oct 12 20:56:02 2003 --- mame-firefox/src/artwork.h Sun Feb 15 11:27:25 2004 *************** *** 75,80 **** --- 75,113 ---- float left, top, right, bottom; }; + struct artwork_piece + { + /* linkage */ + struct artwork_piece * next; + + /* raw data from the .art file */ + UINT8 layer; + UINT8 has_alpha; + int priority; + float alpha; + float brightness; + float top; + float left; + float bottom; + float right; + char * tag; + char * filename; + char * alpha_filename; + + /* bitmaps */ + struct mame_bitmap * rawbitmap; + struct mame_bitmap * prebitmap; + struct mame_bitmap * yrgbbitmap; + UINT32 * scanlinehint; + UINT8 blendflags; + + /* derived/dynamic data */ + int intersects_game; + int visible; + struct rectangle bounds; + }; + + /*************************************************************************** *************** *** 95,100 **** --- 128,138 ---- void artwork_set_overlay(const struct overlay_piece *overlist); void artwork_show(const char *tag, int show); + struct artwork_piece *get_laser_disc_artwork_piece(void); + struct rectangle *get_video_invalid(void); + struct rectangle *get_underlay_invalid(void); + int scale_bitmap(struct artwork_piece *piece, int newwidth, int newheight); + mame_file *artwork_load_artwork_file(const struct GameDriver **driver); #endif /* ARTWORK_H */ diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/core.mak mame-firefox/src/core.mak *** mame/src/core.mak Wed Dec 24 16:31:10 2003 --- mame-firefox/src/core.mak Sun Feb 15 12:11:12 2004 *************** *** 22,27 **** --- 22,28 ---- $(OBJ)/vidhrdw/avgdvg.o $(OBJ)/machine/mathbox.o \ $(OBJ)/vidhrdw/poly.o $(OBJ)/vidhrdw/matrix3d.o \ $(OBJ)/vidhrdw/tlc34076.o \ + $(OBJ)/vidhrdw/laserdsk.o \ $(OBJ)/machine/ticket.o $(OBJ)/machine/eeprom.o \ $(OBJ)/machine/6522via.o $(OBJ)/machine/mb87078.o \ $(OBJ)/machine/random.o \ diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/driver.c mame-firefox/src/driver.c *** mame/src/driver.c Wed Jan 28 19:03:52 2004 --- mame-firefox/src/driver.c Sun Feb 15 11:27:25 2004 *************** *** 3800,3805 **** --- 3800,3806 ---- DRIVER( cloakgr ) /* 136023 (c) 1983 */ DRIVER( cloud9 ) /* (proto) (c) 1983 */ DRIVER( jedi ) /* 136030 (c) 1984 */ + DRIVER( firefox ) /* 136030 (c) 1984 */ /* Atari System 1 games */ DRIVER( peterpak ) /* 136028 (c) 1984 */ diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/drivers/firefox.c mame-firefox/src/drivers/firefox.c *** mame/src/drivers/firefox.c Thu Jan 1 00:00:00 1970 --- mame-firefox/src/drivers/firefox.c Sun Feb 15 12:59:23 2004 *************** *** 0 **** --- 1,1224 ---- + /* + + Fire Fox + -------- + Driver by smf & Chris Hardy & Scott Waye + + short term: + split driver/vidhrdw/sndhrdw/machine + partial screen updates? + tilemap + add option to centre joystick to enter test menu + + long term: + video/graphics mixing + shared riot code + + verify: + screen size + colours + sprites + interrupts + sound flags + video flags + clock speeds + priorities + + AV# 60626 + Atari "Firefox" V + + -------------------------------------------------------------------------------- + + -------------------------------------------------------------------------------- + + Laser Disc - 30 minutes - Color - 1983 + + An interactive CAV laserdisc designed for use in the Atari video arcade game machine. + Contains over 100 visual and sound segments that include all of the branching possibilities of this game. + Each segment is two to five seconds long. This disc will play on any player, + but requires a special level III player for proper control. Video: CAV. Audio: Analog. + + according to ade's code: + + field length is 240 + vblank should start at line 240 & end at line 5 + irq should start at line 96 & end at 128 + + It's far too slow though, using irobot's interrupts makes + the game run faster ( maybe too fast ). + it needs more investigation but remember it's interlaced + so we have to multiply the scanlines by 2. + + he has breakpoints @ because it sits in a loop $E38D & $EE8B. + now we have the watchdog & reset handling emulated it + probably won't do this. + + According to my understanding of the circuit diagram, vblank will be set at scanline 496 and will go low at scan line 16. + + it uses a quad pokey package 137323-1221-406??? + the laser disc is a philips lvp 22vp931 + ( but maybe this works too... Special Drive: Laser Disc Player - Philips VP-832A ) + + From the schematic it looks as though the video is blended with the graphics using the first 2 bits of the blue output and some 74ls4066 with 2000 or 1000 resistors: + + b0 b1 video graphic + 0 0 1+2 0 + 1 0 2 1 graphic is twice as strong as video ? + 0 1 1 2 + 1 1 0 1+2 + + + + */ + + #include "mame.h" + #include "driver.h" + #include "artwork.h" + #include "vidhrdw/generic.h" + #include "vidhrdw/laserdsk.h" + #include "cpu/m6809/m6809.h" + #include "cpu/m6502/m6502.h" + + static int m_b_vblank; + static void *sound_timer; + static int n_adchannel; + static unsigned char *tileram; + static size_t tileram_size; + static unsigned char *tileredram; + static unsigned char *tilegreenram; + static unsigned char *tileblueram; + static unsigned char *spriteredram; + static unsigned char *spritegreenram; + static unsigned char *spriteblueram; + static int m_n_disc_lock; + static int m_n_disc_left_audio; + static int m_n_disc_right_audio; + static int m_n_disc_data; + static int m_n_disc_offset; + static int m_n_disc_packet[ 3 ]; + static int m_n_manchester[ 6 ]; + static int m_n_manchester_offset; + static int m_n_spritebank; + static int disc_reset; + static int disk_opr = 0; + static int irq_set = 0; + static int previous_irq_state = 0; + static int dav = 0x80; + static int dak_just_low = 0; /* simulate the 15 uS time for the player to read the data */ + static int dak = 0x40; /* DAK or DSKFULL active low indicates player has data, + reset when player has read data */ + static int disk_data; /* after a command is sent the first bit indicates an error, except of the data is 0x00 which indicates an invalid manchester data read (whatever that means) */ + static int disk_line = 0; + + static UINT8 nvram_store[ 256 ]; + + static int status1 = 0xff, status2 = 0xff, status3 = 0xff; + + + static NVRAM_HANDLER( firefox ) + { + if( read_or_write ) + { + //mame_fwrite( file, generic_nvram, generic_nvram_size ); + mame_fwrite( file, generic_nvram, generic_nvram_size ); + } + else + { + if( file ) + { + mame_fread( file, generic_nvram, generic_nvram_size ); + } + else + { + memset( generic_nvram, 0xff, generic_nvram_size ); + } + memcpy( nvram_store, generic_nvram, generic_nvram_size ); + } + } + + WRITE_HANDLER( firefox_novram_recall_w ) + { + if( ( data & 0x80 ) != 0 ) + { + memcpy( generic_nvram, nvram_store, generic_nvram_size ); + } + } + + WRITE_HANDLER( firefox_novram_store_w ) + { + if( ( data & 0x80 ) != 0 ) + { + memcpy( nvram_store, generic_nvram, generic_nvram_size ); + } + } + + #define IRQ_EVERY ( 16 ) + + /* FXXXXX for first field + AXXXXX for second field */ + void firefox_scanline_callback( int scanline ) + { + /* this is sort of how irobot works.. */ + /* + fprintf(stderr, "scanline cb %d\n", scanline); + cpu_set_irq_line( 0, M6809_IRQ_LINE, ( scanline & IRQ_EVERY ) ? ASSERT_LINE : CLEAR_LINE ); + */ + + /* should be 96 according to page 28 of the schematic (G64V AND G32V)*/ + /* also should only trigger if has been reset and this is the rising edge */ + /* + cpu_set_irq_line( 0, M6809_IRQ_LINE, ( scanline & 96) ? ASSERT_LINE : CLEAR_LINE ); + */ + if(((scanline & 96) == 96) && !irq_set && !previous_irq_state) + { + irq_set = 1; + previous_irq_state = 1; + cpu_set_irq_line( 0, M6809_IRQ_LINE, ASSERT_LINE ); + } + + if((scanline & 96) != 96) + { + previous_irq_state = 0; + } + + if( scanline >= 496 ) + { + m_b_vblank = 1; + #if 1 + /* only sends manchester data when playing - is this correct ? */ + /*if( laser_disc_speed && (m_n_manchester_offset == 6) )*/ + #endif + } + else if(scanline >= 16) + { + m_b_vblank = 0; + } + if(scanline == disk_line) + { + if( laser_disc_speed) + { + m_n_manchester[ 0 ] = ( ( laser_disc_field & 0x01 )?0xA0:0xF0 ) | ( ( laser_disc_field / 20000 ) % 10 ); + m_n_manchester[ 1 ] = ( ( ( laser_disc_field / 2000 ) % 10 ) << 4 ) | ( ( laser_disc_field / 200 ) % 10 ); + m_n_manchester[ 2 ] = ( ( ( laser_disc_field / 20 ) % 10 ) << 4 ) | ( ( laser_disc_field / 2 ) % 10 ); + m_n_manchester[ 3 ] = status1; + m_n_manchester[ 4 ] = status2; + m_n_manchester[ 5 ] = status3; + m_n_manchester_offset = 0; + cpu_set_irq_line( 0, M6809_FIRQ_LINE, ASSERT_LINE ); + dav = 0; /* buffer contains info */ + } + laser_disc_field += laser_disc_speed; + } + scanline += IRQ_EVERY; + if(scanline >= 512) + scanline -= 512; + + /* interlace so multiply by 2. */ + timer_set( cpu_getscanlinetime( scanline ), scanline, firefox_scanline_callback ); + } + + /* + fff6=firq e4a2 when dav goes active/low + fff8=irq e38f This is through a flip-flop so goes off (high as active low) only when reset_irq is active - low. + fffa=??? e38d + fffc=??? e38d + fffe=reset e7cc + */ + + /* 0x50-52 Used as a copy of the status + 0x59 = 6-length of laser disc return code + 0x53 = pointer to laser disc return + ( LaserDiscBits & 0x80 ) != 0 when return code available + DSKREAD = acknowledge + ReadDiscData = return code + */ + + VIDEO_UPDATE( firefox ) + { + int n_x; + int n_y; + int n_attr; + int offs; + int n_sprite; + int n_row; + + run_laser_disc(); + /* about 1.2 ms from here to end without debug text */ + UINT8 *p_sprite = spriteram + ( 0x200 * m_n_spritebank ); + + fillbitmap( bitmap, 256, &Machine->visible_area ); + + for( n_sprite = 0; n_sprite < 32; n_sprite++ ) + { + n_attr = p_sprite[ 0 ]; + n_y = p_sprite[ 1 ] + ( 256 * ( n_attr & 1 ) ); + n_x = p_sprite[ 2 ] + ( 256 * ( ( n_attr >> 1 ) & 1 ) ); + if( n_x != 0 ) + { + for( n_row = 0; n_row < 8; n_row++ ) + { + drawgfx( bitmap, Machine->gfx[ 1 ], p_sprite[ 15 - n_row ] + 256 * ( ( n_attr >> 6 ) & 3 ), + ( ( n_attr >> 2 ) & 0x03 ) * 2, n_attr & 0x20, n_attr & 0x10, n_x + 8, 500 - n_y, + &Machine->visible_area, TRANSPARENCY_PEN, 0 ); + n_y += 16; + } + } + p_sprite += 16; + } + + offs = 0; + for( n_y = 0; n_y < 64; n_y++ ) + { + for( n_x = 0; n_x < 64; n_x++ ) + { + drawgfx( bitmap, Machine->gfx[ 0 ], tileram[ offs++ ], + 0, 0, 0, n_x * 8, n_y * 8, &Machine->visible_area, TRANSPARENCY_PEN, 0 ); + } + } + #if 0 + { + struct DisplayText dt[ 2 ]; + char text1[ 256 ]; + if( m_n_disc_left_audio ) + { + text1[ 0 ] = 'L'; + } + else + { + text1[ 0 ] = '-'; + } + if( m_n_disc_right_audio ) + { + text1[ 1 ] = 'R'; + } + else + { + text1[ 1 ] = '-'; + } + if( m_n_disc_lock ) + { + text1[ 2 ] = 'G'; + } + else + { + text1[ 2 ] = 'D'; + } + sprintf( text1 + 3, "%03d,%03d", laser_disc_field / 1000, laser_disc_field % 1000 ); + + dt[ 0 ].text = text1; + dt[ 0 ].color = UI_COLOR_NORMAL; + dt[ 0 ].x = ( Machine->uiwidth - Machine->uifontwidth * strlen( dt[ 0 ].text ) ) / 2; + dt[ 0 ].y = Machine->uiheight - Machine->uifontheight; + dt[ 1 ].text = 0; /* terminate array */ + + displaytext( bitmap, dt ); + } + #endif + } + + #define MAINFLAG ( 0x80 ) + #define SOUNDFLAG ( 0x40 ) + + static int port_A = 0; /* 6532 port A data register */ + + /* Configured as follows: */ + /* d7 (in) Main Ready Flag */ + /* d6 (in) Sound Ready Flag */ + /* d5 (out) Mute Speech */ + /* d4 (in) Not Sound Self Test */ + /* d3 (out) Hold Main CPU in Reset? */ + /* + enable delay circuit? */ + /* d2 (in) TMS5220 Not Ready */ + /* d1 (out) TMS5220 Not Read */ + /* d0 (out) TMS5220 Not Write */ + static int port_B = 0; /* 6532 port B data register */ + /* (interfaces to TMS5220 data bus) */ + static int port_A_ddr = 0; /* 6532 Data Direction Register A */ + static int port_B_ddr = 0; /* 6532 Data Direction Register B */ + static int PA7_irq = 0; /* IRQ-on-write flag (sound CPU) */ + static int PA7_edge = 0; /* IRQ-on-write flag (sound CPU) */ + static int irq_flag = 0; /* 6532 interrupt flag register */ + static int soundflags = 0; + static int main_data = 0; + static int sound_data = 0; + + int firefox_soundflags( void ) + { + return soundflags; + } + + READ_HANDLER( firefox_mainrd_r ) + { + soundflags &= ~SOUNDFLAG; + return sound_data; + } + + WRITE_HANDLER( firefox_mainwr_w ) + { + soundflags |= MAINFLAG; + main_data = data; + cpu_set_irq_line( 1, IRQ_LINE_NMI, PULSE_LINE ); + } + + WRITE_HANDLER( firefox_soundrst_w ) + { + if( ( data & 0x80 ) != 0 ) + { + /* reset sound CPU */ + soundflags = 0; + cpu_set_reset_line( 1, ASSERT_LINE ); + } + else + { + cpu_set_reset_line( 1, CLEAR_LINE ); + } + } + + READ_HANDLER( firefox_soundrd_r ) + { + soundflags &= ~MAINFLAG; + return main_data; + } + + WRITE_HANDLER( firefox_soundwr_w ) + { + soundflags |= SOUNDFLAG; + sound_data = data; + } + + READ_HANDLER( firefox_pia_r ) + { + int temp; + switch( offset ) + { + case 0x00: /* Read Port A */ + return ( port_A & port_A_ddr ) | ( ( soundflags | 0x10 | ( ( !tms5220_ready_r() ) << 2 ) ) & ~port_A_ddr ); + case 0x01: /* Read Port A DDR */ + return port_A_ddr; + case 0x02: /* Read Port B */ + return ( port_B & port_B_ddr ); /* speech data read? */ + case 0x03: /* Read Port B DDR */ + return port_B_ddr; + case 0x05: /* Read Interrupt Flag Register */ + temp = irq_flag; + irq_flag = 0; /* Clear int flags */ + cpu_set_irq_line( 1, M6502_IRQ_LINE, CLEAR_LINE ); + return temp; + default: + logerror( "unhandled pia_r %d\n", offset ); + return 0; + } + } + + static void pia_interrupt( int unused ) + { + irq_flag = 0x80; /* set timer interrupt flag */ + cpu_set_irq_line( 1, M6502_IRQ_LINE, ASSERT_LINE ); + } + + static void stop_pia_timer( void ) + { + timer_adjust( sound_timer, TIME_NEVER, 0, 0 ); + irq_flag = 0; /* Clear int flags */ + cpu_set_irq_line( 1, M6502_IRQ_LINE, CLEAR_LINE ); + } + + static void set_pia_timer( int data, int clock_divider ) + { + timer_adjust( sound_timer, TIME_IN_HZ( 1000000 ) * ( data + 1 ) * clock_divider, 0, 0 ); + irq_flag = 0; /* Clear int flags */ + cpu_set_irq_line( 1, M6502_IRQ_LINE, CLEAR_LINE ); + } + + WRITE_HANDLER( firefox_pia_w ) + { + static int old_port_A = 0; + + /* reg 0x0c - 0x0f mirror of 0x04 - 0x07?? */ + + switch( offset ) + { + case 0x00: /* Port A Write */ + port_A = data; + break; + case 0x01: /* Port A DDR Write */ + port_A_ddr = data; + break; + case 0x02: /* Port B Write */ + port_B = data; + break; + case 0x03: /* Port B DDR Write */ + port_B_ddr = data; + break; + case 0x04: /* Edge Detect Control */ + PA7_irq = 0; /* disabled */ + PA7_edge = 0; /* negative edge */ + break; + case 0x05: /* Edge Detect Control */ + PA7_irq = 0; /* disabled */ + PA7_edge = 1; /* positive edge */ + break; + case 0x06: /* Edge Detect Control */ + PA7_irq = 1; /* enabled */ + PA7_edge = 0; /* negative edge */ + break; + case 0x07: /* Edge Detect Control */ + PA7_irq = 1; /* enabled */ + PA7_edge = 1; /* positive edge */ + break; + case 0x14: /* timer divide by 1 */ + stop_pia_timer(); + break; + case 0x15: /* timer divide by 8 */ + stop_pia_timer(); + break; + case 0x16: /* timer divide by 64 */ + stop_pia_timer(); + break; + case 0x17: /* timer divide by 1024 */ + stop_pia_timer(); + break; + case 0x1c: /* timer divide by 1 */ + set_pia_timer( data, 1 ); + break; + case 0x1d: /* timer divide by 8 */ + set_pia_timer( data, 8 ); + break; + case 0x1e: /* timer divide by 64 */ + set_pia_timer( data, 64 ); + break; + case 0x1f: /* timer divide by 1024 */ + set_pia_timer( data, 1024 ); + break; + default: + logerror( "unhandled pia_w %d %d\n", offset, data ); + break; + } + if( ( old_port_A & 1 ) != 0 && ( port_A & port_A_ddr & 1 ) == 0 ) + { + tms5220_data_w( 0, port_B ); + } + if( ( old_port_A & 32 ) == 0 && ( port_A & port_A_ddr & 32 ) == 1 ) + { + tms5220_reset(); + } + old_port_A = port_A & port_A_ddr; + } + + READ_HANDLER( firefox_misc_r ) + { + int n_return; + + n_return = readinputport( 1 ) | firefox_soundflags(); + if( m_b_vblank ) + { + n_return |= 0x20; + } + else + { + n_return &= ~0x20; + } + return n_return; + } + + READ_HANDLER( firefox_pot_r ) + { + if( n_adchannel == 0 ) + { + return readinputport( 4 ); + } + return readinputport( 5 ); + } + + WRITE_HANDLER( firefox_objram_bank_w ) + { + m_n_spritebank = data & 0x03; + } + + WRITE_HANDLER( firefox_rom_bank_w ) + { + cpu_setbank( 2, memory_region( REGION_CPU1 ) + 0x10000 + ( ( data & 0x1f ) * 0x1000 ) ); + } + + static WRITE_HANDLER( firefox_clearirq_w ) + { + irq_set = 0; + cpu_set_irq_line( 0, M6809_IRQ_LINE ,CLEAR_LINE ); + } + + static WRITE_HANDLER( firefox_clearfirq_w ) + { + cpu_set_irq_line( 0, M6809_FIRQ_LINE ,CLEAR_LINE ); + } + + void mix_color( int offset, int red, int green, int blue ) + { + #if 0 + int n_lvdpercent; + int n_videopercent; + + switch( blue & 0x03 ) + { + case 0: + n_lvdpercent = 100; + n_videopercent = 0; + break; + case 1: + n_lvdpercent = 66; + n_videopercent = 34; + break; + case 2: + n_lvdpercent = 33; + n_videopercent = 67; + break; + default: + n_lvdpercent = 0; + n_videopercent = 100; + break; + } + red = ( ( red * n_videopercent ) / 100 ) + ( ( 0x5f * n_lvdpercent ) / 100 ); + green = ( ( green * n_videopercent ) / 100 ) + ( ( 0x5f * n_lvdpercent ) / 100 ); + blue = ( ( blue * n_videopercent ) / 100 ) + ( ( 0x5f * n_lvdpercent ) / 100 ); + if( red > 0xff ) + { + red = 0xff; + } + if( green > 0xff ) + { + green = 0xff; + } + if( blue > 0xff ) + { + blue = 0xff; + } + #endif + palette_set_color( offset, red, green, blue ); + } + + void update_tile_colour( int offset, int data, unsigned char *ram ) + { + ram[ offset ] = data; + mix_color( offset, tileredram[ offset ], tilegreenram[ offset ], tileblueram[ offset ] ); + } + + WRITE_HANDLER( firefox_tile_red_w ) + { + update_tile_colour( offset, data, tileredram ); + } + + WRITE_HANDLER( firefox_tile_green_w ) + { + update_tile_colour( offset, data, tilegreenram ); + } + + WRITE_HANDLER( firefox_tile_blue_w ) + { + update_tile_colour( offset, data, tileblueram ); + } + + void update_sprite_colour( int offset, int data, unsigned char *ram ) + { + ram[ offset ] = data; + mix_color( offset + 256, spriteredram[ offset ], spritegreenram[ offset ], spriteblueram[ offset ] ); + } + + WRITE_HANDLER( firefox_sprite_red_w ) + { + update_sprite_colour( offset, data, spriteredram ); + } + + WRITE_HANDLER( firefox_sprite_green_w ) + { + update_sprite_colour( offset, data, spritegreenram ); + } + + WRITE_HANDLER( firefox_sprite_blue_w ) + { + update_sprite_colour( offset, data, spriteblueram ); + } + + WRITE_HANDLER( firefox_adchannel_w ) + { + n_adchannel = offset; + } + + WRITE_HANDLER( firefox_reset_w ) + { + cpu_set_reset_line( 0, PULSE_LINE ); + } + + WRITE_HANDLER( firefox_led_w ) + { + if( ( data & 0x80 ) != 0 ) + { + set_led_status( offset, 0 ); + } + else + { + set_led_status( offset, 1 ); + } + } + + WRITE_HANDLER( firefox_coin_counter_w ) + { + coin_counter_w( offset, data & 0x80 ); + } + + MACHINE_INIT( firefox ) + { + n_adchannel = 0; + m_n_spritebank = 0; + m_b_vblank = 0; + /* set an initial timer to go off on scanline 0 */ + timer_set( cpu_getscanlinetime( 0 ), 0, firefox_scanline_callback ); + + sound_timer = timer_alloc( pia_interrupt ); + + m_n_disc_packet[ 0 ] = 0; + m_n_disc_packet[ 1 ] = 0; + m_n_disc_packet[ 2 ] = 0; + m_n_disc_offset = 0; + laser_disc_field = 0; + laser_disc_speed = 0; + m_n_manchester_offset = 6; + } + + /* 20 = DISKOPR - Active low + 40 = DISKFULL - Active low + 80 = DISKDAV - Active low data available + */ + READ_HANDLER( firefox_disc_status_r ) + { + int n_data; + n_data = dav | dak | disk_opr; /* always operational */ + logerror( "%08x: disc status r %02x\n", activecpu_get_pc(), n_data & ( 0x80 | 0x40 | 0x20 ) ); + /* + fprintf(stderr, "%08x: reading disc status r %02x\n", activecpu_get_pc(), n_data & ( 0x80 | 0x40 | 0x20 ) ); + */ + if(dak_just_low) + { + /* assume that the next status read will be after 15uS */ + dak = 0x40; + dak_just_low = 0; + } + return n_data; + } + + /* 4105 - DREAD */ + /* this reset RDDSK (&DSKRD) */ + READ_HANDLER( firefox_disc_data_r ) + { + return disk_data; + } + + /* DISK READ ENABLE */ + /* 4218 - DSKREAD, set RDDSK */ + WRITE_HANDLER( firefox_disc_read_w ) + { + dav=0x80; + if( m_n_manchester_offset < 6 ) + { + disk_data = m_n_manchester[ m_n_manchester_offset++ ]; + if(m_n_manchester_offset < 6) + { + dav = 0; /* more data */ + cpu_set_irq_line( 0, M6809_FIRQ_LINE, ASSERT_LINE ); + } + + } + } + + WRITE_HANDLER( firefox_disc_lock_w ) + { + m_n_disc_lock = data & 0x80; + } + + WRITE_HANDLER( firefox_disc_right_audio_enable_w ) + { + m_n_disc_right_audio = data & 0x80; + } + + WRITE_HANDLER( firefox_disc_left_audio_enable_w ) + { + m_n_disc_left_audio = data & 0x80; + } + + WRITE_HANDLER( firefox_disc_reset_w ) + { + disc_reset = (data & 0x80); + if(!disc_reset) + { + laser_disc_speed = 0; + m_n_manchester_offset = 6; /* no data available */ + m_n_disc_offset = 0; + dak = 0x40; + dav = 0x80; + } + } + + /* active low on dbb7 */ + WRITE_HANDLER( firefox_disc_write_w ) + { + if( ( data & 0x80 ) == 0 ) + { + dak = 0; /* should go high after 15 uS */ + dak_just_low = 1; + m_n_disc_packet[ m_n_disc_offset++ ] = m_n_disc_data; + if( m_n_disc_offset == 3 ) + { + m_n_disc_offset = 0; + switch( m_n_disc_packet[ 0 ] & 0xf0 ) + { + case 0xf0: + logerror( "CMD: goto Frame #%01x%02x%02x & play forward\n", m_n_disc_packet[ 0 ] & 0x0f, m_n_disc_packet[ 1 ], m_n_disc_packet[ 2 ] ); + laser_disc_field = + ( ( m_n_disc_packet[ 0 ] & 0x0f ) * 20000 ) + + ( (( m_n_disc_packet[ 1 ] & 0xf0 ) >> 4) * 2000 ) + + ( ( m_n_disc_packet[ 1 ] & 0x0f ) * 200 ) + + ( (( m_n_disc_packet[ 2 ] & 0xf0 ) >> 4) * 20 ) + + ( ( m_n_disc_packet[ 2 ] & 0x0f ) * 2 ); + laser_seek_frame(laser_disc_field >> 1); + /* + fprintf(stderr, "CMD: goto frame #%01x%02x%02x & play forward disc_field %d\n", m_n_disc_packet[ 0 ] & 0x0f, m_n_disc_packet[ 1 ], m_n_disc_packet[ 2 ] , laser_disc_field); + */ + laser_disc_speed = 1; + return; + case 0xd0: + /* + fprintf(stderr, "CMD: goto Frame #%01x%02x%02x & halt (first field)\n", m_n_disc_packet[ 0 ] & 0x0f, m_n_disc_packet[ 1 ], m_n_disc_packet[ 2 ] ); + */ + laser_disc_field = + ( ( m_n_disc_packet[ 0 ] & 0x0f ) * 20000 ) + + ( (( m_n_disc_packet[ 1 ] & 0xf0 ) >> 4) * 2000 ) + + ( ( m_n_disc_packet[ 1 ] & 0x0f ) * 200 ) + + ( (( m_n_disc_packet[ 2 ] & 0xf0 ) >> 4) * 20 ) + + ( ( m_n_disc_packet[ 2 ] & 0x0f ) * 2 ); + laser_seek_frame(laser_disc_field >> 1); + laser_disc_speed = 0; + return; + case 0x00: + switch( m_n_disc_packet[ 0 ] & 0x0f ) + { + case 0x00: + switch( m_n_disc_packet[ 1 ] & 0xf0 ) + { + case 0x00: + laser_disc_speed = 1; + return; + case 0x10: + laser_disc_speed = -1; + return; + case 0x20: + laser_disc_speed = 0; + return; + case 0x40: + return; + case 0x50: + return; + case 0xa0: + laser_disc_speed = 75; + return; + case 0xb0: + laser_disc_speed = -75; + return; + case 0xe0: + return; + case 0xf0: + return; + } + break; + case 0x02: + switch( m_n_disc_packet[ 1 ] ) + { + case 0xb0: + logerror( "CMD: Video ON/OFF %02x\n", m_n_disc_packet[ 2 ] ); + return; + case 0xb1: + logerror( "CMD: Audio-I ON/OFF %02x\n", m_n_disc_packet[ 2 ] ); + return; + case 0xb2: + logerror( "CMD: Audio-II ON/OFF %02x\n", m_n_disc_packet[ 2 ] ); + return; + case 0xb3: + logerror( "CMD: CX ON/OFF %02x\n", m_n_disc_packet[ 2 ] ); + return; + } + break; + } + break; + } + logerror( "CMD: invalid %02x%02x%02x\n", m_n_disc_packet[ 0 ], m_n_disc_packet[ 1 ], m_n_disc_packet[ 2 ] ); + } + } + } + + /* latch the data */ + WRITE_HANDLER( firefox_disc_data_w ) + { + m_n_disc_data = data; + } + + /************************************* + * + * Main CPU memory handlers + * + *************************************/ + + static ADDRESS_MAP_START( readmem , ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE(0x0000, 0x0fff) AM_READ(MRA8_RAM) + AM_RANGE( 0x1000, 0x1fff) AM_READ(MRA8_RAM) + AM_RANGE( 0x2000, 0x27ff) AM_READ(MRA8_RAM) + AM_RANGE( 0x2800, 0x2fff) AM_READ(MRA8_RAM) + AM_RANGE( 0x3000, 0x3fff) AM_READ(MRA8_BANK2) + AM_RANGE( 0x4000, 0x40ff) AM_READ(MRA8_RAM) + AM_RANGE( 0x4100, 0x4100) AM_READ(input_port_0_r) + AM_RANGE( 0x4101, 0x4101) AM_READ(firefox_misc_r) + AM_RANGE( 0x4102, 0x4102) AM_READ(firefox_disc_status_r) + AM_RANGE( 0x4103, 0x4103) AM_READ(input_port_2_r) + AM_RANGE( 0x4104, 0x4104) AM_READ(input_port_3_r) + AM_RANGE( 0x4105, 0x4105) AM_READ(firefox_disc_data_r) + AM_RANGE( 0x4106, 0x4106) AM_READ(firefox_mainrd_r) + AM_RANGE( 0x4107, 0x4107) AM_READ(firefox_pot_r) + AM_RANGE( 0x4400, 0xffff) AM_READ(MRA8_ROM) + ADDRESS_MAP_END + + static ADDRESS_MAP_START( writemem , ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE( 0x0000, 0x0fff) AM_WRITE(MWA8_RAM) + AM_RANGE( 0x1000, 0x1fff) AM_WRITE(MWA8_RAM) AM_BASE(&tileram) AM_SIZE(&tileram_size) + AM_RANGE( 0x2000, 0x27ff) AM_WRITE(MWA8_RAM) AM_BASE(&spriteram) AM_SIZE(&spriteram_size) + AM_RANGE( 0x2b00, 0x2b00) AM_WRITE(firefox_objram_bank_w) + AM_RANGE( 0x2b01, 0x2bff) AM_WRITE(MWA8_RAM) + AM_RANGE( 0x2800, 0x28ff) AM_WRITE(firefox_sprite_red_w) AM_BASE(&spriteredram ) + AM_RANGE( 0x2900, 0x29ff) AM_WRITE(firefox_sprite_green_w) AM_BASE(&spritegreenram ) + AM_RANGE( 0x2a00, 0x2aff) AM_WRITE(firefox_sprite_blue_w) AM_BASE(&spriteblueram ) + AM_RANGE( 0x2c00, 0x2cff) AM_WRITE(firefox_tile_red_w) AM_BASE(&tileredram ) + AM_RANGE( 0x2d00, 0x2dff) AM_WRITE(firefox_tile_green_w) AM_BASE(&tilegreenram) + AM_RANGE( 0x2e00, 0x2eff) AM_WRITE(firefox_tile_blue_w) AM_BASE(&tileblueram) + AM_RANGE( 0x2f00, 0x3fff) AM_WRITE(MWA8_RAM ) + AM_RANGE( 0x4000, 0x40ff) AM_WRITE(MWA8_RAM) AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size ) + AM_RANGE( 0x4200, 0x4200) AM_WRITE(firefox_clearirq_w) + AM_RANGE( 0x4208, 0x4208) AM_WRITE(firefox_clearfirq_w) + AM_RANGE( 0x4210, 0x4210) AM_WRITE(watchdog_reset_w ) + AM_RANGE( 0x4218, 0x4218) AM_WRITE(firefox_disc_read_w ) + AM_RANGE( 0x4220, 0x4221) AM_WRITE(firefox_adchannel_w ) + AM_RANGE( 0x4230, 0x4230) AM_WRITE(firefox_reset_w ) + AM_RANGE( 0x4280, 0x4280) AM_WRITE(firefox_novram_recall_w ) + AM_RANGE( 0x4281, 0x4281) AM_WRITE(firefox_soundrst_w ) + AM_RANGE( 0x4282, 0x4282) AM_WRITE(firefox_novram_store_w ) + AM_RANGE( 0x4283, 0x4283) AM_WRITE(firefox_disc_lock_w ) + AM_RANGE( 0x4284, 0x4284) AM_WRITE(firefox_disc_right_audio_enable_w ) + AM_RANGE( 0x4285, 0x4285) AM_WRITE(firefox_disc_left_audio_enable_w ) + AM_RANGE( 0x4286, 0x4286) AM_WRITE(firefox_disc_reset_w ) + AM_RANGE( 0x4287, 0x4287) AM_WRITE(firefox_disc_write_w ) + AM_RANGE( 0x4288, 0x4289) AM_WRITE(firefox_coin_counter_w ) + AM_RANGE( 0x428c, 0x428f) AM_WRITE(firefox_led_w ) + AM_RANGE( 0x4290, 0x4290) AM_WRITE(firefox_rom_bank_w ) + AM_RANGE( 0x4298, 0x4298) AM_WRITE(firefox_mainwr_w ) + AM_RANGE( 0x42a0, 0x42a7) AM_WRITE(firefox_disc_data_w ) + AM_RANGE( 0x4400, 0xffff) AM_WRITE(MWA8_ROM ) + ADDRESS_MAP_END + + /************************************* + * + * Sound CPU memory handlers + * + *************************************/ + + static ADDRESS_MAP_START( sound_readmem, ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE(0x0000, 0x07ff) AM_READ(MRA8_RAM ) + AM_RANGE( 0x0800, 0x087f) AM_READ(MRA8_RAM ) /* pia ram */ + AM_RANGE( 0x0880, 0x089f) AM_READ(firefox_pia_r ) + AM_RANGE( 0x1000, 0x1000) AM_READ(firefox_soundrd_r ) + AM_RANGE( 0x2000, 0x200f) AM_READ(pokey1_r ) + AM_RANGE( 0x2800, 0x280f) AM_READ(pokey2_r ) + AM_RANGE( 0x3000, 0x300f) AM_READ(pokey3_r ) + AM_RANGE( 0x3800, 0x380f) AM_READ(pokey4_r ) + AM_RANGE( 0x8000, 0xffff) AM_READ(MRA8_ROM ) + ADDRESS_MAP_END + + static ADDRESS_MAP_START( sound_writemem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x07ff) AM_WRITE(MWA8_RAM ) + AM_RANGE( 0x0800, 0x087f) AM_WRITE(MWA8_RAM ) /* pia ram */ + AM_RANGE( 0x0880, 0x089f) AM_WRITE(firefox_pia_w ) + AM_RANGE( 0x1800, 0x1800) AM_WRITE(firefox_soundwr_w ) + AM_RANGE( 0x2000, 0x200f) AM_WRITE(pokey1_w ) + AM_RANGE( 0x2800, 0x280f) AM_WRITE(pokey2_w ) + AM_RANGE( 0x3000, 0x300f) AM_WRITE(pokey3_w ) + AM_RANGE( 0x3800, 0x380f) AM_WRITE(pokey4_w ) + AM_RANGE( 0x8000, 0xffff) AM_WRITE(MWA8_ROM ) + ADDRESS_MAP_END + + /************************************* + * + * Port definitions + * + *************************************/ + + INPUT_PORTS_START( firefox ) + PORT_START /* IN0 */ + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT ) + PORT_SERVICE( 0x04, IP_ACTIVE_LOW ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START /* IN1 */ + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BITX( 0x10, IP_ACTIVE_LOW, IPT_SERVICE, "Diagnostic Step", KEYCODE_F1, IP_JOY_NONE ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN2 ) + + PORT_START /* IN2 */ + PORT_DIPNAME( 0x03, 0x00, "Coins Per Credit" ) + PORT_DIPSETTING( 0x00, "1 Coin 1 Credit" ) + PORT_DIPSETTING( 0x01, "2 Coins 1 Credit" ) + PORT_DIPSETTING( 0x02, "3 Coins 1 Credit" ) + PORT_DIPSETTING( 0x03, "4 Coins 1 Credit" ) + PORT_DIPNAME( 0x0c, 0x00, "Right Coin" ) + PORT_DIPSETTING( 0x00, "1 Coin for 1 Coin Unit" ) + PORT_DIPSETTING( 0x04, "1 Coin for 4 Coin Units" ) + PORT_DIPSETTING( 0x08, "1 Coin for 5 Coin Units" ) + PORT_DIPSETTING( 0x0c, "1 Coin for 6 Coin Units" ) + PORT_DIPNAME( 0x10, 0x00, "Left Coin" ) + PORT_DIPSETTING( 0x00, "1 Coin for 1 Coin Unit" ) + PORT_DIPSETTING( 0x10, "1 Coin for 2 Coin Units" ) + PORT_DIPNAME( 0xe0, 0x00, "Bonus Adder" ) + PORT_DIPSETTING( 0x00, "None" ) + PORT_DIPSETTING( 0x20, "1 Credit for 2 Coin Units" ) + PORT_DIPSETTING( 0xa0, "1 Credit for 3 Coin Units" ) + PORT_DIPSETTING( 0x40, "1 Credit for 4 Coin Units" ) + PORT_DIPSETTING( 0x80, "1 Credit for 5 Coin Units" ) + PORT_DIPSETTING( 0x60, "2 Credits for 4 Coin Units" ) + PORT_DIPSETTING( 0xe0, DEF_STR( Free_Play ) ) + + PORT_START /* IN3 */ + PORT_DIPNAME( 0x01, 0x00, "Missions" ) + PORT_DIPSETTING( 0x00, "All .50" ) + PORT_DIPSETTING( 0x01, ".50 .75" ) + PORT_DIPNAME( 0x06, 0x00, DEF_STR( Difficulty ) ) + PORT_DIPSETTING( 0x00, "Easy" ) + PORT_DIPSETTING( 0x02, "Moderate" ) + PORT_DIPSETTING( 0x04, "Hard" ) + PORT_DIPSETTING( 0x06, "Hardest" ) + PORT_DIPNAME( 0x18, 0x00, "Gas Usage" ) + PORT_DIPSETTING( 0x00, "Easy" ) + PORT_DIPSETTING( 0x08, "Moderate" ) + PORT_DIPSETTING( 0x10, "Hard" ) + PORT_DIPSETTING( 0x18, "Hardest" ) + PORT_DIPNAME( 0x60, 0x00, "Bonus Gas" ) + PORT_DIPSETTING( 0x00, "Easy" ) + PORT_DIPSETTING( 0x20, "Moderate" ) + PORT_DIPSETTING( 0x40, "Hard" ) + PORT_DIPSETTING( 0x60, "Hardest" ) + PORT_DIPNAME( 0x80, 0x00, "Pro Limit" ) + PORT_DIPSETTING( 0x00, "Moderate" ) + PORT_DIPSETTING( 0x80, "Hardest" ) + + PORT_START /* IN4 */ + PORT_ANALOG( 0xff, 0x80, IPT_AD_STICK_Y, 100, 10, 0, 255 ) + + PORT_START /* IN5 */ + PORT_ANALOG( 0xff, 0x80, IPT_AD_STICK_X, 100, 10, 0, 255 ) + + INPUT_PORTS_END + + /************************************* + * + * Graphics definitions + * + *************************************/ + + static struct GfxLayout tilelayout = + { + 8, 8, /* 8*8 tiles */ + 256, /* 256 tiles */ + 4, /* 4 bits per pixel */ + { 0, 1, 2, 3 }, /* the bitplanes are packed in one nibble */ + { 0 * 4, 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, 7 * 4 }, + { 0 * 32, 1 * 32, 2 * 32, 3 * 32, 4 * 32, 5 * 32, 6 * 32, 7 * 32 }, + 32 * 8 /* every tile takes 32 consecutive bytes */ + }; + + static struct GfxLayout spritelayout = + { + 16,16, /* 16*16 sprites */ + RGN_FRAC(1,5), /* NUM characters */ + 5, /* 5 bits per pixel */ + { RGN_FRAC(0,5), RGN_FRAC(1,5), RGN_FRAC(2,5), RGN_FRAC(3,5), RGN_FRAC(4,5) }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16, 8*16, 9*16, 10*16, 11*16, 12*16, 13*16, 14*16, 15*16 }, + 32 * 8 /* every sprite takes 32 consecutive bytes */ + }; + + static struct GfxDecodeInfo gfxdecodeinfo[] = + { + { REGION_GFX1, 0, &tilelayout, 0, 16 }, + { REGION_GFX2, 0, &spritelayout, 256, 32 }, + { -1 } /* end of array */ + }; + + /************************************* + * + * Sound interfaces + * + *************************************/ + + static struct POKEYinterface pokey_interface = + { + 4, /* 4 chips */ + 1000000, /* 1MHz? */ + { 10, 10, 10, 10 }, /* volume */ + /* The 8 pot handlers */ + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + /* The allpot handler */ + { 0, 0, 0, 0 }, + }; + + static struct TMS5220interface tms5220_interface = + { + 640000, /* clock speed (80*samplerate) */ + 50, /* volume */ + 0 /* IRQ handler */ + }; + + /************************************* + * + * Machine driver + * + *************************************/ + + static MACHINE_DRIVER_START( firefox ) + + /* basic machine hardware */ + MDRV_CPU_ADD(M6809,4000000) + MDRV_CPU_PROGRAM_MAP(readmem,writemem) + + MDRV_CPU_ADD(M6502,2000000) + MDRV_CPU_PROGRAM_MAP(sound_readmem,sound_writemem) + + MDRV_FRAMES_PER_SECOND(60) + MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION) + + MDRV_MACHINE_INIT(firefox) + MDRV_NVRAM_HANDLER(firefox) + + /* video hardware */ + MDRV_VIDEO_ATTRIBUTES( VIDEO_TYPE_RASTER | VIDEO_PIXEL_ASPECT_RATIO_2_1 | VIDEO_NEEDS_6BITS_PER_GUN ) + MDRV_SCREEN_SIZE(64*8, 64*8) + MDRV_VISIBLE_AREA(6*8, 54*8-1, 1*8, 62*8-1) + MDRV_GFXDECODE(gfxdecodeinfo) + MDRV_PALETTE_LENGTH(512) + + MDRV_VIDEO_UPDATE(firefox) + + /* sound hardware */ + MDRV_SOUND_ADD(POKEY, pokey_interface) + MDRV_SOUND_ADD(TMS5220, tms5220_interface) + /* laser disk sound */ + MDRV_SOUND_ADD(CUSTOM, laserdisk_interface) + MACHINE_DRIVER_END + + /************************************* + * + * ROM definitions + * + *************************************/ + + ROM_START( firefox ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) /* 64k for code + data & 128k for banked roms */ + ROM_LOAD( "136026.209", 0x04000, 0x4000, CRC(9f559f1b) SHA1(142d14cb5158ea77f6fc6d9bf0ce723842f345e2) ) /* 8b/c */ + ROM_LOAD( "136026.210", 0x08000, 0x4000, CRC(d769b40d) SHA1(2d354649a381f3399cb0161267bd1c36a8f2bb4b) ) /* 7b/c */ + ROM_LOAD( "136026.211", 0x0c000, 0x4000, CRC(7293ab03) SHA1(73d0d173da295ad59e431bab0a9814a71146cbc2) ) /* 6b/c */ + ROM_LOAD( "136026.201", 0x10000, 0x4000, CRC(c118547a) SHA1(4d3502cbde3116588ed944bf1750bab50e4c813c) ) /* 8a */ + /* empty 7a */ + /* empty 6a */ + /* empty 5a */ + ROM_LOAD( "136026.205", 0x20000, 0x4000, CRC(dc21677f) SHA1(576a96c1e07e1362a0a367e76dc369ee8a950144) ) /* 4a */ + ROM_LOAD( "136026.127", 0x24000, 0x2000, CRC(c0c765ab) SHA1(79f6c8c1d00684d7143b2d33a5669bdf5cd01e96) ) /* 3a */ + ROM_RELOAD( 0x26000, 0x2000 ) + /* empty 2a */ + /* empty 1a */ + + ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* 64k for code */ + /* empty 4k/l */ + ROM_LOAD( "136026.128", 0x08000, 0x2000, CRC(5358d870) SHA1(e8f2983a7e612e1a050a3c0b9f19b1077de4c146) ) /* 4m */ + ROM_RELOAD( 0x0a000, 0x2000 ) + ROM_LOAD( "136026.214", 0x0c000, 0x4000, CRC(92378b78) SHA1(62c7a1fee675fa3f9125f8e208b8207f0ce28bbe) ) /* 4n */ + + ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE ) /* tiles */ + ROM_LOAD( "136026.125", 0x0000, 0x2000, CRC(8a32f9f1) SHA1(f899174f55cd4a24a3be4a0f4bb44d3e8e938586) ) /* 6p */ + + ROM_REGION( 0x28000, REGION_GFX2, ROMREGION_DISPOSE ) /* sprites */ + /* empty 6c */ + /* empty 6a */ + ROM_LOAD( "136026.124", 0x00000, 0x4000, CRC(5efe0f6c) SHA1(df35fd9267d966ab379c2f78ed418f4606741b28)) /* 5c */ + ROM_LOAD( "136026.123", 0x04000, 0x4000, CRC(dffe48b3) SHA1(559907651bb425e26a834b467959b15092d23d27)) /* 5a */ + ROM_LOAD( "136026.118", 0x08000, 0x4000, CRC(0ed4df15) SHA1(7aa599f428112fff4bfedf63fafc22f19fa66546)) /* 4c */ + ROM_LOAD( "136026.122", 0x0c000, 0x4000, CRC(8e2c6616) SHA1(59cbd585028bb634034a9dfd552275bd41f01989)) /* 4a */ + ROM_LOAD( "136026.117", 0x10000, 0x4000, CRC(79129084) SHA1(4219ff7cd444ad11e4cb9f1c30ac15fe0cfc5a17)) /* 3c */ + ROM_LOAD( "136026.121", 0x14000, 0x4000, CRC(494972d4) SHA1(fa0e24e911b233e9644d7794ba03f76bfd39aa8c)) /* 3a */ + ROM_LOAD( "136026.116", 0x18000, 0x4000, CRC(d5282d4e) SHA1(de5fdf82a615625aa77b39e035b4206216faaf9c)) /* 2c */ + ROM_LOAD( "136026.120", 0x1c000, 0x4000, CRC(e1b95923) SHA1(b6d0c0af0a8f55e728cd0f4c3222745eefd57f50)) /* 2a */ + ROM_LOAD( "136026.115", 0x20000, 0x4000, CRC(861abc82) SHA1(1845888d07162ae915364a2a91294731f1c5b3bd)) /* 1c */ + ROM_LOAD( "136026.119", 0x24000, 0x4000, CRC(959471b1) SHA1(a032209a209f51d34360d5c7ad32ec62150158d2)) /* 1a */ + ROM_END + + ROM_START( firefoxa ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) /* 64k for code + data & 128k for banked roms */ + ROM_LOAD( "136026.109", 0x04000, 0x4000, CRC(7639270c) SHA1(1)) /* 8b/c */ + ROM_LOAD( "136026.110", 0x08000, 0x4000, CRC(f3102944) SHA1(1)) /* 7b/c */ + ROM_LOAD( "136026.111", 0x0c000, 0x4000, CRC(8a230bb5) SHA1(1)) /* 6b/c */ + ROM_LOAD( "136026.101", 0x10000, 0x4000, CRC(91bba45a) SHA1(1)) /* 8a */ + ROM_LOAD( "136026.102", 0x14000, 0x4000, CRC(5f1e423d) SHA1(1)) /* 7a */ + /* empty 6a */ + /* empty 5a */ + ROM_LOAD( "136026.105", 0x20000, 0x4000, CRC(83f1d4ed) SHA1(1)) /* 4a */ + ROM_LOAD( "136026.106", 0x24000, 0x4000, CRC(c5d8d417) SHA1(1)) /* 3a */ + /* empty 2a */ + /* empty 1a */ + + ROM_REGION( 0x10000, REGION_CPU2, 0 ) /* 64k for code */ + /* empty 4k/l */ + ROM_LOAD( "136026.113", 0x08000, 0x4000, CRC(90988b3b) SHA1(1)) /* 4m */ + ROM_LOAD( "136026.114", 0x0c000, 0x4000, CRC(1437ce14) SHA1(1)) /* 4n */ + + ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE ) /* tiles */ + ROM_LOAD( "136026.125", 0x0000, 0x2000, CRC(8a32f9f1) SHA1(1)) /* 6p */ + + ROM_REGION( 0x28000, REGION_GFX2, ROMREGION_DISPOSE ) /* sprites */ + /* empty 6c */ + /* empty 6a */ + ROM_LOAD( "136026.124", 0x00000, 0x4000, CRC(5efe0f6c) SHA1(1)) /* 5c */ + ROM_LOAD( "136026.123", 0x04000, 0x4000, CRC(dffe48b3) SHA1(1)) /* 5a */ + ROM_LOAD( "136026.118", 0x08000, 0x4000, CRC(0ed4df15) SHA1(1)) /* 4c */ + ROM_LOAD( "136026.122", 0x0c000, 0x4000, CRC(8e2c6616) SHA1(1)) /* 4a */ + ROM_LOAD( "136026.117", 0x10000, 0x4000, CRC(79129084) SHA1(1)) /* 3c */ + ROM_LOAD( "136026.121", 0x14000, 0x4000, CRC(494972d4) SHA1(1)) /* 3a */ + ROM_LOAD( "136026.116", 0x18000, 0x4000, CRC(d5282d4e) SHA1(1)) /* 2c */ + ROM_LOAD( "136026.120", 0x1c000, 0x4000, CRC(e1b95923) SHA1(1)) /* 2a */ + ROM_LOAD( "136026.115", 0x20000, 0x4000, CRC(861abc82) SHA1(1)) /* 1c */ + ROM_LOAD( "136026.119", 0x24000, 0x4000, CRC(959471b1) SHA1(1)) /* 1a */ + ROM_END + + /************************************* + * + * Game drivers + * + *************************************/ + + GAME( 1984, firefox, 0, firefox, firefox, 0, ROT0, "Atari", "Fire Fox (set 1)" ) + GAME( 1984, firefoxa, firefox, firefox, firefox, 0, ROT0, "Atari", "Fire Fox (set 2)" ) diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/drivers/gottlieb.c mame-firefox/src/drivers/gottlieb.c *** mame/src/drivers/gottlieb.c Wed Jan 28 19:01:24 2004 --- mame-firefox/src/drivers/gottlieb.c Sun Feb 15 11:27:25 2004 *************** *** 146,153 **** --- 146,156 ---- ***************************************************************************/ + #include "mame.h" #include "driver.h" + #include "artwork.h" #include "vidhrdw/generic.h" + #include "vidhrdw/laserdsk.h" extern UINT8 *gottlieb_charram; *************** *** 242,249 **** } - static int current_frame = 1; - static int laserdisc_playing; static int lasermpx; static int audioptr; static int audioready=1; --- 245,250 ---- *************** *** 274,285 **** switch (offset) { case 0: ! tmp = current_frame % 100; logerror("LSB frame read: %d\n",tmp); return ((tmp / 10) << 4) | (tmp % 10); break; case 1: ! tmp = (current_frame / 100) % 100; logerror("MSB frame read: %d\n",tmp); return ((tmp / 10) << 4) | (tmp % 10); break; --- 275,286 ---- switch (offset) { case 0: ! tmp = (laser_disc_field >> 1) % 100; logerror("LSB frame read: %d\n",tmp); return ((tmp / 10) << 4) | (tmp % 10); break; case 1: ! tmp = ((laser_disc_field >> 1) / 100) % 100; logerror("MSB frame read: %d\n",tmp); return ((tmp / 10) << 4) | (tmp % 10); break; *************** *** 291,297 **** /* bit 5 disc ready */ /* bit 6 break in audio trasmission */ /* bit 7 missing audio clock */ ! return ((current_frame / 10000) & 0x7) | (audioready << 3) | 0x10 | (discready << 5); } else { /* read audio buffer */ if (skipfirstbyte) audioptr++; skipfirstbyte = 0; --- 292,298 ---- /* bit 5 disc ready */ /* bit 6 break in audio trasmission */ /* bit 7 missing audio clock */ ! return (((laser_disc_field >> 1) / 10000) & 0x7) | (audioready << 3) | 0x10 | (discready << 5); } else { /* read audio buffer */ if (skipfirstbyte) audioptr++; skipfirstbyte = 0; *************** *** 319,324 **** --- 320,326 ---- { static int loop; int cmd; + static int current_frame = 0; /* commands are written in three steps, the first two the command is */ /* written (maybe one to load the latch, the other to start the send), */ *************** *** 350,372 **** { if (cmd == 0x04) /* step forward */ { ! laserdisc_playing = 0; ! current_frame++; } if (cmd == 0x05) /* play */ { ! laserdisc_playing = 1; discready = 1; } if (cmd == 0x0b) /* seek frame */ { ! laserdisc_playing = 0; discready = 0; access_time = 60; /* 1s access time */ } if (cmd == 0x0f) /* stop */ { ! laserdisc_playing = 0; discready = 0; } lastcmd = cmd; --- 352,377 ---- { if (cmd == 0x04) /* step forward */ { ! laser_disc_speed = 0; ! laser_disc_step(1); ! laser_disc_field += 2; } if (cmd == 0x05) /* play */ { ! laser_disc_speed = 1; discready = 1; } if (cmd == 0x0b) /* seek frame */ { ! laser_seek_frame(current_frame); ! laser_disc_field = current_frame << 1; ! laser_disc_speed = 0; discready = 0; access_time = 60; /* 1s access time */ } if (cmd == 0x0f) /* stop */ { ! laser_disc_speed = 0; discready = 0; } lastcmd = cmd; *************** *** 379,390 **** access_time--; if (access_time == 0) discready = 1; ! } else if (laserdisc_playing) { ! odd_field ^= 1; if (odd_field) /* the manual says the video frame number is only present in the odd field) */ { ! current_frame++; ! logerror("current frame : %d\n",current_frame); if (current_frame%53==0) { --- 384,396 ---- access_time--; if (access_time == 0) discready = 1; ! } else if (laser_disc_speed) { ! laser_disc_field += laser_disc_speed; ! odd_field = laser_disc_field & 0x1; if (odd_field) /* the manual says the video frame number is only present in the odd field) */ { ! int current_frame = laser_disc_field >> 1; ! logerror("current frame : %d\n",current_frame); if (current_frame%53==0) { *************** *** 1336,1343 **** { 0 } }; - - /******************************************************************** * * Machine Driver macro --- 1342,1347 ---- *************** *** 1462,1467 **** --- 1466,1473 ---- MDRV_IMPORT_FROM(gottlieb2) MDRV_CPU_MODIFY("main") MDRV_CPU_PROGRAM_MAP(stooges_readmem,stooges_writemem) + /* laser disk sound */ + MDRV_SOUND_ADD(CUSTOM, laserdisk_interface) /* video hardware */ MDRV_GFXDECODE(charRAM_gfxdecodeinfo) *************** *** 1813,1819 **** ROM_LOAD( "mach3fg0.bin", 0x6000, 0x2000, CRC(0bae12a5) SHA1(7bc0b82ccab0e4498a7a2a9dc85f03125f25826e) ) ROM_REGION( 1024*1024, REGION_USER1, 0) /* about 30 min of target data from laserdisc */ ! ROM_LOAD( "m3target.bin", 0, 1024*1024, CRC(6e779a6f) SHA1(e556ad438e637a71f17ea04088de10b39b45f8df) ) ROM_END ROM_START( usvsthem ) --- 1819,1825 ---- ROM_LOAD( "mach3fg0.bin", 0x6000, 0x2000, CRC(0bae12a5) SHA1(7bc0b82ccab0e4498a7a2a9dc85f03125f25826e) ) ROM_REGION( 1024*1024, REGION_USER1, 0) /* about 30 min of target data from laserdisc */ ! ROM_LOAD( "m3target.bin", 0, 0xed400, CRC(a2a9f8e5) SHA1(5ca2e4dd86882009ea1496f91e1fc8612ae4bf5e) ) ROM_END ROM_START( usvsthem ) diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/fileio.c mame-firefox/src/fileio.c *** mame/src/fileio.c Tue Nov 11 22:25:56 2003 --- mame-firefox/src/fileio.c Sun Feb 15 11:27:25 2004 *************** *** 106,111 **** --- 106,114 ---- case FILETYPE_ARTWORK: case FILETYPE_HISTORY: case FILETYPE_LANGUAGE: + case FILETYPE_LASERDISK_VIDEO: + case FILETYPE_LASERDISK_FLAC: + case FILETYPE_LASERDISK_FRAME_SEEKS: #ifndef MESS case FILETYPE_INI: #endif *************** *** 242,247 **** --- 245,255 ---- return generic_fopen(filetype, NULL, gamename, 0, openforwrite ? FILEFLAG_OPENWRITE : FILEFLAG_OPENREAD); #endif + case FILETYPE_LASERDISK_VIDEO: + case FILETYPE_LASERDISK_FLAC: + case FILETYPE_LASERDISK_FRAME_SEEKS: + return generic_fopen(filetype, gamename, filename, 0, FILEFLAG_OPENREAD); + /* anything else */ default: logerror("mame_fopen(): unknown filetype %02x\n", filetype); *************** *** 784,789 **** --- 792,800 ---- case FILETYPE_HIGHSCORE_DB: /* highscore database/history files */ case FILETYPE_HISTORY: /* game history files */ case FILETYPE_CHEAT: /* cheat file */ + case FILETYPE_LASERDISK_VIDEO: + case FILETYPE_LASERDISK_FLAC: + case FILETYPE_LASERDISK_FRAME_SEEKS: default: /* anything else */ extension = NULL; break; diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/fileio.h mame-firefox/src/fileio.h *** mame/src/fileio.h Fri May 23 16:51:20 2003 --- mame-firefox/src/fileio.h Sun Feb 15 11:27:25 2004 *************** *** 40,45 **** --- 40,48 ---- FILETYPE_LANGUAGE, FILETYPE_CTRLR, FILETYPE_INI, + FILETYPE_LASERDISK_FLAC, + FILETYPE_LASERDISK_VIDEO, + FILETYPE_LASERDISK_FRAME_SEEKS, #ifdef MESS FILETYPE_CRC, #endif diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/mame.c mame-firefox/src/mame.c *** mame/src/mame.c Wed Jan 28 19:01:24 2004 --- mame-firefox/src/mame.c Sun Feb 15 11:27:25 2004 *************** *** 1294,1299 **** --- 1294,1303 ---- } + struct mame_display *get_current_display() + { + return ¤t_display; + } /*------------------------------------------------- recompute_fps - recompute the frame rate diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/mame.h mame-firefox/src/mame.h *** mame/src/mame.h Wed Jan 28 19:01:24 2004 --- mame-firefox/src/mame.h Sun Feb 15 11:27:25 2004 *************** *** 383,388 **** --- 383,390 ---- /* return the index of the given CPU, or -1 if not found */ int mame_find_cpu_index(const char *tag); + struct mame_display *get_current_display(void); + #ifdef MESS #include "mess.h" #endif /* MESS */ diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/mame.mak mame-firefox/src/mame.mak *** mame/src/mame.mak Wed Jan 28 19:01:24 2004 --- mame-firefox/src/mame.mak Sun Feb 15 12:12:57 2004 *************** *** 619,624 **** --- 619,625 ---- $(OBJ)/machine/asteroid.o $(OBJ)/sndhrdw/asteroid.o \ $(OBJ)/sndhrdw/llander.o $(OBJ)/drivers/asteroid.o \ $(OBJ)/drivers/bwidow.o \ + $(OBJ)/drivers/firefox.o \ $(OBJ)/sndhrdw/bzone.o $(OBJ)/drivers/bzone.o \ $(OBJ)/sndhrdw/redbaron.o \ $(OBJ)/drivers/tempest.o \ diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/md5.c mame-firefox/src/md5.c *** mame/src/md5.c Thu May 15 04:59:00 2003 --- mame-firefox/src/md5.c Sun Feb 15 11:27:25 2004 *************** *** 44,49 **** --- 44,50 ---- * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ + /* void MD5Init(struct MD5Context *ctx) { *************** *** 55,136 **** ctx->bytes[0] = 0; ctx->bytes[1] = 0; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ - void - MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) - { - UWORD32 t; - - /* Update byte count */ - - t = ctx->bytes[0]; - if ((ctx->bytes[0] = t + len) < t) - ctx->bytes[1]++; /* Carry from low to high */ - - t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ - if (t > len) { - memcpy((md5byte *)ctx->in + 64 - t, buf, len); - return; - } - /* First chunk is an odd size */ - memcpy((md5byte *)ctx->in + 64 - t, buf, t); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += t; - len -= t; - - /* Process data in 64-byte chunks */ - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - memcpy(ctx->in, buf, len); - } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ - void - MD5Final(md5byte digest[16], struct MD5Context *ctx) - { - int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ - md5byte *p = (md5byte *)ctx->in + count; - - /* Set the first char of padding to 0x80. There is always room. */ - *p++ = 0x80; - - /* Bytes of padding needed to make 56 bytes (-8..55) */ - count = 56 - 1 - count; - - if (count < 0) { /* Padding forces an extra block */ - memset(p, 0, count + 8); - byteSwap(ctx->in, 16); - MD5Transform(ctx->buf, ctx->in); - p = (md5byte *)ctx->in; - count = 56; - } - memset(p, 0, count); - byteSwap(ctx->in, 14); - - /* Append length in bits and transform */ - ctx->in[14] = ctx->bytes[0] << 3; - ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; - MD5Transform(ctx->buf, ctx->in); - - byteSwap(ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ - } #ifndef ASM_MD5 --- 56,72 ---- ctx->bytes[0] = 0; ctx->bytes[1] = 0; } + */ /* * Update context to reflect the concatenation of another buffer full * of bytes. */ /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ #ifndef ASM_MD5 *************** *** 151,156 **** --- 87,93 ---- * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ + /* void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) { *************** *** 234,239 **** --- 171,177 ---- buf[2] += c; buf[3] += d; } + */ #endif diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/vidhrdw/gottlieb.c mame-firefox/src/vidhrdw/gottlieb.c *** mame/src/vidhrdw/gottlieb.c Fri Jul 4 19:16:30 2003 --- mame-firefox/src/vidhrdw/gottlieb.c Sun Feb 15 11:27:25 2004 *************** *** 9,14 **** --- 9,15 ---- #include "driver.h" #include "common.h" #include "vidhrdw/generic.h" + #include "vidhrdw/laserdsk.h" UINT8 *gottlieb_charram; *************** *** 198,203 **** --- 199,208 ---- VIDEO_UPDATE( gottlieb ) { + /* some of the games had a laserdisk */ + if(laser_disc_speed) + run_laser_disc(); + if (!background_priority) { tilemap_draw(bitmap, &Machine->visible_area, bg_tilemap, TILEMAP_IGNORE_TRANSPARENCY, 0); diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/vidhrdw/laserdsk.c mame-firefox/src/vidhrdw/laserdsk.c *** mame/src/vidhrdw/laserdsk.c Thu Jan 1 00:00:00 1970 --- mame-firefox/src/vidhrdw/laserdsk.c Sun Feb 15 13:11:58 2004 *************** *** 0 **** --- 1,408 ---- + #include + #include + #include + #include + #include + + #include "mame.h" + #include "driver.h" + #include "palette.h" + #include "common.h" + #include + #include "mpeg2convert.h" + #include "laserdsk.h" + #include "osdepend.h" + #include "FLAC/seekable_stream_decoder.h" + #include "artwork.h" + + #define TRUE 1 + #define FALSE 0 + + const static FLAC__Frame *decode_flac_frame; + const FLAC__int32 *decoded_flac_channel; + static char flacFilename[FILENAME_MAX]; + static FLAC__SeekableStreamDecoder *flacDecoder; + static void *flacFile; + static int decoded_samples = 0; // number of unstreamed samples in the decoded buffer + static int decode_buffer_pos = 0; // track position in the decoded buffer + typedef struct { + long frame; + long long seek_pos; + long long flac_seek_pos; + } FramePtr; + + FramePtr *frame_ptrs; + int no_ptrs; + + + char lsr_filename[20]; + const char *m_gamename; + mame_file *file; + mpeg2dec_t *mpeg2dec = NULL; + const mpeg2_info_t *info; + int framenum = 0; + #define BUFFER_SIZE 65536 + uint8_t buffer[BUFFER_SIZE]; + int g_width = 0, g_height; + int offset, flac_offset; /* allows the audio to come from a different source */ + int state = -1; + + #define PLAYER_FRAME (laser_disc_field >> 1) + + + int laser_disc_speed; + int mpeg_frame = -1; + int laser_disc_field = 0; /* 0 is the first field of the first frame + 1 is the second field of the first frame + etc */ + /* as some laser disc material is interlaced, we only get a full frame every + other field/screen refresh. Attempt to improve performance by doing + the mpeg decode in the first field and the scaling in the second */ + /* the PLAYER_FRAME will move to the next frame on the first field, + but should not be drawn until the second field */ + void run_laser_disc(void) + { + struct artwork_piece *video; + struct mame_display *display; + struct rectangle *u_invalid; + static int last_scaled_field = -1; + + if(laser_disc_speed) + { + /* + fprintf(stderr, "field %d, mpeg %d", + laser_disc_field, mpeg_frame); + */ + if(mpeg_frame < PLAYER_FRAME) + { + laser_disc_step(1); + } + video = get_laser_disc_artwork_piece(); + display = get_current_display(); + if((last_scaled_field != laser_disc_field) && + (laser_disc_field & 1) && + (display->changed_flags & GAME_BITMAP_CHANGED)) + { + copy_current_mpeg_buf_to_bitmap(video->rawbitmap); + + scale_bitmap(video, video->bounds.max_x - video->bounds.min_x + 1, + video->bounds.max_y - video->bounds.min_y + 1); + u_invalid = get_video_invalid(); + /* mark the whole thing as invalid */ + u_invalid->min_x = u_invalid->min_y = 0; + u_invalid->max_x = video->bounds.max_x; + u_invalid->max_y = video->bounds.max_y; + } + } + } + + void load_frame_ptrs(const char *gamename, char *filename) + { + mame_file *f = mame_fopen(gamename, filename, FILETYPE_LASERDISK_FRAME_SEEKS, + 0); + + UINT64 file_size; + int i; + + if(!f) + { + fprintf(stderr, "could not open file %s\n", filename); + exit(-1); + } + file_size = mame_fsize(f); + if((file_size - 2 * sizeof(int)) % sizeof(FramePtr)) + { + fprintf(stderr, "frame file not a multiple of struct size\n"); + return; + } + mame_fread(f, &offset, sizeof(offset)); + mame_fread(f, &flac_offset, sizeof(flac_offset)); + no_ptrs = (file_size - 2 * sizeof(int)) / sizeof(FramePtr); + frame_ptrs = (FramePtr *)(malloc(sizeof(FramePtr) * no_ptrs)); + for(i = 0; i < no_ptrs; i++) + { + /* gcc on windows makes this struct bigger (32) than on Linux (24), so do it by element */ + mame_fread(f, &(frame_ptrs[i].frame), sizeof(long)); + mame_fread(f, &(frame_ptrs[i].seek_pos), sizeof(long long)); + mame_fread(f, &(frame_ptrs[i].flac_seek_pos), sizeof(long long)); + } + + mame_fclose(f); + } + + void copy_current_mpeg_buf_to_bitmap(struct mame_bitmap *bm) + { + int y; + uint8_t * buf; + + if(info->display_fbuf && g_width) + { + buf = info->display_fbuf->buf[0]; + bm->base = buf; + bm->rowpixels = g_width; /* no BITMAP_SAFETY */ + /* initialize the line pointers */ + for (y = 0; y < g_height; y++) + bm->line[y] = &buf[y * g_width * 4]; + } + } + + + int laser_disc_step (int convert_rgb) + { + + int done = FALSE; + int size = 1; + + + if(!mpeg2dec) + { + fprintf(stderr, "mpeg decoder not initialised - is there a laserdisc layer in the artwork file?\n"); + return 0; + } + + do { + state = mpeg2_parse (mpeg2dec); + switch (state) { + case STATE_BUFFER: + size = mame_fread(file, buffer, BUFFER_SIZE); + mpeg2_buffer (mpeg2dec, buffer, buffer + size); + break; + case STATE_SEQUENCE: + + if(convert_rgb) + { + mpeg2_convert (mpeg2dec, mpeg2convert_rgb32, NULL); + } + break; + case STATE_SLICE: + case STATE_END: + if (info->display_fbuf) + { + g_width = info->sequence->width; + g_height = info->sequence->height; + } + mpeg_frame++; + done = TRUE; + break; + } + } while (!done && size); + + return(done); + } + + + void laser_seek_frame(int frame) + { + int skip = 0; + int must_have = 3; + int desired_frame; + int flac_frame; + + desired_frame = frame; + flac_frame = frame + flac_offset; + if(flac_frame < 0) flac_frame = 0; + + frame += offset; + + // seek the audio + if(flacDecoder && !FLAC__seekable_stream_decoder_seek_absolute(flacDecoder, + frame_ptrs[flac_frame].flac_seek_pos)) + { + logerror("could not seek flac\n"); + } + + /* clear buffer */ + mpeg2_reset(mpeg2dec, 0); + + while((must_have > 0) || (frame_ptrs[frame].seek_pos == -1)) + { + skip++; + must_have--; + frame --; + } + + mame_fseek(file, frame_ptrs[frame].seek_pos, SEEK_SET); + + + while(skip-- > 1) + laser_disc_step(0); + + laser_disc_step(1); + mpeg_frame = desired_frame; + } + + void reset_mpeg(void) + { + mame_fclose(file); + mpeg2_close(mpeg2dec); + init_mpeg(m_gamename); + framenum = 0; + g_width = 0; + } + + + void init_mpeg(const char *gamename) + { + sprintf(lsr_filename, "%s.lsr", gamename); + m_gamename = gamename; + file = mame_fopen (gamename, lsr_filename, FILETYPE_LASERDISK_VIDEO, 0); + if (!file) { + fprintf (stderr, "Could not open file %s\n", lsr_filename); + exit (1); + } + + mame_fseek(file, 0, SEEK_SET); + + load_frame_ptrs(gamename, "frame.bin"); + + mpeg2dec = mpeg2_init (); + if (mpeg2dec == NULL) + exit (1); + + info = mpeg2_info (mpeg2dec); + mpeg_frame = 0; + laser_disc_step(1); /* load the stream */ + return; + } + + // callback for the stream + // we need to get length words from the flac decode into the buffer + static void flac_update(int param, INT16 *buffer, int length) + { + FLAC__bool res = true; + + //TODO: check for playing? probably a better way to stop the sound + if(laser_disc_speed) + { + while(length && res) + { + // need to decode some more data + if(!decoded_samples) + { + res = FLAC__seekable_stream_decoder_process_single(flacDecoder); + } + + while(decoded_samples && length) + { + *buffer++ = decoded_flac_channel[decode_buffer_pos++]; + length--; + decoded_samples--; + } + } + } + else + { + /* clear the sound ? */ + memset(buffer, 0, length << 1); + } + } + + static FLAC__SeekableStreamDecoderReadStatus flac_read(const FLAC__SeekableStreamDecoder *decoder, + FLAC__byte buffer[], unsigned *bytes, void *client_data) + { + *bytes = mame_fread(flacFile, buffer, *bytes); + return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; + } + + static FLAC__SeekableStreamDecoderSeekStatus flac_seek(const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 absolute_byte_offset, void *client_data) + { + mame_fseek(flacFile, absolute_byte_offset, SEEK_SET); + return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; + } + + static FLAC__SeekableStreamDecoderTellStatus flac_tell(const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 *absolute_byte_offset, void *client_data) + { + *absolute_byte_offset = mame_ftell(flacFile); + return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; + } + + static FLAC__SeekableStreamDecoderLengthStatus flac_length(const FLAC__SeekableStreamDecoder *decoder, + FLAC__uint64 *stream_length, void *client_data) + { + *stream_length = mame_fsize(flacFile); + return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; + } + + static FLAC__bool flac_eof(const FLAC__SeekableStreamDecoder *decoder, void *client_data) + { + return(mame_feof(flacFile)); + } + + static FLAC__StreamDecoderWriteStatus flac_write(const FLAC__SeekableStreamDecoder *decoder, + const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) + { + decode_flac_frame = frame; + decoded_flac_channel = buffer[0]; + decoded_samples = frame->header.blocksize; + decode_buffer_pos = 0; + return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; // or ABORT + } + + static void flac_metadata(const FLAC__SeekableStreamDecoder *decoder, + const FLAC__StreamMetadata *metadata, void *client_data) + { + + } + + static void flac_error(const FLAC__SeekableStreamDecoder *decoder, + FLAC__StreamDecoderErrorStatus status, void *client_data) + { + logerror("flac decode error %d\n", (int)status); + } + + static void init_flac(void) + { + sprintf(flacFilename, "%s.flac", Machine->gamedrv->name); + flacFile = mame_fopen(Machine->gamedrv->name, flacFilename, FILETYPE_LASERDISK_FLAC, 0); + if(flacFile) + { + flacDecoder = FLAC__seekable_stream_decoder_new(); + FLAC__seekable_stream_decoder_set_read_callback(flacDecoder, flac_read); + FLAC__seekable_stream_decoder_set_seek_callback(flacDecoder, flac_seek); + FLAC__seekable_stream_decoder_set_tell_callback(flacDecoder, flac_tell); + FLAC__seekable_stream_decoder_set_length_callback(flacDecoder, flac_length); + FLAC__seekable_stream_decoder_set_eof_callback(flacDecoder, flac_eof); + FLAC__seekable_stream_decoder_set_write_callback(flacDecoder, flac_write); + FLAC__seekable_stream_decoder_set_metadata_callback(flacDecoder, flac_metadata); + FLAC__seekable_stream_decoder_set_error_callback(flacDecoder, flac_error); + if(FLAC__seekable_stream_decoder_init(flacDecoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) + { + logerror("flac init failed\n"); + } + } + else + { + fprintf(stderr, "flac file %s not found\n", flacFilename); + } + } + + /* laserdisk sound emulation */ + static int custom_start_flac(const struct MachineSound *msound) + { + // name, mixing level, sample_rate, param, callback) + stream_init("laserdisk", 50, 44100, 0, flac_update); + init_flac(); + // return 1 if error + return 0; + } + + static void custom_stop_flac(void) + { + } + + // this seems to be called for every frame? + static void custom_update_flac(void) + { + } + + // What's all this for, perhaps to customise the sound chip per game? + // use the custom driver + struct CustomSound_interface laserdisk_interface = + { + custom_start_flac, /* start */ + custom_stop_flac, /* stop */ + custom_update_flac /* update, could be called through stream_init? */ + }; + diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/vidhrdw/laserdsk.h mame-firefox/src/vidhrdw/laserdsk.h *** mame/src/vidhrdw/laserdsk.h Thu Jan 1 00:00:00 1970 --- mame-firefox/src/vidhrdw/laserdsk.h Sun Feb 15 11:27:26 2004 *************** *** 0 **** --- 1,11 ---- + #include "FLAC/seekable_stream_decoder.h" + #include "sndintrf.h" + + extern int laser_disc_field; + extern int laser_disc_speed; + extern struct CustomSound_interface laserdisk_interface; + void init_mpeg(const char *gamename); + int laser_disc_step(int convert_rgb); + void copy_current_mpeg_buf_to_bitmap(struct mame_bitmap *bm); + void run_laser_disc(void); + void laser_seek_frame(int frame); diff -c -b -B -N -x *.png -x *.swo -x *.exe -x artwork.h.orig -x cfg -x *.txt -x *.swp -x *.orig -x *.rej -x obj -x nvram -x mame.ini -x ChangeLog -x INDEX -x *.com -x *zlib* -x error.log -x *~ -r mame/src/windows/fileio.c mame-firefox/src/windows/fileio.c *** mame/src/windows/fileio.c Wed Dec 24 16:31:12 2003 --- mame-firefox/src/windows/fileio.c Sun Feb 15 11:27:26 2004 *************** *** 361,366 **** --- 361,371 ---- list = &pathlist[FILETYPE_ROM]; break; #endif + case FILETYPE_LASERDISK_FLAC: + case FILETYPE_LASERDISK_VIDEO: + case FILETYPE_LASERDISK_FRAME_SEEKS: + list=&pathlist[FILETYPE_ROM]; + break; default: list = &pathlist[filetype];