Package-Name: xmame
# Available options:
# -o displays=... -- set space-separated display methods to use
#                    (x11/SDL/svgalib); x11 and SDL are mutually exclusive.
#                    If not set, defaults to "SDL svgalib"
Requires: SDL|svgalib
Homepage: http://x.mame.net/
Source: http://x.mame.net/download.html/href="download\x2F(xmame-\d+(\.\d+)+\.tar\.bz2)/[\0-\377]*?xmame-(\d+(.\d+)+).tar.bz2 $1 http://x.mame.net/download/xmame-$1.tar.bz2
Zap-Before-Install: 1
Repack:
	bzcat "$(SOURCE)" | tar xvfp -
Compile:
	rm -rf "$(PREFIX)"/doc
	cp -pr src/unix/doc "$(PREFIX)/"
	rm -f "$(PREFIX)"/doc/*.6
	# Setting CFLAGS on the command line doesn't work (overrides extra flags in src/unix/unix.mak), so do it this way instead.
	perl -pi -e 's|^(include\s+src/unix/unix.mak)|CFLAGS=-pipe -O3 $(GCC_OPT_FLAGS) -ffast-math $(if $(DEBUG),,-fomit-frame-pointer)\n$$1|' makefile.unix
	set -e ; if [ -n "$(PKGOPT_displays)" ] ; then disptmp="$(PKGOPT_displays)" ; else disptmp="SDL svgalib" ; fi ; \
	disp_x11=0 ; disp_SDL=0 ; disp_svgalib=0 ; \
	for display in $$disptmp ; do \
		case $$display in \
			x11) disp_x11=1;; \
			SDL) disp_SDL=1;; \
			svgalib) disp_svgalib=1;; \
			*) echo >&2 "Invalid display list: only x11, SDL, and svgalib are valid"; exit 1;; \
		esac ; \
	done ; \
	if [ $$disp_x11 = 1 -a $$disp_SDL = 1 ] ; then \
		echo >&2 "Invalid display list: x11 and SDL cannot both be enabled" ; \
		exit 1 ; \
	fi ; \
	displays="" ; \
	if [ $$disp_x11 = 1 ] ; then displays="$$displays x11" ; fi ; \
	if [ $$disp_SDL = 1 ] ; then displays="$$displays SDL" ; fi ; \
	if [ $$disp_svgalib = 1 ] ; then displays="$$displays svgalib" ; fi ; \
	displays=`echo "x$$displays" | cut -c3-` ; \
	echo >&2 "Compiling for displays: $$displays" ; \
	for target in mame mess ; do \
		for display in $$displays ; do \
			if test $$display = x11 || packager c $$display ; then \
				echo "*** x$$target.$$display ***" ; \
				if [ $$display = SDL ] ; then JOY_SDL="JOY_SDL=1" ; else JOY_SDL="" ; fi ; \
				if [ $$target = mess -a $$display != svgalib ] ; then MAME_DEBUG="DEBUG=1" ; else MAME_DEBUG="" ; fi ; \
				mkdir -p doc ; \
				$(MAKE) -f makefile.unix all doc/x$${target}rc.dist doc/x$$target.6 install INSTALL=install PREFIX="$(PREFIX)" MANDIR="$(PREFIX)/man/man6" XMAMEROOT="$(PREFIX)/share/mame" TARGET=$$target DISPLAY_METHOD=$$display JOY_STANDARD=1 $$JOY_SDL $$MAME_DEBUG ; \
			fi ; \
		done ; \
	done
	mv -f doc/x*rc.dist "$(PREFIX)"/doc/
	if test -f "$(PREFIX)"/bin/xmame.svgalib ; then \
		mv -f "$(PREFIX)"/bin/xmame.svgalib "$(PREFIX)"/bin/smame ; \
		ln -fs xmame.6 "$(PREFIX)"/man/man6/smame.6 ; \
	else \
		rm -f "$(PREFIX)"/bin/smame "$(PREFIX)"/man/man6/smame.6 ; \
	fi
	if test -f "$(PREFIX)"/bin/xmame.SDL ; then \
		mv -f "$(PREFIX)"/bin/xmame.SDL "$(PREFIX)"/bin/xmame ; \
	elif test -f "$(PREFIX)"/bin/xmame.x11 ; then \
		mv -f "$(PREFIX)"/bin/xmame.x11 "$(PREFIX)"/bin/xmame ; \
	else \
		rm -f "$(PREFIX)"/bin/xmame ; \
	fi
	if test -f "$(PREFIX)"/bin/xmess.svgalib ; then \
		mv -f "$(PREFIX)"/bin/xmess.svgalib "$(PREFIX)"/bin/smess ; \
		ln -fs xmess.6 "$(PREFIX)"/man/man6/smess.6 ; \
	else \
		rm -f "$(PREFIX)"/bin/smess "$(PREFIX)"/man/man6/smess.6 ; \
	fi
	if test -f "$(PREFIX)"/bin/xmess.SDL ; then \
		mv -f "$(PREFIX)"/bin/xmess.SDL "$(PREFIX)"/bin/xmess ; \
	elif test -f "$(PREFIX)"/bin/xmessd.SDL ; then \
		mv -f "$(PREFIX)"/bin/xmessd.SDL "$(PREFIX)"/bin/xmess ; \
	elif test -f "$(PREFIX)"/bin/xmess.x11 ; then \
		mv -f "$(PREFIX)"/bin/xmess.x11 "$(PREFIX)"/bin/xmess ; \
	elif test -f "$(PREFIX)"/bin/xmessd.x11 ; then \
		mv -f "$(PREFIX)"/bin/xmessd.x11 "$(PREFIX)"/bin/xmess ; \
	else \
		rm -f "$(PREFIX)"/bin/xmess ; \
	fi
Install:
	rm -f /usr/bin/{s,x}{mame,mess} /usr/man/man6/{s,x}{mame,mess}.6.gz
	$(MAKE) instbin BIN="smame smess xmame xmess"
	$(MAKE) instman SECTION=6 MAN="smame smess xmame xmess"
Patch: <<EOT
######## begin -skip_disclaimer patch
--- ../xmame-0.106-orig/src/unix/config.c	2006-05-14 04:17:16 +0900
+++ src/unix/config.c	2006-10-07 22:30:42 +0900
@@ -85,6 +85,7 @@
 #endif
 	{ "language", "lang", rc_string, &language, "english", 0, 0, NULL, "Select the language for the menus and osd" },
 	{ "cheat", "c", rc_bool, &options.cheat, "0", 0, 0, NULL, "Enable/disable cheat subsystem" },
+	{ "skip_disclaimer", NULL, rc_bool, &options.skip_disclaimer, "0", 0, 0, NULL, "Skip displaying the disclaimer screen" },
 	{ "skip_gameinfo", NULL, rc_bool, &options.skip_gameinfo, "0", 0, 0, NULL, "Skip displaying the game info screen" },
 #ifdef MESS
 	{ "skip_warnings", NULL, rc_bool, &options.skip_warnings, "0", 0, 0, NULL, "Skip displaying the warnings screen" },
######## end -skip_disclaimer patch
######## begin game-screen-on-debug-window patch (local)
--- ../xmame-0.106-orig/src/unix/video-drivers/SDL.c	2006-05-24 07:44:34 +0900
+++ src/unix/video-drivers/SDL.c	2007-12-26 04:12:51 +0900
@@ -427,6 +427,7 @@
 
   video_mem = video_surface->pixels;
   video_mem += startx * video_surface->format->BytesPerPixel;
+/*AC*/ if(video_surface->w==640 && vis_in_dest_out->max_x==255) video_mem+=480*video_surface->pitch; else
   video_mem += starty * video_surface->pitch;
     
   blit_func(bitmap, vis_in_dest_out, dirty_area, palette, video_mem,
@@ -443,6 +444,7 @@
     drect.y = starty + vis_in_dest_out->min_y;
     drect.w = vis_in_dest_out->max_x - vis_in_dest_out->min_x;
     drect.h = vis_in_dest_out->max_y - vis_in_dest_out->min_y;
+/*AC*/ if(video_surface->w==640 && vis_in_dest_out->max_x==256) drect.y=480;
     SDL_UpdateRects(video_surface,1, &drect);
   }
   
