?? entity.cpp
字號:
#define ALLEGRO_STATICLINK
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
#include <iostream>
#include "functions.h"
#include "types.h"
#include "entity.h"
APIHANDLER::APIHANDLER()
{
}
void APIHANDLER::exec(char *functionname, void *owner)
{
THREAD *jiglet = (THREAD*)owner;
ENTITY *MASTER = (ENTITY*)jiglet->owner;
APIBLOCK *working = &MASTER->api.root;
while(1)
{
//std::cout << "Comparing " << functionname << " with " << working->name << std::endl;
//std::cout << "Comparing result: " << strcmp(functionname,working->name) << std::endl;
if(strcmp(working->name,"ENDOFSEARCH")==0) return;
if(strcmp(functionname,working->name)==0)
{
working->entrypoint(owner);
return;
}
if(working->next==NULL) return;
working=working->next;
}
//std::cout << "FUNCTION NOT FOUND! " << std::endl;
}
void APIHANDLER::install(char *functionname,APIFUNCTION function)
{
APIBLOCK *working = &root;
while(1)
{
if(working->next==NULL) break;
working = working->next;
}
working->AddSon(functionname, function);
}
void ENTITY::MoveTo(int px, int py)
{
x = px;
y = py;
}
void ENTITY::SetExecutionRate(int cyclespersecond, int tickrate)
{
if(tickrate==0 || cyclespersecond==-1) execrate=-1;
else execrate=cyclespersecond/tickrate;
}
void ENTITY::GetFace(int mx, int my)
{
if(face==FACE_LEFT && mx < 0) return;
if(face==FACE_UP && my < 0) return;
if(face==FACE_RIGHT && mx > 0) return;
if(face==FACE_DOWN && my > 0) return;
if(face==FACE_LEFT && mx > 0)
{
face = FACE_RIGHT;
return;
}
if(face==FACE_UP && my > 0)
{
face = FACE_DOWN;
return;
}
if(face==FACE_RIGHT && mx < 0)
{
face = FACE_LEFT;
return;
}
if(face==FACE_DOWN && my < 0)
{
face = FACE_UP;
return;
}
if(my == 0 && (face==FACE_DOWN || face== FACE_UP))
{
face = (mx>0)?FACE_RIGHT:FACE_LEFT;
return;
}
if(mx == 0 && (face==FACE_RIGHT || face==FACE_LEFT))
{
face = (my>0)?FACE_DOWN:FACE_UP;
return;
}
}
void ENTITY::Execute()
{
audio.exec();
if(execrate==-1)
{
while(vm.operational==OPERATE) vm.Execute(100000);
}
else vm.Execute(execrate);
operational=vm.operational;
if(mutterdelay>-1) --mutterdelay;
}
ENTITY::ENTITY(char *myname, char *binary)
{
for(int i=0;i<1337;++i) lastmessage[i]=0;
next = NULL;
vm.setram(this);
SetVM(myname,binary,NULL,0);
}
void ENTITY::SetVM(char *myname, char *binary, ENTITY *pbase, int omax)
{
objectmax=omax;
baseobject = pbase;
audio.start();
execrate=-1;
operational=OPERATE;
vm.loadbinary(binary);
strcpy(name,myname);
messageproc=-1;
mutter=NULL;
mutterdelay=-1;
}
ENTITY::ENTITY()
{
for(int i=0;i<1337;++i) lastmessage[i]=0;
next = NULL;
seconds = 0;
vm.setram(this);
operational = 0;
}
void ENTITY::SetEnvironment(ENVIRONMENT *env)
{
map=env;
}
void ENTITY::SetData(int dx,int dy,int ospr,int ehandle, int szx, int szy)
{
sizex=szx;
sizey=szy;
enginehandle=ehandle;
spr=ospr;
x=dx;
y=dy;
steps=0;
face=FACE_DOWN;
}
void ENTITY::Move(int mx,int my)
{
int rect1x1,rect1x2,rect1y1,rect1y2;
int rect2x1,rect2x2,rect2y1,rect2y2;
int tx,ty;
int movable;
int startx,starty,endx,endy;
int checkx,checky;
if(mx==0 && my==0) return;
tx = x + mx;
ty = y + my;
startx = (tx - sizex)/32;
starty = (y - sizey)/32;
endx = (tx + sizex)/32;
endy = (y + sizey)/32;
if(endx>89)
{
endx=89;
tx = x;
}
if(startx>89)
{
startx = 89;
tx = x;
}
if(endx<0)
{
endx=0;
tx = x;
}
if(startx<0)
{
startx=0;
tx = x;
}
if(endy>89)
{
endy=89;
ty = y;
}
if(starty>89)
{
starty = 89;
ty = y;
}
if(endy<0)
{
endy=0;
ty = y;
}
if(starty<0)
{
starty=0;
ty = y;
}
for(checkx=startx;checkx<=endx;++checkx)
{
for(checky=starty;checky<=endy;++checky)
{
if (map->map[checky][checkx]<=255 || (map->map[checky][checkx]>511 && map->map[checky][checkx]<768))
{
}
else
{
tx = x;
}
}
}
//Move on Y axis
startx = (x - sizex)/32;
starty = (ty - sizey)/32;
endx = (x + sizex)/32;
endy = (ty + sizey)/32;
if(endx>89)
{
endx=89;
tx = x;
}
if(startx>89)
{
startx = 89;
tx = x;
}
if(endx<0)
{
endx=0;
tx = x;
}
if(startx<0)
{
startx=0;
tx = x;
}
if(endy>89)
{
endy=89;
ty = y;
}
if(starty>89)
{
starty = 89;
ty = y;
}
if(endy<0)
{
endy=0;
ty = y;
}
if(starty<0)
{
starty=0;
ty = y;
}
for(checkx=startx;checkx<=endx;++checkx)
{
for(checky=starty;checky<=endy;++checky)
{
if (map->map[checky][checkx]<=255 || (map->map[checky][checkx]>511 && map->map[checky][checkx]<768))
{
}
else
{
ty = y;
}
}
}
GetFace(mx,my);
int failsx = 0;
int failsy = 0;
for(int testmove=0;testmove<objectmax;++testmove)
{
if(baseobject[testmove].operational!=0 && baseobject[testmove].enginehandle!=enginehandle)
{
bool test3 = false;
rect2x1 = baseobject[testmove].x-baseobject[testmove].sizex;
rect2x2 = baseobject[testmove].x+baseobject[testmove].sizex;
rect2y1 = baseobject[testmove].y-baseobject[testmove].sizey;
rect2y2 = baseobject[testmove].y+baseobject[testmove].sizey;
rect1x1 = x+mx-sizex;
rect1x2 = x+mx+sizex;
rect1y1 = y+my-sizey;
rect1y2 = y+my+sizey;
test3 = intersects(rect1x1,rect1x2,rect1y1,rect1y2,rect2x1,rect2x2,rect2y1,rect2y2);
if(test3==true)
{
rect1x1 = x+mx-sizex;
rect1x2 = x+mx+sizex;
rect1y1 = y-sizey;
rect1y2 = y+sizey;
if(intersects(rect1x1,rect1x2,rect1y1,rect1y2,rect2x1,rect2x2,rect2y1,rect2y2)) ++failsx;
rect1x1 = x-sizex;
rect1x2 = x+sizex;
rect1y1 = y+my-sizey;
rect1y2 = y+my+sizey;
if(intersects(rect1x1,rect1x2,rect1y1,rect1y2,rect2x1,rect2x2,rect2y1,rect2y2)) ++failsy;
}
}
}
if(failsx==0)
{
x = tx;
++steps;
}
if(failsy==0)
{
y = ty;
++steps;
}
}
static int threads=0;
THREAD::THREAD(char *ram, int sizeram, int startaddress, void *mymaster)
{
owner=mymaster;
++threads;
yield=0;
next=NULL;
parent=NULL;
THREAD::ram=ram;
THREAD::sizeram=sizeram;
operational=OPERATE;
fstackpointer=0;
stackpointer=0;
pstackpointer=0;
codepointer=startaddress;
}
int THREAD::ExecObj(int cycles)
{
static ENTITY *MASTER=(ENTITY *)owner;
//Execute cycles and return how many cycles are left
//if something like a device poll takes place or whatnot
if(operational!=OPERATE) return cycles;
//Loop until loop is broken by a rule condition
while(cycles>0)
{
--cycles;
#if defined DEBUG
if(codepointer>=sizeram && codepointer<0)
{
// std::cout << "ERR: INVALID CODE POINTER, DISABLING" << std::endl;
operational=0;
return cycles;
}
#endif
if(yield>0)
{
--yield;
return cycles;
}
//Debug teh pointers
//end of Debug
switch (*(int *)(ram+codepointer))
{
case PUSH:
codepointer+=sizeof(int);
stack[stackpointer]=*(int *)(ram+codepointer);
codepointer+=sizeof(int);
++stackpointer;
#if defined DEBUG
if(stackpointer>=STACKSIZE)
{
// std::cout << "ERR: STACK OVERFLOW" << std::endl;
operational=0;
return cycles;
}
#endif
break;
case DPUSH:
codepointer+=sizeof(int);
stack[stackpointer]=*(int *)(ram+codepointer);
++stackpointer;
codepointer+=sizeof(int);
stack[stackpointer]=*(int *)(ram+codepointer);
++stackpointer;
codepointer+=sizeof(int);
#if defined DEBUG
if(stackpointer>=STACKSIZE)
{
// std::cout << "ERR: STACK OVERFLOW" << std::endl;
operational=0;
return cycles;
}
#endif
break;
case POP:
#if defined DEBUG
if(stackpointer<0)
{
// std::cout << "ERR: STACK UNDERFLOW" << std::endl;
operational=0;
return cycles;
}
#endif
--stackpointer;
codepointer+=sizeof(int);
break;
case FUNCTION:
pstack[pstackpointer].type=RETURNADDRESS;
pstack[pstackpointer].address=codepointer+sizeof(int);
++pstackpointer;
--stackpointer;
address=stack[stackpointer];
#if defined DEBUG
if(address<0 || address>(int)(sizeram-sizeof(int)))
{
// std::cout << "INVALID FUNCTION FRAME POINTER: " << address << std::endl;
operational=0;
return cycles;
}
#endif
//swapper is set to first byte of the frame
swapper=address;
//Read in Function Pointer
address=*(int *)(ram+address);
//address is set to the code pointer of the function
#if defined DEBUG
if(address<0 || address>(int)(sizeram-sizeof(int)))
{
// std::cout << "INVALID FUNCTION POINTER IN FUNCTION FRAME: " << address << std::endl;
operational=0;
return cycles;
}
#endif
//set code pointer to address
codepointer=address;
//Start preserving the frame
preserve=swapper+sizeof(int);
while(*(int *)(ram+preserve)!=ENDPARAMS)
{
preserve+=sizeof(int);
}
address=preserve+sizeof(int);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -