summaryrefslogtreecommitdiff
path: root/Xenogears/compil.lex
diff options
context:
space:
mode:
Diffstat (limited to 'Xenogears/compil.lex')
-rw-r--r--Xenogears/compil.lex383
1 files changed, 383 insertions, 0 deletions
diff --git a/Xenogears/compil.lex b/Xenogears/compil.lex
new file mode 100644
index 0000000..f6ceda8
--- /dev/null
+++ b/Xenogears/compil.lex
@@ -0,0 +1,383 @@
+ #include <string.h>
+ /* In text block */
+%s I
+ /* Outside of text block */
+%s O
+ /* Waiting for Width argument */
+%s W
+ /* Waiting for OpCode arguments */
+%s Op
+
+ int num_blocks = 0;
+ int num_lines = 0;
+ int cur_num_lines = 0;
+ int cur_num_block = 0;
+ int line_width = 0;
+ int max_line_width = 0;
+ int block_lines = 0;
+ int block_width = 0;
+ int errstate = 0;
+ void yputc(int c, int a);
+ void unputs(char *);
+
+%%
+
+<INITIAL>"<Blocks:"\ *[[:digit:]]+">"\n {
+ int i;
+ char zeros[4] = {0, 0, 0, 0};
+ num_blocks = atoi(yytext + 8);
+ fprintf(stderr, "Number of blocks: %i\n", num_blocks);
+ num_blocks--;
+ fwrite(&num_blocks, 4, 1, yyout);
+ num_blocks++;
+
+ for (i = 0; i < num_blocks; i++) {
+ fwrite(zeros, 4, 1, yyout);
+ }
+
+ num_lines = 2;
+
+ BEGIN(O);
+ }
+
+<INITIAL>.* {
+ fprintf(stderr, "Invalid file, must begin with <Blocks: XX>\n");
+ errstate = 1;
+ num_lines = 2;
+ num_blocks = 9999;
+ }
+
+<O>"<Text_block lines:"\ *[[:digit:]]+\ + {
+ if (cur_num_block >= num_blocks) {
+ fprintf(stderr, "Error: too much blocks at line %i\n", num_lines);
+ errstate = 1;
+ }
+ block_lines = atoi(yytext + 18);
+ BEGIN(W);
+ }
+
+<W>"width:"\ *[[:digit:]]+">\n" {
+ block_width = atoi(yytext + 6);
+ fprintf(stderr, "Begin of block %i at line %i -- lines = %i, width = %i\n", cur_num_block, num_lines, block_lines, block_width);
+ num_lines++;
+ line_width = 0;
+ max_line_width = 0;
+ cur_num_lines = 1;
+ if (num_blocks != 9999) {
+ long p = ftell(yyout);
+ fseek(yyout, 4 + cur_num_block * 2, SEEK_SET);
+ fwrite(&p, 2, 1, yyout);
+ fseek(yyout, (num_blocks - 1) * 2, SEEK_CUR);
+ putc(block_width, yyout);
+ putc(block_lines, yyout);
+ fseek(yyout, 0, SEEK_END);
+ }
+ BEGIN(I);
+ }
+
+<W>.* {
+ fprintf(stderr, "Error: invalid arguments to command Text_block at line %i: '%s'\n", num_lines, yytext);
+ errstate = 1;
+ BEGIN(O);
+ }
+
+<I>"\n" {
+ if (line_width > block_width) {
+ fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width);
+ }
+ if (line_width > max_line_width)
+ max_line_width = line_width;
+ line_width = 0;
+ num_lines++;
+ cur_num_lines++;
+ if (cur_num_lines > block_lines) {
+ fprintf(stderr, "Warning: too much lines for text block %i at line %i (%i > %i)\n", cur_num_block, num_lines, cur_num_lines, block_lines);
+ }
+ putc(1, yyout);
+ }
+
+<I>"<New>\n" {
+ if (line_width > block_width) {
+ fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width);
+ }
+ if (line_width > max_line_width)
+ max_line_width = line_width;
+ line_width = 0;
+ num_lines++;
+ cur_num_lines = 1;
+ putc(2, yyout);
+ }
+
+<I>"<Wait>\n" {
+ if (line_width > block_width) {
+ fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width);
+ }
+ if (line_width > max_line_width)
+ max_line_width = line_width;
+ line_width = 0;
+ num_lines++;
+ cur_num_lines = 1;
+ putc(1, yyout);
+ putc(3, yyout);
+ }
+
+<I>"<Wait>" {
+ cur_num_lines = 1;
+ putc(3, yyout);
+ }
+
+<I>"<Delay"\ +[[:digit:]]+">" {
+ int d = atoi(yytext + 7);
+ if (d > 255) {
+ fprintf(stderr, "Error: delay too important: %i\n", d);
+ errstate = 1;
+ } else {
+ putc(0xf, yyout);
+ putc(0, yyout);
+ putc(d, yyout);
+ }
+ }
+
+<I>"<Gear"\ +[[:digit:]]+">" {
+ int d = atoi(yytext + 5);
+ if (d > 255) {
+ fprintf(stderr, "Error: gear number too important: %i\n", d);
+ errstate = 1;
+ } else {
+ putc(0xf, yyout);
+ putc(5, yyout);
+ putc(d, yyout);
+ line_width += 16;
+ }
+ }
+
+<I>"<Opcode"\ +/[[:digit:]]+\ +[[:digit:]]+">" {
+ BEGIN(Op);
+ }
+
+<Op>[[:digit:]]+\ +[[:digit:]]+">" {
+ int o1, o2;
+ o1 = atoi(yytext);
+ o2 = atoi(yytext + (o1 < 10 ? 2 : o1 < 100 ? 3 : 4));
+ putc(0xf, yyout);
+ putc(o1, yyout);
+ putc(o2, yyout);
+ BEGIN(I);
+ }
+
+<Op>[^<]*">" {
+ yytext[strlen(yytext - 1)] = 0;
+ fprintf(stderr, "Error: invalid OpCode '%s'\n", yytext);
+ errstate = 1;
+ BEGIN(I);
+ }
+
+<I>" " yputc(0x10, 2);
+<I>"+" yputc(0x11, 2);
+<I>"," yputc(0x12, 2);
+<I>"-" yputc(0x13, 2);
+<I>"." yputc(0x14, 2);
+<I>"/" yputc(0x15, 2);
+<I>[[:digit:]] yputc(*yytext - 0x1a, 2);
+<I>[[:upper:]] yputc(*yytext - 0x21, 2);
+<I>"[" yputc(0x3a, 2);
+<I>"]" yputc(0x3b, 2);
+<I>"=" yputc(0x3c, 2);
+<I>[[:lower:]] yputc(*yytext - 0x24, 2);
+<I>"!" yputc(0x57, 2);
+<I>"\"" yputc(0x58, 2);
+<I>"#" yputc(0x59, 2);
+<I>"%" yputc(0x5a, 2);
+<I>"&" yputc(0x5b, 2);
+<I>"'" yputc(0x5c, 2);
+<I>"(" yputc(0x5d, 2);
+<I>")" yputc(0x5e, 2);
+<I>":" yputc(0x5f, 2);
+<I>"?" yputc(0x60, 2);
+<I>"<"[[:digit:]]">" yputc(*(yytext + 1) + 0x31, 3);
+<I>"<%>" yputc(0x6b, 3);
+<I>"<&>" yputc(0x6c, 3);
+<I>"*" yputc(0x6d, 3);
+<I>"<C>" yputc(0x6e, 3);
+<I>"<S>" yputc(0x6f, 3);
+<I>"<T>" yputc(0x70, 3);
+<I>"<*>" yputc(0x71, 3);
+<I>"<R>" yputc(0x72, 3);
+<I>"<L>" yputc(0x73, 3);
+<I>"<U>" yputc(0x74, 3);
+<I>"<D>" yputc(0x75, 3);
+<I>"<.>" yputc(0x76, 3);
+<I>"<:>" yputc(0x77, 3);
+<I>"</>" yputc(0x79, 3);
+<I>"<..>" yputc(0x7a, 3);
+<I>"<`>" yputc(0x7b, 3);
+<I>"<+>" yputc(0x7d, 3);
+<I>"<->" yputc(0x7e, 3);
+<I>"<X>" yputc(0x7f, 3);
+<I>"<[>" yputc(0x80, 3);
+<I>"<]>" yputc(0x81, 3);
+<I>"<(>" yputc(0x84, 3);
+<I>"<)>" yputc(0x85, 3);
+<I>"<#>" yputc(0x86, 3);
+<I>"`" yputc(0x87, 3);
+<I>"°" yputc(0x88, 3);
+<I>"<=>" yputc(0x89, 3);
+<I>"<?>" yputc(0x8a, 3);
+<I>"<!>" yputc(0x8b, 3);
+<I>"_" yputc(0x8c, 3);
+<I>"~" yputc(0x8d, 3);
+<I>"<...>" yputc(0x8e, 3);
+<I>"<'>" yputc(0x8f, 3);
+
+<I>"<Extra1"\ +[[:digit:]]+">" {
+ int d = atoi(yytext + 7);
+ if (d > 255) {
+ fprintf(stderr, "Error: Extra1 number too important: %i\n", d);
+ errstate = 1;
+ } else {
+ putc(0xfe, yyout);
+ putc(d, yyout);
+ }
+ }
+
+<I>"<Extra2"\ +[[:digit:]]+">" {
+ int d = atoi(yytext + 7);
+ if (d > 255) {
+ fprintf(stderr, "Error: Extra2 number too important: %i\n", d);
+ errstate = 1;
+ } else {
+ putc(0xff, yyout);
+ putc(d, yyout);
+ }
+ }
+
+<I>"<Bare"\ +[[:xdigit:]]{1,2}">" {
+ char str[5] = {'0', 'x', 0, 0, 0};
+ int d;
+ for (yytext += 6; *yytext == ' '; yytext++);
+ str[2] = *(yytext++);
+ str[3] = *(yytext++);
+ sscanf(str, "%i", &d);
+ if (d > 255) {
+ fprintf(stderr, "Error: Bare number too important: %i\n", d);
+ errstate = 1;
+ } else {
+ putc(d, yyout);
+ }
+ }
+
+<I>à|â|ä unput('a');
+<I>é|è|ê|ë unput('e');
+<I>î|ï unput('i');
+<I>ô|ö unput('o');
+<I>û|ü|ù unput('u');
+<I>ç unput('c');
+<I>"<oe>" unput('e'); unput('o');
+<I>"<ae>" unput('e'); unput('a');
+
+<I>"<Fei>" unputs("<Gear 00>");
+<I>"<Elly>" unputs("<Gear 01>");
+<I>"<Citan>" unputs("<Gear 02>");
+<I>"<Bart>" unputs("<Gear 03>");
+<I>"<Billy>" unputs("<Gear 04>");
+<I>"<Rico>" unputs("<Gear 05>");
+<I>"<Emeralda>" unputs("<Gear 06>");
+<I>"<Chu-Chu>" unputs("<Gear 07>");
+<I>"<Maria>" unputs("<Gear 08>");
+<I>"<Citan-2>" unputs("<Gear 09>");
+<I>"<Emeralda-2>" unputs("<Gear 10>");
+<I>"<Weltall>" unputs("<Gear 11>");
+<I>"<Waltall-2>" unputs("<Gear 12>");
+<I>"<Vierge>" unputs("<Gear 13>");
+<I>"<Heimdal>" unputs("<Gear 14>");
+<I>"<Brigandier>" unputs("<Gear 15>");
+<I>"<Renmazuo>" unputs("<Gear 16>");
+<I>"<Stier>" unputs("<Gear 17>");
+<I>"<BigChu-chu>" unputs("<Gear 18>");
+<I>"<Seibzehn>" unputs("<Gear 19>");
+<I>"<Crescens>" unputs("<Gear 20>");
+<I>"<Regurus>" unputs("<Gear 21>");
+<I>"<Fenrir>" unputs("<Gear 22>");
+<I>"<Andvari>" unputs("<Gear 23>");
+<I>"<Renmazuo>" unputs("<Gear 24>");
+<I>"<Stier-2>" unputs("<Gear 25>");
+<I>"<Xenogears>" unputs("<Gear 26>");
+<I>"<BARTHOS>" unputs("<Gear 27>");
+<I>"<Yggdra>" unputs("<Gear 29>");
+<I>"<Perso1>" unputs("<Gear 128>");
+<I>"<Perso2>" unputs("<Gear 129>");
+<I>"<Perso3>" unputs("<Gear 130>");
+
+
+<I>"\n<End_of_block>" {
+ if (line_width > max_line_width)
+ max_line_width = line_width;
+ if (max_line_width < block_width)
+ fprintf(stderr, "Warning: block %i too large (%i < %i)\n", cur_num_block, max_line_width, block_width);
+ if (line_width > block_width)
+ fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width);
+ num_lines++;
+ cur_num_block++;
+ putc(0, yyout);
+ BEGIN(O);
+ }
+
+<I>"<"[^\>\n]*">" {
+ yytext[strlen(yytext) - 1] = 0;
+ fprintf(stderr, "Error: Invalid command at line %i: '%s'\n", num_lines, yytext + 1);
+ errstate = 1;
+ }
+
+<O>\n num_lines++;
+<O>. /* Eat up comments */
+
+<I>. {
+ fprintf(stderr, "Invalid character at line %i: '%c'\n", num_lines, *yytext);
+ errstate = 1;
+ }
+
+. {
+ fprintf(stderr, "Hu uh, something's wrong at line %i...\n", num_lines);
+ }
+
+%%
+
+int yywrap(void) {
+ if (cur_num_block < num_blocks) {
+ fprintf(stderr, "Warning: Too few blocks at end of file.\n");
+ }
+ exit(errstate ? -1 : 0);
+}
+
+int main(int argc, char ** argv) {
+ if ((argc < 2) || (argc > 3)) {
+ fprintf(stderr, "Usage: %s <output> [input]\n", argv[0]);
+ exit(-1);
+ }
+ if (!(yyout = fopen(argv[1], "wb"))) {
+ fprintf(stderr, "Error: can't open file %s\n", argv[1]);
+ exit(-1);
+ }
+ if (argc == 3) {
+ if (!(yyin = fopen(argv[2], "rb"))) {
+ fprintf(stderr, "Error: can't open file %s\n", argv[2]);
+ exit(-1);
+ }
+ }
+ fprintf(stderr, "Creating file %s\n", argv[1]);
+ yylex();
+ exit(errstate ? -1 : 0);
+}
+
+void yputc(int c, int a) {
+ line_width += a;
+ putc(c, yyout);
+}
+
+void unputs(char * s) {
+ int l = strlen(s), i;
+
+ for (i = l - 1; i >= 0; i--) {
+ unput(s[i]);
+ }
+}