--- ../xmame-0.106-orig/src/unix/video.c	2006-05-16 01:52:43 +0900
+++ src/unix/video.c	2007-12-26 04:12:51 +0900
@@ -553,9 +553,9 @@
 
 	/* setup debugger related stuff */
 	debug_params.width      = options.debug_width;
-	debug_params.height     = options.debug_height;
+	debug_params.height     = options.debug_height+240; /*AC*/
 	debug_params.max_width  = options.debug_width;
-	debug_params.max_height = options.debug_height;
+	debug_params.max_height = options.debug_height+240; /*AC*/
 
 	/* apply vis area override hacks */
 	if ((clone_of = driver_get_clone(drivers[game_index])) && !strcmp(clone_of->name, "megatech"))
@@ -879,6 +879,7 @@
 
 void change_debugger_focus(int new_debugger_focus)
 {
+/*AC*/ if(debugger_has_focus) return;
 	if (debugger_has_focus != new_debugger_focus)
 	{
 		debugger_has_focus = new_debugger_focus;
@@ -888,8 +889,10 @@
 						SYSDEP_DISPLAY_PROPERTIES_CHANGED) &&
 					normal_palette)
 			{
+#if 0 /*AC*/
 				sysdep_palette_destroy(normal_palette);
 				normal_palette = NULL;
+#endif
 			}
 		}
 		else
