[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]

(*
I have *really* simple code I wrote for loading a 320x200x256 pcx if
that'd do. I have other stuff that you could work with, but it's not
mine and not finished.

CL/  Display a background .PCX (a map in this case), and allow for the
CL/movement of foreground objects w/o affecting the background .PCX.

What you want to do is use virtual screens or page flipping, depending
on the graphic mode. If you're in low res (really easy!) 320x200x256,
you can easily use 64k virtual screens (just arrays of [0..199,0..319]
for simplicity) and treat *them* like a screen. Then dump them to the
real screen once all your updates are done.  For higher vid modes,
virtual screens can get a *bit* more complex, 'specially for 16 color
modes.

CL/Item_REc = rec
CL/             name : string [30];
CL/             amt : byte;
CL/          end;
CL/Item_Type = array[1..5] of Item_Rec;

CL/Map_Rec = Record
CL/            Occupant : Byte; { Player=1, Nobody=0, etc }
CL/            Items    : Item_type;
CL/            Case Terrain:Char of
CL/              'F' : etc,etc...
CL/         End; { Map_rec }
CL/map_type = array[1..100,1..100] of map_rec;

CL/var
CL/  Map : map_type;

Well, the list of items should be link listed. I mean, not *every* map
will always have 5 items, right? Save memory that way.  Also, use
item numbers instead of signifying an item by it's entire name.  Using
a record structure something like this might help a bit:
*)

Type
  PItemRec = ^ItemRec;
  ItemRec = record
    name  : string[28];
    idnum : word;
    next  : PItemRec;
  end; {ItemRec 35 bytes}

  PItemIdx = ^ItemIdx;
  ItemIdx = record
     idnum : word;      {maximum of ~65535 items, depending on mem}
     amt   : Byte;
     next  : PItemIdx;
   end; {ItemIdx 7 bytes }

  PPlayerIdx = ^PlayerIdx
  PlayerIdx = record
    idnum : word;
    next : PPlayerIdx
  end; {PlayerIdx 6 bytes} {This will allow for more than one player
                            on a map coord if you want. Just an idea}

  Map_Rec = Record
    Occupants : PPlayerIdx;  {list of players}
    Items     : PItemIdx;    {list of items}
    Case Terrain:char etc
  End; { Map_rec 9 bytes}

{If you only want one player per square at a time, you can change
occupants to type byte, makeing map_rec 6 bytes, increasing your maximum
map size by like 1/3

Again, you could do linked lists for the map, but I'm sure you won't
have *that* big a map...  85x85 should be ok, right?
}

  pmap_type = ^Map_Type;  {This will save your data segment some room}
  map_type = array[1..85,1..85] of map_rec;   {with 9 byte maprec}
  map_type = array[1..104,1..104] of map_rec; {with 6 byte maprec}

{here's some examples of how to access these variables}

Procedure AddItem(NewName:string;NewId:Word;Var List:PItemIdx);
var
  NewItem:PItemRec;
begin
  New(Newitem);       {alloc mem for new item}
  with newitem^ do
    begin
      name:=newname;
      Idnum:=newid;
      Next:=List;     {chain "list" after newitem}
    end;
  List:=NewItem;      {Insert into front of list}
end;

Var
  Map      : PMap_Type;
  ItemList : PItemRec;
  t,i      : integer;
  pPlr     : PPlayerIdx;
  pItm     : PItemIdx;

begin
  new(map);      { get heap memory for the MAP pointer}
  ItemList:=nil;    { no items in master list yet}

  fillchar(map^,sizeof(map^),0);  { clear *ALL* map memory to zeros }

  {Make some arbitary items}
  Additem('Sword',0,ItemList);
  Additem('Shield',1,ItemList);
  Additem('Dagger',2,ItemList);
  Additem('Helm',3,ItemList);

  For T:=1 to 85 do
    for I:=1 to 85 do
      begin
        terrain:=terraintypes[random(10)]; {whatever}
        if random(100) then
          begin
            new(pitm); {make a new item idex}
            with pitm^ do
              begin
                idnum:=random(4);
                amt:=1;
                next:=nil;
              end;
            Map^[t,i].items^:=pitm;
          end;
      end;

{these next lines should clean up the entire map, no matter how many
items, players or whatever you have around.  As long as you don't have
any invalid pointers...<G>}

  For T:=1 to 85 do
    for I:=1 to 85 do
      begin
        while occupant<>nil do
          begin
            pplr:=occupant;
            occupant:=occupant^.next;
            dispose(pplr);
          end;
        while items<>nil do
          begin
            pitm:=items;
            items:=items^.next;
            dispose(pitm);
          end;
      end;
  dispose(map);  { free heap memory for the MAP pointer}
end.


[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]