*/
Looking for work? Check out our jobs area.
*/

View SRC\UMK.C

BOBOLI THE MIGHTY KNIGHT Networked Medieval Conflict

Submitted By: Unknown
Rating: starstarstar (Rate It)


#include "umk.h"
#include "mgraph.h"
#include <stdlib.h>
#include <stdio.h>

static unsigned long umk_xmin,umk_xmax;
static unsigned long umk_src,umk_dst,umk_caddr;
static byte umk_wid,umk_hgt,umk_data;
static byte umk_flag;

void umk_free(umkset u)
{
  byte i;
  if(u[0].img!=NULL) free(u[0].img);
  u[0].img=NULL;
}

int umk_load(char *name,umkset u)
{
  FILE *f;
  unsigned long amt,pos;
  byte count;
  int i;
  f=fopen(name,"rb");
  /* if file doesn't exist, fail */
  if(f==NULL) return -1;
  fseek(f,0,SEEK_END);
  amt=ftell(f);
  fseek(f,0,SEEK_SET);
  fread(&count,1,1,f);
  /* if unable to allocate memory, fail */
  if(!(u[0].img=malloc(amt))) {
    fclose(f);
    return -1;
  }
  pos=0;
  for(i=0;i<count;i++) {
    u[i].img=(byte *)(u[0].img+pos);
    fread(&u[i].width,1,2,f);
    fread(&u[i].height,1,2,f);
    fread(&u[i].size,1,2,f);
    fread(u[i].img,1,u[i].size,f);
    pos+=u[i].size;
  }
  fclose(f);
  initmg();
  return 0;
}

int mat_load(char *name,colmat c)
{
  FILE *f;
  if(!(f=fopen(name,"rb"))) return -1;
  fread(c,1,sizeof(colmat),f);
  fclose(f);
  return 0;
}

void umk_draw(int x,int y,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
loop1:
       cmpb $0,%dl
       jz   linedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  nonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp  loop1
nonzero:
       cmpl _umk_xmax,%edi
       ja   dontplot
       cmpl _umk_xmin,%edi
       jb   dontplot
       cmpb $0,_umk_flag
       jnz  dontplot
       movb %al,%es:(%edi)
dontplot:
       incl %edi
       decb %dl
       jmp  loop1
linedone:
       decb %dh
       jz   done
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  bfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  loop1
bfhandle:
       decb _umk_flag
       jmp  loop1
done:
       popa"
);
}

void umk_255draw(int x,int y,byte c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  umk_data=c;
  if(y>200-u.height) umk_hgt=200-y;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
tloop1:
       cmpb $0,%dl
       jz   tlinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  tnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp  tloop1
tnonzero:
       cmpl _umk_xmax,%edi
       ja   tdontplot
       cmpl _umk_xmin,%edi
       jb   tdontplot
       cmpb $0,_umk_flag
       jnz  tdontplot
       cmpb $255,%al
       jne  tplotit
       movb _umk_data,%al
tplotit:
       movb %al,%es:(%edi)
tdontplot:
       incl %edi
       decb %dl
       jmp  tloop1
tlinedone:
       decb %dh
       jz   tdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  tbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  tloop1
tbfhandle:
       decb _umk_flag
       jmp  tloop1
tdone:
       popa"
);
}


void umk_solid(int x,int y,byte col,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  umk_data=col;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       addl $63999,_umk_dst
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movb _umk_data,%bl
sloop1:
       cmpb $0,%dl
       jz slinedone
       movw %ds:(%esi),%ax
       cmpb $0,%al
       jnz snonzero
       xorl %ecx,%ecx
       subb %ah,%dl
       movb %ah,%cl
       addl %ecx,%edi
       incl %esi
       incl %esi
       jmp sloop1
snonzero:
       cmpl _umk_xmax,%edi
       ja sdontplot
       cmpl _umk_xmin,%edi
       jb sdontplot
       cmpb $0,_umk_flag
       jnz sdontplot
       movb %bl,%es:(%edi)
sdontplot:
       incl %esi
       incl %edi
       decb %dl
       jmp sloop1
slinedone:
       decb %dh
       jz sdone
       xorw %ax,%ax
       xorl %ecx,%ecx
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz sbfhandle
       movl _umk_dst,%ecx
       cmpl %ecx,%edi
       ja sdone
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       cmpl %ecx,_umk_xmax
       jb sloop1
       movl %ecx,_umk_xmax
       jmp sloop1
sbfhandle:
       decb _umk_flag
       jmp sloop1
sdone:
       popa"
);
}

