aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/dtputil/anmutil.cpp63
-rwxr-xr-xtools/dtputil/build3
-rw-r--r--tools/dtputil/dtputil.cpp43
-rw-r--r--tools/lsrc/lsrc.cpp348
-rw-r--r--tools/lsrc/scriptshared.hpp150
-rw-r--r--tools/lsrc/test.lsr25
6 files changed, 632 insertions, 0 deletions
diff --git a/tools/dtputil/anmutil.cpp b/tools/dtputil/anmutil.cpp
new file mode 100644
index 0000000..6636e2c
--- /dev/null
+++ b/tools/dtputil/anmutil.cpp
@@ -0,0 +1,63 @@
+#include "../../include/smdatapack.hpp"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+int main(int argc,char** argv)
+{
+ if(argc<3)
+ return printf("usage: %s <r/w> <anmfilename> [filetoread1/filetowrite1] ...\n",argv[0]),1;
+ if(argv[1][0]=='w')
+ {
+ smDtpFileW file;
+ for(int i=3;i<argc;++i)
+ {
+ char* rp=argv[i];
+ if(*rp=='.'&&*(rp+1)=='/')rp+=2;
+ if(!file.addFile(rp,argv[i]))
+ printf("error adding file: %s\n",argv[i]);
+ }
+ char *wn=new char[strlen(argv[2])+10];
+ strcat(wn,".writing");
+ file.writeDtp(wn);
+ char comm[256];
+ sprintf(comm,"zcat %s > %s",wn,argv[2]);
+ if(system(comm))
+ puts("Error while trying decompressing the file, you may have to decompress it yourself.");
+ else{sprintf(comm,"rm %s",wn);system(comm);}
+ delete wn;
+ }
+ if(argv[1][0]=='r')
+ {
+ smDtpFileR file;
+ FILE *pFile;DWORD size,rsize;char *buff;
+ pFile=fopen(argv[2],"rb");
+ if(!pFile)return 0;
+ fseek(pFile,0,SEEK_END);size=ftell(pFile);rewind(pFile);
+ buff=(char*)malloc(sizeof(char)*size);
+ if(!buff)return 0;
+ rsize=fread(buff,1,size,pFile);
+ if(rsize!=size)return 0;
+ file.openDtpFromMemory(buff,size);
+ if(argc==3)
+ {
+ for(char* c=file.getFirstFile();c;c=file.getNextFile(c))
+ {
+ puts(c);
+ char *ptr=file.getFilePtr(c);
+ if(!ptr)printf("error\n");else
+ printf("size:%lu, first bytes:%c%c%c\n",file.getFileSize(c),*ptr,*(ptr+1),*(ptr+2));
+ file.releaseFilePtr(c);
+ }
+ }
+ else
+ for(int i=3;i<argc;++i)
+ {
+ char *ptr=file.getFilePtr(argv[i]);
+ printf("size:%lu, first bytes:%c%c%c\n",file.getFileSize(argv[i]),*ptr,*(ptr+1),*(ptr+2));
+ file.releaseFilePtr(argv[i]);
+ }
+ file.closeDtp();
+ free(buff);
+ fclose(pFile);
+ }
+}
diff --git a/tools/dtputil/build b/tools/dtputil/build
new file mode 100755
index 0000000..7093351
--- /dev/null
+++ b/tools/dtputil/build
@@ -0,0 +1,3 @@
+#!/bin/bash
+g++ dtputil.cpp -Wall -o dtputil -lz -Wl,../../extensions/libsmeltext.a -g
+g++ anmutil.cpp -Wall -o anmutil -lz -Wl,../../extensions/libsmeltext.a -g \ No newline at end of file
diff --git a/tools/dtputil/dtputil.cpp b/tools/dtputil/dtputil.cpp
new file mode 100644
index 0000000..142a679
--- /dev/null
+++ b/tools/dtputil/dtputil.cpp
@@ -0,0 +1,43 @@
+#include "../../include/smdatapack.hpp"
+#include <cstdio>
+int main(int argc,char** argv)
+{
+ if(argc<3)
+ return printf("usage: %s <r/w> <dtpfilename> [filetoread1/filetowrite1] ...\n",argv[0]),1;
+ if(argv[1][0]=='w')
+ {
+ smDtpFileW file;
+ for(int i=3;i<argc;++i)
+ {
+ char* rp=argv[i];
+ if(*rp=='.'&&*(rp+1)=='/')rp+=2;
+ if(!file.addFile(rp,argv[i]))
+ printf("error adding file: %s\n",argv[i]);
+ }
+ file.writeDtp(argv[2]);
+ }
+ if(argv[1][0]=='r')
+ {
+ smDtpFileR file;
+ file.openDtp(argv[2]);
+ if(argc==3)
+ {
+ for(char* c=file.getFirstFile();c;c=file.getNextFile(c))
+ {
+ puts(c);
+ char *ptr=file.getFilePtr(c);
+ if(!ptr)printf("error\n");else
+ printf("size:%lu, first bytes:%c%c%c\n",file.getFileSize(c),*ptr,*(ptr+1),*(ptr+2));
+ file.releaseFilePtr(c);
+ }
+ }
+ else
+ for(int i=3;i<argc;++i)
+ {
+ char *ptr=file.getFilePtr(argv[i]);
+ printf("size:%lu, first bytes:%c%c%c\n",file.getFileSize(argv[i]),*ptr,*(ptr+1),*(ptr+2));
+ file.releaseFilePtr(argv[i]);
+ }
+ file.closeDtp();
+ }
+}
diff --git a/tools/lsrc/lsrc.cpp b/tools/lsrc/lsrc.cpp
new file mode 100644
index 0000000..a31d248
--- /dev/null
+++ b/tools/lsrc/lsrc.cpp
@@ -0,0 +1,348 @@
+/*
+ * Extra coding style for parser.cpp...
+ * 1. write C-like C++ code...(e.g. typedef struct _x{...}x; instead of
+ * struct x{...};
+ * 2. DO NOT USE STL!
+ * 3. if you don't like the rules above, you can ignore them though...
+ */
+//parser: prehistoric version.
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cmath>
+#include <cstdarg>
+#include "scriptshared.hpp"
+/*
+ * SPara...
+ * type=-1: Invalid Parameter
+ * type=0 : integer, data.i
+ * type=1 : real, data.r
+ * type=2 : int register, #data.i
+ * type=3 : real register, #data.i
+ * type=4 : int array member, const subs, #data.i
+ * type=5 : real array member, const subs, #data.i
+ * type=6 : int array member, register subs, #[intreg]data.i
+ * type=7 : real array member, register subs, #[intreg]data.i
+ * type=8 : function name
+ */
+SInst result[65537];
+int infunc,lc;
+char line[256],fst[16];
+void error(const char *szFormat, ...)
+{
+ va_list ap;
+ va_start(ap, szFormat);
+ vfprintf(stderr, szFormat, ap);
+ va_end(ap);
+ fprintf(stderr,"\n");
+ exit(1);
+}
+int hexBit(char b)
+{
+ if(b>='0'&&b<='9')return b-'0';
+ if(b>='a'&&b<='f')return b-'a'+10;
+ if(b>='A'&&b<='F')return b-'A'+10;
+ return -1;
+}
+Udata parseNumber(char *l,char *r,int mode)//0:real, 1:int
+{
+ int i=0,m=1;double d=0,mlt=0.1;Udata res;
+ char *c=l;res.d=0LL;
+ if(*c=='x')
+ {
+ ++c;
+ for(;~hexBit(*c)&&c!=r;++c)i*=16,i+=hexBit(*c);
+ if(c!=r){res.r=nan("");return res;}
+ res.i=m*i;return res;
+ }
+ if(*c=='-')m=-1,++c;
+ for(;*c>='0'&&*c<='9'&&c!=r;++c)i*=10,i+=*c-'0';
+ if(c==r){res.i=m*i;return res;}
+ if(*c!='.'||mode==1){res.r=nan("");return res;}
+ ++c;
+ for(;*c>='0'&&*c<='9'&&c!=r;++c)d+=(*c-'0')*mlt,mlt*=0.1;
+ if(c!=r){res.r=nan("");return res;}
+ res.r=d+i;return res;
+}
+int parsePara(char *cont,char *contr,SPara *para,int mode)
+/* mode:
+ * 0:all(excluding function name)
+ * 1:register only
+ * 2:constant only
+ * 3:integer only
+ * 4:integer register only
+ * 5:real only <-shouldn't this accept all?...
+ * 6:real register only
+ * 7:function name
+ */
+{
+ para->type=-1;
+ if(mode==6)
+ {
+ para->fnc=(char*)calloc(16,sizeof(char));
+ strcpy(para->fnc,cont);
+ para->type=8;
+ return 0;
+ }
+ if(cont[0]=='r')
+ {
+ if(mode==2||mode==3||mode==4)return 1;//reject if...
+ if(cont[1]=='[')//r[number], r[ixx]
+ {
+ char *c=&cont[2];
+ while(*c!=']'&&c!=contr)++c;
+ if(*c!=']')return 1;//brace mismatch
+ if(cont[2]=='i')
+ {
+ Udata d=parseNumber(&cont[3],c,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>99)return 1;
+ para->type=7;para->data=d;
+ return 0;
+ }
+ Udata d=parseNumber(&cont[2],c,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>9999)return 1;
+ para->type=5;para->data=d;
+ return 0;
+ }
+ if(strlen(cont)==3)
+ {
+ if(cont[1]=='d'&&cont[2]=='t')
+ {para->type=3;para->data.i=100;return 0;}
+ if(cont[1]=='a'&&cont[2]=='t')
+ {para->type=3;para->data.i=101;return 0;}
+ if(cont[1]=='r'&&cont[2]=='t')
+ {para->type=3;para->data.i=102;return 0;}
+ }
+ Udata d=parseNumber(&cont[1],contr,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>99)return 1;
+ para->type=3;para->data=d;
+ return 0;
+ }
+ if(cont[0]=='i')
+ {
+ if(mode==2/*||mode==5||mode==6*/)return 1;//reject if...
+ if(cont[1]=='[')//i[number], i[ixx]
+ {
+ char *c=&cont[2];
+ while(*c!=']'&&c!=contr)++c;
+ if(*c!=']')return 1;//brace mismatch
+ if(cont[2]=='i')
+ {
+ Udata d=parseNumber(&cont[3],c,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>99)return 1;
+ para->type=6;para->data=d;
+ return 0;
+ }
+ Udata d=parseNumber(&cont[2],c,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>9999)return 1;
+ para->type=4;para->data=d;
+ return 0;
+ }
+ if(strlen(cont)==3)
+ {
+ if(cont[1]=='r'&&cont[2]=='t')
+ {para->type=2;para->data.i=100;return 0;}
+ }
+ Udata d=parseNumber(&cont[1],contr,1);
+ if(isnan(d.r))return 1;
+ if(d.i<0||d.i>99)return 1;
+ para->type=2;para->data=d;
+ return 0;
+ }
+ if(mode==1||mode==4||mode==6)return 1;
+ Udata tryi=parseNumber(cont,contr,1);
+ Udata tryr=parseNumber(cont,contr,0);
+ if(isnan(tryr.r))return 1;
+ if(isnan(tryi.r)&&mode==3)return 1;
+ if(!isnan(tryi.r))return para->type=0,para->data=tryi,0;
+ if(!isnan(tryr.r))return para->type=1,para->data=tryr,0;
+ return 1;
+}
+int parseInstruction(char *line,SInst *inst)
+{
+ int r=-1;memset(fst,0,sizeof(fst));
+ sscanf(line,"%s",fst);
+#define bindInst(a,b) if(!strcmp(fst,a))r=b
+ bindInst("nop",0x00);
+ bindInst("push",0x01);bindInst("call",0x02);
+ bindInst("mov",0x03);bindInst("add",0x04);
+ bindInst("sub",0x05);bindInst("mul",0x06);
+ bindInst("div",0x07);bindInst("mod",0x08);
+ bindInst("and",0x09);bindInst("lor",0x0A);
+ bindInst("xor",0x0B);bindInst("not",0x0C);
+ bindInst("inc",0x0D);bindInst("dec",0x0E);
+ bindInst("clrstk",0x0F);
+ bindInst("ltz",0x11);bindInst("elz",0x12);
+ bindInst("gtz",0x13);bindInst("egz",0x14);
+ bindInst("eqz",0x15);bindInst("nez",0x16);
+ bindInst("jmp",0x21);bindInst("jez",0x22);
+ bindInst("jnz",0x23);
+#undef bindInst
+ if(~r)inst->id=r;else return r=inst->id=0;
+ char second[16],third[16];
+ switch(r)
+ {
+ case 0x01:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,0);
+ case 0x02:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,6);
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ sscanf(line,"%*s%s%s",second,third);
+ return
+ parsePara(second,second+strlen(second),&inst->para1,1)||
+ parsePara(third,third+strlen(third),&inst->para2,0);
+ case 0x08:
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ sscanf(line,"%*s%s%s",second,third);
+ return
+ parsePara(second,second+strlen(second),&inst->para1,4)||
+ parsePara(third,third+strlen(third),&inst->para2,3);
+ case 0x0C:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,4);
+ case 0x0D:
+ case 0x0E:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,1);
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,1);
+ case 0x21:
+ sscanf(line,"%*s%s",second);
+ return parsePara(second,second+strlen(second),&inst->para1,2);//should be const int...
+ case 0x22:
+ case 0x23:
+ sscanf(line,"%*s%s%s",second,third);
+ return
+ parsePara(second,second+strlen(second),&inst->para1,1)||
+ parsePara(third,third+strlen(third),&inst->para2,2);
+ }
+ return 0;
+}
+#define printPara(x) \
+if(x.type!=8) \
+printf("para type: %d\npara data: %d/0x%X/%f\n",x.type,x.data.i,x.data.i,x.data.r); \
+else \
+printf("para type: %d\npara data: %s\n",x.type,x.fnc);
+void compile()
+{
+ infunc=lc=0;
+ while(fgets(line,512,stdin))
+ {
+ for(unsigned i=0;i<strlen(line);++i)
+ if(line[i]==';'||line[i]==0x0A){line[i]='\0';}
+ ++lc;
+ if(line[0]=='.')
+ {
+ if(infunc)error("error at line %d: no subroutine supported.",lc);
+ infunc=1;result[lc].id=0xFF;
+ result[lc].para1.type=8;
+ result[lc].para1.fnc=(char*)calloc(16,sizeof(char));
+ memcpy(result[lc].para1.fnc,line+1,strlen(line+1));
+ }else
+ if(line[0]==',')
+ {
+ if(!infunc)error("error at line %d: end of no function?",lc);
+ infunc=0;result[lc].id=0xFE;
+ }else
+ if(parseInstruction(line,&result[lc]))error("error at line %d.",lc);
+ if(!infunc&&result[lc].id&&result[lc].id<0xFE)error("error at line %d:\
+ no instrunctions except nops are allowed out of a function.",lc);
+ }
+}
+void writePara(SPara a)
+{
+ fputc(a.type,stdout);
+ int startbit=7;
+ if(a.type==0||a.type==4||a.type==5)startbit=4;
+ if(a.type==1)startbit=0;
+ unsigned long long d=a.data.d;
+ unsigned long long c[8],shft=0,und=0xFFLL;
+ for(int i=7;i>=0;--i)
+ {
+ c[i]=d&und;c[i]>>=shft;
+ und<<=8LL;shft+=8LL;
+ }
+ fprintf(stderr,"writtend lld: %lld=0x%llx\n0x",d,d);
+ for(int i=startbit;i<8;++i)fprintf(stderr,"%llx",c[i]);
+ fprintf(stderr,"\n");
+ for(int i=startbit;i<8;++i)fputc((int)c[i],stdout);
+}
+void writeResult()
+{
+ for(int i=1;i<=lc;++i)
+ {
+ fprintf(stderr,"InstID=0x%X\n",result[i].id);
+ switch(result[i].id)
+ {
+ case 0xFF: case 0x02:
+ fputc(result[i].id,stdout);
+ fputc(strlen(result[i].para1.fnc),stdout);
+ fputs(result[i].para1.fnc,stdout);
+ break;
+ case 0x00: case 0x0F: case 0xFE:
+ fputc(result[i].id,stdout);
+ break;
+ case 0x01: case 0x0C: case 0x0D:
+ case 0x0E: case 0x11: case 0x12:
+ case 0x13: case 0x14: case 0x15:
+ case 0x16: case 0x21:
+ fputc(result[i].id,stdout);
+ writePara(result[i].para1);
+ break;
+ case 0x03: case 0x04: case 0x05:
+ case 0x06: case 0x07: case 0x08:
+ case 0x09: case 0x0A: case 0x0B:
+ case 0x22: case 0x23:
+ fputc(result[i].id,stdout);
+ writePara(result[i].para1);
+ writePara(result[i].para2);
+ break;
+ }
+ }
+}
+int main(int argc,char** argv)//for test purpose...
+{
+ /*char *test;
+ test=(char*)"1234";
+ Udata d=parseNumber(test,test+strlen(test),0);
+ printf("%d %X %f\n",d.i,d.i,d.r);
+ test=(char*)"r12";
+ SPara a;
+ printf("result=%d\n",parsePara(test,test+strlen(test),&a,0));
+ printf("type=%d\n",a.type);
+ printf("data.i=%d\n",a.data.i);
+ printf("data.r=%f\n",a.data.r);
+ test=(char*)"call orz617274873";
+ SInst itest;
+ puts("Instruction cache test...");
+ printf("result=%d\n",CacheStatement(test,&itest));
+ printf("id=%d\n",itest.id);
+ printPara(itest.para1);
+ printPara(itest.para2);*/
+ if(argc<3)return puts("Usage: lsrc <input file> <output file>"),0;
+ freopen(argv[1],"r",stdin);
+ compile();
+ freopen(argv[2],"w",stdout);
+ writeResult();
+ return 0;
+}
+
diff --git a/tools/lsrc/scriptshared.hpp b/tools/lsrc/scriptshared.hpp
new file mode 100644
index 0000000..65c02bc
--- /dev/null
+++ b/tools/lsrc/scriptshared.hpp
@@ -0,0 +1,150 @@
+#ifndef SCRIPTSHARED_H
+#define SCRIPTSHARED_H
+#include <cmath>
+#define eps 1e-6
+typedef union _Udata{//data union
+ int i;double r;unsigned long d;
+ _Udata(){d=0;}
+}Udata;
+typedef struct _Idata{//data union, with type tag and operators
+ _Udata D;
+ int type;//0=int, 1=double
+ _Idata(){D.d=0;type=0;}
+ _Idata(int _type,int _data)
+ {type=_type;if(type==0)D.i=_data;else D.r=(double)_data;}
+ double &r(){return D.r;}
+ int &i(){return D.i;}
+ unsigned long &d(){return D.d;}
+ _Idata operator =(_Idata r)
+ {
+ if(type==1&&r.type==0)this->r()=(double)r.i();
+ else if(type==0&&r.type==1)this->i()=(int)r.r();
+ else this->d()=r.d();
+ return *this;
+ }
+ _Idata operator +=(_Idata r)
+ {
+ if(type==1&&r.type==0)this->r()+=(double)r.i();
+ if(type==0&&r.type==1)this->i()+=(int)r.r();
+ if(type==0&&r.type==0)this->i()+=r.i();
+ if(type==1&&r.type==1)this->r()+=r.r();
+ return *this;
+ }
+ _Idata operator -=(_Idata r)
+ {
+ if(type==1&&r.type==0)this->r()-=(double)r.i();
+ if(type==0&&r.type==1)this->i()-=(int)r.r();
+ if(type==0&&r.type==0)this->i()-=r.i();
+ if(type==1&&r.type==1)this->r()-=r.r();
+ return *this;
+ }
+ _Idata operator *=(_Idata r)
+ {
+ if(type==1&&r.type==0)this->r()*=(double)r.i();
+ if(type==0&&r.type==1)this->i()*=(int)r.r();
+ if(type==0&&r.type==0)this->i()*=r.i();
+ if(type==1&&r.type==1)this->r()*=r.r();
+ return *this;
+ }
+ _Idata operator /=(_Idata r)
+ {
+ if(type==1&&r.type==0)this->r()/=(double)r.i();
+ if(type==0&&r.type==1)this->i()/=(int)r.r();
+ if(type==0&&r.type==0)this->i()/=r.i();
+ if(type==1&&r.type==1)this->r()/=r.r();
+ return *this;
+ }
+ _Idata operator %=(_Idata r)
+ {
+ if(type==1&&r.type==0)throw;
+ if(type==0&&r.type==1)throw;
+ if(type==0&&r.type==0)this->i()%=r.i();
+ if(type==1&&r.type==1)throw;
+ return *this;
+ }
+ _Idata operator &=(_Idata r)
+ {
+ if(type==1&&r.type==0)throw;
+ if(type==0&&r.type==1)throw;
+ if(type==0&&r.type==0)this->i()&=r.i();
+ if(type==1&&r.type==1)throw;
+ return *this;
+ }
+ _Idata operator |=(_Idata r)
+ {
+ if(type==1&&r.type==0)throw;
+ if(type==0&&r.type==1)throw;
+ if(type==0&&r.type==0)this->i()|=r.i();
+ if(type==1&&r.type==1)throw;
+ return *this;
+ }
+ _Idata operator ^=(_Idata r)
+ {
+ if(type==1&&r.type==0)throw;
+ if(type==0&&r.type==1)throw;
+ if(type==0&&r.type==0)this->i()^=r.i();
+ if(type==1&&r.type==1)throw;
+ return *this;
+ }
+ _Idata operator ~()
+ {
+ if(type==1)throw;
+ if(type==0)i()=~i();
+ return *this;
+ }
+ _Idata operator ++()
+ {
+ if(type==1)throw;
+ if(type==0)i()=i()+1;
+ return *this;
+ }
+ _Idata operator --()
+ {
+ if(type==1)throw;
+ if(type==0)i()=i()-1;
+ return *this;
+ }
+ bool ltz()
+ {
+ if(type==0)return i()<0;
+ if(type==1)return fabs(r())>eps&&r()<0;
+ throw;
+ }
+ bool elz()
+ {
+ if(type==0)return i()<=0;
+ if(type==1)return fabs(r())<eps||(fabs(r())>eps&&r()<0);
+ throw;
+ }
+ bool gtz()
+ {
+ if(type==0)return i()>0;
+ if(type==1)return fabs(r())>eps&&r()>0;
+ throw;
+ }
+ bool egz()
+ {
+ if(type==0)return i()>=0;
+ if(type==1)return fabs(r())<eps||(fabs(r())>eps&&r()>0);
+ throw;
+ }
+ bool eqz()
+ {
+ if(type==0)return i()==0;
+ if(type==1)return fabs(r())<eps;
+ throw;
+ }
+ bool nez()
+ {
+ if(type==0)return i()!=0;
+ if(type==1)return fabs(r())>eps;
+ throw;
+ }
+}Idata;
+typedef struct _SPara{Udata data;int type;char *fnc;}SPara;//parameters
+typedef struct _SInst//instructions
+{
+ int id;
+ SPara para1,para2;
+}SInst;
+#endif
diff --git a/tools/lsrc/test.lsr b/tools/lsrc/test.lsr
new file mode 100644
index 0000000..25ca8fe
--- /dev/null
+++ b/tools/lsrc/test.lsr
@@ -0,0 +1,25 @@
+.init
+mov r00 0
+,
+
+.update
+add i00 1 ;++i00
+mov i01 i00 ;if(i00<15)
+sub i01 15
+ltz i01
+jnz i01 24
+mov i00 0 ;reset the timer
+push 6.28
+push 0.0
+call randr ;get the random angle
+mov r01 rrt
+push 5.0
+push 1.0
+call randr ;get the random speed
+push r01
+push rrt
+push 300.0
+push 400.0
+call createBullet ;CreateBullet(400,300,speed,angle)
+nop ;no-op
+,