Code: Select all
/*
** readMacro converts binary AkelPad .macro files to editable text files and vice versa.
** Version 0.1_2012-09-23. This file and the code it contains are in the public domain.
**
** readMacro takes three or four arguments: readMacro mode [infile] [outfile]
** mode is either -decode (from .macro file to text) or -encode (text to .macro).
**
** In decoding mode infile is a .macro file and outfile (optional) is the output
** textfile (if no outfile is given, readMacro writes to stdout).
**
** If encoding infile (optional) is a textfile, outfile is the output .macro file
** (if no infile is given, readMacro reads from stdin).
**
** Decoding a .macro into a text file and encoding this back into a .macro file
** should produce identical files.
*/
#include <malloc.h>
#include <stdio.h>
#include <string.h>
typedef struct _KEYACT {
unsigned char bVk;
unsigned int dwFlags;
} KEYACT;
#define VK_MAX 0x92
char *VKs[VK_MAX]={0};
char *flags[5]={"d", // KEYDOWN
"dx", // KEYDOWN and EXTENDED
"u", // KEYUP
"ux", // KEYUP and EXTENDED
"0x%04x" // undefined
};
int error(char *err) {
fprintf(stderr,"%s\n",err);
return -1;
}
int main(int argc, char **argv) {
FILE *infile,*outfile;
VKs[0x08]="back";
VKs[0x09]="tab";
VKs[0x0C]="clear";
VKs[0x0D]="return";
VKs[0x10]="shift";
VKs[0x11]="control";
VKs[0x12]="menu";
VKs[0x13]="pause";
VKs[0x14]="capital";
VKs[0x15]="kana";
VKs[0x17]="junja";
VKs[0x18]="final";
VKs[0x19]="hanja";
VKs[0x19]="kanji";
VKs[0x1B]="escape";
VKs[0x1C]="convert";
VKs[0x1D]="nonconvert";
VKs[0x1E]="accept";
VKs[0x1F]="modechange";
VKs[0x20]="space";
VKs[0x21]="prior";
VKs[0x22]="next";
VKs[0x23]="end";
VKs[0x24]="home";
VKs[0x25]="left";
VKs[0x26]="up";
VKs[0x27]="right";
VKs[0x28]="down";
VKs[0x29]="select";
VKs[0x2A]="print";
VKs[0x2B]="execute";
VKs[0x2C]="snapshot";
VKs[0x2D]="insert";
VKs[0x2E]="delete";
VKs[0x2F]="help";
VKs[0x30]="0";
VKs[0x31]="1";
VKs[0x32]="2";
VKs[0x33]="3";
VKs[0x34]="4";
VKs[0x35]="5";
VKs[0x36]="6";
VKs[0x37]="7";
VKs[0x38]="8";
VKs[0x39]="9";
VKs[0x41]="a";
VKs[0x42]="b";
VKs[0x43]="c";
VKs[0x44]="d";
VKs[0x45]="e";
VKs[0x46]="f";
VKs[0x47]="g";
VKs[0x48]="h";
VKs[0x49]="i";
VKs[0x4A]="j";
VKs[0x4B]="k";
VKs[0x4C]="l";
VKs[0x4D]="m";
VKs[0x4E]="n";
VKs[0x4F]="o";
VKs[0x50]="p";
VKs[0x51]="q";
VKs[0x52]="r";
VKs[0x53]="s";
VKs[0x54]="t";
VKs[0x55]="u";
VKs[0x56]="v";
VKs[0x57]="w";
VKs[0x58]="x";
VKs[0x59]="y";
VKs[0x5A]="z";
VKs[0x5B]="lwin";
VKs[0x5C]="rwin";
VKs[0x5D]="apps";
VKs[0x5F]="sleep";
VKs[0x60]="numpad0";
VKs[0x61]="numpad1";
VKs[0x62]="numpad2";
VKs[0x63]="numpad3";
VKs[0x64]="numpad4";
VKs[0x65]="numpad5";
VKs[0x66]="numpad6";
VKs[0x67]="numpad7";
VKs[0x68]="numpad8";
VKs[0x69]="numpad9";
VKs[0x6A]="multiply";
VKs[0x6B]="add";
VKs[0x6C]="separator";
VKs[0x6D]="subtract";
VKs[0x6E]="decimal";
VKs[0x6F]="divide";
VKs[0x70]="f1";
VKs[0x71]="f2";
VKs[0x72]="f3";
VKs[0x73]="f4";
VKs[0x74]="f5";
VKs[0x75]="f6";
VKs[0x76]="f7";
VKs[0x77]="f8";
VKs[0x78]="f9";
VKs[0x79]="f10";
VKs[0x7A]="f11";
VKs[0x7B]="f12";
VKs[0x7C]="f13";
VKs[0x7D]="f14";
VKs[0x7E]="f15";
VKs[0x7F]="f16";
VKs[0x80]="f17";
VKs[0x81]="f18";
VKs[0x82]="f19";
VKs[0x83]="f20";
VKs[0x84]="f21";
VKs[0x85]="f22";
VKs[0x86]="f23";
VKs[0x87]="f24";
VKs[0x90]="numlock";
VKs[0x91]="scroll";
// If adding further elements change VK_MAX!
if (argc<3||argc>4) return error("Wrong number of arguments: mode [infile] [outfile]\n"
" mode is either -decode (from .macro file to text) or -encode (text to .macro).\n"
" If decoding infile is a .macro file, outfile (optional) is the output textfile\n"
" (if no outfile is given, readMacro writes to stdout).\n"
" If encoding infile (optional) is a textfile, outfile is the output .macro file\n"
" (if no infile us given, readMacro reads from stdin).\n");
if (!stricmp(argv[1],"-decode")) {
unsigned long fileLen,n=0;
char flag[16];
KEYACT *ka;
if (!(infile=fopen(argv[2],"rb"))) return error("Unable to open infile");
fseek(infile,0,SEEK_END);
fileLen=ftell(infile);
fseek(infile,0,SEEK_SET);
ka=(KEYACT *)malloc(fileLen);
if (!ka) {
fclose(infile);
return error("Memory allocation failed");
}
fread(ka,fileLen,1,infile);
fclose(infile);
if (argc==3) outfile=stdout;
else if (!(outfile=fopen(argv[3],"w+"))) return error("Unable to open outfile");
while (n<fileLen) {
if (ka->dwFlags>3) sprintf(flag,flags[4],ka->dwFlags);
else strcpy(flag,flags[ka->dwFlags]);
if (VKs[ka->bVk]&&ka->dwFlags<4) fprintf(outfile,"%s %s\n",VKs[ka->bVk],flag);
else fprintf(outfile,"# %i %s\n",ka->bVk,flag);
ka++;
n=n+sizeof(KEYACT);
}
if (argc==4) fclose(outfile);
free(ka);
fprintf(stderr,"Conversion successful, %i items converted.\n",n/sizeof(KEYACT));
}
else if (!stricmp(argv[1],"-encode")) {
char buf[64];
KEYACT ka;
int j=0;
if (argc==3) infile=stdin;
else if (!(infile=fopen(argv[2],"r"))) return error("Unable to open infile");
if (!(outfile=fopen(argv[argc-1],"wb"))) {
fclose(infile);
return error("Unable to open outfile");
}
while (fgets(buf,sizeof(buf),infile)) {
char *delim=strchr(buf,'\n');
int i;
if (buf[0]=='#') continue;
if (delim) *delim=0;
if (!(delim=strchr(buf,' '))) {
printf("warning: unrecognised input\n");
continue;
}
*delim=0;
delim++;
memset(&ka,0,sizeof(ka));
if (!stricmp(delim,flags[0])) ka.dwFlags=0;
else if (!stricmp(delim,flags[1])) ka.dwFlags=1;
else if (!stricmp(delim,flags[2])) ka.dwFlags=2;
else if (!stricmp(delim,flags[3])) ka.dwFlags=3;
else {
printf("warning: unrecognised flag, entry skipped\n");
continue;
}
ka.bVk=255;
for (i=0;i<VK_MAX;i++) {
if (VKs[i]&&(!stricmp(buf,VKs[i]))) {
ka.bVk=(unsigned char)i;
break;
}
}
if (ka.bVk==255) {
printf("warning: unrecognised VK, entry skipped\n");
continue;
}
printf("%08x %08x\n",ka.bVk,ka.dwFlags);
if (fwrite(&ka,sizeof(ka),1,outfile)!=1) {
fclose(infile);
fclose(outfile);
error("Error while writing outfile");
}
j++;
}
if (argc==4) fclose(infile);
fclose(outfile);
fprintf(stderr,"Conversion successful, %i items converted.\n",j);
}
else return error("Unrecognised mode switch, use either -decode or -encode");
return 1;
}