void umk_shadowlimit(rect r,int x,int y,colmat col,umkrec u,scrntype scrn)
{
  long yy;
  if(y>r.y2) return;
  if(y<=r.y-u.height) return;
  if(x<=r.x-u.width) return;
  if(x>r.x2) return;
  yy=(long)scrn+y*320;
  umk_src=(long)u.img;
  umk_dst=x+yy;
  umk_xmin=r.x+yy;
  umk_xmax=r.x2+yy;
  if(y<r.y) {
    yy=(long)scrn+r.y*320;
    umk_xmin=r.x+yy;
    umk_xmax=r.x2+yy;
    umk_flag=r.y-y;
  } else umk_flag=0;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>r.y2-u.height) umk_hgt=r.y2-y+1;
  umk_caddr=(long)col;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %ecx,%ecx
       xorl %eax,%eax
       xorw %bx,%bx
       movb _umk_wid,%bl
       movw $320,%cx
       subw %bx,%cx
       movl _umk_caddr,%ebx
       cmpb $0,_umk_flag
       jnz slquickstart
slloop1:
       cmpb $0,%dl
       jz   sllinedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz  slnonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       addl %eax,%edi
       incl %esi
       jmp  slloop1
slnonzero:
       cmpl _umk_xmax,%edi
       ja   slpastend
       cmpl _umk_xmin,%edi
       jb   sldontplot
       movb %es:(%edi),%al
       movb %ds:(%ebx,%eax),%al
       movb %al,%es:(%edi)
sldontplot:
       incl %esi
       incl %edi
       decb %dl
       jmp  slloop1
slpastend:
       call slquickfinish
sllinedone:
       decb %dh
       jz   sldone
       addl %ecx,%edi
       movb _umk_wid,%dl
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  slloop1
slqfinish2:
       movb (%esi),%al
       cmpb $0,%al
       jnz  slquickfinish
       incl %esi
       movb (%esi),%al
       decb %al
       addl %eax,%edi
       subb %al,%dl
slquickfinish:
       # this is called when the drawing has hit xmax, so that it will
       # just hurry through the rest of the line
       incl %esi
       incl %edi
       decb %dl
       jnz  slqfinish2
       ret
slquickstart:
       decl %esi
       decl %edi
       incb %dl
       call slquickfinish
       movb _umk_wid,%al
       subl %eax,%edi
       addl $320,%edi
       movb %al,%dl
       decb %dh
       decb _umk_flag
       jnz  slquickstart
       jmp  slloop1
sldone:
       popa"
);
}

void umk_255limit(rect r,int x,int y,byte col,umkrec u,scrntype scrn)
{
  long yy;
  if(y>r.y2) return;
  if(y<=r.y-u.height) return;
  if(x<=r.x-u.width) return;
  if(x>r.x2) return;
  yy=(long)scrn+y*320;
  umk_src=(long)u.img;
  umk_dst=x+yy;
  umk_xmin=r.x+yy;
  umk_xmax=r.x2+yy;
  if(y<r.y) {
    yy=(long)scrn+r.y*320;
    umk_xmin=r.x+yy;
    umk_xmax=r.x2+yy;
    umk_flag=r.y-y;
  } else umk_flag=0;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>r.y2-u.height) umk_hgt=r.y2-y+1;
  umk_data=col;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %ecx,%ecx
       xorl %eax,%eax
       movb _umk_wid,%bl
       movw $320,%cx
       subw %bx,%cx
       xorl %ebx,%ebx
       cmpb $0,_umk_flag
       jnz l2quickstart
l2loop1:
       cmpb $0,%dl
       jz l2linedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz  l2nonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       addl %eax,%edi
       incl %esi
       jmp  l2loop1
l2nonzero:
       cmpl _umk_xmax,%edi
       ja   l2pastend
       cmpl _umk_xmin,%edi
       jb   l2dontplot
       cmpb $255,%al
       je   l2255
       movb %al,%es:(%edi)
l2dontplot:
       incl %esi
       incl %edi
       decb %dl
       jmp  l2loop1
l2255: movb _umk_data,%al
       movb %al,%es:(%edi)
       jmp  l2dontplot