@@ -941,6 +944,12 @@
 	{
 		if (display->changed_flags & DEBUG_BITMAP_CHANGED)
 			update_debug_display(display);
+		{ /*AC*/
+			rectangle vis_area = game_vis_area;
+			msg = sysdep_display_update(display->game_bitmap,
+					&vis_area, &(display->game_bitmap_update),
+					normal_palette, display->led_state, flags);
+		}
 	}
 	else
 	{
######## end game-screen-on-debug-window patch (local)
EOT
NoPatch: <<EOT
######## begin sound boost removal patch
--- ../xmame-0.95-orig/mess/sound/nes_apu2.c	2005-03-13 11:33:32 +0900
+++ mess/sound/nes_apu2.c	2005-05-15 22:39:21 +0900
@@ -852,9 +852,6 @@
 			prev_sample = next_sample;
 		}
 
-		/* little extra kick for the kids */
-		accum <<= 1;
-
 		/* prevent clipping */
 		if (accum > 0x7FFF)
 		accum = 0x7FFF;
######## end sound boost removal patch
######## begin snapshot fix patch
diff -urN ../xmame-0.95-orig/src/vidhrdw/ppu2c03b.c src/vidhrdw/ppu2c03b.c
--- ../xmame-0.95-orig/src/vidhrdw/ppu2c03b.c	2005-03-29 13:20:14 +0900
+++ src/vidhrdw/ppu2c03b.c	2005-05-15 23:03:00 +0900
@@ -59,7 +59,8 @@
 	int						sprite_page;			/* current sprite page */
 	int						back_color;				/* background color */
 	UINT8					*ppu_page[4];			/* ppu pages */
-	int						nes_vram[8];			/* keep track of 8 .5k vram pages to speed things up */
+	UINT8					ppu_pagenum[4];			/* ppu page numbers (for save states) */
+	UINT32					nes_vram[8];			/* keep track of 8 .5k vram pages to speed things up */
 	int						scan_scale;				/* scan scale */
 	int						scanlines_per_frame;	/* number of scanlines per frame */
 } ppu2c03b_chip;
@@ -70,6 +71,8 @@
 /* chips state - allocated at init time */
 static ppu2c03b_chip *chips = 0;
 
+static void ppu2c03b_presave( void );
+static void ppu2c03b_postload( void );
 static void scanline_callback( int num );
 
 void (*ppu_latch)( offs_t offset );
@@ -269,12 +272,84 @@
 
 		/* setup our videoram handlers based on mirroring */
 		ppu2c03b_set_mirroring( i, intf->mirroring[i] );
