MSXはアンドロイドの夢を見るか10

PC限定ですがUSBゲームパッドを使えるように以下を修正。

fMSX.c

#ifndef _IS01
        case 23: N++;
                 if(N>=argc)
                   printf("%s: No joystick type supplied\n",argv[0]);
                 else
                   switch(JoyCount++)
                   {
                     case 0: JoyTypeA=atoi(argv[N]);break;
                     case 1: JoyTypeB=atoi(argv[N]);break;
                     default: printf("%s: Excessive -joy option\n",argv[0]);
                   }
                 break;
#endif
#ifndef SDL
        case 24: N++;
                 if(N>=argc)
                   printf("%s: No home directory name supplied\n",argv[0]);
                 else
                   ProgDir=argv[N];
                 break;
(省略)

SDLgfx.c

#ifdef _IS01
//#include <android/log.h>
static int alt=0;
#else
SDL_Joystick *joy=NULL;
#define SDL_INIT       SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK
#endif
(省略)
  /* Init the SDL library */
  if(Verbose)
    printf("Initializing SDL drivers:\n  Init SDL library...");
  if (SDL_Init(SDL_INIT)<0) {
    if(Verbose) puts("FAILED");
    return(0);
  }
#ifndef _IS01
  if (SDL_NumJoysticks()==1) joy=SDL_JoystickOpen(0);
#endif
(省略)