l2pastend:
       call l2quickfinish
l2linedone:
       decb %dh
       jz l2done
       addl %ecx,%edi
       movb _umk_wid,%dl
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp l2loop1
l2qfinish2:
       movb (%esi),%al
       cmpb $0,%al
       jnz l2quickfinish
       incl %esi
       movb (%esi),%al
       decb %al
       addl %eax,%edi
       subb %al,%dl
l2quickfinish:
       # this is called when the drawing has hit xmax, so that it will
       # just hurry through the rest of the line
       incl %esi
       incl %edi
       decb %dl
       jnz l2qfinish2
       ret
l2quickstart:
       decl %esi
       decl %edi
       incb %dl
       call l2quickfinish
       movb _umk_wid,%al
       subl %eax,%edi
       addl $320,%edi
       movb %al,%dl
       decb %dh
       decb _umk_flag
       jnz l2quickstart
       jmp l2loop1
l2done:
       popa"
);
}

void umk_limit(rect r,int x,int y,umkrec u,scrntype scrn)
{
  long yy;
  if(y>r.y2) return;
  if(y<=r.y-u.height) return;
  if(x<=r.x-u.width) return;
  if(x>r.x2) return;
  yy=(long)scrn+y*320;
  umk_src=(long)u.img;
  umk_dst=x+yy;
  umk_xmin=r.x+yy;
  umk_xmax=r.x2+yy;
  if(y<r.y) {
    yy=(long)scrn+r.y*320;
    umk_xmin=r.x+yy;
    umk_xmax=r.x2+yy;
    umk_flag=r.y-y;
  } else umk_flag=0;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>r.y2-u.height) umk_hgt=r.y2-y+1;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %ebx,%ebx
       xorl %ecx,%ecx
       xorl %eax,%eax
       cmpb $0,_umk_flag
       jnz lquickstart
lloop1:
       cmpb $0,%dl
       jz llinedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz lnonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       addl %eax,%edi
       incl %esi
       jmp lloop1
lnonzero:
       cmpl _umk_xmax,%edi
       ja lpastend
       cmpl _umk_xmin,%edi
       jb ldontplot
       movb %al,%es:(%edi)
ldontplot:
       incl %esi
       incl %edi
       decb %dl
       jmp lloop1
lpastend:
       call lquickfinish
llinedone:
       decb %dh
       jz ldone
       movb _umk_wid,%bl
       movw $320,%cx
       subw %bx,%cx
       addl %ecx,%edi
       movb %bl,%dl
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp lloop1
lqfinish2:
       movb (%esi),%al
       cmpb $0,%al
       jnz lquickfinish
       incl %esi
       movb (%esi),%al
       decb %al
       addl %eax,%edi
       subb %al,%dl
lquickfinish:
       # this is called when the drawing has hit xmax, so that it will
       # just hurry through the rest of the line
       incl %esi
       incl %edi
       decb %dl
       jnz lqfinish2
       ret
lquickstart:
       decl %esi
       decl %edi
       incb %dl
       call lquickfinish
       movb _umk_wid,%al
       subl %eax,%edi
       addl $320,%edi
       movb %al,%dl
       decb %dh
       decb _umk_flag
       jnz lquickstart
       jmp lloop1
ldone:
       popa"
);
}

/* draws amt pixels, skips 1, draws amt more */
void umk_partial(int x,int y,byte amt,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>199-u.height) umk_hgt=200-y;
  umk_data=amt;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movb _umk_data,%bl
       xorl %eax,%eax
       xorl %ecx,%ecx
ploop1:
       cmpb $0,%dl
       jz   plinedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz  pnonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       addl %eax,%edi
       incl %esi
       jmp  ploop1
pnonzero:
       cmpl _umk_xmax,%edi
       ja   pdontplot2
       cmpl _umk_xmin,%edi
       jb   pdontplot2
       cmpb $0,_umk_flag
       jnz  pdontplot2
       decb %bl
       cmpb $0,%bl
       jz   pdontplot
       movb %al,%es:(%edi)
       incl %esi
       incl %edi
       decb %dl
       jmp  ploop1
pdontplot:
       movb _umk_data,%bl
pdontplot2:
       incl %esi
       incl %edi
       decb %dl
       jmp  ploop1
plinedone:
       decb %dh
       jz   pdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  pbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  ploop1
