Monogame testing

Trying Monogame libraries out, took around 2 hours to convert an old XNA game to run on android. Only a few issues encountered. The first is my own fault. The game did not instantly respond to button presses. In XNA using mouse state was allowed even on phones touchscreen, whilst Android only seems to respond to touch functions. The second issue is that the resolution of the game was only about a third of the size of the screen. This is due to the game being made for use of Windows Phone 7, which was 800 by 480, which by today’s standards is pretty small. I came up with my own  solution for this, which was to draw to a RenderTarget2D, and the draw it with a scale, this worked perfectly, even after the first compile. I created a method for also scaling up the physical position of buttons so that it correctly works with the new scale.

The only other issue I encountered was with content loading. Monogame was missing references needed to compile when using a separate shared project, which need specifying before compiling in the pipeline application.

I hope to use this for a few projects in the future.

Attiny85 development board

So I ordered an item on Ebay without any research as it was cheap. I ordered an Attiny 8DIP development board with a micro USB connection. It arrived along with the chips, and I try to plug in to my laptop. Almost instantly it shows a windows notification saying that the USB device has malfunctioned. Every single place that sold the board had no data sheets or information that went with it. I came across this site which finally started answering my questions. Looking at the board there is no more than about 10 components and wasn’t expecting much functionality. I found that the board is a clone of a Digispark development board. These other boards has surface mount chips. The chips coulld talk directly to the PC. Looking at this thread, I realised that my issue was that my chip itself required setting up initially before this board could be used. The Digispark chips contained a boot-loader in the program memory taking around 2k or of their 8k total and this gave it the ability to talk over USB. With that boot-loader and the instructions in the link, I got the blink sketch to upload to the chip.

Custom PS4 Remote Control

I play a lot of games, and switching between device is always very annoying, so I had an idea to try and create a way to navigate both PS4 and Xbox One, I had to use multiple remotes or controllers. Trying to watch a video on PS4 using a controller was a huge problem, always hitting keys, especially triggers when just placing the controller on a surface would fast forward a video for example.

I had the official remote for Xbox One, which is a useful remote. It lights up when it moves so its easy to find, and it also is a very simple layout, with around 15 – 20 buttons. With the use of Kinect it allowed me to control the TV volume which is useful. I generally watch YouTube videos or watch DVDs using the Xbox due to the remote, and built in video options, such as casting. Unluckily for me I’d rather use my PS4, so could not use this remote, or could I….

I came up with this.

Because I like the Xbox One official remote, I wanted to be able to use this for the PS4 too. I ordered a IR receiver which I used with my Arduino Uno. With this I was able to receive the infrared signals the remote was sending out. Using these signals and a few changes to the sketch code, it was relatively easy to control outputs to turn devices on or off.

I then needed a way to connect this to the PS4, which doesn’t have an infrared receiver. I knew that a keyboard could be connected, as I had seen this option whilst navigating the settings menu. I plugged in a USB keyboard, and it worked straight away. Using arrow keys to navigate, escape to go back and enter to advance. There were then a few features I could not work out, so I used the power of the internet to find the keys I was missing, most noticeably, the home button, which is the only way out of games and some applications. This turned out to be the pause/break button. Other keys were needed for items such as for DVD menus which are F1 to F3. Now I had this information, I needed a way to use an Arduino to create this keyboards buttons.

An Arduino Uno cannot be used for this, or at least not directly. I instead needed an Arduino that can act as a keyboard. An Arduino with an ATmega32u4 chip, which can act as a HID (Human Interface Device), which means it can act as a game pad, mouse, or any type of device that can sends commands to a computer. In this case we want to use it as a keyboard.

I used a Arduino Micro Pro along with and along with the built in libraries for Keyboard, allows a keystroke, or combination of keystrokes to be sent to whatever device is connected to it via USB.

Basic buttons were easy to reproduce, but again, the button I struggled to use was the pause/break key, which was a 72 with an offset of 136, due to the way the input is validated.

All that was left to do was to link the IR remote button codes to the keyboard commands to send.

Plugging into the PS4 and using the remote works instantly.

One thing that I added after is that when a button is held, the command isn’t repeated, instead a repeat code is sent, so additional code was added so a button can be held down.

Code and schematics to follow…

/*
   IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
   An IR detector/demodulator must be connected to the input RECV_PIN.
   Version 0.1 July, 2009
   Copyright 2009 Ken Shirriff
   http://arcfn.com
*/
#include "HID-Project.h"
#include 
int RECV_PIN = 2;
int LED_PIN = 13;
IRrecv irrecv(RECV_PIN);
decode_results results;

//////////////////////////// V I P E R - I R - R E M O T E////////////////////////////

//#define EXIT                     //POWER
#define BACK   18596923                //MODE
#define MUTE          18575503           //MUTE

#define PLAY         18550513            //PLAY/PAUSE
#define SKIPBWD      18602023               //REWIND SHORT
#define SKIPFWD       18569383              //FORWARD SHORT

#define ENT                  18564283    //EQ
#define VOLUME_DN      18581623          //VOL -
#define VOLUME_UP       18548983         //VOL +
#define BWD    18589783                  //#0
#define FWD     18557143                 //RPT
#define STOP       18585703           //U/SD
#define MENU 18572443
#define TOPMENU 18609673
#define FORWARD       18557143              //#1
#define REWIND    18589783                //#2
#define SWITCH     18577033               //#3 Next Program ALT+TAB
#define XBOX 18556633
#define CHNUP            18565303       //#4 Next Next Program ALT+TAB+TAB
#define CHNDOWN           18597943        //#4 Next Next Program ALT+TAB+TAB

