tuxnes-devel Mailing List for TuxNES (Page 15)
Brought to you by:
tmmm
You can subscribe to this list here.
2001 |
Jan
|
Feb
(18) |
Mar
(32) |
Apr
(61) |
May
(3) |
Jun
(8) |
Jul
(4) |
Aug
(50) |
Sep
(9) |
Oct
(3) |
Nov
|
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(12) |
Feb
(16) |
Mar
(13) |
Apr
(5) |
May
(14) |
Jun
(1) |
Jul
(5) |
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
|
2003 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(7) |
Dec
(24) |
2004 |
Jan
(23) |
Feb
(39) |
Mar
(8) |
Apr
|
May
(54) |
Jun
|
Jul
(20) |
Aug
(17) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2005 |
Jan
(4) |
Feb
(2) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
(3) |
2006 |
Jan
(3) |
Feb
(1) |
Mar
(5) |
Apr
(1) |
May
(6) |
Jun
(10) |
Jul
(8) |
Aug
(1) |
Sep
(2) |
Oct
(16) |
Nov
(18) |
Dec
(6) |
2007 |
Jan
(20) |
Feb
(9) |
Mar
(1) |
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
(13) |
Sep
(19) |
Oct
(6) |
Nov
(4) |
Dec
(3) |
2008 |
Jan
(3) |
Feb
(2) |
Mar
|
Apr
|
May
(1) |
Jun
(3) |
Jul
(4) |
Aug
(3) |
Sep
(13) |
Oct
(9) |
Nov
(28) |
Dec
(28) |
2009 |
Jan
(9) |
Feb
(14) |
Mar
(10) |
Apr
(24) |
May
(40) |
Jun
(23) |
Jul
(34) |
Aug
(7) |
Sep
(3) |
Oct
|
Nov
|
Dec
(11) |
2010 |
Jan
(7) |
Feb
(5) |
Mar
(3) |
Apr
|
May
(5) |
Jun
(5) |
Jul
(2) |
Aug
(2) |
Sep
|
Oct
(2) |
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Jeroen Ruigrok/a. <as...@wx...> - 2002-04-29 20:58:30
|
-On [20020429 19:39], Jason Short (jd...@us...) wrote: >A little bit of research makes me think that AM_PROG_AS is associated >with automake 1.5. I have: It is. And why can't you update? :) -- Jeroen Ruigrok van der Werven / asmodai / Kita no Mono as...@wx..., finger as...@ni... http://www.softweyr.com/asmodai/ | http://www.tendra.org/ Believe in Angels... |
From: Jason S. <jd...@us...> - 2002-04-29 17:35:27
|
Although I used to be able to compile TuxNES from CVS, I no longer can: [jdorje@localhost tuxnes]$ ./autogen.sh aclocal: configure.in: 43: macro `AM_PROG_AS' not found in library A little bit of research makes me think that AM_PROG_AS is associated with automake 1.5. I have: jdorje@localhost tuxnes]$ automake --version automake (GNU automake) 1.4-p5 Copyright (C) 1999, 2001 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Tom Tromey <tr...@cy...> [jdorje@localhost tuxnes]$ autoconf --version Autoconf version 2.13 [jdorje@localhost tuxnes]$ libtool --version ltmain.sh (GNU libtool) 1.4 (1.920 2001/04/24 23:26:18) I would play the release version, but it's over a year old now (!), and had a number of problems when last I tried it. jason short |
From: Mike M. <mel...@pc...> - 2002-04-28 19:37:26
|
On Sun, 28 Apr 2002, W. Michael Petullo wrote: > I just added an SDL audio player to TuxNES's CVS tree. This new audio > code is used when the sdl renderer is selected. It's a little noisy > and has some rough edges but the basics work. > > This is the last of my SDL additions. Now that TuxNES can use SDL to > render video, handle input, and play sound, it should be simple to port > TuxNES to any platform supported by SDL. Well, at least the UNIX-like > ones. UNIX-like, and x86-like platforms...:) Thanks for the contributions. -- -Mike Melanson |
From: W. M. P. <mi...@fl...> - 2002-04-28 15:49:31
|
I just added an SDL audio player to TuxNES's CVS tree. This new audio code is used when the sdl renderer is selected. It's a little noisy and has some rough edges but the basics work. This is the last of my SDL additions. Now that TuxNES can use SDL to render video, handle input, and play sound, it should be simple to port TuxNES to any platform supported by SDL. Well, at least the UNIX-like ones. Take care. -- Mike :wq |
From: W. M. P. <mi...@fl...> - 2002-04-01 18:07:28
|
I just checked some changes into CVS: 1. Added an SDL renderer that plays in full-screen mode. 2. Added a more portable, SDL-based joystick handler. This is currently used only by the SDL renderer. 3. Created a file of shared code, renderer_util.c, which cleans up the renderer code a lot. I would be interested to hear if change three broke the w or ggi renderers. Please let me know what you think. -- Mike :wq |
From: W. M. P. <mi...@fl...> - 2002-03-30 21:52:51
|
Enclosed you should find a patch to tuxnes that causes SDL to handle joystick input when the SDL renderer is chosen. Once I finish my next objective, SDL sound, it should be easy to port tuxnes to many different platforms. This patch requires my SDL patch, which I emailed to this mailing list a while ago. My SDL patch is also available at http://www.flyn.org. Please let me know what you think. Could the tuxnes SourceForge maintainers add the ability to submit patches using SourceForge? ================================================================================ diff -u --new-file --recursive tuxnes-0.75-sdl/Makefile.am tuxnes-0.75-sdl-js/Makefile.am --- tuxnes-0.75-sdl/Makefile.am Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-sdl-js/Makefile.am Wed Mar 27 19:56:26 2002 @@ -4,9 +4,9 @@ bin_SCRIPTS = romfixer noinst_PROGRAMS = comptbl -tuxnes_SOURCES = x86.S d6502.c dynrec.c emu.c fb.c gamegenie.c io.c mapper.c \ - sdl.c sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ - mapper.h renderer.c renderer.h ntsc_pal.c unzip.c unzip.h \ +tuxnes_SOURCES = x86.S d6502.c dynrec.c emu.c fb.c gamegenie.c io.c js.c \ + mapper.c sdl.c sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h \ + globals.h mapper.h renderer.c renderer.h ntsc_pal.c unzip.c unzip.h \ ziploader.c ziploader.h EXTRA_tuxnes_SOURCES = pixels.h tuxnes_LDADD = table.o diff -u --new-file --recursive tuxnes-0.75-sdl/configure.in tuxnes-0.75-sdl-js/configure.in --- tuxnes-0.75-sdl/configure.in Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-sdl-js/configure.in Fri Mar 29 21:04:35 2002 @@ -145,9 +145,10 @@ if test "x$with_sdl" != "xno"; then OCPPFLAGS="$CPPFLAGS" - CPPFLAGS="-I/usr/local/include" + CPPFLAGS="-I/usr/local/include -lpthread" AC_CHECK_HEADERS(SDL/SDL.h, CFLAGS="$CFLAGS -I/usr/local/include") AC_CHECK_LIB(SDL, SDL_Init) + AC_CHECK_LIB(pthread, pthread_create) CPPFLAGS="$OCPPFLAGS" fi diff -u --new-file --recursive tuxnes-0.75-sdl/emu.c tuxnes-0.75-sdl-js/emu.c --- tuxnes-0.75-sdl/emu.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75-sdl-js/emu.c Sat Mar 30 22:07:53 2002 @@ -26,9 +26,6 @@ #include <errno.h> #include <fcntl.h> #include <getopt.h> -#ifdef HAVE_LINUX_JOYSTICK_H -#include <linux/joystick.h> -#endif /* HAVE_LINUX_JOYSTICK_H */ #include <pwd.h> #include <signal.h> #include <stdio.h> @@ -77,10 +74,6 @@ int verbose = 0; /* joystick variables */ -unsigned char jsaxes[2] = {2, 2}; -unsigned char jsbuttons[2] = {2, 2}; -int jsfd[2] = {-1, -1}; -int jsversion[2] = {0x000800, 0x000800}; char *jsdevice[2] = {0, 0}; char *rendname = "auto"; @@ -1612,56 +1605,6 @@ } basefilename[baseend - basestart + 1] = '\0'; - /* initialize joysticks */ - { - int stick; - - for (stick = 0; stick < 2; stick ++) - { - if (jsdevice[stick]) - { -#ifdef HAVE_LINUX_JOYSTICK_H - if ((jsfd[stick] = open (jsdevice[stick], O_RDONLY)) < 0) - { - perror (jsdevice[stick]); - } - else - { - ioctl (jsfd[stick], JSIOCGVERSION, jsversion + stick); - ioctl (jsfd[stick], JSIOCGAXES, jsaxes + stick); - ioctl (jsfd[stick], JSIOCGBUTTONS, jsbuttons + stick); - fcntl (jsfd[stick], F_SETFL, O_NONBLOCK); /* set joystick to non-blocking */ - if( jsbuttons[stick] == 2 ) - { /* modify button map for a 2-button joystick */ - if( !js_usermapped2button[stick][0] ) - js_nesmaps[stick].button[0] = BUTTONB; - if( !js_usermapped2button[stick][1] ) - js_nesmaps[stick].button[1] = BUTTONA; - } - - if (verbose) - { - fprintf (stderr, - "Joystick %d (%s) has %d axes and %d buttons. Driver version is %d.%d.%d.\n", - stick + 1, - jsdevice[stick], - jsaxes[stick], - jsbuttons[stick], - jsversion[stick] >> 16, - (jsversion[stick] >> 8) & 0xff, - jsversion[stick] & 0xff); - } - } -#else - fprintf (stderr, - "Joystick support was disabled at compile-time. To enable it, make sure\n" - "you are running a recent version of the Linux kernel with the joystick\n" - "driver enabled, and install the header file <linux/joystick.h>.\n"); -#endif /* HAVE_LINUX_JOYSTICK_H */ - } - } - } - /* Select a sound sample format */ { struct SampleFormat *match = 0; @@ -2195,7 +2138,7 @@ renderer = match; } - /* Initialize graphic display */ + /* Initialize graphic display -- SDL needs to be initialized before js. */ if (renderer->InitDisplay (argc, argv)) { fprintf (stderr, @@ -2204,6 +2147,18 @@ exit (1); } + /* initialize joysticks */ + { + int stick; + for (stick = 0; stick < 2; stick ++) + { + if (jsdevice[stick] || ! strcmp ("sdl", renderer->name)) + { + renderer->InitJoystick(stick); + } + } + } + /* trap traps */ if (! disassemble) if ((oldtraphandler = signal (SIGTRAP, &traphandler)) == SIG_ERR) diff -u --new-file --recursive tuxnes-0.75-sdl/ggi.c tuxnes-0.75-sdl-js/ggi.c --- tuxnes-0.75-sdl/ggi.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75-sdl-js/ggi.c Wed Mar 27 20:03:22 2002 @@ -38,7 +38,6 @@ void quit(void); void START(void); void fbinit(void); -void HandleJoystickLinux(int); #ifdef HAVE_GGI #include <ggi/gii.h> @@ -1292,16 +1291,6 @@ do { struct timeval tv = { 0, 0 }; - /* Handle joystick input */ - if (jsfd[0] >= 0) - { - HandleJoystickLinux(0); - } - if (jsfd[1] >= 0) - { - HandleJoystickLinux(1); - } - /* Handle GGI input */ while (ggiEventPoll(visualGGI, emKeyPress | emKeyRelease, &tv)) { ggi_event ev; diff -u --new-file --recursive tuxnes-0.75-sdl/globals.h tuxnes-0.75-sdl-js/globals.h --- tuxnes-0.75-sdl/globals.h Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75-sdl-js/globals.h Sat Mar 30 21:43:31 2002 @@ -68,10 +68,6 @@ extern int *palette, *palette2; extern char *tuxnesdir; extern char *basefilename; /* filename without extension */ -extern unsigned char jsaxes[2]; -extern unsigned char jsbuttons[2]; -extern int jsfd[2]; -extern int jsversion[2]; extern char *jsdevice[2]; extern struct js_nesmap { unsigned char button[JS_MAX_BUTTONS]; diff -u --new-file --recursive tuxnes-0.75-sdl/io.c tuxnes-0.75-sdl-js/io.c --- tuxnes-0.75-sdl/io.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75-sdl-js/io.c Wed Mar 27 20:08:00 2002 @@ -502,6 +502,8 @@ last_clock = CLOCK; renderer->UpdateDisplay (); + renderer->HandleJoystick (0); + renderer->HandleJoystick (1); /*printf("donmi: stack at %x\n",STACKPTR); */ diff -u --new-file --recursive tuxnes-0.75-sdl/js.c tuxnes-0.75-sdl-js/js.c --- tuxnes-0.75-sdl/js.c Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75-sdl-js/js.c Sat Mar 30 22:09:28 2002 @@ -0,0 +1,409 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: This file handles joystick input. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_FEATURES_H +#include <features.h> +#endif /* HAVE_FEATRES_H */ + +#include <stdio.h> +#include <string.h> +#include "globals.h" +#include "renderer.h" + +#ifdef HAVE_LINUX_JOYSTICK_H +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <linux/joystick.h> +#endif /* HAVE_LINUX_JOYSTICK_H */ + +char jsaxes[2] = { 2, 2 }; +char jsbuttons[2] = { 2, 2 }; +int jsfd[2] = { -1, -1 }; +int jsversion[2] = { 0x000800, 0x000800 }; + +#ifdef HAVE_SDL +#include <SDL/SDL.h> + +SDL_Joystick *sdl_js; + +/* ============================ InitJoystickSDL () ========================= */ +void InitJoystickSDL(int stick) +{ + SDL_JoystickEventState(SDL_ENABLE); + if (! (sdl_js = SDL_JoystickOpen(stick))) + printf (stderr, "Error initializing joystick %d\n", stick);; +} + +/* ============================ handle_key () ============================== */ +static void handle_key(SDL_KeyboardEvent * ev) +{ + if (ev->keysym.sym == SDLK_ESCAPE) + exit(0); + /* the coin and dipswitch inputs work only in VS UniSystem mode */ + if (unisystem) + switch (ev->keysym.sym) { + case SDLK_LEFTBRACKET: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 1; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 1; + else + coinslot &= ~1; + break; + case SDLK_RIGHTBRACKET: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 2; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 2; + else + coinslot &= ~2; + break; + case SDLK_BACKSLASH: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 4; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 4; + else + coinslot &= ~4; + break; + case SDLK_q: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x01; + break; + case SDLK_w: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x02; + break; + case SDLK_e: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x04; + break; + case SDLK_r: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x08; + break; + case SDLK_t: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x10; + break; + case SDLK_y: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x20; + break; + case SDLK_u: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x40; + break; + case SDLK_i: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x80; + break; + default: + break; + } + switch (ev->keysym.sym) { + /* controller 1 keyboard mapping */ + case SDLK_RETURN: + case SDLK_KP_ENTER: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= STARTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= STARTBUTTON; + else + controller[0] &= ~STARTBUTTON; + break; + case SDLK_TAB: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= SELECTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= SELECTBUTTON; + else + controller[0] &= ~SELECTBUTTON; + break; + case SDLK_UP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= UP; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= UP; + else + controller[0] &= ~UP; + break; + case SDLK_DOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= DOWN; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= DOWN; + else + controller[0] &= ~DOWN; + break; + case SDLK_LEFT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= LEFT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= LEFT; + else + controller[0] &= ~LEFT; + break; + case SDLK_RIGHT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= RIGHT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= RIGHT; + else + controller[0] &= ~RIGHT; + break; + case SDLK_HOME: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | LEFT); + else + controllerd[0] &= ~(UP | LEFT); + break; + case SDLK_PAGEUP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | RIGHT); + else + controllerd[0] &= ~(UP | RIGHT); + break; + case SDLK_END: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | LEFT); + else + controllerd[0] &= ~(DOWN | LEFT); + break; + case SDLK_PAGEDOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | RIGHT); + else + controllerd[0] &= ~(DOWN | RIGHT); + break; + case SDLK_z: + case SDLK_x: + case SDLK_d: + case SDLK_INSERT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONB; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONB; + else + controller[0] &= ~BUTTONB; + break; + case SDLK_a: + case SDLK_c: + case SDLK_SPACE: + case SDLK_DELETE: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONA; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONA; + else + controller[0] &= ~BUTTONA; + break; + case SDLK_F7: + case SDLK_PRINT: + case SDLK_s: + SaveScreenshotSDL(); + break; + default: + break; + } +} + +/* ============================ HandleJoystickSDL () ======================= */ +void HandleJoystickSDL(int stick) +{ + /* Handles all input, actually. */ + SDL_Event event; + int axis_i; + while (SDL_PollEvent(&event)) { + switch (event.type) { + int nes_button; + case SDL_KEYDOWN: + case SDL_KEYUP: + handle_key(&event.key); + break; + case SDL_QUIT: + exit(0); + case SDL_JOYAXISMOTION: + /* Left-right movement */ + if (event.jaxis.value < -JS_IGNORE) { + js_axismeso[event.jaxis.axis] = + js_nesmaps[stick].axis[event.jaxis.axis].neg; + controller[stick] &= + ~js_nesmaps[stick].axis[event.jaxis.axis].pos; + } else if (event.jaxis.value > JS_IGNORE) { + js_axismeso[event.jaxis.axis] = + js_nesmaps[stick].axis[event.jaxis.axis].pos; + controller[stick] &= + ~js_nesmaps[stick].axis[event.jaxis.axis].neg; + } else { + js_axismeso[event.jaxis.axis] = 0; + controller[stick] &= + ~js_nesmaps[stick].axis[event.jaxis.axis].neg; + controller[stick] &= + ~js_nesmaps[stick].axis[event.jaxis.axis].pos; + } + for (axis_i = JS_MAX_AXES; --axis_i >= 0;) + controller[stick] |= js_axismeso[axis_i]; + break; + case SDL_JOYBUTTONDOWN: + nes_button = js_nesmaps[stick].button[event.jbutton.button]; + if (nes_button != PAUSEDISPLAY) { + controller[stick] |= nes_button; + } else { + renderer_data.pause_display = !renderer_data.pause_display; + desync = 1; + } + break; + case SDL_JOYBUTTONUP: + nes_button = js_nesmaps[stick].button[event.jbutton.button]; + if (nes_button != PAUSEDISPLAY) { + controller[stick] &= ~nes_button; + } else { + renderer_data.pause_display = !renderer_data.pause_display; + desync = 1; + } + break; + } + } +} +#endif /* HAVE_SDL */ + +/* ============================ InitJoystickLinux () ======================= */ +void InitJoystickLinux(int stick) +{ +#ifdef HAVE_LINUX_JOYSTICK_H + if ((jsfd[stick] = open(jsdevice[stick], O_RDONLY)) < 0) { + perror(jsdevice[stick]); + } else { + ioctl(jsfd[stick], JSIOCGVERSION, jsversion + stick); + ioctl(jsfd[stick], JSIOCGAXES, jsaxes + stick); + ioctl(jsfd[stick], JSIOCGBUTTONS, jsbuttons + stick); + fcntl(jsfd[stick], F_SETFL, O_NONBLOCK); /* set joystick to non-blocking */ + if (jsbuttons[stick] == 2) { /* modify button map for a 2-button joystick */ + if (!js_usermapped2button[stick][0]) + js_nesmaps[stick].button[0] = BUTTONB; + if (!js_usermapped2button[stick][1]) + js_nesmaps[stick].button[1] = BUTTONA; + } + if (verbose) { + fprintf(stderr, + "Joystick %d (%s) has %d axes and %d buttons. Driver version is %d.%d.%d.\n", + stick + 1, + jsdevice[stick], + jsaxes[stick], + jsbuttons[stick], + jsversion[stick] >> 16, + (jsversion[stick] >> 8) & 0xff, + jsversion[stick] & 0xff); + } + } +#else + fprintf(stderr, + "Joystick support was disabled at compile-time. To enable it, make sure\n" + "you are running a recent version of the Linux kernel with the joystick\n" + "driver enabled, and install the header file <linux/joystick.h>.\n"); +#endif /* HAVE_LINUX_JOYSTICK_H */ +} + +/* ============================ HandleJoystickLinux () ===================== */ +void HandleJoystickLinux(int stick) +{ +#ifdef HAVE_LINUX_JOYSTICK_H + struct js_event js; + int nes_button; + int axis_i; + while (read(jsfd[stick], &js, sizeof(struct js_event)) == + sizeof(struct js_event)) { + /* verbose joystick reporting */ +/* if (verbose) */ +/* { */ +/* fprintf (stderr, "%s: type %d number %d value %d\n", */ +/* jsdevice[stick], js.type, js.number, js.value); */ +/* } */ + switch (js.type) { + case 1: /* button report */ + nes_button = js_nesmaps[stick].button[js.number]; + printf("%d\n", js.number); + if (nes_button != PAUSEDISPLAY) { + if (js.value) + controller[stick] |= nes_button; + else + controller[stick] &= ~nes_button; + } else /* (nes_button == PAUSEDISPLAY) */ if (js.value) { + renderer_data.pause_display = !renderer_data.pause_display; + desync = 1; + } + break; + case 2: /* axis report */ + if (js.value < -JS_IGNORE) { + js_axismeso[js.number] = + js_nesmaps[stick].axis[js.number].neg; + controller[stick] &= + ~js_nesmaps[stick].axis[js.number].pos; + } else if (js.value > JS_IGNORE) { + js_axismeso[js.number] = + js_nesmaps[stick].axis[js.number].pos; + controller[stick] &= + ~js_nesmaps[stick].axis[js.number].neg; + } else { + js_axismeso[js.number] = 0; + controller[stick] &= + ~js_nesmaps[stick].axis[js.number].neg; + controller[stick] &= + ~js_nesmaps[stick].axis[js.number].pos; + } + for (axis_i = JS_MAX_AXES; --axis_i >= 0;) + controller[stick] |= js_axismeso[axis_i]; + break; + } + } + if (errno != EAGAIN) { + if (errno) { + perror(jsdevice[stick]); + } else { + fprintf(stderr, + "%s: device violates joystick protocol, disabling\n", + jsdevice[stick]); + close(jsfd[stick]); + jsfd[stick] = -1; + } + } +#endif /* HAVE_LINUX_JOYSTICK_H */ +} diff -u --new-file --recursive tuxnes-0.75-sdl/js.h tuxnes-0.75-sdl-js/js.h --- tuxnes-0.75-sdl/js.h Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75-sdl-js/js.h Wed Mar 27 20:17:06 2002 @@ -0,0 +1,28 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: This file handles joystick input. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_FEATURES_H +#include <features.h> +#endif /* HAVE_FEATRES_H */ + +#ifdef HAVE_LINUX_JOYSTICK_H +#include <linux/joystick.h> +#endif /* HAVE_LINUX_JOYSTICK_H */ + +#ifdef HAVE_SDL +void InitJoystickSDL(int stick); +void HandleJoystickSDL(int stick); +#endif /* HAVE_SDL */ + +void InitJoystickLinux(int stick); +void HandleJoystickLinux(int stick); diff -u --new-file --recursive tuxnes-0.75-sdl/renderer.c tuxnes-0.75-sdl-js/renderer.c --- tuxnes-0.75-sdl/renderer.c Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-sdl-js/renderer.c Fri Mar 29 21:02:50 2002 @@ -26,6 +26,7 @@ #include "mapper.h" #include "renderer.h" #include "sound.h" +#include "js.h" #ifdef HAVE_X extern int InitDisplayX11(int argc, char **argv); @@ -57,6 +58,8 @@ int InitDisplayNone(int argc, char **argv); void UpdateColorsNone(void); void UpdateDisplayNone(void); +void InitJoystickNone(int stick); +void HandleJoystickNone(int stick); /* imports */ extern void fbinit(void); @@ -67,36 +70,43 @@ #ifdef HAVE_X { "x11", "X11 renderer", 0, - InitDisplayX11, UpdateDisplayX11, UpdateColorsX11 }, + InitDisplayX11, UpdateDisplayX11, UpdateColorsX11, InitJoystickLinux, + HandleJoystickLinux }, { "diff", "differential X11 renderer", RENDERER_DIFF, - InitDisplayX11, UpdateDisplayX11, UpdateColorsX11 }, + InitDisplayX11, UpdateDisplayX11, UpdateColorsX11, InitJoystickLinux, + HandleJoystickLinux }, { "old", "old X11 renderer (tile-based)", RENDERER_OLD, - InitDisplayX11, UpdateDisplayOldX11, UpdateColorsX11 }, + InitDisplayX11, UpdateDisplayOldX11, UpdateColorsX11, InitJoystickLinux, + HandleJoystickLinux }, #endif /* HAVE_X */ #ifdef HAVE_SDL { "sdl", "SDL renderer", 0, - InitDisplaySDL, UpdateDisplaySDL, UpdateColorsSDL }, + InitDisplaySDL, UpdateDisplaySDL, UpdateColorsSDL, InitJoystickSDL, + HandleJoystickSDL }, #endif /* HAVE_SDL */ #ifdef HAVE_GGI { "ggi", "GGI renderer", 0, - InitDisplayGGI, UpdateDisplayGGI, UpdateColorsGGI }, + InitDisplayGGI, UpdateDisplayGGI, UpdateColorsGGI, InitJoystickLinux, + HandleJoystickLinux }, #endif /* HAVE_GGI */ #ifdef HAVE_W { "w", "W renderer", 0, - InitDisplayW, UpdateDisplayW, UpdateColorsW }, + InitDisplayW, UpdateDisplayW, UpdateColorsW, InitJoystickLinux, + HandleJoystickLinux }, #endif /* HAVE_W */ { "auto", "Choose one automatically", 0, - InitDisplayAuto, 0, 0 }, + InitDisplayAuto, 0, 0, 0, 0 }, { "none", "Don't draw anything", 0, - InitDisplayNone, UpdateDisplayNone, UpdateColorsNone }, - { 0, 0, 0, 0, 0, 0 } /* terminator */ + InitDisplayNone, UpdateDisplayNone, UpdateColorsNone, InitJoystickNone, + HandleJoystickNone }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* terminator */ }, *renderer = 0; struct RendererConfig renderer_config = { @@ -228,19 +238,6 @@ usleep (16666 * (frame - timeframe - 1)); } - /* Input loop */ - do { - /* Handle joystick input */ - if (jsfd[0] >= 0) - { - HandleJoystickLinux(0); - } - if (jsfd[1] >= 0) - { - HandleJoystickLinux(1); - } - } while (renderer_data.pause_display); - /* Check the time. If we're getting behind, skip next frame to stay in sync. */ gettimeofday (&time, NULL); timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ @@ -262,3 +259,15 @@ { /* no-op */ } + +void +InitJoystickNone(int stick) +{ + /* no-op */ +} + +void +HandleJoystickNone(int stick) +{ + /* no-op */ +} diff -u --new-file --recursive tuxnes-0.75-sdl/renderer.h tuxnes-0.75-sdl-js/renderer.h --- tuxnes-0.75-sdl/renderer.h Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-sdl-js/renderer.h Wed Mar 27 20:08:20 2002 @@ -50,6 +50,8 @@ int (*InitDisplay)(int argc, char **argv); void (*UpdateDisplay)(void); void (*UpdateColors)(void); + void (*InitJoystick)(int stick); + void (*HandleJoystick)(int stick); }; /* the currently selected renderer */ diff -u --new-file --recursive tuxnes-0.75-sdl/sdl.c tuxnes-0.75-sdl-js/sdl.c --- tuxnes-0.75-sdl/sdl.c Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-sdl-js/sdl.c Sat Mar 30 15:56:56 2002 @@ -85,7 +85,7 @@ /* ============================ SaveScreenshotSDL () ======================= */ -static void SaveScreenshotSDL(void) +void SaveScreenshotSDL(void) { int status; /* make sure we don't over-write screenshots written by a concurrent TuxNES process */ @@ -116,7 +116,7 @@ } bpp = BPP; bytes_per_line = 256 * magstep * BPP / 8; - if (SDL_Init(SDL_INIT_VIDEO) < 0) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); exit(1); } @@ -128,7 +128,7 @@ SDL_GetError()); exit(1); } - SDL_WM_ToggleFullScreen(screen); + //SDL_WM_ToggleFullScreen(screen); rfb = fb = screen->pixels; for (i = 0; i < 64; i++) { unsigned char r, g, b; @@ -144,212 +144,12 @@ return 0; } -/* ============================ handle_key () ============================== */ -static void handle_key(SDL_KeyboardEvent * ev) -{ - if (ev->keysym.sym == SDLK_ESCAPE) - exit(0); - - /* the coin and dipswitch inputs work only in VS UniSystem mode */ - if (unisystem) - switch (ev->keysym.sym) { - case SDLK_LEFTBRACKET: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - coinslot ^= 1; - } else if (ev->type == SDL_KEYDOWN) - coinslot |= 1; - else - coinslot &= ~1; - break; - case SDLK_RIGHTBRACKET: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - coinslot ^= 2; - } else if (ev->type == SDL_KEYDOWN) - coinslot |= 2; - else - coinslot &= ~2; - break; - case SDLK_BACKSLASH: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - coinslot ^= 4; - } else if (ev->type == SDL_KEYDOWN) - coinslot |= 4; - else - coinslot &= ~4; - break; - case SDLK_q: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x01; - break; - case SDLK_w: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x02; - break; - case SDLK_e: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x04; - break; - case SDLK_r: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x08; - break; - case SDLK_t: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x10; - break; - case SDLK_y: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x20; - break; - case SDLK_u: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x40; - break; - case SDLK_i: - if (ev->type == SDL_KEYDOWN) - dipswitches ^= 0x80; - break; - default: - break; - } - - switch (ev->keysym.sym) { - /* controller 1 keyboard mapping */ - case SDLK_RETURN: - case SDLK_KP_ENTER: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= STARTBUTTON; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= STARTBUTTON; - else - controller[0] &= ~STARTBUTTON; - break; - case SDLK_TAB: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= SELECTBUTTON; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= SELECTBUTTON; - else - controller[0] &= ~SELECTBUTTON; - break; - case SDLK_UP: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= UP; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= UP; - else - controller[0] &= ~UP; - break; - case SDLK_DOWN: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= DOWN; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= DOWN; - else - controller[0] &= ~DOWN; - break; - case SDLK_LEFT: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= LEFT; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= LEFT; - else - controller[0] &= ~LEFT; - break; - case SDLK_RIGHT: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= RIGHT; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= RIGHT; - else - controller[0] &= ~RIGHT; - break; - case SDLK_HOME: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controllerd[0] ^= (UP | LEFT); - } else if (ev->type == SDL_KEYDOWN) - controllerd[0] |= (UP | LEFT); - else - controllerd[0] &= ~(UP | LEFT); - break; - case SDLK_PAGEUP: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controllerd[0] ^= (UP | RIGHT); - } else if (ev->type == SDL_KEYDOWN) - controllerd[0] |= (UP | RIGHT); - else - controllerd[0] &= ~(UP | RIGHT); - break; - case SDLK_END: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controllerd[0] ^= (DOWN | LEFT); - } else if (ev->type == SDL_KEYDOWN) - controllerd[0] |= (DOWN | LEFT); - else - controllerd[0] &= ~(DOWN | LEFT); - break; - case SDLK_PAGEDOWN: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controllerd[0] ^= (DOWN | RIGHT); - } else if (ev->type == SDL_KEYDOWN) - controllerd[0] |= (DOWN | RIGHT); - else - controllerd[0] &= ~(DOWN | RIGHT); - break; - case SDLK_z: - case SDLK_x: - case SDLK_d: - case SDLK_INSERT: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= BUTTONB; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= BUTTONB; - else - controller[0] &= ~BUTTONB; - break; - case SDLK_a: - case SDLK_c: - case SDLK_SPACE: - case SDLK_DELETE: - if (renderer_config.sticky_keys) { - if (ev->type == SDL_KEYDOWN) - controller[0] ^= BUTTONA; - } else if (ev->type == SDL_KEYDOWN) - controller[0] |= BUTTONA; - else - controller[0] &= ~BUTTONA; - break; - case SDLK_F7: - case SDLK_PRINT: - case SDLK_s: - SaveScreenshotSDL(); - break; - default: - break; - } -} - /* ============================ UpdateDisplaySDL () ======================== */ void UpdateDisplaySDL(void) { struct timeval time; unsigned static int frame; unsigned int timeframe; - SDL_Event event; /* FIXME: Write SDL audio handler */ UpdateAudio(); gettimeofday(&time, NULL); @@ -374,25 +174,6 @@ if (frame > timeframe + 1 && frameskip == 0) { usleep(16666 * (frame - timeframe - 1)); } - - /* FIXME: write SDL handler */ - if (jsfd[0] >= 0) - HandleJoystickLinux(0); - - if (jsfd[1] >= 0) - HandleJoystickLinux(1); - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - handle_key(&event.key); - break; - case SDL_QUIT: - exit(0); - } - } - gettimeofday(&time, NULL); timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ if (halfspeed) diff -u --new-file --recursive tuxnes-0.75-sdl/w.c tuxnes-0.75-sdl-js/w.c --- tuxnes-0.75-sdl/w.c Wed Apr 11 23:45:48 2001 +++ tuxnes-0.75-sdl-js/w.c Wed Mar 27 20:03:56 2002 @@ -45,7 +45,6 @@ void quit(void); void START(void); void fbinit(void); -void HandleJoystickLinux(int); #ifdef HAVE_W #include <Wlib.h> @@ -1082,16 +1081,6 @@ do { WEVENT *ev; - /* Handle joystick input */ - if (jsfd[0] >= 0) - { - HandleJoystickLinux(0); - } - if (jsfd[1] >= 0) - { - HandleJoystickLinux(1); - } - /* Handle W input */ while ((ev = w_queryevent (0, 0, 0, 0))) { switch (ev -> type) diff -u --new-file --recursive tuxnes-0.75-sdl/x11.c tuxnes-0.75-sdl-js/x11.c --- tuxnes-0.75-sdl/x11.c Wed Apr 11 23:45:48 2001 +++ tuxnes-0.75-sdl-js/x11.c Wed Mar 27 20:32:53 2002 @@ -37,15 +37,12 @@ #include <endian.h> #endif -#ifdef HAVE_LINUX_JOYSTICK_H -#include <linux/joystick.h> -#endif /* HAVE_LINUX_JOYSTICK_H */ - #include "consts.h" #include "globals.h" #include "mapper.h" #include "renderer.h" #include "sound.h" +#include "js.h" #ifdef HAVE_X @@ -122,9 +119,6 @@ unsigned char redrawall = 1; /* Redraw all scanlines */ unsigned char palette_cache[tilecachedepth][32]; -/* imports */ -void HandleJoystickLinux(int); - #ifdef HAVE_X /* exported functions */ @@ -841,85 +835,6 @@ fbinit (); return 0; } -#endif /* HAVE_X */ - -void -HandleJoystickLinux(int stick) -{ -#ifdef HAVE_LINUX_JOYSTICK_H - struct js_event js; - int nes_button; - int axis_i; - - while (read (jsfd[stick], &js, sizeof (struct js_event)) == - sizeof (struct js_event)) - { - /* verbose joystick reporting */ -/* if (verbose) */ -/* { */ -/* fprintf (stderr, "%s: type %d number %d value %d\n", */ -/* jsdevice[stick], js.type, js.number, js.value); */ -/* } */ - - switch (js.type) - { - case 1: /* button report */ - nes_button = js_nesmaps[stick].button[js.number]; - if( nes_button != PAUSEDISPLAY ) - { - if( js.value ) - controller[stick] |= nes_button; - else - controller[stick] &= ~nes_button; - } - else /* (nes_button == PAUSEDISPLAY) */ - if( js.value ) - { - renderer_data.pause_display = ! renderer_data.pause_display; - desync = 1; - } - break; - case 2: /* axis report */ - if (js.value < -JS_IGNORE) - { - js_axismeso[js.number] = js_nesmaps[stick].axis[js.number].neg; - controller[stick] &= ~js_nesmaps[stick].axis[js.number].pos; - } - else if (js.value > JS_IGNORE) - { - js_axismeso[js.number] = js_nesmaps[stick].axis[js.number].pos; - controller[stick] &= ~js_nesmaps[stick].axis[js.number].neg; - } - else - { - js_axismeso[js.number] = 0; - controller[stick] &= ~js_nesmaps[stick].axis[js.number].neg; - controller[stick] &= ~js_nesmaps[stick].axis[js.number].pos; - } - for( axis_i = JS_MAX_AXES; --axis_i >= 0; ) - controller[stick] |= js_axismeso[axis_i]; - break; - } - } - - if (errno != EAGAIN) - { - if (errno) - { - perror (jsdevice[stick]); - } - else - { - fprintf (stderr, "%s: device violates joystick protocol, disabling\n", - jsdevice[stick]); - close (jsfd[stick]); - jsfd[stick] = -1; - } - } -#endif /* HAVE_LINUX_JOYSTICK_H */ -} - -#ifdef HAVE_X void HandleKeyboardX11(XEvent ev) @@ -1588,16 +1503,6 @@ /* Input loop */ do { - /* Handle joystick input */ - if (jsfd[0] >= 0) - { - HandleJoystickLinux(0); - } - if (jsfd[1] >= 0) - { - HandleJoystickLinux(1); - } - /* Handle X input */ while (XPending (display) || ev.type == -1) { @@ -1782,16 +1687,6 @@ /* Input loop */ do { - /* Handle joystick input */ - if (jsfd[0] >= 0) - { - HandleJoystickLinux(0); - } - if (jsfd[1] >= 0) - { - HandleJoystickLinux(1); - } - /* Handle X input */ while (XPending (display) || ev.type == -1) { ================================================================================ -- Mike :wq |
From: W. M. P. <mi...@fl...> - 2002-03-24 17:00:15
|
Enclosed you should find a patch to TuxNES 0.75 that attempts to share code between renderers at bit more. It adds a file named renderer_util.c that is a collection of functions used by the renderers. This patch requires my SDL patch, which I emailed to this mailing list a few days ago. My SDL patch is also available at http://www.flyn.org. I have not tested the trivial changes to w.c and ggi.c, as I do not use these systems. Please let me know what you think. ================================================================================ diff -u --new-file --recursive tuxnes-0.75-sdl/Makefile.am tuxnes-0.75-codeshare/Makefile.am --- tuxnes-0.75-sdl/Makefile.am Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-codeshare/Makefile.am Sun Mar 24 16:28:43 2002 @@ -6,8 +6,8 @@ tuxnes_SOURCES = x86.S d6502.c dynrec.c emu.c fb.c gamegenie.c io.c mapper.c \ sdl.c sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ - mapper.h renderer.c renderer.h ntsc_pal.c unzip.c unzip.h \ - ziploader.c ziploader.h + mapper.h renderer.c renderer.h renderer_util.c ntsc_pal.c unzip.c \ + unzip.h ziploader.c ziploader.h EXTRA_tuxnes_SOURCES = pixels.h tuxnes_LDADD = table.o diff -u --new-file --recursive tuxnes-0.75-sdl/ggi.c tuxnes-0.75-codeshare/ggi.c --- tuxnes-0.75-sdl/ggi.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75-codeshare/ggi.c Sun Mar 24 17:31:06 2002 @@ -20,8 +20,6 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> -#include <sys/time.h> -#include <dirent.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -1047,8 +1045,7 @@ ggiFillscreen (visualGGI); ggiSetGCForeground (visualGGI, whitepixel); ggiFlush (visualGGI); - gettimeofday (&time, NULL); - renderer_data.basetime = time.tv_sec; + set_renderer_basetime(); return 0; } @@ -1145,24 +1142,7 @@ /* do audio update */ UpdateAudio(); - - /* Check the time. If we're getting behind, skip a frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ - + set_timeframe(&frame, &timeframe, &desync); if (! nodisplay) { drawimage (PBL); @@ -1281,13 +1261,7 @@ needsredraw = 0; redrawbackground = 0; redrawall = 0; - - /* Slow down if we're getting ahead */ - if (frame > timeframe + 1 && frameskip == 0) - { - usleep (16666 * (frame - timeframe - 1)); - } - + resynchronize(frame, timeframe, frameskip); /* Input loop */ do { struct timeval tv = { 0, 0 }; @@ -1310,20 +1284,7 @@ HandleKeyboardGGI (ev); } } while (renderer_data.pause_display); - - /* Check the time. If we're getting behind, skip next frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (frame >= timeframe || frame % 20 == 0) - frameskip = 0; - else - frameskip = 1; + set_frameskip (frame, &timeframe, &frameskip); } #endif diff -u --new-file --recursive tuxnes-0.75-sdl/renderer.c tuxnes-0.75-codeshare/renderer.c --- tuxnes-0.75-sdl/renderer.c Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-codeshare/renderer.c Sun Mar 24 17:29:49 2002 @@ -204,24 +204,7 @@ /* do audio update */ UpdateAudio(); - - /* Check the time. If we're getting behind, skip a frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ - + set_timeframe(&frame, &timeframe, &desync); /* Slow down if we're getting ahead */ if (frame > timeframe + 1 && frameskip == 0) { @@ -240,20 +223,7 @@ HandleJoystickLinux(1); } } while (renderer_data.pause_display); - - /* Check the time. If we're getting behind, skip next frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (frame >= timeframe || frame % 20 == 0) - frameskip = 0; - else - frameskip = 1; + set_frameskip (frame, &timeframe, &frameskip); } /* Update the colors on the screen if the palette changed */ diff -u --new-file --recursive tuxnes-0.75-sdl/renderer_util.c tuxnes-0.75-codeshare/renderer_util.c --- tuxnes-0.75-sdl/renderer_util.c Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75-codeshare/renderer_util.c Sun Mar 24 17:27:28 2002 @@ -0,0 +1,130 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: Shared code used by all of the tuxnes renderers. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <dirent.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <globals.h> +#include <stdio.h> +#include <sys/time.h> +#include <renderer.h> +#include <unistd.h> + +/* ============================ screenshot_init () ========================= */ +void screenshot_init(char *ext, char **ssfile, int *ssnumber) +{ + DIR *dir; + struct dirent *dirp; + int currentnumber = 0; + /* Allocate space for (tuxnesdir) + (basefilename-snap-xxxx.ext) + ('\0') */ + if ((*ssfile = (char *) malloc(strlen(tuxnesdir) + + strlen(basefilename) + 1 + 4 + + 1 + 4 + 1 + 3 + 1)) == NULL) { + perror("malloc"); + exit(1); + } + sprintf(*ssfile, "%s-snap-", basefilename); + /* open the screenshot directory */ + if ((dir = opendir(tuxnesdir)) == NULL) { + return; + } + /* iterate through the files and establish the starting screenshot number */ + while ((dirp = readdir(dir)) != NULL) { + if ((strlen(dirp->d_name) >= 8) + && (strncmp(dirp->d_name, *ssfile, strlen(*ssfile)) + == 0) + && + (strncmp + (dirp->d_name + strlen(dirp->d_name) - 4, ext, + strlen(ext)) == 0)) { + dirp->d_name[strlen(dirp->d_name) - 4] = '\0'; + if ((currentnumber = + atoi(dirp->d_name + strlen(*ssfile))) > *ssnumber) { + *ssnumber = currentnumber; + } + } + } + if (++*ssnumber > 9999) { + *ssnumber = 0; + } + closedir(dir); +} + +/* ============================ screenshot_check_filename () =============== */ +void screenshot_check_filename(char *ext, char *ssfile, int *ssnumber) +{ + /* make sure we don't over-write screenshots written by a concurrent TuxNES process */ + { + struct stat buf[1]; + do + sprintf(ssfile, "%s%s-snap-%04u%s", tuxnesdir, + basefilename, *ssnumber++, ext); + while ((!stat(ssfile, buf)) && !(*ssnumber > 9999)); + } + if (*ssnumber > 9999) + *ssnumber = 0; +} + +/* ============================ set_renderer_basetime () =================== */ +void set_renderer_basetime(void) +{ + struct timeval time; + gettimeofday(&time, NULL); + renderer_data.basetime = time.tv_sec; +} + +/* ============================ set_frameskip () =========================== */ +void set_frameskip(int frame, int *timeframe, int *frameskip) +{ + struct timeval time; + gettimeofday(&time, NULL); + *timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + if (halfspeed) + *timeframe >>= 1; + if (doublespeed == 2) + *timeframe <<= 1; + else if (doublespeed > 2) + *timeframe *= doublespeed; + if (frame >= *timeframe || frame % 20 == 0) + *frameskip = 0; + else + *frameskip = 1; + +} + +/* ============================ set_timeframe () =========================== */ +void set_timeframe(int *frame, int *timeframe, int *desync) +{ + struct timeval time; + gettimeofday(&time, NULL); + *timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ + *timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + (*frame)++; + if (halfspeed) + *timeframe >>= 1; + if (doublespeed > 1) + *timeframe *= doublespeed; + if (*desync) + *frame = *timeframe; + *desync = 0; + if (*frame < *timeframe - 20 && *frame % 20 == 0) + *desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ +} + +/* ============================ resynchronize () =========================== */ +void resynchronize(int frame, int timeframe, int frameskip) +{ + if (frame > timeframe + 1 && frameskip == 0) + usleep(16666 * (frame - timeframe - 1)); +} diff -u --new-file --recursive tuxnes-0.75-sdl/renderer_util.h tuxnes-0.75-codeshare/renderer_util.h --- tuxnes-0.75-sdl/renderer_util.h Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75-codeshare/renderer_util.h Sun Mar 24 17:27:57 2002 @@ -0,0 +1,31 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: Shared code used by all of the tuxnes renderers. + */ + +#ifndef _RENDERER_UTIL_H +#define _RENDERER_UTIL_H + +/* ============================ screenshot_init () ========================= */ +void screenshot_init(char *ext, char **ssfile, int *ssnumber); + +/* ============================ screenshot_check_filename () =============== */ +void screenshot_check_filename(char *ext, char *ssfile, int *ssnumber); + +/* ============================ set_renderer_basetime () =================== */ +void set_renderer_basetime(void); + +/* ============================ set_frameskip () =========================== */ +void set_frameskip(int frame, int *timeframe, int *frameskip); + +/* ============================ set_timeframe () =========================== */ +void set_timeframe(int *frame, int *timeframe, int *desync); + +/* ============================ resynchronize () =========================== */ +void resynchronize (int frame, int timeframe, int frameskip); + +#endif /* RENDERER_UTIL_H */ diff -u --new-file --recursive tuxnes-0.75-sdl/sdl.c tuxnes-0.75-codeshare/sdl.c --- tuxnes-0.75-sdl/sdl.c Sun Mar 24 17:34:31 2002 +++ tuxnes-0.75-codeshare/sdl.c Sun Mar 24 17:31:39 2002 @@ -19,6 +19,7 @@ #include "globals.h" #include "mapper.h" #include "renderer.h" +#include "renderer_util.h" #include "sound.h" #ifdef HAVE_SDL @@ -27,12 +28,8 @@ #include <SDL/SDL_endian.h> #include <stdlib.h> #include <string.h> -#include <sys/time.h> #include <unistd.h> -/* FIXME: Share with x11.c, w.c, etc. */ -#include <dirent.h> -#include <sys/stat.h> char *screenshotfile; static int screenshotnumber = 0; @@ -41,64 +38,10 @@ SDL_Surface *screen; unsigned int paletteSDL[64]; -/* ============================ InitScreenshotSDL () ======================= */ -static void InitScreenshotSDL(void) -{ - DIR *dir; - struct dirent *dirp; - int currentnumber = 0; - /* Allocate space for (tuxnesdir) + (basefilename-snap-xxxx.bmp) + ('\0') */ - if ((screenshotfile = (char *) malloc(strlen(tuxnesdir) + - strlen(basefilename) + 1 + 4 + - 1 + 4 + 1 + 3 + 1)) == NULL) { - perror("malloc"); - exit(1); - } - sprintf(screenshotfile, "%s-snap-", basefilename); - /* open the screenshot directory */ - if ((dir = opendir(tuxnesdir)) == NULL) { - return; - } - /* iterate through the files and establish the starting screenshot number */ - while ((dirp = readdir(dir)) != NULL) { - if ((strlen(dirp->d_name) >= 8) - && - (strncmp(dirp->d_name, screenshotfile, strlen(screenshotfile)) - == 0) - && - (strncmp - (dirp->d_name + strlen(dirp->d_name) - 4, ".bmp", - strlen(".bmp")) == 0)) { - dirp->d_name[strlen(dirp->d_name) - 4] = '\0'; - if ((currentnumber = - atoi(dirp->d_name + strlen(screenshotfile))) > - screenshotnumber) { - screenshotnumber = currentnumber; - } - } - } - if (++screenshotnumber > 9999) { - screenshotnumber = 0; - } - closedir(dir); -} - - /* ============================ SaveScreenshotSDL () ======================= */ static void SaveScreenshotSDL(void) { - int status; - /* make sure we don't over-write screenshots written by a concurrent TuxNES process */ - { - struct stat buf[1]; - do - sprintf(screenshotfile, "%s%s-snap-%04u.bmp", tuxnesdir, - basefilename, screenshotnumber++); - while ((!stat(screenshotfile, buf)) && !(screenshotnumber > 9999)); - } - if (screenshotnumber > 9999) { - screenshotnumber = 0; - } + screenshot_check_filename (".bmp", screenshotfile, &screenshotnumber); SDL_SaveBMP(screen, screenshotfile); } @@ -106,7 +49,6 @@ int InitDisplaySDL(int argc, char **argv) { int i; - struct timeval time; if (magstep < 1) magstep = 1; if (magstep > maxsize) { @@ -128,7 +70,7 @@ SDL_GetError()); exit(1); } - SDL_WM_ToggleFullScreen(screen); + //SDL_WM_ToggleFullScreen(screen); rfb = fb = screen->pixels; for (i = 0; i < 64; i++) { unsigned char r, g, b; @@ -138,9 +80,8 @@ paletteSDL[i] = (r << 11) | (g << 5) | (b); } fbinit(); - InitScreenshotSDL(); - gettimeofday(&time, NULL); - renderer_data.basetime = time.tv_sec; + screenshot_init(".bmp", &screenshotfile, &screenshotnumber); + set_renderer_basetime(); return 0; } @@ -346,34 +287,18 @@ /* ============================ UpdateDisplaySDL () ======================== */ void UpdateDisplaySDL(void) { - struct timeval time; unsigned static int frame; unsigned int timeframe; SDL_Event event; /* FIXME: Write SDL audio handler */ UpdateAudio(); - gettimeofday(&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ + + set_timeframe(&frame, &timeframe, &desync); drawimage(PBL); if (!frameskip) { SDL_UpdateRect(screen, 0, 0, 0, 0); } - if (frame > timeframe + 1 && frameskip == 0) { - usleep(16666 * (frame - timeframe - 1)); - } + resynchronize(frame, timeframe, frameskip); /* FIXME: write SDL handler */ if (jsfd[0] >= 0) @@ -392,19 +317,7 @@ exit(0); } } - - gettimeofday(&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (frame >= timeframe || frame % 20 == 0) - frameskip = 0; - else - frameskip = 1; + set_frameskip (frame, &timeframe, &frameskip); } /* ============================ UpdateColorsSDL () ========================= */ diff -u --new-file --recursive tuxnes-0.75-sdl/w.c tuxnes-0.75-codeshare/w.c --- tuxnes-0.75-sdl/w.c Wed Apr 11 23:45:48 2001 +++ tuxnes-0.75-codeshare/w.c Sun Mar 24 17:31:04 2002 @@ -20,8 +20,6 @@ #include <sys/stat.h> #include <sys/types.h> -#include <sys/time.h> -#include <dirent.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> @@ -606,7 +604,6 @@ { int x; rgb_t color; - struct timeval time; if (magstep < 1) { magstep = 1; @@ -930,8 +927,7 @@ scanlines = old_scanlines; } w_flush (); - gettimeofday (&time, NULL); - renderer_data.basetime = time.tv_sec; + set_renderer_basetime(); return 0; } @@ -1029,31 +1025,13 @@ void UpdateDisplayW(void) { - struct timeval time; unsigned static int frame; unsigned int timeframe; static int nodisplay = 0; /* do audio update */ UpdateAudio(); - - /* Check the time. If we're getting behind, skip a frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ - + set_timeframe(&frame, &timeframe, &desync); if (! nodisplay) { drawimage (PBL); @@ -1071,13 +1049,7 @@ needsredraw = 0; redrawbackground = 0; redrawall = 0; - - /* Slow down if we're getting ahead */ - if (frame > timeframe + 1 && frameskip == 0) - { - usleep (16666 * (frame - timeframe - 1)); - } - + resynchronize(frame, timeframe, frameskip); /* Input loop */ do { WEVENT *ev; @@ -1142,20 +1114,7 @@ } } } while (renderer_data.pause_display); - - /* Check the time. If we're getting behind, skip next frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (frame >= timeframe || frame % 20 == 0) - frameskip = 0; - else - frameskip = 1; + set_frameskip (frame, &timeframe, &frameskip); } #endif diff -u --new-file --recursive tuxnes-0.75-sdl/x11.c tuxnes-0.75-codeshare/x11.c --- tuxnes-0.75-sdl/x11.c Wed Apr 11 23:45:48 2001 +++ tuxnes-0.75-codeshare/x11.c Sun Mar 24 17:31:27 2002 @@ -20,15 +20,14 @@ #include <sys/stat.h> #include <sys/types.h> -#include <sys/time.h> #include <sys/wait.h> -#include <dirent.h> #include <errno.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <renderer_util.h> #if defined(__FreeBSD__) #include <machine/endian.h> #elif defined(__NetBSD__) || defined(__OpenBSD__) @@ -181,7 +180,6 @@ void fbinit(void); void quit(void); void START(void); -static void InitScreenshotX11(void); static void SaveScreenshotX11(void); static void DiffUpdateOldX11(void); static void DoBackgroundOldX11(void); @@ -258,71 +256,11 @@ #endif void -InitScreenshotX11(void) -{ - DIR *dir; - struct dirent *dirp; - int currentnumber = 0; - - /* Allocate space for (tuxnesdir) + (basefilename-snap-xxxx.xpm) + ('\0') */ - if ((screenshotfile = (char *) malloc (strlen (tuxnesdir) + - strlen (basefilename) + 1 + 4 + 1 + 4 + 1 + 3 + 1)) == NULL) - { - perror ("malloc"); - exit (1); - } - sprintf(screenshotfile, "%s-snap-", basefilename); - - /* open the screenshot directory */ - if ((dir = opendir (tuxnesdir)) == NULL) - { - return; - } - - /* iterate through the files and establish the starting screenshot number */ - while ((dirp = readdir (dir)) != NULL) - { - if ((strlen(dirp->d_name) >= 8) - && (strncmp (dirp->d_name, screenshotfile, strlen (screenshotfile)) == 0) - && (strncmp (dirp->d_name + strlen (dirp->d_name) - 4, ".xpm", - strlen (".xpm")) == 0)) - { - dirp->d_name[strlen (dirp->d_name) - 4] = '\0'; - if ((currentnumber = atoi (dirp->d_name + strlen (screenshotfile))) > - screenshotnumber) - { - screenshotnumber = currentnumber; - } - } - } - - if (++screenshotnumber > 9999) - { - screenshotnumber = 0; - } - - closedir (dir); -} - -void SaveScreenshotX11(void) { int status; - /* make sure we don't over-write screenshots written by a concurrent TuxNES process */ - { - struct stat buf[1]; - - do - sprintf (screenshotfile, "%s%s-snap-%04u.xpm", tuxnesdir, basefilename, - screenshotnumber ++); - while ((! stat (screenshotfile, buf)) && ! (screenshotnumber > 9999)); - } - - if (screenshotnumber > 9999) - { - screenshotnumber = 0; - } + screenshot_check_filename (".xpm", screenshotfile, &screenshotnumber); #ifdef HAVE_XPM if (renderer->_flags & RENDERER_OLD) { @@ -394,7 +332,6 @@ int x, y; int geometry_mask; int border; - struct timeval time; char *wname[] = { PRETTY_NAME, PACKAGE @@ -709,8 +646,7 @@ for (y = 0; y < tilecachedepth; y++) for (x = 0; x < 256; x++) tiledirty[y][x] = 1; - gettimeofday (&time, NULL); - renderer_data.basetime = time.tv_sec; + set_renderer_basetime(); layout = XCreatePixmap (display, w, 256 * magstep, 240 * magstep, depth); #ifdef HAVE_SHM @@ -837,7 +773,7 @@ XFillRectangle (display, w, blackgc, 0, 0, width, height); - InitScreenshotX11 (); + screenshot_init(".xpm", &screenshotfile, &screenshotnumber); fbinit (); return 0; } @@ -1405,7 +1341,6 @@ UpdateDisplayX11(void) { static XEvent ev; - struct timeval time; unsigned static int frame; unsigned int timeframe; static int sleep = 0; /* Initially we start with the emulation running. If you want to wait until the window receives input focus, change this. */ @@ -1413,24 +1348,7 @@ /* do audio update */ UpdateAudio(); - - /* Check the time. If we're getting behind, skip a frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ - + set_timeframe(&frame, &timeframe, &desync); if (! nodisplay) { drawimage (PBL); @@ -1579,13 +1497,7 @@ redrawall = needsredraw = 0; } } - - /* Slow down if we're getting ahead */ - if (frame > timeframe + 1 && frameskip == 0) - { - usleep (16666 * (frame - timeframe - 1)); - } - + resynchronize(frame, timeframe, frameskip); /* Input loop */ do { /* Handle joystick input */ @@ -1694,20 +1606,7 @@ needsredraw = 0; redrawbackground = 0; redrawall = 0; - - /* Check the time. If we're getting behind, skip next frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (frame >= timeframe || frame % 20 == 0) - frameskip = 0; - else - frameskip = 1; + set_frameskip (frame, &timeframe, &frameskip); } /* @@ -1729,7 +1628,6 @@ UpdateDisplayOldX11(void) { static XEvent ev; - struct timeval time; unsigned static int frame; unsigned int timeframe; static int sleep = 0; /* Initially we start with the emulation running. If you want to wait until the window receives input focus, change this. */ @@ -1737,24 +1635,7 @@ /* do audio update */ UpdateAudio(); - - /* Check the time. If we're getting behind, skip a frame to stay in sync. */ - gettimeofday (&time, NULL); - timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ - timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ - frame++; - if (halfspeed) - timeframe >>= 1; - if (doublespeed == 2) - timeframe <<= 1; - else if (doublespeed > 2) - timeframe *= doublespeed; - if (desync) - frame = timeframe; - desync = 0; - if (frame < timeframe - 20 && frame % 20 == 0) - desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ - + set_timeframe(&frame, &timeframe, &desync); if (! nodisplay) { if (frame >= timeframe || frame % 20 == 0) @@ -1773,13 +1654,7 @@ DrawSpritesOldX11(); } } - - /* Slow down if we're getting ahead */ - if (frame > timeframe + 1) - { - usleep (16666 * (frame - timeframe - 1)); - } - + resynchronize(frame, timeframe, frameskip); /* Input loop */ do { /* Handle joystick input */ ================================================================================ -- Mike :wq |
From: W. M. P. <mi...@fl...> - 2002-03-23 15:13:01
|
> > > I'm trying to add an SDL renderer to tuxnes. Eventually this will give > > > us full-screen support and additional platforms for free. > > > [...] > > I have the basic renderer working, though I don't really understand > > tuxnes's color code (UpdateColor.* functions). > > [...] > The palette stuff is confusing. The first time it took me a while to > figure it out. The second time (when I went back and converted it to use > hardware palette entries) again took me a while, so I took notes that time: > [...] Great, thanks for the help. I now have a SDL video renderer working. I can now play NES titles in full screen mode. I would also like to implement the following, submitting the changes as seperate patches: 1. Make repeated code into shared code: o magstep init code o synchronization (frameskip) code o InitScreenshot.*/SaveScreenshot.* 2. Implement UpdateAudio using SDL. 3. Implement joystick code using SDL. Here is the patch: ================================================================================ diff -u --new-file --recursive tuxnes-0.75-vanilla/Makefile.am tuxnes-0.75/Makefile.am --- tuxnes-0.75-vanilla/Makefile.am Mon Apr 16 14:43:25 2001 +++ tuxnes-0.75/Makefile.am Sat Mar 9 10:42:48 2002 @@ -5,7 +5,7 @@ noinst_PROGRAMS = comptbl tuxnes_SOURCES = x86.S d6502.c dynrec.c emu.c fb.c gamegenie.c io.c mapper.c \ - sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ + sdl.c sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ mapper.h renderer.c renderer.h ntsc_pal.c unzip.c unzip.h \ ziploader.c ziploader.h EXTRA_tuxnes_SOURCES = pixels.h diff -u --new-file --recursive tuxnes-0.75-vanilla/configure.in tuxnes-0.75/configure.in --- tuxnes-0.75-vanilla/configure.in Mon Apr 16 03:08:07 2001 +++ tuxnes-0.75/configure.in Sat Mar 9 10:51:44 2002 @@ -31,7 +31,7 @@ dnl Don't assume we want high level optimisations, it is known to dnl produce broken code on certain architectures using certain compilers dnl -------------------------------------------------------------------- -CFLAGS="-O" +CFLAGS="-O -g" AC_SUBST(CFLAGS) dnl -------------------------------------------------------------------- @@ -138,6 +138,20 @@ AC_CHECK_LIB(snss, openSnssFile) dnl -------------------------------------------------------------------- +dnl Check for SDL +dnl -------------------------------------------------------------------- +AC_ARG_WITH(sdl,\ +[ --without-sdl disable check for SDL (Simple Directmedia Lib.)]) + +if test "x$with_sdl" != "xno"; then + OCPPFLAGS="$CPPFLAGS" + CPPFLAGS="-I/usr/local/include" + AC_CHECK_HEADERS(SDL/SDL.h, CFLAGS="$CFLAGS -I/usr/local/include") + AC_CHECK_LIB(SDL, SDL_Init) + CPPFLAGS="$OCPPFLAGS" +fi + +dnl -------------------------------------------------------------------- dnl Check for GGI dnl -------------------------------------------------------------------- AC_ARG_WITH(ggi,\ diff -u --new-file --recursive tuxnes-0.75-vanilla/renderer.c tuxnes-0.75/renderer.c --- tuxnes-0.75-vanilla/renderer.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75/renderer.c Sat Mar 9 10:47:10 2002 @@ -34,6 +34,12 @@ extern void UpdateDisplayOldX11(void); #endif +#ifdef HAVE_SDL +extern int InitDisplaySDL(int argc, char **argv); +extern void UpdateColorsSDL(void); +extern void UpdateDisplaySDL(void); +#endif + #ifdef HAVE_GGI extern int InitDisplayGGI(int argc, char **argv); extern void UpdateColorsGGI(void); @@ -69,6 +75,11 @@ RENDERER_OLD, InitDisplayX11, UpdateDisplayOldX11, UpdateColorsX11 }, #endif /* HAVE_X */ +#ifdef HAVE_SDL + { "sdl", "SDL renderer", + 0, + InitDisplaySDL, UpdateDisplaySDL, UpdateColorsSDL }, +#endif /* HAVE_SDL */ #ifdef HAVE_GGI { "ggi", "GGI renderer", 0, diff -u --new-file --recursive tuxnes-0.75-vanilla/renderer.h tuxnes-0.75/renderer.h --- tuxnes-0.75-vanilla/renderer.h Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75/renderer.h Sat Mar 9 10:33:45 2002 @@ -29,6 +29,12 @@ #endif #endif +#ifdef HAVE_LIBSDL +#ifdef HAVE_SDL_SDL_H +#define HAVE_SDL 1 +#endif +#endif + /* only the no-op renderer `none' is universally known */ extern int InitDisplayNone(int argc, char **argv); extern void UpdateColorsNone(void); diff -u --new-file --recursive tuxnes-0.75-vanilla/sdl.c tuxnes-0.75/sdl.c --- tuxnes-0.75-vanilla/sdl.c Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75/sdl.c Sat Mar 23 15:08:19 2002 @@ -0,0 +1,419 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: This file handles the I/O subsystem when using SDL. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_FEATURES_H +#include <features.h> +#endif /* HAVE_FEATRES_H */ + +#include "consts.h" +#include "globals.h" +#include "mapper.h" +#include "renderer.h" +#include "sound.h" + +#ifdef HAVE_SDL + +#include <SDL/SDL.h> +#include <SDL/SDL_endian.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> + +/* FIXME: Share with x11.c, w.c, etc. */ +#include <dirent.h> +#include <sys/stat.h> +char *screenshotfile; +static int screenshotnumber = 0; + +#define BPP 16 + +SDL_Surface *screen; +unsigned int paletteSDL[64]; + +/* ============================ InitScreenshotSDL () ======================= */ +static void InitScreenshotSDL(void) +{ + DIR *dir; + struct dirent *dirp; + int currentnumber = 0; + /* Allocate space for (tuxnesdir) + (basefilename-snap-xxxx.bmp) + ('\0') */ + if ((screenshotfile = (char *) malloc(strlen(tuxnesdir) + + strlen(basefilename) + 1 + 4 + + 1 + 4 + 1 + 3 + 1)) == NULL) { + perror("malloc"); + exit(1); + } + sprintf(screenshotfile, "%s-snap-", basefilename); + /* open the screenshot directory */ + if ((dir = opendir(tuxnesdir)) == NULL) { + return; + } + /* iterate through the files and establish the starting screenshot number */ + while ((dirp = readdir(dir)) != NULL) { + if ((strlen(dirp->d_name) >= 8) + && + (strncmp(dirp->d_name, screenshotfile, strlen(screenshotfile)) + == 0) + && + (strncmp + (dirp->d_name + strlen(dirp->d_name) - 4, ".bmp", + strlen(".bmp")) == 0)) { + dirp->d_name[strlen(dirp->d_name) - 4] = '\0'; + if ((currentnumber = + atoi(dirp->d_name + strlen(screenshotfile))) > + screenshotnumber) { + screenshotnumber = currentnumber; + } + } + } + if (++screenshotnumber > 9999) { + screenshotnumber = 0; + } + closedir(dir); +} + + +/* ============================ SaveScreenshotSDL () ======================= */ +static void SaveScreenshotSDL(void) +{ + int status; + /* make sure we don't over-write screenshots written by a concurrent TuxNES process */ + { + struct stat buf[1]; + do + sprintf(screenshotfile, "%s%s-snap-%04u.bmp", tuxnesdir, + basefilename, screenshotnumber++); + while ((!stat(screenshotfile, buf)) && !(screenshotnumber > 9999)); + } + if (screenshotnumber > 9999) { + screenshotnumber = 0; + } + SDL_SaveBMP(screen, screenshotfile); +} + +/* ============================ InitDisplaySDL () ========================== */ +int InitDisplaySDL(int argc, char **argv) +{ + int i; + struct timeval time; + if (magstep < 1) + magstep = 1; + if (magstep > maxsize) { + fprintf(stderr, "Warning: Enlargement factor %d is too large!\n", + magstep); + magstep = maxsize; + } + bpp = BPP; + bytes_per_line = 256 * magstep * BPP / 8; + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + if ((screen = + SDL_SetVideoMode(256 * magstep, 240 * magstep, BPP, + SDL_SWSURFACE)) == NULL) { + fprintf(stderr, "Unable to set 256x240 video: %s\n", + SDL_GetError()); + exit(1); + } + SDL_WM_ToggleFullScreen(screen); + rfb = fb = screen->pixels; + for (i = 0; i < 64; i++) { + unsigned char r, g, b; + r = (NES_palette[i] >> 16 >> 3) & 0x1f; + g = (NES_palette[i] >> 8 >> 2) & 0x3f; + b = (NES_palette[i] >> 3) & 0x1f; + paletteSDL[i] = (r << 11) | (g << 5) | (b); + } + fbinit(); + InitScreenshotSDL(); + gettimeofday(&time, NULL); + renderer_data.basetime = time.tv_sec; + return 0; +} + +/* ============================ handle_key () ============================== */ +static void handle_key(SDL_KeyboardEvent * ev) +{ + if (ev->keysym.sym == SDLK_ESCAPE) + exit(0); + + /* the coin and dipswitch inputs work only in VS UniSystem mode */ + if (unisystem) + switch (ev->keysym.sym) { + case SDLK_LEFTBRACKET: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 1; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 1; + else + coinslot &= ~1; + break; + case SDLK_RIGHTBRACKET: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 2; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 2; + else + coinslot &= ~2; + break; + case SDLK_BACKSLASH: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 4; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 4; + else + coinslot &= ~4; + break; + case SDLK_q: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x01; + break; + case SDLK_w: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x02; + break; + case SDLK_e: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x04; + break; + case SDLK_r: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x08; + break; + case SDLK_t: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x10; + break; + case SDLK_y: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x20; + break; + case SDLK_u: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x40; + break; + case SDLK_i: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x80; + break; + default: + break; + } + + switch (ev->keysym.sym) { + /* controller 1 keyboard mapping */ + case SDLK_RETURN: + case SDLK_KP_ENTER: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= STARTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= STARTBUTTON; + else + controller[0] &= ~STARTBUTTON; + break; + case SDLK_TAB: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= SELECTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= SELECTBUTTON; + else + controller[0] &= ~SELECTBUTTON; + break; + case SDLK_UP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= UP; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= UP; + else + controller[0] &= ~UP; + break; + case SDLK_DOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= DOWN; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= DOWN; + else + controller[0] &= ~DOWN; + break; + case SDLK_LEFT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= LEFT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= LEFT; + else + controller[0] &= ~LEFT; + break; + case SDLK_RIGHT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= RIGHT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= RIGHT; + else + controller[0] &= ~RIGHT; + break; + case SDLK_HOME: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | LEFT); + else + controllerd[0] &= ~(UP | LEFT); + break; + case SDLK_PAGEUP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | RIGHT); + else + controllerd[0] &= ~(UP | RIGHT); + break; + case SDLK_END: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | LEFT); + else + controllerd[0] &= ~(DOWN | LEFT); + break; + case SDLK_PAGEDOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | RIGHT); + else + controllerd[0] &= ~(DOWN | RIGHT); + break; + case SDLK_z: + case SDLK_x: + case SDLK_d: + case SDLK_INSERT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONB; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONB; + else + controller[0] &= ~BUTTONB; + break; + case SDLK_a: + case SDLK_c: + case SDLK_SPACE: + case SDLK_DELETE: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONA; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONA; + else + controller[0] &= ~BUTTONA; + break; + case SDLK_F7: + case SDLK_PRINT: + case SDLK_s: + SaveScreenshotSDL(); + break; + default: + break; + } +} + +/* ============================ UpdateDisplaySDL () ======================== */ +void UpdateDisplaySDL(void) +{ + struct timeval time; + unsigned static int frame; + unsigned int timeframe; + SDL_Event event; + /* FIXME: Write SDL audio handler */ + UpdateAudio(); + gettimeofday(&time, NULL); + timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ + timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + frame++; + if (halfspeed) + timeframe >>= 1; + if (doublespeed == 2) + timeframe <<= 1; + else if (doublespeed > 2) + timeframe *= doublespeed; + if (desync) + frame = timeframe; + desync = 0; + if (frame < timeframe - 20 && frame % 20 == 0) + desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ + drawimage(PBL); + if (!frameskip) { + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + if (frame > timeframe + 1 && frameskip == 0) { + usleep(16666 * (frame - timeframe - 1)); + } + + /* FIXME: write SDL handler */ + if (jsfd[0] >= 0) + HandleJoystickLinux(0); + + if (jsfd[1] >= 0) + HandleJoystickLinux(1); + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + handle_key(&event.key); + break; + case SDL_QUIT: + exit(0); + } + } + + gettimeofday(&time, NULL); + timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + if (halfspeed) + timeframe >>= 1; + if (doublespeed == 2) + timeframe <<= 1; + else if (doublespeed > 2) + timeframe *= doublespeed; + if (frame >= timeframe || frame % 20 == 0) + frameskip = 0; + else + frameskip = 1; +} + +/* ============================ UpdateColorsSDL () ========================= */ +void UpdateColorsSDL(void) +{ + int i; + palette[24] = paletteSDL[VRAM[0x3f00] & 63]; + for (i = 0; i < 24; i++) + palette[i] = paletteSDL[VRAM[0x3f01 + i + (i / 3)] & 63]; +} + +#endif /* HAVE_SDL */ ================================================================================ -- Mike :wq |
From: Mike M. <mel...@pc...> - 2002-03-20 16:47:51
|
On Wed, 20 Mar 2002, Mark J. Tilford wrote: > > I found the following file with google. I don't know how accurate it is, > though: > > ---------------------------------------- > Nesticle(ver 0.42) stafile infomation > ---------------------------------------- > By: goroh Oh yeah, that one. Matt Conte reverse engineered a much better description, if I could only find it... Thanks... -- -Mike Melanson |
From: Mark J. T. <ti...@ug...> - 2002-03-20 16:40:39
|
I found the following file with google. I don't know how accurate it is, though: ---------------------------------------- Nesticle(ver 0.42) stafile infomation ---------------------------------------- By: goroh Mail: gor...@ge... Date: 1997/12/12 URL : http://www.geocities.co.jp/SiliconValley/2368/staform.txt I'm Japanese,so I'm not good at English. Thenk you for your reading. Prease e-mail me with your impression(and mistakes in grammer). ========================== 1. sta format ========================== 0000h(2000h) Extend RAM Dump 2000h(0800h) Static RAM Dump 2800h(0002h) Current reg PC 2802h(0001h) Current reg A 2803h(0001h) Current reg S SO-BDIZC |||||||+- Carry flag ||||||+-- Zero flag |||||+--- Interrupt flag ||||+---- Decimal mode flag |||+----- BRK flag ||+------ 0 |+------- Overflow flag +-------- Sign flag 2804h(0001h) Current reg X 2805h(0001h) Current reg Y 2806h(0001h) Current reg SP 2807h(0100h) Sprite Setting (unknown fill #$00) 2907h(4000h) PPU-RAM Dump 0000h Pattern Table Dump (if chr-bank size=0, else fill #$00) 2000h NameTable & Attribute Dump 5907h(00c9h) Other Setting 0077h Current H,V setting 0:H 1:V ------------------------ Mark Jeffrey Tilford ti...@ug... |
From: Mike M. <mel...@pc...> - 2002-03-11 23:58:04
|
On Mon, 11 Mar 2002, Byron Stanoszek wrote: > Can you tell me what the status is of supporting MMC5-style games (I'm assuming > Castlevania II falls under this category)? I'm thinking about making a 32-bit > Castlevania II clone as my first project in playing with the Linux port of the > Playstation 2. Castlevania III, actually (Dracula's Curse), was the most famous example of an MMC5 game. Castlevania II: Simon's Quest is supported in TuxNES (if your experience differs, please let us know). > Also, how hard is it to write support for one of these mappers? Can't be too > bad using source from other NES emulators, no? With the proper architecture in place, it's not difficult. However, MMC5 runs into some limitations with the way the original Nestra codebase was written in the first place which makes it very difficult, if not impossible, to implement with the current architecture. The specific issue has to do with the way the MMC5's registers are mapped to memory locations below 0x8000 in the NES CPU memory map (Nestra basically expected them to always be mapped at 0x8000 or higher). -- -Mike Melanson |
From: Byron S. <ga...@wi...> - 2002-03-11 23:35:01
|
Mike and/or others, Can you tell me what the status is of supporting MMC5-style games (I'm assuming Castlevania II falls under this category)? I'm thinking about making a 32-bit Castlevania II clone as my first project in playing with the Linux port of the Playstation 2. Also, how hard is it to write support for one of these mappers? Can't be too bad using source from other NES emulators, no? Thanks, -Byron -- Byron Stanoszek Ph: (330) 644-3059 Systems Programmer Fax: (330) 644-8110 Commercial Timesharing Inc. Email: by...@co... |
From: Ben S. <BSi...@Kn...> - 2002-03-11 00:33:20
|
TuxNES team, Hi, and sorry I've been to busy to reply earlier. I would like to applaud you on your good work: It's great to see SDL support. Tuxnes now supports three of the four popular cross-platform display systems (X11, GGI, and SDL -- VNC support is till to come.) I believe the palette arrangement used by TuxNES is a relic from Quor's original Nestra code, about which he may wish to comment (I believe he's still subscribed.) From reading the code, it seems to me that Nestra was originally designed for 8-bit palettized display (only) and TrueColor support was added later, almost as an afterthought. Under X11, a window using a palettized display does not -- at least by default -- have access to the full 256-entry palette. Instead, all open windows share a single palette, and palette entry contention is a common problem. I suspect Nestra's palette usage may be an attempt to minimize the number of used palette entries. Palettized display (PseudoColor under X11) is a very straightforward choice for emulating the NES, since the NES allows programs to change the displayed color for each logical tile/sprite color. In palettized mode, TuxNES changes the video card's palette registers to reflect changes to the NES palette. However, this straighforward choice becomes less logical once mid-screen palette updates are taken into account. On the NES, many programs update the palette entries for some colors partway trhough the rendering process in order to increase the apparent palette size. Since these palette changes are intimately related to the NTSC/PAL video timings, they are hard to emulate correctly on a modern PC (where beam position is either difficult or impossible to determine, and people expect flicker-free high-refresh-rate video modes, not to mention high resolution and multiple windows visible at the same time.) To overcome this (and accurately simulate the appearance of NES games,) the TrueColor renderers in TuxNES allow the color palette to be updated mid-screen, and render each NES pixel as an RGB triple. When a palette entry changes, all pixels generated from that palette entry must be recalculated and redrawn. In other words: In palettized mode, TuxNES simulates the NES video hardware and expects the monitor to accurately simulate an NTSC/PAL television (which it rarely does.) In TrueColor mode, TuxNES simulates both the NES video hardware and an NTSC/PAL television. This is slower than palettized mode, but more accurate. The one major bit of NES graphics hardware still unemulated by TuxNES is the "color emphasis" feature, which allows a sort of global palette tinting similar in spirit to the X11 DirectColor visual class. Like other palette changes, this needs to be pre-rendered into RGB to accurately simulate mid-screen updates. Finally, I highly recommend Chris Covell's demos for those experimenting with the NES graphics hardware (whether real or in TuxNES.) -Ben P.S. I'm glad to see that the W Window System code has proved of some use to someone. When I wrote it I feared I would be the only one to ever run or use it. ;) -----Original Message----- From: Jim Ursetto Sent: Sun 3/10/2002 8:19 AM To: tux...@li... Subject: Re: [Tuxnes-devel] Trying to add SDL Renderer At 07:41am on 2002 March 10, W. Michael Petullo did write: > > I'm trying to add an SDL renderer to tuxnes. Eventually this will give > > us full-screen support and additional platforms for free. > > [...] >=20 > I have the basic renderer working, though I don't really understand > tuxnes's color code (UpdateColor.* functions). As I understand it, > the NES is only able to display 24 colors at once. Because of this, > the emulator's palette must be updated to the appropriate colors for each > frame and these colors have to be mapped to a display's 8-, 16-, 24-, > or 32-bit colorspace. The palette stuff is confusing. The first time it took me a while to figure it out. The second time (when I went back and converted it to use hardware palette entries) again took me a while, so I took notes that time: ---- Palette conversion: paletteDC[] holds the 64 16-bit DC versions of the 64 total NES colors. palette[] holds 25 16-bit RGB565 values, all of which are cornfusing. The 2 NES palettes have 16 entries each, broken down into 4 groups of 4. Color 0 is transparent (letting the background (or background color) shine through). Color 0 is mirrored to 4, 8, 12. Also, color 0 is mirrored between the two palettes. In this array: 0..11 are the current tile colors. 0,1,2 correspond to colors 1, 2, and 3. 3,4,5 and 6,7,8 are 5, 6, 7 and 9, 10, 11. 9,10,11 are 13, 14, and 15. 12..23 are the current sprite colors. 24 is the current background color, set in UpdateColors. Methinks this was a (misguided?) attempt to save space. tilecolor is the 2-bit value from the attribute table. curpal[] holds 4 16-bit RGB565 values corresponding to the 4 possible colors for the current tile. The index into curpal is the 2-bit value from the name table. curpal[0] is always set to the value in palette[24] upon entering drawimage. curpal[1,2,3] are set to palette[0,1,2], [3,4,5], [6,7,8], or [9,10,11] depending on the value of tilecolor (2 bits provides 4 selections). ------------------------ The following code does not use hardware palette entries (i.e. not PseudoColor). The code in InitDisplay that converts the 32-bit NES_palette values into 16-bit RGB565 native values is: for (x=3D0; x < 64; x++) { /* RGB565 */ uint8 r,g,b; r =3D (NES_palette[x] >> 16 >> 3) & 0x1f; g =3D (NES_palette[x] >> 8 >> 2) & 0x3f; b =3D (NES_palette[x] >> 3) & 0x1f; paletteDC[x] =3D (r << 11) | (g << 5) | (b); } The update colors function is very simple (except for the unnecessarily complicated palette array organization): void UpdateColorsDC(void) { int x; palette[24] =3D paletteDC[VRAM[0x3f00] & 63]; for (x =3D 0; x < 24; x++) {=20 palette[x] =3D paletteDC[VRAM[0x3f01 + x + (x / 3)] & 63]; } =20 This should get you started. I have hardware palette code too if you need it. --=20 "closing my eyes, i got a glimpse of several entities moving in front of a giant complex control panel. the creatures were bipedal and of about human size. it was impossible to say more other than they did not move like the giant insect creatures i have seen clearly under the influence of stropharia mushrooms." -- zarkov, "a hit of dmt 10/9/84" ji...@3e... / 0x43340710 / 517B C658 D2CB 260D 3E1F 5ED1 6DB3 FBB9 4334 0710 _______________________________________________ Tuxnes-devel mailing list Tux...@li... https://lists.sourceforge.net/lists/listinfo/tuxnes-devel |
From: Jim U. <ji...@3e...> - 2002-03-10 16:19:35
|
At 07:41am on 2002 March 10, W. Michael Petullo did write: > > I'm trying to add an SDL renderer to tuxnes. Eventually this will give > > us full-screen support and additional platforms for free. > > [...] > > I have the basic renderer working, though I don't really understand > tuxnes's color code (UpdateColor.* functions). As I understand it, > the NES is only able to display 24 colors at once. Because of this, > the emulator's palette must be updated to the appropriate colors for each > frame and these colors have to be mapped to a display's 8-, 16-, 24-, > or 32-bit colorspace. The palette stuff is confusing. The first time it took me a while to figure it out. The second time (when I went back and converted it to use hardware palette entries) again took me a while, so I took notes that time: ---- Palette conversion: paletteDC[] holds the 64 16-bit DC versions of the 64 total NES colors. palette[] holds 25 16-bit RGB565 values, all of which are cornfusing. The 2 NES palettes have 16 entries each, broken down into 4 groups of 4. Color 0 is transparent (letting the background (or background color) shine through). Color 0 is mirrored to 4, 8, 12. Also, color 0 is mirrored between the two palettes. In this array: 0..11 are the current tile colors. 0,1,2 correspond to colors 1, 2, and 3. 3,4,5 and 6,7,8 are 5, 6, 7 and 9, 10, 11. 9,10,11 are 13, 14, and 15. 12..23 are the current sprite colors. 24 is the current background color, set in UpdateColors. Methinks this was a (misguided?) attempt to save space. tilecolor is the 2-bit value from the attribute table. curpal[] holds 4 16-bit RGB565 values corresponding to the 4 possible colors for the current tile. The index into curpal is the 2-bit value from the name table. curpal[0] is always set to the value in palette[24] upon entering drawimage. curpal[1,2,3] are set to palette[0,1,2], [3,4,5], [6,7,8], or [9,10,11] depending on the value of tilecolor (2 bits provides 4 selections). ------------------------ The following code does not use hardware palette entries (i.e. not PseudoColor). The code in InitDisplay that converts the 32-bit NES_palette values into 16-bit RGB565 native values is: for (x=0; x < 64; x++) { /* RGB565 */ uint8 r,g,b; r = (NES_palette[x] >> 16 >> 3) & 0x1f; g = (NES_palette[x] >> 8 >> 2) & 0x3f; b = (NES_palette[x] >> 3) & 0x1f; paletteDC[x] = (r << 11) | (g << 5) | (b); } The update colors function is very simple (except for the unnecessarily complicated palette array organization): void UpdateColorsDC(void) { int x; palette[24] = paletteDC[VRAM[0x3f00] & 63]; for (x = 0; x < 24; x++) { palette[x] = paletteDC[VRAM[0x3f01 + x + (x / 3)] & 63]; } This should get you started. I have hardware palette code too if you need it. -- "closing my eyes, i got a glimpse of several entities moving in front of a giant complex control panel. the creatures were bipedal and of about human size. it was impossible to say more other than they did not move like the giant insect creatures i have seen clearly under the influence of stropharia mushrooms." -- zarkov, "a hit of dmt 10/9/84" ji...@3e... / 0x43340710 / 517B C658 D2CB 260D 3E1F 5ED1 6DB3 FBB9 4334 0710 |
From: W. M. P. <mi...@fl...> - 2002-03-10 13:45:04
|
> I'm trying to add an SDL renderer to tuxnes. Eventually this will give > us full-screen support and additional platforms for free. > [...] I have the basic renderer working, though I don't really understand tuxnes's color code (UpdateColor.* functions). As I understand it, the NES is only able to display 24 colors at once. Because of this, the emulator's palette must be updated to the appropriate colors for each frame and these colors have to be mapped to a display's 8-, 16-, 24-, or 32-bit colorspace. I am just confused how x11.c, w.c, and ggi.c are accomplishing this. Enclosed is my SDL patch thus far. It has a severely broken sdl.c:UpdateColorsSDL function. Could someone please enlighten me on how tuxnes's color code works? Thanks. ================================================================================ diff -u --new-file --recursive tuxnes-0.75-vanilla/Makefile.am tuxnes-0.75/Makefile.am --- tuxnes-0.75-vanilla/Makefile.am Mon Apr 16 14:43:25 2001 +++ tuxnes-0.75/Makefile.am Sat Mar 9 10:42:48 2002 @@ -5,7 +5,7 @@ noinst_PROGRAMS = comptbl tuxnes_SOURCES = x86.S d6502.c dynrec.c emu.c fb.c gamegenie.c io.c mapper.c \ - sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ + sdl.c sound.c sound.h ggi.c x11.c w.c consts.h gamegenie.h globals.h \ mapper.h renderer.c renderer.h ntsc_pal.c unzip.c unzip.h \ ziploader.c ziploader.h EXTRA_tuxnes_SOURCES = pixels.h diff -u --new-file --recursive tuxnes-0.75-vanilla/config.h.in tuxnes-0.75/config.h.in --- tuxnes-0.75-vanilla/config.h.in Tue Mar 27 03:11:27 2001 +++ tuxnes-0.75/config.h.in Sat Mar 9 10:11:44 2002 @@ -1,153 +1,195 @@ /* config.h.in. Generated automatically from configure.in by autoheader. */ +/* + * `autoheader' will generate config.h.in for TuxNES + * + * Original by (probably) Mike + * + * BSD extensions by Jeroen Ruigrok van der Werven + * + * $Id: acconfig.h,v 1.4 1999/11/06 13:51:19 asmodai Exp $ + */ -/* Define to empty if the keyword does not work. */ +/* Package name of TuxNES */ +#undef PACKAGE + +/* Version of TuxNES */ +#undef VERSION + +/* Define if you have the gnugetopt library */ +#undef HAVE_LIBGNUGETOPT + +/* Define to empty if `const' does not conform to ANSI C. */ #undef const -/* Define if you have a working `mmap' system call. */ -#undef HAVE_MMAP +/* Define if you have the <dirent.h> header file, and it defines `DIR'. */ +#undef HAVE_DIRENT_H -/* Define as __inline if that's what the C compiler calls it. */ -#undef inline +/* Define if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H -/* Define as the return type of signal handlers (int or void). */ -#undef RETSIGTYPE +/* Define if you have the <features.h> header file. */ +#undef HAVE_FEATURES_H -/* Define to `unsigned' if <sys/types.h> doesn't define. */ -#undef size_t +/* Define if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS +/* Define if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY -/* Define if you can safely include both <sys/time.h> and <time.h>. */ -#undef TIME_WITH_SYS_TIME +/* Define if you have the <ggi/ggi.h> header file. */ +#undef HAVE_GGI_GGI_H -/* Define if your processor stores words with the most significant - byte first (like Motorola and SPARC, unlike Intel and VAX). */ -#undef WORDS_BIGENDIAN +/* Define if you have the <ggi/gii.h> header file. */ +#undef HAVE_GGI_GII_H -/* Define if the X Window System is missing or not being used. */ -#undef X_DISPLAY_MISSING +/* Define if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H -/* Define if you have the gnugetopt library */ -#undef HAVE_LIBGNUGETOPT +/* Define if you have the `ggi' library (-lggi). */ +#undef HAVE_LIBGGI -/* Define if you have the getpagesize function. */ -#undef HAVE_GETPAGESIZE +/* Define if you have the `gii' library (-lgii). */ +#undef HAVE_LIBGII -/* Define if you have the gettimeofday function. */ -#undef HAVE_GETTIMEOFDAY +/* Define if you have the `m' library (-lm). */ +#undef HAVE_LIBM -/* Define if you have the strtod function. */ -#undef HAVE_STRTOD +/* Define if you have the `pbm' library (-lpbm). */ +#undef HAVE_LIBPBM -/* Define if you have the strtoul function. */ -#undef HAVE_STRTOUL +/* Define if you have the `pgm' library (-lpgm). */ +#undef HAVE_LIBPGM -/* Define if you have the <dirent.h> header file. */ -#undef HAVE_DIRENT_H +/* Define if you have the `ppm' library (-lppm). */ +#undef HAVE_LIBPPM -/* Define if you have the <fcntl.h> header file. */ -#undef HAVE_FCNTL_H +/* Define if you have the `SDL' library (-lSDL). */ +#undef HAVE_LIBSDL -/* Define if you have the <features.h> header file. */ -#undef HAVE_FEATURES_H +/* Define if you have the `snss' library (-lsnss). */ +#undef HAVE_LIBSNSS -/* Define if you have the <ggi/ggi.h> header file. */ -#undef HAVE_GGI_GGI_H +/* Define if you have the `W' library (-lW). */ +#undef HAVE_LIBW -/* Define if you have the <ggi/gii.h> header file. */ -#undef HAVE_GGI_GII_H +/* Define if you have the `Xext' library (-lXext). */ +#undef HAVE_LIBXEXT + +/* Define if you have the `Xpm' library (-lXpm). */ +#undef HAVE_LIBXPM -/* Define if you have the <linux/joystick.h> header file. */ +/* Define if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define if you have the <linux/joystick.h> header file. */ #undef HAVE_LINUX_JOYSTICK_H -/* Define if you have the <linux/soundcard.h> header file. */ +/* Define if you have the <linux/soundcard.h> header file. */ #undef HAVE_LINUX_SOUNDCARD_H -/* Define if you have the <ndir.h> header file. */ +/* Define if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H -/* Define if you have the <ppm.h> header file. */ +/* Define if you have the <ppm.h> header file. */ #undef HAVE_PPM_H -/* Define if you have the <snss.h> header file. */ +/* Define if you have the <SDL/SDL.h> header file. */ +#undef HAVE_SDL_SDL_H + +/* Define if you have the <snss.h> header file. */ #undef HAVE_SNSS_H -/* Define if you have the <strings.h> header file. */ +/* Define if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H -/* Define if you have the <sys/dir.h> header file. */ +/* Define if you have the `strtod' function. */ +#undef HAVE_STRTOD + +/* Define if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define if you have the <sys/dir.h> header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H -/* Define if you have the <sys/ipc.h> header file. */ +/* Define if you have the <sys/ipc.h> header file. */ #undef HAVE_SYS_IPC_H -/* Define if you have the <sys/ndir.h> header file. */ +/* Define if you have the <sys/ndir.h> header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H -/* Define if you have the <sys/shm.h> header file. */ +/* Define if you have the <sys/shm.h> header file. */ #undef HAVE_SYS_SHM_H -/* Define if you have the <sys/soundcard.h> header file. */ +/* Define if you have the <sys/soundcard.h> header file. */ #undef HAVE_SYS_SOUNDCARD_H -/* Define if you have the <sys/time.h> header file. */ +/* Define if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define if you have the <sys/time.h> header file. */ #undef HAVE_SYS_TIME_H -/* Define if you have the <unistd.h> header file. */ +/* Define if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H -/* Define if you have the <Wlib.h> header file. */ +/* Define if you have the <Wlib.h> header file. */ #undef HAVE_WLIB_H -/* Define if you have the <X11/extensions/Xext.h> header file. */ +/* Define if you have the <X11/extensions/Xext.h> header file. */ #undef HAVE_X11_EXTENSIONS_XEXT_H -/* Define if you have the <X11/extensions/XShm.h> header file. */ +/* Define if you have the <X11/extensions/XShm.h> header file. */ #undef HAVE_X11_EXTENSIONS_XSHM_H -/* Define if you have the <X11/vroot.h> header file. */ +/* Define if you have the <X11/vroot.h> header file. */ #undef HAVE_X11_VROOT_H -/* Define if you have the <X11/xpm.h> header file. */ +/* Define if you have the <X11/xpm.h> header file. */ #undef HAVE_X11_XPM_H -/* Define if you have the ggi library (-lggi). */ -#undef HAVE_LIBGGI - -/* Define if you have the gii library (-lgii). */ -#undef HAVE_LIBGII - -/* Define if you have the m library (-lm). */ -#undef HAVE_LIBM - -/* Define if you have the pbm library (-lpbm). */ -#undef HAVE_LIBPBM - -/* Define if you have the pgm library (-lpgm). */ -#undef HAVE_LIBPGM - -/* Define if you have the ppm library (-lppm). */ -#undef HAVE_LIBPPM - -/* Define if you have the snss library (-lsnss). */ -#undef HAVE_LIBSNSS +/* Define as `__inline' if that's what the C compiler calls it, or to nothing + if it is not supported. */ +#undef inline -/* Define if you have the W library (-lW). */ -#undef HAVE_LIBW +/* Name of package */ +#undef PACKAGE -/* Define if you have the Xext library (-lXext). */ -#undef HAVE_LIBXEXT +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE -/* Define if you have the Xpm library (-lXpm). */ -#undef HAVE_LIBXPM +/* Define to `unsigned' if <sys/types.h> does not define. */ +#undef size_t -/* Define if you have the z library (-lz). */ -#undef HAVE_LIBZ +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS -/* Name of package */ -#undef PACKAGE +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME /* Version number of package */ #undef VERSION +/* Define if your processor stores words with the most significant byte first + (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING diff -u --new-file --recursive tuxnes-0.75-vanilla/configure.in tuxnes-0.75/configure.in --- tuxnes-0.75-vanilla/configure.in Mon Apr 16 03:08:07 2001 +++ tuxnes-0.75/configure.in Sat Mar 9 10:51:44 2002 @@ -31,7 +31,7 @@ dnl Don't assume we want high level optimisations, it is known to dnl produce broken code on certain architectures using certain compilers dnl -------------------------------------------------------------------- -CFLAGS="-O" +CFLAGS="-O -g" AC_SUBST(CFLAGS) dnl -------------------------------------------------------------------- @@ -138,6 +138,20 @@ AC_CHECK_LIB(snss, openSnssFile) dnl -------------------------------------------------------------------- +dnl Check for SDL +dnl -------------------------------------------------------------------- +AC_ARG_WITH(sdl,\ +[ --without-sdl disable check for SDL (Simple Directmedia Lib.)]) + +if test "x$with_sdl" != "xno"; then + OCPPFLAGS="$CPPFLAGS" + CPPFLAGS="-I/usr/local/include" + AC_CHECK_HEADERS(SDL/SDL.h, CFLAGS="$CFLAGS -I/usr/local/include") + AC_CHECK_LIB(SDL, SDL_Init) + CPPFLAGS="$OCPPFLAGS" +fi + +dnl -------------------------------------------------------------------- dnl Check for GGI dnl -------------------------------------------------------------------- AC_ARG_WITH(ggi,\ diff -u --new-file --recursive tuxnes-0.75-vanilla/renderer.c tuxnes-0.75/renderer.c --- tuxnes-0.75-vanilla/renderer.c Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75/renderer.c Sat Mar 9 10:47:10 2002 @@ -34,6 +34,12 @@ extern void UpdateDisplayOldX11(void); #endif +#ifdef HAVE_SDL +extern int InitDisplaySDL(int argc, char **argv); +extern void UpdateColorsSDL(void); +extern void UpdateDisplaySDL(void); +#endif + #ifdef HAVE_GGI extern int InitDisplayGGI(int argc, char **argv); extern void UpdateColorsGGI(void); @@ -69,6 +75,11 @@ RENDERER_OLD, InitDisplayX11, UpdateDisplayOldX11, UpdateColorsX11 }, #endif /* HAVE_X */ +#ifdef HAVE_SDL + { "sdl", "SDL renderer", + 0, + InitDisplaySDL, UpdateDisplaySDL, UpdateColorsSDL }, +#endif /* HAVE_SDL */ #ifdef HAVE_GGI { "ggi", "GGI renderer", 0, diff -u --new-file --recursive tuxnes-0.75-vanilla/renderer.h tuxnes-0.75/renderer.h --- tuxnes-0.75-vanilla/renderer.h Wed Apr 11 23:45:47 2001 +++ tuxnes-0.75/renderer.h Sat Mar 9 10:33:45 2002 @@ -29,6 +29,12 @@ #endif #endif +#ifdef HAVE_LIBSDL +#ifdef HAVE_SDL_SDL_H +#define HAVE_SDL 1 +#endif +#endif + /* only the no-op renderer `none' is universally known */ extern int InitDisplayNone(int argc, char **argv); extern void UpdateColorsNone(void); diff -u --new-file --recursive tuxnes-0.75-vanilla/sdl.c tuxnes-0.75/sdl.c --- tuxnes-0.75-vanilla/sdl.c Thu Jan 1 01:00:00 1970 +++ tuxnes-0.75/sdl.c Sun Mar 10 14:18:32 2002 @@ -0,0 +1,337 @@ +/* + * This file is part of the TuxNES project codebase. + * + * Please see the README and COPYING files for more information regarding + * this project. + * + * Description: This file handles the I/O subsystem when using SDL. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_FEATURES_H +#include <features.h> +#endif /* HAVE_FEATRES_H */ + +#include "consts.h" +#include "globals.h" +#include "mapper.h" +#include "renderer.h" +#include "sound.h" + +#ifdef HAVE_SDL + +#include <SDL/SDL.h> +#include <SDL/SDL_endian.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> + +#define BPP 8 + +SDL_Surface *screen; + +/* ============================ InitDisplaySDL () ========================== */ +int InitDisplaySDL(int argc, char **argv) +{ + int i; + struct timeval time; + if (magstep < 1) + magstep = 1; + if (magstep > maxsize) { + fprintf(stderr, "Warning: Enlargement factor %d is too large!\n", + magstep); + magstep = maxsize; + } + bpp = BPP; + bytes_per_line = 256 * magstep * BPP / 8; + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + if ((screen = + SDL_SetVideoMode(256 * magstep, 240 * magstep, BPP, + SDL_SWSURFACE)) == NULL) { + fprintf(stderr, "Unable to set 256x240 video: %s\n", + SDL_GetError()); + exit(1); + } + SDL_WM_ToggleFullScreen(screen); + rfb = fb = screen->pixels; + fbinit(); + gettimeofday(&time, NULL); + renderer_data.basetime = time.tv_sec; + return 0; +} + +/* ============================ handle_key () ============================== */ +static void handle_key(SDL_KeyboardEvent * ev) +{ + if (ev->keysym.sym == SDLK_ESCAPE) + exit (0); + + /* the coin and dipswitch inputs work only in VS UniSystem mode */ + if (unisystem) + switch (ev->keysym.sym) { + case SDLK_LEFTBRACKET: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 1; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 1; + else + coinslot &= ~1; + break; + case SDLK_RIGHTBRACKET: if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 2; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 2; + else + coinslot &= ~2; + break; + case SDLK_BACKSLASH: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + coinslot ^= 4; + } else if (ev->type == SDL_KEYDOWN) + coinslot |= 4; + else + coinslot &= ~4; + break; + case SDLK_q: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x01; + break; + case SDLK_w: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x02; + break; + case SDLK_e: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x04; + break; + case SDLK_r: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x08; + break; + case SDLK_t: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x10; + break; + case SDLK_y: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x20; + break; + case SDLK_u: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x40; + break; + case SDLK_i: + if (ev->type == SDL_KEYDOWN) + dipswitches ^= 0x80; + break; + default: + break; + } + + switch (ev->keysym.sym) { + /* controller 1 keyboard mapping */ + case SDLK_RETURN: + case SDLK_KP_ENTER: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= STARTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= STARTBUTTON; + else + controller[0] &= ~STARTBUTTON; + break; + case SDLK_TAB: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= SELECTBUTTON; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= SELECTBUTTON; + else + controller[0] &= ~SELECTBUTTON; + break; + case SDLK_UP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= UP; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= UP; + else + controller[0] &= ~UP; + break; + case SDLK_DOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= DOWN; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= DOWN; + else + controller[0] &= ~DOWN; + break; + case SDLK_LEFT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= LEFT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= LEFT; + else + controller[0] &= ~LEFT; + break; + case SDLK_RIGHT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= RIGHT; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= RIGHT; + else + controller[0] &= ~RIGHT; + break; + case SDLK_HOME: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | LEFT); + else + controllerd[0] &= ~(UP | LEFT); + break; + case SDLK_PAGEUP: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (UP | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (UP | RIGHT); + else + controllerd[0] &= ~(UP | RIGHT); + break; + case SDLK_END: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | LEFT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | LEFT); + else + controllerd[0] &= ~(DOWN | LEFT); + break; + case SDLK_PAGEDOWN: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controllerd[0] ^= (DOWN | RIGHT); + } else if (ev->type == SDL_KEYDOWN) + controllerd[0] |= (DOWN | RIGHT); + else + controllerd[0] &= ~(DOWN | RIGHT); + break; + case SDLK_z: + case SDLK_x: + case SDLK_d: + case SDLK_INSERT: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONB; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONB; + else + controller[0] &= ~BUTTONB; + break; + case SDLK_a: + case SDLK_c: + case SDLK_SPACE: + case SDLK_DELETE: + if (renderer_config.sticky_keys) { + if (ev->type == SDL_KEYDOWN) + controller[0] ^= BUTTONA; + } else if (ev->type == SDL_KEYDOWN) + controller[0] |= BUTTONA; + else + controller[0] &= ~BUTTONA; + break; + default: + break; + } +} + +/* ============================ UpdateDisplaySDL () ======================== */ +void UpdateDisplaySDL(void) +{ + struct timeval time; + unsigned static int frame; + unsigned int timeframe; + SDL_Event event; + /* FIXME: Write SDL audio handler */ + UpdateAudio(); + gettimeofday(&time, NULL); + timeframe = (time.tv_sec - renderer_data.basetime) * 50 + time.tv_usec / 20000; /* PAL */ + timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + frame++; + if (halfspeed) + timeframe >>= 1; + if (doublespeed == 2) + timeframe <<= 1; + else if (doublespeed > 2) + timeframe *= doublespeed; + if (desync) + frame = timeframe; + desync = 0; + if (frame < timeframe - 20 && frame % 20 == 0) + desync = 1; /* If we're more than 20 frames behind, might as well stop counting. */ + drawimage(PBL); + if (!frameskip) { + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + if (frame > timeframe + 1 && frameskip == 0) { + usleep(16666 * (frame - timeframe - 1)); + } + + /* FIXME: write SDL handler */ + if (jsfd[0] >= 0) + HandleJoystickLinux(0); + + if (jsfd[1] >= 0) + HandleJoystickLinux(1); + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + handle_key(&event.key); + break; + case SDL_QUIT: + exit(0); + } + } + + gettimeofday(&time, NULL); + timeframe = (time.tv_sec - renderer_data.basetime) * 60 + time.tv_usec / 16666; /* NTSC */ + if (halfspeed) + timeframe >>= 1; + if (doublespeed == 2) + timeframe <<= 1; + else if (doublespeed > 2) + timeframe *= doublespeed; + if (frame >= timeframe || frame % 20 == 0) + frameskip = 0; + else + frameskip = 1; +} + +/* ============================ UpdateColorsSDL () ========================= */ +void UpdateColorsSDL(void) +{ + /* FIXME */ + int i; + for (i = 0; i < 25; i++) + palette[i] = i; +} + +#endif /* HAVE_SDL */ ================================================================================ -- Mike :wq |
From: W. M. P. <mi...@fl...> - 2002-03-09 20:00:13
|
> > After looking at the X11 renderer code, I concluded that the global > > variable fb is a video frame buffer filled by tuxnes's emulator code. > > I thought that the following pseudo code would display a NES frame: > > > drawimage(PBL) > > Memory Copy (SDLbuf, p, 240 * 256) > > SDL Display(SDLbuf) > > I'm curious--why don't you have the render draw directly into the > SDL buffer? Looks like you're doing double work. Changed in accordance with your suggestion. > Anyway, if you want an example of rendering look at the GGI renderer, > it's probably easier to follow than X11 because the operation is similar to > SDL (as far as I know). Thanks. W.c actually ended up being a very good reference. My problem was that I didn't understand the palette handling code. I was not initializing the palette prior to calling drawimage. I now have rudimentary SDL support working in full-screen mode. I will finish my patch up and submit it in the near future. In addition, I plan on using my experience writing a renderer to clean up some of tuxnes's interfaces a bit. There is also a lot of repeated code in w.c, sdl.c, x11.c, and ggi.c that I would like to consolidate. I will submit these changes as a separate patch. -- Mike :wq |
From: Jim U. <ji...@3e...> - 2002-03-09 15:52:12
|
At 06:37am on 2002 March 09, W. Michael Petullo did write: > After looking at the X11 renderer code, I concluded that the global > variable fb is a video frame buffer filled by tuxnes's emulator code. > I thought that the following pseudo code would display a NES frame: > drawimage(PBL) > Memory Copy (SDLbuf, p, 240 * 256) > SDL Display(SDLbuf) I'm curious--why don't you have the render draw directly into the SDL buffer? Looks like you're doing double work. Anyway, if you want an example of rendering look at the GGI renderer, it's probably easier to follow than X11 because the operation is similar to SDL (as far as I know). -- "You cannot simultaneously have mass adoption and rigor" -- Clay Shirky ji...@3e... / 0x43340710 / 517B C658 D2CB 260D 3E1F 5ED1 6DB3 FBB9 4334 0710 |
From: W. M. P. <mi...@fl...> - 2002-03-09 13:30:52
|
I'm trying to add an SDL renderer to tuxnes. Eventually this will give us full-screen support and additional platforms for free. After looking at the X11 renderer code, I concluded that the global variable fb is a video frame buffer filled by tuxnes's emulator code. I thought that the following pseudo code would display a NES frame: Init: bpp = 8 fbinit () Update: drawimage(PBL) Memory Copy (SDLbuf, p, 240 * 256) SDL Display(SDLbuf) When I implement this, the video displayed looks like static and does not move. Even if I had some video parameters wrong, I would expect the video show some type of motion. Could someone please describe to me the correct process to retrieve and display a video frame from the rendering engine? Thanks. -- Mike :wq |
From: Jim U. <ji...@3e...> - 2002-02-28 01:57:49
|
I'm pleased to announce the release of tuxnes-dc v0.2, a port of TuxNES v0.75 to the Dreamcast. You can pick it up at http://3e8.org/hacks.html. Features -------- - Standard line-based renderer, locked to 30 fps (frameskip = 1). - Experimental accelerated tile renderer. Some games work great, some games don't. If you see garbage on the screen, try pressing B to clear it up. Generally runs at 60 fps. - Sound. Good, but subject to occasional artifacts. - Save games. Only to PC using dctool; VMU saving is not implemented yet. - 6502 interpreted core written in C. - Basic game select screen. Changes in tuxnes-dc v0.2 ------------------------- - Added experimental tile renderer (press Y at game select screen). Many games work fine. Press B to clear up screen corruption. Runs at 60 fps. - Sound code much improved; will not break up when speed drops too low. This allows arbitrary frameskip (but the line renderer is still locked to 30 fps). Noise channel clipped from time to time due to synchronization issues. - Fix palette bug that caused colors to be slightly off. - Fixed some sound and video corruption due to global variables; sporadic problems remain. Hope you enjoy it. Jim -- "... [WM97/Melissa-V] triggers immediately and attempts to delete data on your M:, N:, O:, P:, Q:, S:, F:, I:, X:, Z:, H:, and L: network drives." ji...@3e... / 0x43340710 / 517B C658 D2CB 260D 3E1F 5ED1 6DB3 FBB9 4334 0710 |
From: keegan <ic...@su...> - 2002-02-22 19:04:24
|
On Thu, Feb 21, 2002 at 10:25:30AM +0100, Jeroen Ruigrok/asmodai wrote: > -On [20020218 02:00], keegan (ic...@su...) wrote: > >I have made Debian packages for TuxNES 0.75, and would like to publish > >them as part of the distribution. My packages are available now at > >http://rune.thebasement.org/~ice/debian/ - if anyone here runs Debian > >and would like to test them, or let me know that someone else has > >already done this, please do. And keep up the great work! TuxNES is by > >far the most complete/accurate Linux NES emulator I have found. > > Well, > > is there any way we can make the packaging easier? Thanks very much for the offer, but it is pretty much complete. It's passing all of the build environment tests I can find, and no bugs have been reported yet. > I notice some projects have a debian directory. Would adding something like > this to the CVS tree help? There has been some significant discussion on this topic on the Debian lists, and the general concensus is that this complicates releases more than it helps them, due to the various idiosyncracies of packaging. > [Note: I am not a Linux user since years and wouldn't know much of the > specifics package builders need nowadays.] That's okay. I really appreciate your offer for help. With nice, clean upstream source releases (like yours :), my job is really quite straightforward. Keep up the good work. I am planning on making a small package status webpage tonight, but unfortunately my web server (with the packages) is down at the moment. Thanks again, Keegan |
From: Jeroen Ruigrok/a. <as...@wx...> - 2002-02-21 09:25:38
|
-On [20020218 02:00], keegan (ic...@su...) wrote: >I have made Debian packages for TuxNES 0.75, and would like to publish >them as part of the distribution. My packages are available now at >http://rune.thebasement.org/~ice/debian/ - if anyone here runs Debian >and would like to test them, or let me know that someone else has >already done this, please do. And keep up the great work! TuxNES is by >far the most complete/accurate Linux NES emulator I have found. Well, is there any way we can make the packaging easier? I notice some projects have a debian directory. Would adding something like this to the CVS tree help? [Note: I am not a Linux user since years and wouldn't know much of the specifics package builders need nowadays.] -- Jeroen Ruigrok van der Werven / asmodai / Kita no Mono asmodai@[wxs.nl|xmach.org], finger as...@ni... http://www.softweyr.com/asmodai/ | http://www.[tendra|xmach].org/ In a world that is chaotic, time is an island of order... |
From: keegan <ic...@su...> - 2002-02-18 00:58:23
|
Hello everyone, I have made Debian packages for TuxNES 0.75, and would like to publish them as part of the distribution. My packages are available now at http://rune.thebasement.org/~ice/debian/ - if anyone here runs Debian and would like to test them, or let me know that someone else has already done this, please do. And keep up the great work! TuxNES is by far the most complete/accurate Linux NES emulator I have found. Many thanks, Keegan Quinn |
From: J.D. <jo...@ce...> - 2002-02-16 05:29:49
|
Mike Melanson wrote: > > I would like to implement a fullscreen mode in X11 tuxnes. Is anyone > > else working on a similar feature? Any comments? > > Nope, not that I know of. Go for it. > If someone ever gets a chance, it might also be nice to see support for video output via SDL (http://www.libsdl.org/). It allows full screen or windowed mode, with or without X11, on a number of different platforms. Kind regards, - John |
From: Mike M. <mel...@pc...> - 2002-02-16 03:28:19
|
On Thu, 14 Feb 2002, Jeroen Ruigrok/asmodai wrote: > -On [20020130 16:30], Mike Melanson (mel...@pc...) wrote: > >I'll post those items somewhere publically accessible tonight. > > And? :) And...I got lazy and didn't bother looking for them. But I finally dug up the latest known version of the SNSS document and posted it here: http://www.pcisys.net/~melanson/snss-tff.txt Still trying to find that STA format document. -- -Mike Melanson |
From: Jim U. <ji...@3e...> - 2002-02-15 17:35:32
|
At 09:36am on 2002 February 15, Mike Melanson did write: > On Fri, 15 Feb 2002, W. Michael Petullo wrote: > > > I would like to implement a fullscreen mode in X11 tuxnes. Is anyone > > else working on a similar feature? Any comments? > > Nope, not that I know of. Go for it. It has been shown that the DGA target of the GGI renderer works fine fullscreen. However, the X11 renderer can't do this natively yet. -- "But if food is so good for you, how come the body keeps trying to get rid of it?" -- breatharian.com ji...@3e... / 0x43340710 / 517B C658 D2CB 260D 3E1F 5ED1 6DB3 FBB9 4334 0710 |