pbfhandle:
       decb _umk_flag
       jmp ploop1
pdone:
       popa"
);
}

/* draws 1 pixel, skips amt, draws 1 more */
void umk_unpartial(int x,int y,byte amt,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>199-u.height) umk_hgt=200-y;
  umk_data=amt;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movb _umk_data,%bl
       xorl %eax,%eax
       xorl %ecx,%ecx
uloop1:
       cmpb $0,%dl
       jz   ulinedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz  unonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       addl %eax,%edi
       incl %esi
       jmp  uloop1
unonzero:
       decb %bl
       cmpb $0,%bl
       jz   uplot
udontplot:
       incl %esi
       incl %edi
       decb %dl
       jmp  uloop1
uplot:
       cmpl _umk_xmax,%edi
       ja   udontplot
       cmpl _umk_xmin,%edi
       jb   udontplot
       cmpb $0,_umk_flag
       jnz  udontplot
       movb %al,%es:(%edi)
       movb _umk_data,%bl
       incl %esi
       incl %edi
       decb %dl
       jmp  uloop1
ulinedone:
       decb %dh
       jz   udone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  ubfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  uloop1
ubfhandle:
       decb _umk_flag
       jmp uloop1
udone:
       popa"
);
}

void umk_colour(int x,int y,byte c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  umk_data=c;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
       mov _umk_data,%bl
cloop1:
       cmpb $0,%dl
       jz clinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz cnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp cloop1
cnonzero:
       cmpl _umk_xmax,%edi
       ja cdontplot
       cmpl _umk_xmin,%edi
       jb cdontplot
       cmpb $0,_umk_flag
       jnz cdontplot
       andb $15,%al
       addb %bl,%al
       movb %al,%es:(%edi)
cdontplot:
       incl %edi
       decb %dl
       jmp cloop1
clinedone:
       decb %dh
       jz cdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz cbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp cloop1
cbfhandle:
       decb _umk_flag
       jmp cloop1
cdone:
       popa"
);
}

/* constrain colour to a given 16-colour range- that is, if 19 is the colour
   passed to this procedure, it will only draw in colours from 19 to 31. */

void umk_colour2(int x,int y,byte c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  umk_data=c;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
       movb _umk_data,%bl
       movb _umk_data,%bh
       shrb $4,%bh
       shlb $4,%bh
       addb $15,%bh
c2loop1:
       cmpb $0,%dl
       jz c2linedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz c2nonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp c2loop1
c2nonzero:
       cmpl _umk_xmax,%edi
       ja c2dontplot
       cmpl _umk_xmin,%edi
       jb c2dontplot
       cmpb $0,_umk_flag
       jnz c2dontplot
       andb $15,%al
       addb %bl,%al
       cmpb %bh,%al
       jbe  c2plotit
       movb %bh,%al
c2plotit:
       movb %al,%es:(%edi)
c2dontplot:
       incl %edi
       decb %dl
       jmp c2loop1
c2linedone:
       decb %dh
       jz c2done
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz c2bfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp c2loop1
c2bfhandle:
       decb _umk_flag
       jmp c2loop1
c2done:
       popa"
);
}

void umk_robot(int x,int y,byte c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  umk_data=c;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
       movb _umk_data,%bl
       movb _umk_data,%bh
       shrb $4,%bh
       shlb $4,%bh
       addb $15,%bh
rloop1:
       cmpb $0,%dl
       jz rlinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz rnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp rloop1
rnonzero:
       cmpl _umk_xmax,%edi
       ja rdontplot
       cmpl _umk_xmin,%edi
       jb rdontplot
       cmpb $0,_umk_flag
       jnz rdontplot
       andb $15,%al
       cmpb $15,%al
       je   rplotit
       incb %al
rplotit:
       addb %bl,%al
       cmpb $255,%al
       jne  rplotok
       movb $239,%al
rplotok:
       movb %al,%es:(%edi)
rdontplot:
       incl %edi
       decb %dl
       jmp rloop1
rlinedone:
       decb %dh
       jz   rdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  rbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  rloop1
rbfhandle:
       decb _umk_flag
       jmp  rloop1
rdone:
       popa"
);
}

void umk_phase(int x,int y,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movl %edi,%ebx
       xorl %eax,%eax
       xorl %ecx,%ecx
phloop1:
       cmpb $0,%dl
       jz phlinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  phnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       addl %eax,%ebx
       jmp  phloop1
phnonzero:
       cmpl _umk_xmax,%edi
       ja   phdontplot
       cmpl _umk_xmin,%edi
       jb   phdontplot
       cmpb $0,_umk_flag
       jnz  phdontplot
       movb %es:(%ebx),%al
       movb %al,%es:(%edi)
phdontplot:
       incl %edi
       decb %dl
       movb %es:(%edi),%al
       rcrb $1,%al
       jc   phoddbyte
       incl %ebx
phoddbyte:
       incl %ebx
       jmp  phloop1
phlinedone:
       decb %dh
       jz   phdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movl %edi,%ebx
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  phbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  phloop1
phbfhandle:
       decb _umk_flag
       jmp  phloop1
phdone:
       popa"
);
}

void umk_shadow(int x,int y,colmat c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  umk_caddr=(long)c;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
       movl _umk_caddr,%ebx
shloop1:
       cmpb $0,%dl
       jz shlinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  shnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp  shloop1
shnonzero:
       cmpl _umk_xmax,%edi
       ja   shdontplot
       cmpl _umk_xmin,%edi
       jb   shdontplot
       cmpb $0,_umk_flag
       jnz  shdontplot
       movb %es:(%edi),%al
       movb %ds:(%ebx,%eax),%al
       movb %al,%es:(%edi)
shdontplot:
       incl %edi
       decb %dl
       jmp  shloop1
shlinedone:
       decb %dh
       jz   shdone
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  shbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  shloop1
shbfhandle:
       decb _umk_flag
       jmp  shloop1
shdone:
       popa"
);
}

void umk_altern(int x,int y,colmat c,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  umk_caddr=(long)c;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movl _umk_caddr,%ebx
       xorl %eax,%eax
aloop1:
       cmpb $0,%dl
       jz   alinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  anonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       addl %eax,%edi
       jmp  aloop1
anonzero:
       cmpl _umk_xmax,%edi
       ja   adontplot
       cmpl _umk_xmin,%edi
       jb   adontplot
       cmpb $0,_umk_flag
       jnz  adontplot
       movb %ds:(%ebx,%eax),%al
       movb %al,%es:(%edi)
adontplot:
       incl %edi
       decb %dl
       jmp  aloop1
alinedone:
       decb %dh
       jz   adone
       xorl %ecx,%ecx
       movb _umk_wid,%al
       movw $320,%cx
       subw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  abfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  aloop1
abfhandle:
       decb _umk_flag
       jmp  aloop1
adone:
       popa"
);
}

void umk_flip(int x,int y,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x-1+u.width+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>200-u.height) umk_hgt=200-y;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %eax,%eax
       xorl %ecx,%ecx
floop1:
       cmpb $0,%dl
       jz   flinedone
       movb %ds:(%esi),%al
       incl %esi
       cmpb $0,%al
       jnz  fnonzero
       movb %ds:(%esi),%al
       incl %esi
       subb %al,%dl
       subl %eax,%edi
       jmp  floop1
fnonzero:
       cmpl _umk_xmax,%edi
       ja   fdontplot
       cmpl _umk_xmin,%edi
       jb   fdontplot
       cmpb $0,_umk_flag
       jnz  fdontplot
       movb %al,%es:(%edi)
fdontplot:
       decl %edi
       decb %dl
       jmp  floop1
flinedone:
       decb %dh
       jz   fdone
       movb _umk_wid,%al
       movw $320,%cx
       addw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  fbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  floop1
fbfhandle:
       decb _umk_flag
       jmp  floop1
fdone:
       popa"
);
}

void umk_flip_solid(int x,int y,byte col,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x-1+u.width+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  umk_data=col;
  if(y>200-u.height) umk_hgt=200-y;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movb _umk_data,%bl
fsloop1:
       cmpb $0,%dl
       jz   fslinedone
       movw %ds:(%esi),%ax
       cmpb $0,%al
       jnz  fsnonzero
       xorl %ecx,%ecx
       subb %ah,%dl
       movb %ah,%cl
       subl %ecx,%edi
       incl %esi
       incl %esi
       jmp  fsloop1
fsnonzero:
       cmpl _umk_xmax,%edi
       ja   fsdontplot
       cmpl _umk_xmin,%edi
       jb   fsdontplot
       cmpb $0,_umk_flag
       jnz  fsdontplot
       movb %bl,%es:(%edi)
fsdontplot:
       incl %esi
       decl %edi
       decb %dl
       jmp  fsloop1
fslinedone:
       decb %dh
       jz   fsdone
       xorl %ecx,%ecx
       xorw %ax,%ax
       movb _umk_wid,%al
       movw $320,%cx
       addw %ax,%cx
       addl %ecx,%edi
       movb %al,%dl
       cmpb $0,_umk_flag
       jnz  fsbfhandle
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  fsloop1
fsbfhandle:
       decb _umk_flag
       jmp  fsloop1
fsdone:
       popa"
);
}

