Maniac Mansion Wiki

Wanna know the trick? A VM carries out several script sequences at once that change parameters for sprites.

#include <stdio.h>

#include <time.h>

#include <fcntl.h>


#define NUM_SCRIPTS 3

#define GLOBAL_STATES 16


signed int data[1024*NUM_SCRIPTS+GLOBAL_STATES];


#define OBJ_NUM(n) (1024*n)


#define X_SCROLL    1024*NUM_SCRIPTS

#define Y_SCROLL    1024*NUM_SCRIPTS+1

#define TIMERTICK   1024*NUM_SCRIPTS+2


unsigned char sprite[400*6];

unsigned char screen[160][120];




void put_sprite(int xstart,int ystart, int n)

{

  int x=0;

  int y=0;

  signed int scroll;   

   scroll=data [X_SCROLL];

  // printf("Setze es an Position %d %d",xstart-scroll, ystart);

  while ( y < 20 )

  {

   x=0;

   while ( x < 20 )

  {

   if ( xstart+x-scroll > 0 && xstart+x-scroll < 160 &&

        ystart+y > 0 && ystart+y < 90 )

   {

    if ( sprite[n*400+x+y*20]!=255 )

    {

     if ( sprite[n*400+x+y*20]< 64 ) 

      screen[xstart+x-scroll][y+ystart]=':';

     else

     if ( sprite[n*400+x+y*20]< 128 ) 

      screen[xstart+x-scroll][y+ystart]=176;

     else

     if ( sprite[n*400+x+y*20]< 196 ) 

      screen[xstart+x-scroll][y+ystart]=177;

     else

if ( sprite[n*400+x+y*20]< 255 ) 

      screen[xstart+x-scroll][y+ystart]=219;

    }

    }

    x++;

   }

   y++;


  }


}






/*

  0 von Skriptbeginn: X-Koordinate eines Sprites

  1 von Skriptbeginn: Y-Koordinate eines Sprites

  2 : Sprite-Phase

  3: Pfadsuche-X

  4: Pfadsuche-Y

  5: KI-Backtracking X

  6: KI-Backtracking Y

  7: KI-Backtracking Phase

   der Rest ist frei

*/



struct

{

 signed int instruction[1024][3];

 signed int instr_ptr;

 unsigned int locked;

} script[NUM_SCRIPTS];



#define ADD 0

#define SUB 1

#define MOV 2

#define IFCMP 3

#define JMP 4

#define LOCK 5

#define UNLOCK 6




void VM_Step(void)

{

 int n=0;

 while ( n < NUM_SCRIPTS )

 {

  if (! script[n].locked )

  {

   if ( script[n].instruction[script[n].instr_ptr][0]==ADD )

   {

    data[script[n].instruction[script[n].instr_ptr][1]]+=

      data[script[n].instruction[script[n].instr_ptr][2]];

    script[n].instr_ptr++;     

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==SUB )

   {

   data[script[n].instruction[script[n].instr_ptr][1]]-=

      data[script[n].instruction[script[n].instr_ptr][2]];

    script[n].instr_ptr++;     

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==MOV )

   {

     data[script[n].instruction[script[n].instr_ptr][1]]=

      data[script[n].instruction[script[n].instr_ptr][2]];

     script[n].instr_ptr++;     

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==IFCMP )

   {

     if (    data[script[n].instruction[script[n].instr_ptr][1]]==

      data[script[n].instruction[script[n].instr_ptr][2]]);

     else script[n].instr_ptr++;

    script[n].instr_ptr++;     

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==JMP )

   {

    script[n].instr_ptr=script[n].instruction[script[n].instr_ptr][1];

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==LOCK )

   {

    int n2;

    n2=0;

    while ( n2< NUM_SCRIPTS ){

           if (!( n2==n) )script[n].locked=1; n2++; } 

    script[n].instr_ptr++;     

   }

   else

   if ( script[n].instruction[script[n].instr_ptr][0]==UNLOCK )

   {

    script[n].locked=0;

    script[n].instr_ptr++;     

   }



  }

  n++;

 }


}





int main(void)

{

 clock_t timertick;


  FILE *spritefile;

  spritefile=fopen(".\\sprites","rb");


  fread(sprite,20*20*6,sizeof(unsigned char),spritefile);

  fclose(spritefile);

  #define VMCODE(n,adress,opcode,op1,op2) script[n].instruction[adress][0]=opcode,\

                                          script[n].instruction[adress][1]=op1,\

script[n].instruction[adress][2]=op2,

VMCODE(0,0,ADD,X_SCROLL,100)

VMCODE(0,1,JMP,0,0) 

  /*

VMCODE(1,0,IFCMP,TIMERTICK,101)

VMCODE(1,1,MOV,X_SCROLL,0)

VMCODE(1,2,JMP,0,0) 

   */

  VMCODE(1,0,IFCMP,TIMERTICK,101)

VMCODE(1,1,ADD,2,101)

VMCODE(1,2,JMP,0,0) 


  VMCODE(2,0,JMP,0,0) 

  data[X_SCROLL]=0;

  data[Y_SCROLL]=0;

  data[TIMERTICK]=0;

  data[100]=1;

  data[101]=1;

  data[2]=0;

  timertick=clock()/100;

  while (1 )

  {

   VM_Step();

   if ( clock()/100 != timertick ) data [TIMERTICK]=1, timertick=clock()/100;

   else data[TIMERTICK]=0;

   int x=0, y=0;

    while ( y < 90)

    {

     x=0;

while ( x< 160)

{

screen[x][y]=' ';

      x++;

}

      y++;

    }

     put_sprite(20,20,data[2]);

system("cls\n");

y=0;

while ( y < 85)

    {

     x=0;

while ( x< 160)

{

printf("%c%c%c%c",screen[x][y], screen[x+1][y], screen[x+2][y], screen[x+3][y]);

      x+=4;

}

printf("\n");

      y++;

    }

}



}