From: baylor@ccwf.cc.utexas.edu (Baylor)
Newsgroups: rec.games.programmer
Subject: Ok IBM guys, What am I doing wrong?
Date: 16 Oct 92 05:10:20 GMT
Organization: The University of Texas at Austin, Austin TX


	I wrote a simple sprite routine that was trying to test  what
kind of format i needed to store my sprites in (for a sprite editor).
My progrtam works, and quickly, and i think i have the hang of creating
sprites in linear video modes.
	But this demo doesn't seem to work, with very strange bugs.
	The demo is a pacman circling the screen, with a rainbow 
trialing him. It compiles fine, but the results going vertically are
bizzare.
	It's in normal mode 13, no clipping, no page swiching, plenty
of flicker. It's not meant to be a finished product, only a demo to see
if I could do something. If you like the code and want to polish it,
feel free, but know i stole most of the basic ideas from Josh at 
Xenion software (hope i got that right).
	And let me know if it works on your computer - maybe it's just
me.
	Anyway, Pacman starts in the top left corner and goes down, across
up the right side then back across the top to the left corner. To track
his preformance, he leaves behind him a rainbow, showing where he's been.
	But when he goes down the left side, the background gets erased.
When he goes up, the rainbow becomes a straight-out white box instead of
a nifty 16-color hue.
	I haven't the faintest idea how to debug something this low level.
If you have any ideas, let me know.


Program Test_13;
(* Programmer : Baylor Wetzel                                    *)
(* Date       : 10/14/92                                         *)
(* Purpose:  A stupid test to get the hang of plotting pixels in *)
(*           Mode $13                                            *)

uses crt;

const
     Screen_Offset  = $0A000;
     Max_Icon_X     = 16;
     Max_Icon_Y     = 16;

type
    Icon = array [1..Max_Icon_X, 1..Max_Icon_Y] of byte;

const
    (* A bad way to define an icon - numbers are colors *)
    (* between 0 and 255. 0 is black, 14 is yellow      *)
    PacMan : Icon =
         ( (04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04),  (* 0 *)
           (04,00,00,00,00,00,14,14,14,14,14,00,00,00,00,04),  (* 1 *)
           (04,00,00,00,14,14,14,14,14,14,14,14,00,00,00,04),  (* 2 *)
           (04,00,00,14,14,14,14,14,14,14,14,14,14,00,00,04),  (* 3 *)
           (04,00,14,14,14,14,14,14,14,00,00,14,14,14,00,04),  (* 4 *)
           (04,00,14,14,14,14,14,14,14,00,00,14,14,14,00,04),  (* 5 *)
           (04,14,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 6 *)
           (04,14,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 7 *)
           (04,14,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 8 *)
           (04,14,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 9 *)
           (04,14,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 10 *)
           (04,00,14,14,14,14,14,14,14,14,14,14,14,14,14,04),  (* 11 *)
           (04,00,00,14,14,14,14,14,14,14,14,14,14,14,00,04),  (* 12 *)
           (04,00,00,00,14,14,14,14,14,14,14,14,14,00,00,04),  (* 13 *)
           (04,00,00,00,00,00,14,14,14,14,14,00,00,00,00,04),  (* 14 *)
           (04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04)   (* 15 *)
         );
    RainBow : Icon =
         ( (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 0 *)
           (01,01,01,01,01,01,01,01,01,01,01,01,01,01,01,01),  (* 1 *)
           (02,02,02,02,02,02,02,02,02,02,02,02,02,02,02,02),  (* 2 *)
           (03,03,03,03,03,03,03,03,03,03,03,03,03,03,03,03),  (* 3 *)
           (04,04,04,04,04,04,04,04,04,04,04,04,04,04,04,04),  (* 4 *)
           (05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05),  (* 5 *)
           (06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06),  (* 6 *)
           (07,07,07,07,07,07,07,07,07,07,07,07,07,07,07,07),  (* 7 *)
           (08,08,08,08,08,08,08,08,08,08,08,08,08,08,08,08),  (* 8 *)
           (09,09,09,09,09,09,09,09,09,09,09,09,09,09,09,09),  (* 9 *)
           (10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10),  (* 10 *)
           (11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11),  (* 11 *)
           (12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12),  (* 12 *)
           (13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13),  (* 13 *)
           (14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14),  (* 14 *)
           (15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15)   (* 15 *)
         );
    BackGround : Icon =
         ( (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 0 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 1 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 2 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 3 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 4 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 5 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 6 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 7 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 8 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 9 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 10 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 11 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 12 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 13 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00),  (* 14 *)
           (00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00)  (* 15 *)
         );
var
   ch   : char;
   i,j  : word;