void umk_flip_limit(rect r,int x,int y,umkrec u,scrntype scrn)
{
  long yy;
  if(y>r.y2) return;
  if(y<=r.y-u.height) return;
  if(x<=r.x-u.width) return;
  if(x>r.x2) return;
  yy=(long)scrn+y*320;
  umk_src=(long)u.img;
  umk_dst=x-1+u.width+yy;
  umk_xmin=r.x+yy;
  umk_xmax=r.x2+yy;
  if(y<r.y) {
    yy=(long)scrn+r.y*320;
    umk_xmin=r.x+yy;
    umk_xmax=r.x2+yy;
    umk_flag=r.y-y;
  } else umk_flag=0;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>r.y2-u.height) umk_hgt=r.y2-y+1;
  umk_data=(byte)r.y2;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       xorl %ebx,%ebx
       xorl %eax,%eax
       cmpb $0,_umk_flag
       jnz flquickstart
flloop1:
       cmpb $0,%dl
       jz   fllinedone
       movb %ds:(%esi),%al
       cmpb $0,%al
       jnz  flnonzero
       incl %esi
       movb %ds:(%esi),%al
       subb %al,%dl
       subl %eax,%edi
       incl %esi
       jmp  flloop1
flnonzero:
       cmpl _umk_xmax,%edi
       ja   fldontplot
       cmpl _umk_xmin,%edi
       jb   flpastend
       movb %al,%es:(%edi)
fldontplot:
       incl %esi
       decl %edi
       decb %dl
       jmp  flloop1
flpastend:
       call flquickfinish
fllinedone:
       decb %dh
       jz   fldone
       xorl %ecx,%ecx
       movb _umk_wid,%bl
       movw $320,%cx
       addw %bx,%cx
       addl %ecx,%edi
       movb %bl,%dl
       addl $320,_umk_xmin
       addl $320,_umk_xmax
       jmp  flloop1
flqfinish2:
       movb (%esi),%al
       cmpb $0,%al
       jnz  flquickfinish
       incl %esi
       movb (%esi),%al
       decb %al
       subl %eax,%edi
       subb %al,%dl
flquickfinish:
       # this is called when the drawing has hit xmax, so that it will
       # just hurry through the rest of the line
       incl %esi
       decl %edi
       decb %dl
       jnz  flqfinish2
       ret
flquickstart:
       decl %esi
       incl %edi
       incb %dl
       call flquickfinish
       movb _umk_wid,%al
       addl %eax,%edi
       addl $320,%edi
       movb %al,%dl
       decb %dh
       decb _umk_flag
       jnz  flquickstart
       jmp  flloop1
fldone:
       popa"
);
}

void umk_flip_partial(int x,int y,byte amt,umkrec u,scrntype scrn)
{
  if(y>199) return;
  if(y<=-u.height) return;
  if(x<=-u.width) return;
  if(x>319) return;
  umk_src=(long)u.img;
  umk_dst=(long)scrn+x-1+u.width+y*320;
  umk_xmin=(long)scrn+y*320;
  if(y<0) {
    umk_xmin=(long)scrn;
    umk_flag=-y;
  } else umk_flag=0;
  umk_xmax=umk_xmin+319;
  umk_wid=u.width;
  umk_hgt=u.height;
  if(y>199-u.height) umk_hgt=200-y;
  umk_data=amt;
  asm("pusha
       push %ds
       pop  %es
       movl _umk_src,%esi
       movl _umk_dst,%edi
       movb _umk_wid,%dl
       movb _umk_hgt,%dh
       movb _umk_data,%bl
       xorl %eax,%eax
       xorl %ecx,%ecx
fploop1:
       cmpb $0,%dl
       jz   fplinedone
      &