Guest User

PJM>BK2 Input Log converter v0.3.1

a guest
Sep 17th, 2015
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 14.14 KB | None | 0 0
  1. /**
  2.  * PJM>BK2 Input converter v0.3.1
  3.  * Author: CoolKirby
  4.  * Language: Java (Comments in English)
  5.  * First created: 9/12/15
  6.  * Last revised: 9/17/15
  7.  * Works with 1 and 2-player, DualShock and PSX Controller PJMs!
  8.  * Supports both DualShock and PSX Controller output: use 'convert.pjm' for DS, 'convert_pad.pjm' for PSX Controller
  9.  *
  10.  * Recent Changes: Support for native DualShock PJMs, Disc No./Disc Open/Disc Close/Reset, catch and correct most malformed PJMs
  11. */
  12.  
  13. import java.io.IOException; //Necessary to prevent exceptions
  14. import java.io.FileReader;
  15. import java.io.BufferedReader;
  16. import java.io.FileWriter;
  17. import java.io.PrintWriter;
  18.  
  19. /*
  20. Input formats:
  21. PJM #XO^1234LDRUS..s
  22. BK2 UDLRsSQTOXlrLR...
  23. num 0123456789ABCDEFa
  24.  
  25.      PJM:|Sq|Cros|Circ|Trian|....R1|...L1|....R2|......L2|..Left|.Down|Rt|Up|St|*L3|*R3|Sel|
  26.            6    9    8     7     11    10     13       12      2     1  3  0  5  14  15   4
  27.            #    X    O     ^      1     2      3        4      L     D  R  U  S   L   R   s
  28.      BK2:|Up|Down|Left|Right|Select|Start|Square|Triangle|Circle|Cross|L1|R1|L2| R2|*L3|*R3|*MODE| *DualShock only
  29.            0    1    2     3      4     5      6        7      8     9 10 11 12  13  14  15    16
  30.            U    D    L     R      s     S      Q        T      O     X  l  r  L   R   <   >     M
  31.      
  32.       PJM ..............||0|    BK2  |   -1,...|  128,  128,  128,  128,.................|
  33. */
  34.  
  35. public class PJMConverter{
  36.   public static void main(String[] args) throws IOException{
  37.       try{
  38.         countLinesDS("convert.pjm"); //File to read from (input - PJM)
  39.       }catch(IOException e){
  40.         try{ //Nested try-catch for alternate read option
  41.           countLinesStd("convert_pad.pjm"); //Standard PSX Controller file to read from (input - PJM)
  42.         }catch(IOException ee){
  43.           System.out.println(e.getMessage());
  44.         }
  45.       }
  46.   }
  47.  
  48.   public static void countLinesDS(String path) throws IOException{
  49.     Boolean DualShockOut=true;
  50.     countLines(path,DualShockOut); //If integrated into BizHawk, it could set this based on existing PSX settings
  51.   }
  52.  
  53.   public static void countLinesStd(String path) throws IOException{
  54.     Boolean DualShockOut=false;
  55.     countLines(path,DualShockOut);
  56.   }
  57.  
  58.   public static void countLines(String path, Boolean DualShockOut) throws IOException{
  59.       FileReader a = new FileReader(path);
  60.       BufferedReader num = new BufferedReader(a); //Open countLines text buffer
  61.        
  62.       String aLine;
  63.       int numLines=0;
  64.      
  65.       while ((aLine=num.readLine()) != null){ //Count number of lines in the PJM
  66.         numLines++;
  67.       }
  68.       num.close(); //Close countLines text buffer
  69.      
  70.       if(numLines<2){ //Assume error if input file has 0 or 1 lines
  71.         System.out.println("Input PJM is too short! Conversion failed. Please check your file.");
  72.         System.exit(5000);
  73.       }
  74.      
  75.       OpenFile(path,numLines,DualShockOut);
  76.   }
  77.      
  78.   public static void OpenFile(String path, int numLines, Boolean DualShockOut) throws IOException{
  79.       String output="Input Log.txt"; //File to write to (output - BK2)
  80.      
  81.       FileReader fr = new FileReader(path); // Loads initial PJM
  82.       BufferedReader reader = new BufferedReader(fr); // Reads whole lines in to speed up script
  83.      
  84.       String[] PJMData = new String[numLines]; // Create the array of PJM input with the calculated # of lines
  85.       int inputStart; //will contain index of first . or # char
  86.      
  87.       PJMData[0]=reader.readLine(); //Read the first line of the PJM separately
  88.       if(PJMData[0].indexOf('#')==-1) //Find where the input starts
  89.         inputStart=PJMData[0].indexOf('.');
  90.       else
  91.         inputStart=PJMData[0].indexOf('#'); //Failsafe in case Square was pressed on first frame
  92.       PJMData[0]=PJMData[0].substring(inputStart,PJMData[0].length()); //Strip off the PJM header
  93.      
  94.       for(int i=1;i<numLines;i++){ //Read the rest of the PJM starting from frame 2
  95.         PJMData[i]=reader.readLine();
  96.         if(numLines-i==0){
  97.           PJMData[i]=reader.readLine(); //"Catch" the elusive last input line and add it to the table
  98.         }
  99.       }
  100.      
  101.       reader.close();
  102.      
  103.       parseFile(PJMData,numLines,path,output,DualShockOut);
  104.   }
  105.  
  106.   public static void parseFile(String[] PJMData, int numLines, String path, String output, Boolean DualShockOut) throws IOException {
  107.     int numBK2Lines=numLines+1;
  108.    
  109.     Boolean P2=false,DSInput=false; //Player 2 and DualShock off unless turned on below
  110.     int numDots, P2do=0; //number of input spaces (dots) for PSX Controller; offset of P2 DualShock input dots
  111.     int numTrayOps=0, discNum=1, specNumPos=16; //number of tray operations, % 2 R0 is closed tray, R1 is open; disc #; |1| position
  112.     char SpecOpen,SpecClose,SpecReset; //default values for "special" characters preceding input
  113.    
  114.     if(PJMData[1].charAt(14)=='.'){ //discreetly checks for DS and Player 2 input without confusing the P1 scanner
  115.       DSInput=true; //1 player, DualShock detected
  116.       specNumPos=34;
  117.       if(PJMData[1].charAt(33)=='.'||PJMData[1].charAt(33)=='#'){
  118.         P2=true; //2 players, DualShock detected
  119.         P2do=18;
  120.         DSInput=true;
  121.         specNumPos=66;
  122.       }
  123.     }else{
  124.       if(PJMData[1].charAt(15)=='.'||PJMData[1].charAt(15)=='#'){
  125.         P2=true; //2 players, Standard Controller
  126.         specNumPos=30;
  127.       }
  128.     }
  129.    
  130.     if(DualShockOut) //If user wants DualShock input from a regular PJM, blank the last three dots
  131.       numDots=17;
  132.     else //The opposite: if user wants PSX Controller input from a DS PJM, remove the DS-specific input
  133.       numDots=14;
  134.    
  135.     String[] BK2Data = new String[numBK2Lines]; //1 line larger to fit BK2 LogKey comment
  136.     String[] BK2DataP2 = new String[numBK2Lines]; //second array for holding Player 2 input
  137.    
  138.     char[] Button = new char[numDots]; //array for pressed buttons on an input line
  139.     String[] SpecButton = new String[numBK2Lines]; //array for Disc #, Reset, Tray Open & Close
  140.    
  141.     String[] SpecJoystick = new String[numBK2Lines]; //array for DualShock joystick values (0-255)
  142.     String[] SpecJoystickP2 = new String[numBK2Lines]; //second array for holding Player 2 input
  143.    
  144.     //Add in BizHawk LogKey line for author's convenience
  145.     if(P2){ //If Player 2 input exists, recognize it
  146.       if(DualShockOut) //2 players + DualShock for both
  147.         BK2Data[0]="LogKey:#Disc Select|Open|Close|Reset|#P1 LStick X|P1 LStick Y|P1 RStick X|P1 RStick Y|P1 Up|P1 Down|P1 Left|P1 Right|P1 Select|P1 Start|P1 Square|P1 Triangle|P1 Circle|P1 Cross|P1 L1|P1 R1|P1 L2|P1 R2|P1 L3|P1 R3|P1 MODE|#P2 LStick X|P2 LStick Y|P2 RStick X|P2 RStick Y|P2 Up|P2 Down|P2 Left|P2 Right|P2 Select|P2 Start|P2 Square|P2 Triangle|P2 Circle|P2 Cross|P2 L1|P2 R1|P2 L2|P2 R2|P2 L3|P2 R3|P2 MODE|";
  148.       else //2 players + Standard Controller for both
  149.         BK2Data[0]="LogKey:#Disc Select|Open|Close|Reset|#P1 Up|P1 Down|P1 Left|P1 Right|P1 Select|P1 Start|P1 Square|P1 Triangle|P1 Circle|P1 Cross|P1 L1|P1 R1|P1 L2|P1 R2|#P2 Up|P2 Down|P2 Left|P2 Right|P2 Select|P2 Start|P2 Square|P2 Triangle|P2 Circle|P2 Cross|P2 L1|P2 R1|P2 L2|P2 R2|";
  150.     }else{
  151.       if(DualShockOut) //1 player + DualShock
  152.         BK2Data[0]="LogKey:#Disc Select|Open|Close|Reset|#P1 LStick X|P1 LStick Y|P1 RStick X|P1 RStick Y|P1 Up|P1 Down|P1 Left|P1 Right|P1 Select|P1 Start|P1 Square|P1 Triangle|P1 Circle|P1 Cross|P1 L1|P1 R1|P1 L2|P1 R2|P1 L3|P1 R3|P1 MODE|";
  153.       else //1 player + Standard Controller
  154.         BK2Data[0]="LogKey:#Disc Select|Open|Close|Reset|#P1 Up|P1 Down|P1 Left|P1 Right|P1 Select|P1 Start|P1 Square|P1 Triangle|P1 Circle|P1 Cross|P1 L1|P1 R1|P1 L2|P1 R2|";
  155.     }
  156.     for(int i=1,p=0;i<numBK2Lines;i++,p++){ // The big parser! Player 1 Input
  157.       BK2Data[i]="";
  158.       for(int b=0;b<numDots;b++) // The default blank Input Log line
  159.         Button[b]='.';
  160.       SpecOpen='.'; SpecClose='.'; SpecReset='.'; //Re-initialize Special characters
  161.      
  162.       if(PJMData[p].charAt(specNumPos)=='1') //Reset Button
  163.         SpecReset='r';
  164.       if(PJMData[p].charAt(specNumPos)=='2'){ //Determine if PJM opened or closed the disc drive
  165.         if(numTrayOps%2==0)
  166.           SpecOpen='!'; //first, third, etc. calls are treated as opening drive
  167.         else{
  168.           SpecClose='!'; //second, fourth, etc. calls are treated as closing drive
  169.           discNum++; //insert the next disc
  170.         }
  171.         numTrayOps++;
  172.       }
  173.       SpecButton[i]="|    "+discNum+','+SpecOpen+SpecClose+SpecReset+'|'; //assemble beginning spec characters
  174.      
  175.       if(numDots==17){ //DualShock Joystick values
  176.         if(DSInput==false||PJMData[p].charAt(19)<'0'||PJMData[p].charAt(19)>'9')
  177.           SpecJoystick[i]="128,  128,  128,  128,"; //if no Stick value listed, assume malformed PJM and prefill values with defaults
  178.         else //P1 LStick and RStick positions
  179.           SpecJoystick[i]=PJMData[p].substring(17,20)+",  "+PJMData[p].substring(21,24)+",  "+PJMData[p].substring(25,28)+",  "+PJMData[p].substring(29,32)+",";
  180.         if(P2){
  181.           if(DSInput==false||PJMData[p].charAt(52)<'0'||PJMData[p].charAt(52)>'9') //try 19 next*
  182.             SpecJoystickP2[i]="128,  128,  128,  128,"; //if no Stick value listed, assume malformed PJM and prefill values with defaults
  183.           else //P2 LStick and RStick positions
  184.             SpecJoystickP2[i]=PJMData[p].substring(50,53)+",  "+PJMData[p].substring(54,57)+",  "+PJMData[p].substring(58,61)+",  "+PJMData[p].substring(62,65)+",";
  185.         }
  186.       }
  187.      
  188.       if(PJMData[p].charAt(0)=='#') //P1 Square
  189.         Button[6]='Q';
  190.       if(PJMData[p].charAt(1)=='X') //P1 Cross
  191.         Button[9]='X';
  192.       if(PJMData[p].charAt(2)=='O') //P1 Circle
  193.         Button[8]='O';
  194.       if(PJMData[p].charAt(3)=='^') //P1 Triangle
  195.         Button[7]='T';
  196.       if(PJMData[p].charAt(4)=='1') //P1 R1
  197.         Button[11]='r';
  198.       if(PJMData[p].charAt(5)=='2') //P1 L1
  199.         Button[10]='l';
  200.       if(PJMData[p].charAt(6)=='3') //P1 R2
  201.         Button[13]='R';
  202.       if(PJMData[p].charAt(7)=='4') //P1 L2
  203.         Button[12]='L';
  204.       if(PJMData[p].charAt(8)=='L') //P1 D-Pad Left
  205.         Button[2]='L';
  206.       if(PJMData[p].charAt(9)=='D') //P1 D-Pad Down
  207.         Button[1]='D';
  208.       if(PJMData[p].charAt(10)=='R') //P1 D-Pad Right
  209.         Button[3]='R';
  210.       if(PJMData[p].charAt(11)=='U') //P1 D-Pad Up
  211.         Button[0]='U';
  212.       if(PJMData[p].charAt(12)=='S') //P1 Start
  213.         Button[5]='S';
  214.       if(DSInput){ //DualShock specific
  215.         if(DualShockOut){ //Only output DualShock buttons if DSOut=true
  216.           if(PJMData[p].charAt(13)=='L') //P1 L3
  217.             Button[14]='<';
  218.           if(PJMData[p].charAt(14)=='R') //P1 R3
  219.             Button[15]='>';
  220.         }
  221.         if(PJMData[p].charAt(15)=='s') //P1 Select from DualShock PJM
  222.           Button[4]='s';
  223.       }else{
  224.         if(PJMData[p].charAt(13)=='s') //P1 Select from PSX Controller PJM
  225.           Button[4]='s';
  226.       }
  227.       for(int s=0;s<numDots;s++) // Set buttons to input line positions
  228.         BK2Data[i]=BK2Data[i]+Button[s];
  229.      
  230.       if(P2){ //If Player 2 input exists, parse it!
  231.         BK2DataP2[i]="";
  232.         for(int b=0;b<numDots;b++) // The default blank Input Log line
  233.           Button[b]='.';
  234.        
  235.         if(PJMData[p].charAt(P2do+15)=='#') //P2 Square
  236.           Button[6]='Q';
  237.         if(PJMData[p].charAt(P2do+16)=='X') //P2 Cross
  238.           Button[9]='X';
  239.         if(PJMData[p].charAt(P2do+17)=='O') //P2 Circle
  240.           Button[8]='O';
  241.         if(PJMData[p].charAt(P2do+18)=='^') //P2 Triangle
  242.           Button[7]='T';
  243.         if(PJMData[p].charAt(P2do+19)=='1') //P2 R1
  244.           Button[11]='r';
  245.         if(PJMData[p].charAt(P2do+20)=='2') //P2 L1
  246.           Button[10]='l';
  247.         if(PJMData[p].charAt(P2do+21)=='3') //P2 R2
  248.           Button[13]='R';
  249.         if(PJMData[p].charAt(P2do+22)=='4') //P2 L2
  250.           Button[12]='L';
  251.         if(PJMData[p].charAt(P2do+23)=='L') //P2 D-Pad Left
  252.           Button[2]='L';
  253.         if(PJMData[p].charAt(P2do+24)=='D') //P2 D-Pad Down
  254.           Button[1]='D';
  255.         if(PJMData[p].charAt(P2do+25)=='R') //P2 D-Pad Right
  256.           Button[3]='R';
  257.         if(PJMData[p].charAt(P2do+26)=='U') //P2 D-Pad Up
  258.           Button[0]='U';
  259.         if(PJMData[p].charAt(P2do+27)=='S') //P2 Start
  260.           Button[5]='S';
  261.         if(DSInput){ //DualShock specific
  262.           if(DualShockOut){ //Only output DualShock buttons if DSOut=true
  263.             if(PJMData[p].charAt(P2do+28)=='L') //P2 L3
  264.               Button[14]='<';
  265.             if(PJMData[p].charAt(P2do+29)=='R') //P2 R3
  266.               Button[15]='>';
  267.           }
  268.           if(PJMData[p].charAt(P2do+30)=='s') //P2 Select from DualShock PJM
  269.             Button[4]='s';
  270.         }else{
  271.           if(PJMData[p].charAt(28)=='s') //P2 Select from PSX Controller PJM
  272.             Button[4]='s';
  273.         }
  274.         for(int s=0;s<numDots;s++) // Set buttons to input line positions
  275.           BK2DataP2[i]=BK2DataP2[i]+Button[s];
  276.       }
  277.     }
  278.    
  279.     System.out.println(numBK2Lines+" lines in finished BK2");
  280.    
  281.     //Write File
  282.     FileWriter write = new FileWriter(output);
  283.     PrintWriter print_line = new PrintWriter(write); //use PrintWriter to print "%n" character on both Windows and Unix
  284.    
  285.     //Output all BK2 Input, including beginning and ending lines
  286.     print_line.printf("%s"+"%n",BK2Data[0]); //First line is LogKey, no appended data needed
  287.    
  288.     for(int l=1;l<=numLines;l++){
  289.       if(P2){
  290.         if(DualShockOut) //2 players + DualShock
  291.           print_line.printf("%s"+"  "+"%s"+"%s"+"|  "+"%s"+"%s"+"|"+"%n",SpecButton[l],SpecJoystick[l],BK2Data[l],SpecJoystickP2[l],BK2DataP2[l]);
  292.         else //2 players + Standard Controller
  293.           print_line.printf("%s"+"%s"+"|"+"%s"+"|"+"%n",SpecButton[l],BK2Data[l],BK2DataP2[l]);
  294.       }else{
  295.         if(DualShockOut) //1 player + DualShock
  296.           print_line.printf("%s"+"  "+"%s"+"%s"+"|"+"%n",SpecButton[l],SpecJoystick[l],BK2Data[l]);
  297.         else //1 player + Standard Controller
  298.           print_line.printf("%s"+"%s"+"|"+"%n",SpecButton[l],BK2Data[l]);
  299.       }
  300.     }
  301.    
  302.     print_line.close(); // Close file printing stream
  303.     System.out.println("Done! Check out Input Log.txt");
  304.   }
  305. }
Advertisement
Add Comment
Please, Sign In to add comment