#define UP            18577543           //#5 UP Arrow 
#define LFT            18547963          //#7 Enter 
#define DWN           18610183           //#8 Left Arrow 
#define RHT             18580603         //#9 Right Arrow 

/////////////////////////  MEDIA PLAYER HOT KEYS   /////////////////////////////////

#define PLAY_FUN    Keyboard.press(KEY_SPACE);delay(100); Keyboard.releaseAll();
#define SWITCH_FUN         Keyboard.press(KEY_PAUSE); delay(100); Keyboard.releaseAll();

#define BACK_FUN         Keyboard.press(HID_KEYBOARD_ESCAPE); delay(100); Keyboard.releaseAll();
#define MUTE_FUN           Consumer.press(MEDIA_VOLUME_MUTE); delay(100); Keyboard.releaseAll();
#define VOLUME_UP_FUN      Consumer.press(MEDIA_VOLUME_UP);      delay(100); Keyboard.releaseAll();
#define VOLUME_DN_FUN      Consumer.press(MEDIA_VOLUME_DOWN);    delay(100); Keyboard.releaseAll();
#define SKIPBWD_FUN           Keyboard.press(KEY_LEFT_ARROW); delay(100); Keyboard.releaseAll();
#define SKIPFWD_FUN          Keyboard.press( KEY_RIGHT_ARROW); delay(100); Keyboard.releaseAll();
#define FWD_FUN            Keyboard.press(KEY_RIGHT_ARROW);  delay(100); Keyboard.releaseAll();
#define BWD_FUN           Keyboard.press( KEY_LEFT_ARROW); delay(100); Keyboard.releaseAll();
#define STOP_FUN        Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll();
#define UP_FUN             Keyboard.press(KEY_UP_ARROW);   delay(100); Keyboard.releaseAll();
#define DWN_FUN            Keyboard.press(KEY_DOWN_ARROW);      delay(100); Keyboard.releaseAll();
#define ENT_FUN            Keyboard.press(KEY_RETURN); delay(100); Keyboard.releaseAll();
#define LFT_FUN            Keyboard.press(KEY_LEFT_ARROW);   delay(100); Keyboard.releaseAll();
#define RHT_FUN            Keyboard.press(KEY_RIGHT_ARROW);   delay(100); Keyboard.releaseAll();
#define CHNUP_FUN            Keyboard.press(KEY_RIGHT_ARROW);  delay(100); Keyboard.releaseAll();
#define CHNDOWN_FUN            Keyboard.press(KEY_RIGHT_ARROW); delay(100); Keyboard.releaseAll();
#define MENU_FUN            Keyboard.press(HID_KEYBOARD_F3); delay(100); Keyboard.releaseAll();
#define TOPMENU_FUN            Keyboard.press(HID_KEYBOARD_F2); delay(100); Keyboard.releaseAll();
long lastValue = 0xFFFFFFFF;
///////////////////////////  SETUP //////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(LED_PIN, OUTPUT);
  Keyboard.begin();
}
////////////////////////// main prog ////////////////////////////////////
void loop() {
  if (irrecv.decode(&results))
  {
    digitalWrite(LED_PIN, HIGH);
    if (results.value == 0xFFFFFFFF)
    {
      results.value = lastValue;
    }
    /////////////////// ADD YOUR FUNCTIO0N HERE //////////////////////////

    if (results.value == MUTE)        {
      MUTE_FUN;
    }
    else if (results.value == BACK)        {
      BACK_FUN;
    }
    else if (results.value == SWITCH)        {
      SWITCH_FUN;
    }
    else if (results.value == PLAY)        {
      PLAY_FUN;
    }
    else if (results.value == STOP)        {
      STOP_FUN;
    }
     else if (results.value == FWD)        {
      FWD_FUN;
    }
    else if (results.value == BWD)        {
      BWD_FUN;
    }
    else if (results.value == SKIPFWD)        {
      SKIPFWD_FUN;
    }
    else if (results.value == SKIPBWD)        {
      SKIPBWD_FUN;
    }
    else if (results.value == CHNUP)        {
      CHNUP_FUN;
    }
    else if (results.value == CHNDOWN)        {
      CHNDOWN_FUN;
    }
    else if (results.value == ENT)         {
      ENT_FUN;
    }
    else if (results.value == MENU)         {
      MENU_FUN;
    }
    else if (results.value == TOPMENU)         {
      TOPMENU_FUN;
    }
    else if (results.value == VOLUME_UP)   {
      VOLUME_UP_FUN;
    }
    else if (results.value == VOLUME_DN)   {
      VOLUME_DN_FUN;
    }
    else if (results.value == UP)          {
      UP_FUN;
    }
    else if (results.value == LFT)         {
      LFT_FUN;
    }
    else if (results.value == DWN)         {
      DWN_FUN;
    }
    else if (results.value == RHT)         {
      RHT_FUN;
    }
    else {
      Serial.println(results.value, DEC);       //ir code
    }
    if (results.value != 0xFFFFFFFF)
    {
      lastValue = results.value  ;
    }
    //delay(100);
    digitalWrite(LED_PIN, LOW);
    irrecv.resume(); // Receive the next value
  }
}