-	}
+
+		/* state information to save */
+		state_save_register_UINT8( "ppu2c03b", i, "videoram", chips[i].videoram, VIDEORAM_SIZE );
+		state_save_register_UINT8( "ppu2c03b", i, "spriteram", chips[i].spriteram, SPRITERAM_SIZE );
+		state_save_register_UINT32( "ppu2c03b", i, "colortable_mono", chips[i].colortable_mono,
+		                           sizeof(default_colortable_mono)/sizeof(*default_colortable_mono) );
+		state_save_register_int( "ppu2c03b", i, "scanline", &chips[i].scanline );
+		state_save_register_int( "ppu2c03b", i, "reg_control0", &chips[i].regs[PPU_CONTROL0] );
+		state_save_register_int( "ppu2c03b", i, "reg_control1", &chips[i].regs[PPU_CONTROL1] );
+		state_save_register_int( "ppu2c03b", i, "reg_status", &chips[i].regs[PPU_STATUS] );
+		state_save_register_int( "ppu2c03b", i, "reg_sprite_address", &chips[i].regs[PPU_SPRITE_ADDRESS] );
+		state_save_register_int( "ppu2c03b", i, "reg_sprite_data", &chips[i].regs[PPU_SPRITE_DATA] );
+		state_save_register_int( "ppu2c03b", i, "reg_scroll", &chips[i].regs[PPU_SCROLL] );
+		state_save_register_int( "ppu2c03b", i, "reg_address", &chips[i].regs[PPU_ADDRESS] );
+		state_save_register_int( "ppu2c03b", i, "reg_data", &chips[i].regs[PPU_DATA] );
+		state_save_register_int( "ppu2c03b", i, "refresh_data", &chips[i].refresh_data );
+		state_save_register_int( "ppu2c03b", i, "refresh_latch", &chips[i].refresh_latch );
+		state_save_register_int( "ppu2c03b", i, "x_fine", &chips[i].x_fine );
+		state_save_register_int( "ppu2c03b", i, "toggle", &chips[i].toggle );
+		state_save_register_int( "ppu2c03b", i, "add", &chips[i].add );
+		state_save_register_int( "ppu2c03b", i, "videoram_addr", &chips[i].videoram_addr );
+		state_save_register_int( "ppu2c03b", i, "videoram_addr_latch", &chips[i].videoram_addr_latch );
+		state_save_register_int( "ppu2c03b", i, "videoram_data_latch", &chips[i].videoram_data_latch );
+		state_save_register_int( "ppu2c03b", i, "tile_page", &chips[i].tile_page );
+		state_save_register_int( "ppu2c03b", i, "sprite_page", &chips[i].sprite_page );
+		state_save_register_int( "ppu2c03b", i, "back_color", &chips[i].back_color );
+		state_save_register_UINT8( "ppu2c03b", i, "ppu_pagenum", chips[i].ppu_pagenum, 4 );
+		state_save_register_UINT32( "ppu2c03b", i, "nes_vram", chips[i].nes_vram, 8 );
+		state_save_register_int( "ppu2c03b", i, "scan_scale", &chips[i].scan_scale );
+		state_save_register_int( "ppu2c03b", i, "scanlines_per_frame", &chips[i].scanlines_per_frame );
+	}
+
+	/* register presave/postload functions */
+	state_save_register_func_presave(ppu2c03b_presave);
+	state_save_register_func_postload(ppu2c03b_postload);
 
 	/* success */
 	return 0;
 }
 