(******************************************************************)
Procedure Put_Picture (X,Y : word; Pic : Icon); assembler;
(* Assumes you know width and height        *)
(* Only Does One page Linear Mode           *)
(* Not Optimized for speed, but not slow    *)
  Asm
     mov   ax,320  (* Since this is Linear Mode 13, width is always 320 *)
     mul   y       (* Mul - multiply al or ax by argument *)

     add   ax,X    (* This gets the screen offset - *)
                   (* (Y*ScreenWidth) + X           *)

     mov   dx,ds   (* save value of ds - like pushing it  *)
                   (* DS is an important register so make *)
                   (* sure and save it                    *)

     mov   di,ax   (* Load address (offset) to write to into di *)
     mov   ax,Screen_Offset  (* Because can't load directly into ES *)
     mov   es,ax   (* Screen Position is at ES:DI *)
                   (* Now points to A000:x,y      *)

     lds   si,Pic          (* Load the address of Pic into SI *)

     mov   bx,Max_Icon_Y   (* Set BX to number of rows *)

     (* Loop is                                        *)
     (*      for BX:=Max_Icon_Y downto 0 do            *)
     (*          for CX:=Max_Icon_X downto 0 do        *)
     (*              PutPixel(x+cx,y+bx, Pic[cx,bx])   *)

  @@CopyLoop:
     mov   cx,Max_Icon_X   (* length of row used as counter *)
                           (* CX is almost always used as a counter *)

     push  di              (* save the start offset *)
     rep   movsb       (* repeat Move String Byte CX times    *)
                       (* Repeat MovSB moves CX bytes         *)
                       (* from DS:SI to ES:DI                 *)

     pop   di               (* restore start offset ... *)
     add   di,320           (* and move to next line    *)

     dec   bx          (* BX should hold the number of rows *)
     jnz   @@CopyLoop  (* Loop until BX (rows left) = 0 *)

     mov   ds,dx       (* restore value of ds *)
  End;
(******************************************************************)
Procedure Put_Picture2 (X,Y : word; Pic : Icon); assembler;
(* Assumes you know width and height        *)
(* Only Does One page Linear Mode           *)
(* Not Optimized for speed, but not slow    *)
  Asm
     mov   ax,320  (* Since this is Linear Mode 13, width is always 320 *)
     mul   y       (* Mul - multiply al or ax by argument *)

     add   ax,X    (* This gets the screen offset - *)
                   (* (Y*ScreenWidth) + X           *)

     mov   dx,ds   (* save value of ds - like pushing it  *)
                   (* DS is an important register so make *)
                   (* sure and save it                    *)

     mov   di,ax   (* Load address (offset) to write to into di *)
     mov   ax,Screen_Offset  (* Because can't load directly into ES *)
     mov   es,ax   (* Screen Position is at ES:DI *)
                   (* Now points to A000:x,y      *)

     lds   si,Pic          (* Load the address of Pic into SI *)

     mov   bx,16   (* Set BX to number of rows *)

     (* Loop is                                        *)
     (*      for BX:=Max_Icon_Y downto 0 do            *)
     (*          for CX:=Max_Icon_X downto 0 do        *)
     (*              PutPixel(x+cx,y+bx, Pic[cx,bx])   *)

  @@CopyLoop:
     mov   cx,16   (* length of row used as counter *)
                           (* CX is almost always used as a counter *)
     push  di
     rep   movsb       (* repeat Move String Byte CX times    *)
                       (* Repeat MovSB moves CX bytes         *)
                       (* from DS:SI to ES:DI                 *)
     pop   di
     add   di,320

     dec   bx          (* BX should hold the number of rows *)
     jnz   @@CopyLoop  (* Loop until BX (rows left) = 0 *)

     mov   ds,dx       (* restore value of ds *)
  End;
(******************************************************************)
Procedure Set_Mode_13; assembler;
  Asm
     mov ax,13h
     int 10h
  End;
(******************************************************************)
(******************************************************************)
BEGIN
     Set_Mode_13;
(*
     for i:= 1 to 9 do
         for j:= 1 to 9 do
             Put_Picture (i*16,j*16,Rainbow);
     for i:= 0 to 40 do
             begin
                  Put_Picture (i*7,i*4,PacMan);
                  delay (20);
                  Put_Picture (i*7,i*4,BackGround);
             end;
*)
     (* Go Down *)
     for j:=0 to 183 do
         begin
              Put_Picture (0,j,PacMan);
              delay (20);
              Put_Picture (0,j,RainBow);
         end;
     ch:=readkey;

     (* Go Right *)
     for i:=0 to 303 do
         begin
              Put_Picture (i,183,PacMan);
              Put_Picture (i,183,RainBow);
         end;
     ch:=readkey;

     (* Go Up *)
     for j:=183 downto 0 do
         begin
              Put_Picture (303,j,PacMan);
              Put_Picture (303,j,RainBow);
         end;
     ch:=readkey;

     (* Go Left *)
     for i:=303 downto 0 do
         begin
              Put_Picture (i,0,PacMan);
              Put_Picture (i,0,RainBow);
         end;

     ch:=readkey;
END.

Black     3 0 : DarkGray     3  8
Blue      3 1 : LightBlue    3  9
Green     3 2 : LightGreen   3 10
Cyan      3 3 : LightCyan    3 11
Red       3 4 : LightRed     3 12
Magenta   3 5 : LightMagenta 3 13
Brown     3 6 : Yellow       3 14
LightGray 3 7 : White        3 15
Newsgroups: rec.games.programmer