/** Keyboard() ***********************************************/
/** Check for keyboard events, parse them, and modify MSX   **/
/** keyboard matrix.                                        **/
/*************************************************************/
void Keyboard(void)
{

  SDL_Event event;
  static byte Control=0;
  int key,I;
#ifndef _IS01
  Sint16 axis;
#endif

  /* Check for keypresses/keyreleases */
  while(SDL_PollEvent(&event)) {

    key=event.key.keysym.sym;
    if(event.type==SDL_QUIT) ExitNow=1;
#ifndef _IS01
	if (joy) {
        SDL_JoystickUpdate();
	    if (SDL_JoystickGetButton(joy,0)) {
			JoyState|=0x10;
		} else {
			JoyState&=0xEF;
		}
	    if (SDL_JoystickGetButton(joy,1)) {
			JoyState|=0x20;
		} else {
			JoyState&=0xDF;
		}
	    axis=SDL_JoystickGetAxis(joy,0);
	    if (axis>=256) {
			JoyState|=0x08;
		} else if(axis<=-256) {
			JoyState|=0x04;
		} else {
			JoyState&=0xFB;
			JoyState&=0xF7;
		}
		axis=SDL_JoystickGetAxis(joy,1);
		if (axis>=256) {
			JoyState|=0x02;
		} else if(axis<=-256) {
			JoyState|=0x01;
		} else {
			JoyState&=0xFE;
			JoyState&=0xFD;
		}
	}
#endif
    /***************/
    /* KEY PRESSED */
    /***************/

    if(event.type==SDL_KEYDOWN) {

      switch(key)
	  {
	  
	  /******************************/
	  /* F6: SWITCH AUTOFIRE ON/OFF */
	  /******************************/

	  case SDLK_F6:
	  if(Control) {
	    AutoFire=!AutoFire;
	    if(AutoFire) NewMessage(strdup("\n Autofire On \n\n"));
	    else NewMessage(strdup("\n Autofire Off \n\n"));
	  }
	  break;


	  /************************/
	  /* CTRL+F7: TAPE REWIND */
	  /************************/

	  case SDLK_F7:
	  if(Control) {
	    RewindTape();
	    NewMessage(strdup("\n Tape Rewound \n\n"));
	  }
	  break;


	  /***********************/
	  /* F9: LOAD STATE      */
	  /* CTRL+F9: SAVE STATE */
	  /***********************/

	  case SDLK_F9:
	  if(StateName) { 
	    char StateNotification[512];
	    sprintf(StateNotification,"\n State %s %s \n\n",
		    StateName,Control?"saved":"loaded");
	    if(Control) SaveState(StateName); else LoadState(StateName); 
	    NewMessage(strdup(StateNotification));
	  }
	  break;


	  /******************************/
	  /* END: SWITCH IMAGE FILTER   */
	  /* CTRL+END: FLIP STEREO/MONO */
	  /******************************/

	  case SDLK_END:
	   if (Control) {
	     if (UseStereo) {
	       UseStereo=0;
	       NewMessage(strdup("\n Mono \n\n"));
	     } else {
	       UseStereo=1;
	       NewMessage(strdup("\n Stereo \n\n"));
	     }
	   } else {
	     if (WIDTH==640) {
	       UseFilter++;
	       if (UseFilter>5) UseFilter=0;
	       NewMessage(strdup(filter_name[UseFilter]));
	       full_scanline(screen,&XBuf);/* clear scanlines */
	     }
	   }
	   break;


	   /**************************/
	   /* CTRL+F10: SWITCH DISKA */
	   /* CTRL+F11: SWITCH DISKB */
	   /**************************/

	  case SDLK_F10:
	  case SDLK_F11:
           if(Control) {
             I=(key==SDLK_F11)? 1:0;
             if(Disks[I][0]) {
	           char DiskNotification[512];
	           CurDisk[I]=(CurDisk[I]+1)%MAXDISKS;
	           if(!Disks[I][CurDisk[I]]) CurDisk[I]=0;
	           ChangeDisk(I,Disks[I][CurDisk[I]]);
	           /* notify user */
	           sprintf(DiskNotification,
		       "\n Disk %c: %s \n\n",
		       'A'+I,Disks[I][CurDisk[I]]);
	           NewMessage(strdup(DiskNotification));
	        }
	       }
           break;


	   /**********************/
	   /* F12: EXIT EMULATOR */
	   /* CTRL+F12: DEBUGER  */
	   /**********************/

	  case SDLK_F12:
#ifdef DEBUG
	  if(Control) CPU.Trace=!CPU.Trace; 
	  else
#endif
	  ExitNow=1;
	  break;


	  /***************************/
	  /* SCROLL-LOCK: RESET      */
	  /* CTRL+SCROLL: HARD RESET */
	  /***************************/

	  case 0x4000010e: // <-
	  case SDLK_SCROLLOCK:
	  if(Control) 
	    ResetMSX(1);
	  else 	      
	    ResetMSX(0);
	  break;


	  /********************************/
	  /* CURSOR KEYS: CURSOR MOVEMENT */
	  /********************************/
#ifdef _IS01
	  case SDLK_UP:    JoyState|=0x01;break;
      case SDLK_DOWN:  JoyState|=0x02;break;
      case SDLK_LEFT:  JoyState|=0x04;break;
      case SDLK_RIGHT: JoyState|=0x08;break;
      case SDLK_LALT:  JoyState|=0x10;break;
      case SDLK_LCTRL:
	    if(key==SDLK_LCTRL) JoyState|=0x20;
	    Control=1;
	    break;
	}
      /***********************************/
      /* OTHER KEYS: reset bit in KeyMap */
      /***********************************/
	  if (key==SDLK_LALT) {
		  key=SDLK_UNKNOWN;
      }
	  if (key==0x7f) key=0x8;
	  if (key==0x400000e1) key=0x130;
	  if (key==0x400000e5) key=0x13f;
	  if (key==0x4000004e) key=0x133;
	  if (key==0x4000004b) key=0x134;
	  if (key==0x4000010c) {
		  XKeyMap[Keys[0x132][0]]&=~Keys[0x132][1];
		  key=0x121;
	  }
	  if (key==0x40000051) key=0x112;
	  if (key==0x40000052) key=0x111;
	  if (key==0x4000004f) key=0x113;
	  if (key==0x40000050) key=0x114;
	  if (key==0x40000076) key=0x116; // MENU
	  if (alt && key==SDLK_l) key=SDLK_SEMICOLON;
	  if (alt && key==SDLK_SLASH) key=SDLK_QUOTE;
	  if (alt && key==SDLK_COMMA) key=SDLK_RIGHTBRACKET;
	  if (alt && key==SDLK_PERIOD) key=0x60;
	  if (alt && key==SDLK_p) key=SDLK_LEFTBRACKET;
	  if (alt && key==SDLK_MINUS) key=SDLK_BACKSLASH;
	  if (alt && key==SDLK_0) key=SDLK_EQUALS;
	  if (alt && key==SDLK_q) key=SDLK_TAB;
	  if (alt && key==SDLK_1) key=0x11a;
	  if (alt && key==SDLK_2) key=0x11b;
	  if (alt && key==SDLK_3) key=0x11c;
	  if (alt && key==SDLK_4) key=0x11d;
	  if (alt && key==SDLK_5) key=0x11e;
	  if (alt && key==0x8) key=0x115;
	  if (alt && key==SDLK_m) key=0x131;
      if(key<0x150) XKeyMap[Keys[key][0]]&=~Keys[key][1];
#else
	}
	if (key==SDLK_END) key=0x60;
	if (key==SDLK_RCTRL) key=0x131;
    if(key<0x150) XKeyMap[Keys[key][0]]&=~Keys[key][1];
#endif
  }

    /****************/
    /* KEY RELEASED */
    /****************/
    
  if(event.type==SDL_KEYUP) {	

      /* Special keys released... */
#ifdef _IS01
    switch(key)
	{
	case SDLK_UP:    JoyState&=0xFE;break;
	case SDLK_DOWN:  JoyState&=0xFD;break;
	case SDLK_LEFT:  JoyState&=0xFB;break;
	case SDLK_RIGHT: JoyState&=0xF7;break;
	case SDLK_LALT:  JoyState&=0xEF;break;
	case SDLK_LCTRL: JoyState&=0xDF;Control=0;break;
	}

	  if (key==SDLK_LALT) {
		  key=SDLK_UNKNOWN;
		  alt++;
		  if (alt > 1) alt=0;
      }
//      __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "key: %0x",key);
	  if (key==0x7f) key=0x8;
	  if (key==0x400000e1) key=0x130;
	  if (key==0x400000e5) key=0x13f;
	  if (key==0x4000004e) key=0x133;
	  if (key==0x4000004b) key=0x134;
	  if (key==0x4000010c) {
		  XKeyMap[Keys[0x132][0]]|=Keys[0x132][1];
		  key=0x121;
      }
	  if (key==0x40000051) key=0x112;
	  if (key==0x40000052) key=0x111;
	  if (key==0x4000004f) key=0x113;
	  if (key==0x40000050) key=0x114;
	  if (key==0x40000076) key=0x116; // MENU
	  if (alt && key==SDLK_l) key=SDLK_SEMICOLON;
	  if (alt && key==SDLK_SLASH) key=SDLK_QUOTE;
	  if (alt && key==SDLK_COMMA) key=SDLK_RIGHTBRACKET;
	  if (alt && key==SDLK_PERIOD) key=0x60;
	  if (alt && key==SDLK_p) key=SDLK_LEFTBRACKET;
	  if (alt && key==SDLK_MINUS) key=SDLK_BACKSLASH;
	  if (alt && key==SDLK_0) key=SDLK_EQUALS;
	  if (alt && key==SDLK_q) key=SDLK_TAB;
	  if (alt && key==SDLK_1) key=0x11a;
	  if (alt && key==SDLK_2) key=0x11b;
	  if (alt && key==SDLK_3) key=0x11c;
	  if (alt && key==SDLK_4) key=0x11d;
	  if (alt && key==SDLK_5) key=0x11e;
	  if (alt && key==0x8) key=0x115;
	  if (alt && key==SDLK_m) key=0x131;
      if(key<0x150) XKeyMap[Keys[key][0]]|=Keys[key][1];
#else
	  if (key==SDLK_END) key=0x60;
	  if (key==SDLK_RCTRL) key=0x131;
//      printf("key: %0x\n",key);
      /* Key released: set bit in KeyMap */
      if(key<0x150) XKeyMap[Keys[key][0]]|=Keys[key][1];
#endif
  }
  }
  /* Copy local keymap to the global one */
  memcpy(KeyMap,XKeyMap,sizeof(XKeyMap));
}

実行時の引数にも以下が必要なので注意!

  • joy 1