+static void ppu2c03b_presave( void )
+{
+	int i, j;
+	for( i = 0; i < intf->num; i++ )
+	{
+		/* store VRAM page numbers */
+		for( j = 0; j < 4; j++ ) {
+			int ofs = chips[i].ppu_page[j] - chips[i].videoram;
+			chips[i].ppu_pagenum[j] = (ofs & 0x0C00) >> 10;
+		}
+	}
+}
+
+static void ppu2c03b_postload( void )
+{
+	int i, j, save_vramaddr, save_add;
+	for( i = 0; i < intf->num; i++ )
+	{
+		/* set VRAM page pointers */
+		for( j = 0; j < 4; j++ ) {
+			int addr = 0x2000 | (chips[i].ppu_pagenum[j] << 10);
+			chips[i].ppu_page[j] = &(chips[i].videoram[addr]);
+		}
+		/* set dirty flags */
+		memset( chips[i].dirtychar, 1, CHARGEN_NUM_CHARS );
+		chips[i].chars_are_dirty = 1;
+		/* update colors */
+		save_vramaddr = chips[i].videoram_addr;
+		save_add = chips[i].add;
+		chips[i].videoram_addr = 0x3F00;
+		chips[i].add = 1;
+		for (j = 0; j < 0x20; j++)
+			ppu2c03b_w( i, PPU_DATA, chips[i].videoram[0x3F00|j] );
+		chips[i].videoram_addr = save_vramaddr;
+		chips[i].add = save_add;
+	}
+}
+
 static void draw_background( const int num, UINT8 *line_priority )
 {
 	/* cache some values locally */
diff -urN ../xmame-0.95-orig/mess/sound/nesintf.c mess/sound/nesintf.c
--- ../xmame-0.95-orig/mess/sound/nesintf.c	2005-03-13 11:33:32 +0900
+++ mess/sound/nesintf.c	2005-05-15 23:21:39 +0900
@@ -6,8 +6,15 @@
 #include "nesintf.h"
 #include "nes_apu2.h"
 
+#define NESPSG_NREGS 0x16
+
+/* for savestates */
+static UINT8 active[MAX_NESPSG];
+static UINT8 regs[MAX_NESPSG][NESPSG_NREGS];
+
 struct nes_sound
 {
+	int index;
 	apu_t *apu;
 	const struct NESinterface *intf;
 	sound_stream *stream;
@@ -42,6 +49,8 @@
 {
 	apu_t *apu;
 
+	if (offset < NESPSG_NREGS)
+		regs[0][offset] = data;
 	if (offset == 0x14) /* OAM DMA */
 	{
 		if (get_info(0)->intf->apu_callback_w)
@@ -64,6 +73,8 @@
 
 WRITE8_HANDLER(NESPSG_1_w)
 {
+	if (offset < NESPSG_NREGS)
+		regs[1][offset] = data;
 	if (offset == 0x14) /* OAM DMA */
 	{
 		if (get_info(1)->intf->apu_callback_w)
@@ -91,11 +102,51 @@
 
 
 
+static void NESPSG_postload(void)
+{
+	int i, j;
+	for (i = 0; i < MAX_NESPSG; i++) {
+		void (*writefunc)(offs_t offs, UINT8 data) = NULL;
+		if (i == 0)
+		    writefunc = NESPSG_0_w;
+		else if (i == 1)
+		    writefunc = NESPSG_1_w;
+		/* else segfault */
+		if (!active[i])
+			continue;
+		/* first turn off any current sound */
+		writefunc(0x15, 0);
+		for (i = 0; i < 0x14; i++)
+			writefunc(i, 0);
+		/* restore channel on/off status */
+		writefunc(0x15, regs[i][0x15]);
+		/* now fake writes to each channel's registers to actually
+		 * get the sound going */
+		/* FIXME: regs[] doesn't reflect the actual value after
+		 * period slide, etc... should save/load be done in the
+		 * actual APU code? */
+		for (j = 0; j < 0x14; j++)
+			writefunc(j, regs[i][j]);
+	}
+}
+
 static void *NESPSG_sh_start(int sndindex, int clock, const void *config)
 {
 	int sample_rate;
 	struct nes_sound *info;
 	const struct NESinterface *intf;
+	static int firsttime = 1;
+
+	if (firsttime)
+	{
+		int i;
+		for (i = 0; i < MAX_NESPSG; i++) {
+			state_save_register_UINT8("nes_apu", i, "active", &active[i], 1);
+			state_save_register_UINT8("nes_apu", i, "regs", regs[i], NESPSG_NREGS);
+		}
+		state_save_register_func_postload(NESPSG_postload);
+		firsttime = 0;
+	}
 
 	info = (struct nes_sound *) auto_malloc(sizeof(*info));
 	intf = (const struct NESinterface *) config;
@@ -109,6 +160,8 @@
 		return NULL;
 
 	info->intf = intf;
+	info->index = sndindex;
+	active[sndindex] = 1;
 
 	apu_setcontext(info->apu);
 	apu_reset();
@@ -129,6 +182,7 @@
 	struct nes_sound *info;
 	info = (struct nes_sound *) param;
 	apu_destroy(&info->apu);
+	active[info->index] = 0;
 }
 
 
######## end snapshot fix patch
EOT

/pkg/xmame/
/usr/bin/smame
/usr/bin/smess
/usr/bin/xmame
/usr/bin/xmess
/usr/man/man6/smame.6.gz
/usr/man/man6/smess.6.gz
/usr/man/man6/xmame.6.gz
/usr/man/man6/xmess.6.gz
