Differences between revisions 5 and 6
Revision 5 as of 2015-03-10 20:34:21
Size: 28979
Editor: asbesto
Comment:
Revision 6 as of 2015-03-10 20:40:48
Size: 8729
Editor: asbesto
Comment:
Deletions are marked like this. Additions are marked like this.
Line 202: Line 202:
Siccome l'upload dei file qua non sta funzionando, PORCODIO, ecco il programma in C:

{{{
/*
ADAFRUIT RETROGAME UTILITY: remaps buttons on Raspberry Pi GPIO header
to virtual USB keyboard presses. Great for classic game emulators!
Retrogame is interrupt-driven and efficient (usually under 0.3% CPU use)
and debounces inputs for glitch-free gaming.

Connect one side of button(s) to GND pin (there are several on the GPIO
header, but see later notes) and the other side to GPIO pin of interest.
Internal pullups are used; no resistors required. Avoid pins 8 and 10;
these are configured as a serial port by default on most systems (this
can be disabled but takes some doing). Pin configuration is currently
set in global table; no config file yet. See later comments.

Must be run as root, i.e. 'sudo ./retrogame &' or configure init scripts
to launch automatically at system startup.

Requires uinput kernel module. This is typically present on popular
Raspberry Pi Linux distributions but not enabled on some older varieties.
To enable, either type:

    sudo modprobe uinput

Or, to make this persistent between reboots, add a line to /etc/modules:

    uinput

Prior versions of this code, when being compiled for use with the Cupcade
or PiGRRL projects, required CUPCADE to be #defined. This is no longer
the case; instead a test is performed to see if a PiTFT is connected, and
one of two I/O tables is automatically selected.

Written by Phil Burgess for Adafruit Industries, distributed under BSD
License. Adafruit invests time and resources providing this open source
code, please support Adafruit and open-source hardware by purchasing
products from Adafruit!


Copyright (c) 2013 Adafruit Industries.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <sys/mman.h>
#include <linux/input.h>
#include <linux/uinput.h>


// START HERE ------------------------------------------------------------
// This table remaps GPIO inputs to keyboard values. In this initial
// implementation there's a 1:1 relationship (can't attach multiple keys
// to a button) and the list is fixed in code; there is no configuration
// file. Buttons physically connect between GPIO pins and ground. There
// are only a few GND pins on the GPIO header, so a breakout board is
// often needed. If you require just a couple extra ground connections
// and have unused GPIO pins, set the corresponding key value to GND to
// create a spare ground point.

#define GND -1
struct {
 int pin;
 int key;
} *io, // In main() this pointer is set to one of the two tables below.
   ioTFT[] = {
 // This pin/key table is used if an Adafruit PiTFT display
 // is detected (e.g. Cupcade or PiGRRL).
 // Input Output (from /usr/include/linux/input.h)
        // usiamo i gpio in sequenza numerica, non a cazzo.
        // codice colori come le resistenze.
        // GND cavetto NERO.
 { 2, KEY_LEFT }, // marrone Joystick (4 pins)
 { 3, KEY_RIGHT }, // rosso
 { 4, KEY_DOWN }, // arancio
 { 7, KEY_UP }, // giallo
 { 8, KEY_LEFTCTRL }, // verde A/Fire/jump/primary
 { 9, KEY_LEFTALT }, // blu B/Bomb/secondary
 { 10, KEY_SPACE }, // viola C/SPACE/BUTTON 3
 { 11, KEY_1 }, // grigio START joy START
 { 17, KEY_5 }, // bianco COIN
 { 18, KEY_ESC }, // altro nero, joy SELECT
 { -1, -1 } }, // END OF LIST, DO NOT CHANGE
 // MAME must be configured with 'z' & 'x' as buttons 1 & 2 -
 // this was required for the accompanying 'menu' utility to
 // work (catching crtl/alt w/ncurses gets totally NASTY).
 // Credit/start are likewise moved to 'r' & 'q,' reason being
 // to play nicer with certain emulators not liking numbers.
 // GPIO options are 'maxed out' with PiTFT + above table.
 // If additional buttons are desired, will need to disable
 // serial console and/or use P5 header. Or use keyboard.
   ioStandard[] = {
 // This pin/key table is used when the PiTFT isn't found
 // (using HDMI or composite instead), as with our original
 // retro gaming guide.
 // Input Output (from /usr/include/linux/input.h)
        // usiamo i gpio in sequenza numerica, non a cazzo.
        // codice colori come le resistenze.
        // GND cavetto NERO.
 { 2, KEY_LEFT }, // marrone Joystick (4 pins)
 { 3, KEY_RIGHT }, // rosso
 { 4, KEY_DOWN }, // arancio
 { 7, KEY_UP }, // giallo
 { 8, KEY_LEFTCTRL }, // verde A/Fire/jump/primary
 { 9, KEY_LEFTALT }, // blu B/Bomb/secondary
 { 10, KEY_SPACE }, // viola C/SPACE/BUTTON 3
 { 11, KEY_1 }, // grigio START joy START
 { 17, KEY_5 }, // bianco COIN
 { 18, KEY_ESC }, // altro nero, joy SELECT
 // For credit/start/etc., use USB keyboard or add more buttons.
 { -1, -1 } }; // END OF LIST, DO NOT CHANGE

// A "Vulcan nerve pinch" (holding down a specific button combination
// for a few seconds) issues an 'esc' keypress to MAME (which brings up
// an exit menu or quits the current game). The button combo is
// configured with a bitmask corresponding to elements in the above io[]
// array. The default value here uses elements 6 and 7 (credit and start
// in the Cupcade pinout). If you change this, make certain it's a combo
// that's not likely to occur during actual gameplay (i.e. avoid using
// joystick directions or hold-for-rapid-fire buttons).
// Also key auto-repeat times are set here. This is for navigating the
// game menu using the 'gamera' utility; MAME disregards key repeat
// events (as it should).
const unsigned long vulcanMask = (1L << 6) | (1L << 7);
const int vulcanKey = KEY_ESC, // Keycode to send
                    vulcanTime = 1500, // Pinch time in milliseconds
                    repTime1 = 500, // Key hold time to begin repeat
                    repTime2 = 100; // Time between key repetitions


// A few globals ---------------------------------------------------------

char
  *progName, // Program name (for error reporting)
   sysfs_root[] = "/sys/class/gpio", // Location of Sysfs GPIO files
   running = 1; // Signal handler will set to 0 (exit)
volatile unsigned int
  *gpio; // GPIO register table
const int
   debounceTime = 20; // 20 ms for button debouncing


// Some utility functions ------------------------------------------------

// Set one GPIO pin attribute through the Sysfs interface.
int pinConfig(int pin, char *attr, char *value) {
 char filename[50];
 int fd, w, len = strlen(value);
 sprintf(filename, "%s/gpio%d/%s", sysfs_root, pin, attr);
 if((fd = open(filename, O_WRONLY)) < 0) return -1;
 w = write(fd, value, len);
 close(fd);
 return (w != len); // 0 = success
}

// Un-export any Sysfs pins used; don't leave filesystem cruft. Also
// restores any GND pins to inputs. Write errors are ignored as pins
// may be in a partially-initialized state.
void cleanup() {
 char buf[50];
 int fd, i;
 sprintf(buf, "%s/unexport", sysfs_root);
 if((fd = open(buf, O_WRONLY)) >= 0) {
  for(i=0; io[i].pin >= 0; i++) {
   // Restore GND items to inputs
   if(io[i].key == GND)
    pinConfig(io[i].pin, "direction", "in");
   // And un-export all items regardless
   sprintf(buf, "%d", io[i].pin);
   write(fd, buf, strlen(buf));
  }
  close(fd);
 }
}

// Quick-n-dirty error reporter; print message, clean up and exit.
void err(char *msg) {
 printf("%s: %s. Try 'sudo %s'.\n", progName, msg, progName);
 cleanup();
 exit(1);
}

// Interrupt handler -- set global flag to abort main loop.
void signalHandler(int n) {
 running = 0;
}

// Returns 1 if running on early Pi board, 0 otherwise.
// Relies on info in /proc/cmdline by default; if this is
// unreliable in the future, easy change to /proc/cpuinfo.
int isRevOnePi(void) {
 FILE *fp;
 char buf[1024], *ptr;
 int n, rev = 0;
#if 1
 char *filename = "/proc/cmdline",
      *token = "boardrev=",
      *fmt = "%x";
#else
 char *filename = "/proc/cpuinfo",
      *token = "Revision", // Capital R!
      *fmt = " : %x";
#endif

 if((fp = fopen(filename, "r"))) {
  if((n = fread(buf, 1, sizeof(buf)-1, fp)) > 0) {
   buf[n] = 0;
   if((ptr = strstr(buf, token))) {
    sscanf(&ptr[strlen(token)], fmt, &rev);
   }
  }
  fclose(fp);
 }

 return ((rev == 0x02) || (rev == 0x03));
}


// Main stuff ------------------------------------------------------------

#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000)
#define BLOCK_SIZE (4*1024)
#define GPPUD (0x94 / 4)
#define GPPUDCLK0 (0x98 / 4)

int main(int argc, char *argv[]) {

 // A few arrays here are declared with 32 elements, even though
 // values aren't needed for io[] members where the 'key' value is
 // GND. This simplifies the code a bit -- no need for mallocs and
 // tests to create these arrays -- but may waste a handful of
 // bytes for any declared GNDs.
 char buf[50], // For sundry filenames
                        c; // Pin input value ('0'/'1')
 int fd, // For mmap, sysfs, uinput
                        i, j, // Asst. counter
                        bitmask, // Pullup enable bitmask
                        timeout = -1, // poll() timeout
                        intstate[32], // Last-read state
                        extstate[32], // Debounced state
                        lastKey = -1; // Last key down (for repeat)
 unsigned long bitMask, bit; // For Vulcan pinch detect
 volatile unsigned char shortWait; // Delay counter
 struct input_event keyEv, synEv; // uinput events
 struct pollfd p[32]; // GPIO file descriptors

 progName = argv[0]; // For error reporting
 signal(SIGINT , signalHandler); // Trap basic signals (exit cleanly)
 signal(SIGKILL, signalHandler);

 // Select io[] table for Cupcade (TFT) or 'normal' project.
 io = (access("/etc/modprobe.d/adafruit.conf", F_OK) ||
       access("/dev/fb1", F_OK)) ? ioStandard : ioTFT;

 // If this is a "Revision 1" Pi board (no mounting holes),
 // remap certain pin numbers in the io[] array for compatibility.
 // This way the code doesn't need modification for old boards.
 if(isRevOnePi()) {
  for(i=0; io[i].pin >= 0; i++) {
   if( io[i].pin == 2) io[i].pin = 0;
   else if(io[i].pin == 3) io[i].pin = 1;
   else if(io[i].pin == 27) io[i].pin = 21;
  }
 }

 // ----------------------------------------------------------------
 // Although Sysfs provides solid GPIO interrupt handling, there's
 // no interface to the internal pull-up resistors (this is by
 // design, being a hardware-dependent feature). It's necessary to
 // grapple with the GPIO configuration registers directly to enable
 // the pull-ups. Based on GPIO example code by Dom and Gert van
 // Loo on elinux.org

 if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
  err("Can't open /dev/mem");
 gpio = mmap( // Memory-mapped I/O
   NULL, // Any adddress will do
   BLOCK_SIZE, // Mapped block length
   PROT_READ|PROT_WRITE, // Enable read+write
   MAP_SHARED, // Shared with other processes
   fd, // File to map
   GPIO_BASE ); // Offset to GPIO registers
 close(fd); // Not needed after mmap()
 if(gpio == MAP_FAILED) err("Can't mmap()");
 // Make combined bitmap of pullup-enabled pins:
 for(bitmask=i=0; io[i].pin >= 0; i++)
  if(io[i].key != GND) bitmask |= (1 << io[i].pin);
 gpio[GPPUD] = 2; // Enable pullup
 for(shortWait=150;--shortWait;); // Min 150 cycle wait
 gpio[GPPUDCLK0] = bitmask; // Set pullup mask
 for(shortWait=150;--shortWait;); // Wait again
 gpio[GPPUD] = 0; // Reset pullup registers
 gpio[GPPUDCLK0] = 0;
 (void)munmap((void *)gpio, BLOCK_SIZE); // Done with GPIO mmap()


 // ----------------------------------------------------------------
 // All other GPIO config is handled through the sysfs interface.

 sprintf(buf, "%s/export", sysfs_root);
 if((fd = open(buf, O_WRONLY)) < 0) // Open Sysfs export file
  err("Can't open GPIO export file");
 for(i=j=0; io[i].pin >= 0; i++) { // For each pin of interest...
  sprintf(buf, "%d", io[i].pin);
  write(fd, buf, strlen(buf)); // Export pin
  pinConfig(io[i].pin, "active_low", "0"); // Don't invert
  if(io[i].key == GND) {
   // Set pin to output, value 0 (ground)
   if(pinConfig(io[i].pin, "direction", "out") ||
      pinConfig(io[i].pin, "value" , "0"))
    err("Pin config failed (GND)");
  } else {
   // Set pin to input, detect rise+fall events
   if(pinConfig(io[i].pin, "direction", "in") ||
      pinConfig(io[i].pin, "edge" , "both"))
    err("Pin config failed");
   // Get initial pin value
   sprintf(buf, "%s/gpio%d/value",
     sysfs_root, io[i].pin);
   // The p[] file descriptor array isn't necessarily
   // aligned with the io[] array. GND keys in the
   // latter are skipped, but p[] requires contiguous
   // entries for poll(). So the pins to monitor are
   // at the head of p[], and there may be unused
   // elements at the end for each GND. Same applies
   // to the intstate[] and extstate[] arrays.
   if((p[j].fd = open(buf, O_RDONLY)) < 0)
    err("Can't access pin value");
   intstate[j] = 0;
   if((read(p[j].fd, &c, 1) == 1) && (c == '0'))
    intstate[j] = 1;
   extstate[j] = intstate[j];
   p[j].events = POLLPRI; // Set up poll() events
   p[j].revents = 0;
   j++;
  }
 } // 'j' is now count of non-GND items in io[] table
 close(fd); // Done exporting


 // ----------------------------------------------------------------
 // Set up uinput

#if 1
 // Retrogame normally uses /dev/uinput for generating key events.
 // Cupcade requires this and it's the default. SDL2 (used by
 // some newer emulators) doesn't like it, wants /dev/input/event0
 // instead. Enable that code by changing to "#if 0" above.
 if((fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK)) < 0)
  err("Can't open /dev/uinput");
 if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
  err("Can't SET_EVBIT");
 for(i=0; io[i].pin >= 0; i++) {
  if(io[i].key != GND) {
   if(ioctl(fd, UI_SET_KEYBIT, io[i].key) < 0)
    err("Can't SET_KEYBIT");
  }
 }
 if(ioctl(fd, UI_SET_KEYBIT, vulcanKey) < 0) err("Can't SET_KEYBIT");
 struct uinput_user_dev uidev;
 memset(&uidev, 0, sizeof(uidev));
 snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "retrogame");
 uidev.id.bustype = BUS_USB;
 uidev.id.vendor = 0x1;
 uidev.id.product = 0x1;
 uidev.id.version = 1;
 if(write(fd, &uidev, sizeof(uidev)) < 0)
  err("write failed");
 if(ioctl(fd, UI_DEV_CREATE) < 0)
  err("DEV_CREATE failed");
#else // SDL2 prefers this event methodology
 if((fd = open("/dev/input/event0", O_WRONLY | O_NONBLOCK)) < 0)
  err("Can't open /dev/input/event0");
#endif

 // Initialize input event structures
 memset(&keyEv, 0, sizeof(keyEv));
 keyEv.type = EV_KEY;
 memset(&synEv, 0, sizeof(synEv));
 synEv.type = EV_SYN;
 synEv.code = SYN_REPORT;
 synEv.value = 0;

 // 'fd' is now open file descriptor for issuing uinput events


 // ----------------------------------------------------------------
 // Monitor GPIO file descriptors for button events. The poll()
 // function watches for GPIO IRQs in this case; it is NOT
 // continually polling the pins! Processor load is near zero.

 while(running) { // Signal handler can set this to 0 to exit
  // Wait for IRQ on pin (or timeout for button debounce)
  if(poll(p, j, timeout) > 0) { // If IRQ...
   for(i=0; i<j; i++) { // Scan non-GND pins...
    if(p[i].revents) { // Event received?
     // Read current pin state, store
     // in internal state flag, but
     // don't issue to uinput yet --
     // must wait for debounce!
     lseek(p[i].fd, 0, SEEK_SET);
     read(p[i].fd, &c, 1);
     if(c == '0') intstate[i] = 1;
     else if(c == '1') intstate[i] = 0;
     p[i].revents = 0; // Clear flag
    }
   }
   timeout = debounceTime; // Set timeout for debounce
   c = 0; // Don't issue SYN event
   // Else timeout occurred
  } else if(timeout == debounceTime) { // Button debounce timeout
   // 'j' (number of non-GNDs) is re-counted as
   // it's easier than maintaining an additional
   // remapping table or a duplicate key[] list.
   bitMask = 0L; // Mask of buttons currently pressed
   bit = 1L;
   for(c=i=j=0; io[i].pin >= 0; i++, bit<<=1) {
    if(io[i].key != GND) {
     // Compare internal state against
     // previously-issued value. Send
     // keystrokes only for changed states.
     if(intstate[j] != extstate[j]) {
      extstate[j] = intstate[j];
      keyEv.code = io[i].key;
      keyEv.value = intstate[j];
      write(fd, &keyEv,
        sizeof(keyEv));
      c = 1; // Follow w/SYN event
      if(intstate[j]) { // Press?
       // Note pressed key
       // and set initial
       // repeat interval.
       lastKey = i;
       timeout = repTime1;
      } else { // Release?
       // Stop repeat and
       // return to normal
       // IRQ monitoring
       // (no timeout).
       lastKey = timeout = -1;
      }
     }
     j++;
     if(intstate[i]) bitMask |= bit;
    }
   }

   // If the "Vulcan nerve pinch" buttons are pressed,
   // set long timeout -- if this time elapses without
   // a button state change, esc keypress will be sent.
   if((bitMask & vulcanMask) == vulcanMask)
    timeout = vulcanTime;
  } else if(timeout == vulcanTime) { // Vulcan timeout occurred
   // Send keycode (MAME exits or displays exit menu)
   keyEv.code = vulcanKey;
   for(i=1; i>= 0; i--) { // Press, release
    keyEv.value = i;
    write(fd, &keyEv, sizeof(keyEv));
    usleep(10000); // Be slow, else MAME flakes
    write(fd, &synEv, sizeof(synEv));
    usleep(10000);
   }
   timeout = -1; // Return to normal processing
   c = 0; // No add'l SYN required
  } else if(lastKey >= 0) { // Else key repeat timeout
   if(timeout == repTime1) timeout = repTime2;
   else if(timeout > 30) timeout -= 5; // Accelerate
   c = 1; // Follow w/SYN event
   keyEv.code = io[lastKey].key;
   keyEv.value = 2; // Key repeat event
   write(fd, &keyEv, sizeof(keyEv));
  }
  if(c) write(fd, &synEv, sizeof(synEv));
 }

 // ----------------------------------------------------------------
 // Clean up

 ioctl(fd, UI_DEV_DESTROY); // Destroy and
 close(fd); // close uinput
 cleanup(); // Un-export pins

 puts("Done.");

 return 0;
}

}}}
Schema dei collegamenti:

{{http://zaverio.com/~asbesto/gaming_gpio-rev2-new.png}}
Line 761: Line 247:
== Allegati ==

 * http://zaverio.com/~asbesto/retrotasti.tar.gz
 * http://zaverio.com/~asbesto/gaming_gpio-rev2-new.png
 * http://zaverio.com/~asbesto/retrogame.c

Mamestation

Realizzare una mini console per giochi emulati MAME scopo esposizione o autofinanziamento utilizzando Raspberry PI, joystick e tasti

Note tecniche RetroPie

File di config utili:

  • /etc/profile

qui dentro, per decidere cosa far partire:

#[ -n "${SSH_CONNECTION}" ] || emulationstation # lancia la stazione con tutti gli emulatori x giocare
#[ -n "${SSH_CONNECTION}" ] || /home/pi/asteroida # lancia asteroids come gioco mame
[ -n "${SSH_CONNECTION}" ] || /home/pi/nessa # lancia super mario clouds
#[ -n "${SSH_CONNECTION}" ] II /home/pi/ponta # lancia emulatore giochi pontaccio
  • /home/pi/asteroida

serve a far partire mame con asteroid:

/opt/retropie/emulators/mame4all-pi/mame asteroid
  • /home/pi/nessa

serve a far partire gioco NES / installazione super mario clouds

/opt/retropie/emulators/RetroArch/installdir/bin/retroarch -L /opt/retropie/emulatorcores/fceu-next/fceumm-code/fceumm_libretro.so --config /opt/retropie/configs/all/retroarch.cfg --appendconfig /opt/retropie/configs/nes/retroarch.cfg /home/pi/RetroPie/roms/nes/SuperMarioClouds.nes

VICE Emulatore C64 per giochi Pontaccio

da dentro Retropie-setup:

  • prima installi il pacchetto vice da retropie_packages.sh
  • poi installi i BINARI (opzione 1) da retropie_setup.sh

cosi' ti trovi l'emulatore che funziona ma va lanciato a mano:

Il menu di gestione dell'emulatore si apre con F12. da qui gli dici di emulare un mouse, e magicamente il cursore sparisce (!!!). Poi devi dargli save configuration.

ti da' segmentation fault?

devi lanciarlo con opzione -sdlbitdepth 16 altrimenti con 32 si incazza e segfaulta. ;)

Preparazione giochi

  • Attacca il tape all'emulatore da menu (Attach tape) clickando sul loader del gioco, cosi lui carica e lancia
  • Appena lanciato crea snapshot sotto forma di file .vsf ;)

Lanciare emulatore COMMODORE 64 su raspberry

/opt/retropie/emulators/vice-2.4/installdir/bin/x64 -sdlbitdepth 16 -1 /home/pi/pontaccio/superg4/SUPERG_4.tap -autostart /home/pi/pontaccio/superg4/mani.vsf 

file di autoavvio pontaccio, da lanciare dentro /etc/profile

Si chiama "ponta" e sta in /home/pi/

#
# asbesto 11/8/2014 aklab
#

ritardo=5m
comando="/opt/retropie/emulators/vice-2.4/installdir/bin/x64"
opzione="-sdlbitdepth 16"
nascondi=" 1>/dev/null 2>/dev/null &"
#
nastro1="/home/pi/pontaccio/superg1/superg1.tap"
snapshot11="/home/pi/pontaccio/superg1/cactus.vsf"
snapshot12="/home/pi/pontaccio/superg1/flags.vsf"
snapshot13="/home/pi/pontaccio/superg1/lifts.vsf"
#
nastro2="/home/pi/pontaccio/superg4/superg4.tap"
snapshot21="/home/pi/pontaccio/superg4/alfabetopazzo.vsf"
snapshot22="/home/pi/pontaccio/superg4/ammazzamedia.vsf"
snapshot23="/home/pi/pontaccio/superg4/compleanno.vsf"
snapshot24="/home/pi/pontaccio/superg4/mani.vsf"
#
nastro3="/home/pi/pontaccio/superg5/superg5.tap"
#
snapshot31="/home/pi/pontaccio/superg5/jessica.vsf"
snapshot32="/home/pi/pontaccio/superg5/superg.vsf"
#
sleppa="sleep 2m"


$comando $opzione -1 $nastro1 -autostart $snapshot11 &
$sleppa ; killall x64
$comando $opzione -1 $nastro1 -autostart $snapshot12 &
$sleppa ; killall x64 
$comando $opzione -1 $nastro1 -autostart $snapshot13 & 
$sleppa ; killall x64 

$comando $opzione -1 $nastro2 -autostart $snapshot21 &
$sleppa ; killall x64
$comando $opzione -1 $nastro2 -autostart $snapshot22 &
$sleppa ; killall x64 
$comando $opzione -1 $nastro2 -autostart $snapshot23 & 
$sleppa ; killall x64 
$comando $opzione -1 $nastro2 -autostart $snapshot24 &
$sleppa ; killall x64

$comando $opzione -1 $nastro3 -autostart $snapshot31 &
$sleppa ; killall x64 
$comando $opzione -1 $nastro3 -autostart $snapshot32 & 
$sleppa ; killall x64 

sleep 10
/home/pi/ponta 


#/opt/retropie/emulators/vice-2.4/installdir/bin/x64 -sdlbitdepth 16 \
#-1 /home/pi/pontaccio/superg4/SUPERG_4.tap \
#-autostart /home/pi/pontaccio/superg4/mani.vsf &

BRUTALE, ma fa.

Joypad USB con piu' di sei tasti

Problema: http://blog.petrockblock.com/forums/topic/mame4all-pi-with-ps3-controller/#post-7163

MAME va ricompilato:

There was a issue raised at mame4all-pi repository that resolved the problem. Apparently there is code that rejects controllers with more than 6 axes. Here is what I did. In a terminal, type

sudo nano home/pi/RetroPie/emulators/mame4all-pi/src/rpi/minimal.cpp

Comment out lines 168 to 174 so it appears as below.
//      if (SDL_JoystickNumAxes(myjoy) > 6)
//      {
//              SDL_JoystickClose(myjoy);
//              myjoy=0;
//              logerror("Error detected invalid joystick/keyboard\n");
//              break;
//      }

Save and exit.

Next you need to recompile the code so type in the terminal.

cd home/pi/RetroPie/emulators/mame4all-pi/
make

Reboot and your PS3 controller should now work.

Configurazione Joypad

Per configurare il joypad devi farlo sia dai menu di emulationstation, sia da MAME premendo TAB. e' un dito in culo ma poi funziona tutto, compresi insert coin e 1 player start.

Emulazione tastiera tramite contatti GPIO su raspberry

Serve per avere dei pulsanti esterni che corrispondono a tasti sulla tastiera, senza doverne collegare o modificare una.

Il programmino

E' retrogame.c in allegato che si trova in fondo alla pagina nel pacchetto retrotasti.tar.gz. Li i tasti sono programmati cosi:

   ioStandard[] = {
        // This pin/key table is used when the PiTFT isn't found
        // (using HDMI or composite instead), as with our original
        // retro gaming guide.
        // Input   Output (from /usr/include/linux/input.h)
        // usiamo i gpio in sequenza numerica, non a cazzo. 
        // codice colori come le resistenze. 
        //  GND cavetto NERO. 
        {   2,     KEY_LEFT     },   //  marrone Joystick (4 pins)
        {   3,     KEY_RIGHT    },   //  rosso
        {   4,     KEY_DOWN     },   //  arancio
        {   7,     KEY_UP       },   //  giallo
        {   8,     KEY_LEFTCTRL },   //  verde A/Fire/jump/primary
        {   9,     KEY_LEFTALT  },   //  blu B/Bomb/secondary
        {  10,     KEY_SPACE    },   //  viola C/SPACE/BUTTON 3 
        {  11,     KEY_1        },   //  grigio START joy START 
        {  17,     KEY_5        },   //  bianco COIN 
        {  18,     KEY_ESC      },   //  altro nero, joy SELECT 
        // For credit/start/etc., use USB keyboard or add more buttons.
        {  -1,     -1           } }; // END OF LIST, DO NOT CHANGE

Schema dei collegamenti:

http://zaverio.com/~asbesto/gaming_gpio-rev2-new.png

Configurazione per udev di merda

Va creato il file /etc/udev/rules.d/10-retrogame.rules con dentro:

SUBSYSTEM=="input", ATTRS{name}=="retrogame", ENV{ID_INPUT_KEYBOARD}="1"

start automatico del gestore dei tasti esterni

retrogame eseguibile va compilato ("make retrogame" da dentro la cartella del pacchetto retrotasti.tar.gz), poi va lanciato in automatico aggiungendo a /etc/rc.local, prima di "exit 0", la seguente riga:

/home/pi/Adafruit-Retrogame/retrogame &

basta riavviare e tutto deve funzionare a dovere.

I tasti configurati in retrogame.c sono 1, 5, control sinistro, alt sinistro, spazio, esc, e le 4 freccette. Questi tasti vanno configurati a loro volta dentro MAME e dentro, eventualmente, gli altri emulatori.

SONO CAZZI DI CHI LO FARA'

Lasciare solo UN emulatore (mame) o disabilitarne alcuni dalla lista di emulationstation

si deve editare es_systems.cfg che sta in /etc/emulationstation/ CANCELLANDO (non commentando!) quelli non voluti.

Prima fatti una copia di sicurezza! :)

root@raspberrypi:/etc/emulationstation# ls -la
total 64
drwxr-xr-x   3 root root  4096 Aug 14 10:16 .
drwxr-xr-x 101 root root  4096 Aug 14 09:57 ..
-rwxr-xr-x   1 root root 15279 Aug 14 10:16 es_systems.cfg
-rw-r--r--   1 root root 16420 Aug 14 10:14 es_systems.cfg.originale

Problema Bianco e Nero se connesso a tv/monitor

Succede perche' va a 60 Hz anziche' 50. C'e' un settaggio da toccare in /boot/config.txt, e' abbastanza intuitivo, riguarda PAL.

Allegati


CategoryMuseo

Museo/Mamestation (last edited 2022-08-18 16:22:11 by asbesto)