home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 167 / pascal / mvesprt.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-08-19  |  9.9 KB  |  338 lines

  1. PROGRAM MOVE_SPRITE; { Christopher Reed  7/16/87 }
  2. (* This program demonstrates the movement of a sprite-like object under control
  3.    of the mouse.  Its important feature is that it does not use any bizarre
  4.    type coercion.  (At least at the Pascal level).
  5.  
  6.    To run this program you need two aditional files in Degas Low-rez,
  7.    uncompressed, format,   ...PI1.
  8.    The first provides a background (Field_Screen). The second provides the
  9.    Sprite.  The upper-left square, 32 pixels on a side, is currently firm-coded
  10.    as the sprite shape.  See CONST sprite_w & sprite_h.  XYWH = 0,0,32,32.
  11.  
  12.    I have to admit that I started with the demos in 'The ST Sprite Factory'.
  13.    Its unfortunate that Mike Hollenbeck's JOYSTICK sample program is so complex
  14.    Its complexity will scare off most programers.  This program shows that
  15.    this complexity is not necessary. *)
  16.  
  17. (* TO DO:
  18.    Implement a MASK building function that can be used for transparent
  19.       (foreground) sprite movement.
  20.    Re-define the sprite file.  There is no need to carry full screen
  21.       image files around (32000 bytes).
  22. *)
  23.  
  24. (* problems:  There is stuff in the input file so I can't use keypress,
  25.     as a progress control.  Where did it come from?
  26.    I'm not happy with the movement, the sprite seems to show up twice.
  27.  *)
  28.  
  29.  CONST
  30.   (*$I gemconst.pas *)
  31.   sprite_w = 32 ;
  32.   sprite_h = 32 ;
  33.  
  34. TYPE
  35.    scr_def_ptr  = ^Screendata ;
  36.    Screendata   =  PACKED ARRAY[0..32511] OF byte;
  37.    ptr_screen   = ^scrn_memory;   { pointer to the screen array }
  38.    scrn_memory  =  packed array [ 0..31999 ] of BYTE;
  39.  
  40.    c_pallet = array[0..15] of integer;
  41.  
  42.    degas_pic = record
  43.       rez : integer;
  44.       pal : c_pallet;
  45.       scr : scrn_memory;
  46.    end;
  47.    degas_file = file of degas_pic;
  48.  
  49.    mfdb = record
  50.       addr    : ptr_screen ;
  51.       wid_pix : integer ;
  52.       ht_pix  : integer ;
  53.       wid_wds : integer ;
  54.       flag    : integer ;
  55.       num_planes : integer ;
  56.       rfe3, rfe2, rfe1 : integer ;
  57.    end ;
  58.    mfdb_ptr = ^mfdb;
  59.  
  60.    Ctrl_Parms = record
  61.       c6, c5, c4, c3, c2, c1, c0 : integer ; { PPascal puts them 'right' }
  62.       source_addr : mfdb_ptr ;
  63.       dest_addr   : mfdb_ptr ;
  64.    end ;
  65.    Int_In_Parms    = ARRAY [ 0..15 ] OF integer ;
  66.    Int_Out_Parms   = ARRAY [ 0..45 ] OF integer ;
  67.    Pts_In_Parms    = ARRAY [ 0..11 ] OF integer ;
  68.    Pts_Out_Parms   = ARRAY [ 0..11 ] OF integer ;
  69.  
  70.  (*$I gemtype.pas *)
  71.  
  72.  VAR
  73.    dummy : integer;
  74.  
  75.    copy_screen   : ptr_screen;
  76.    sprite_screen : ptr_screen ;
  77.    field_screen  : ptr_screen ;
  78.  
  79.    field_mfdb,
  80.    build_mfdb,
  81.    sprite_mfdb   : MFDB_ptr;
  82.  
  83.    Visible_Screen : ptr_screen ;
  84.    Build_Screen   : ptr_screen ;
  85.  
  86.    orig_phy_screen,
  87.    orig_log_screen : ptr_screen ;
  88.    orig_pallet   : c_pallet ;
  89.    intro_pallet  : c_pallet ;
  90.  
  91.    (*$I gemsubs.pas *)      (* Include all GEM subroutines *)
  92.  
  93. function physbase : ptr_screen;
  94.    Xbios( 2 );
  95.  
  96. function logbase : ptr_screen;
  97.    Xbios(3);
  98.  
  99. function Getrez : integer;
  100.    Xbios(4);
  101.  
  102. procedure Setscreen(Logloc, Phyloc : ptr_screen; Rez : integer);
  103.    Xbios(5);
  104.  
  105. procedure set_colors ( var c : c_pallet ) ;
  106.    Xbios(6);
  107.  
  108. function get_colr( reg,col : integer ) : integer;
  109.    Xbios(7);
  110.  
  111. procedure set_colr( reg,col : integer ) ;
  112.    Xbios(7);
  113.  
  114. procedure wait_vsync;
  115.    xbios (37);
  116.  
  117. procedure init_mfdb(var form : MFDB_ptr; raster_addr : ptr_screen);
  118. begin
  119.         { and initialize all fields of the MFDB }
  120.    new ( form );
  121.    with form^ do
  122.     begin
  123.       addr       := raster_addr;
  124.         { some low rez assumptions here }
  125.       wid_pix    := 320;     { low rez }
  126.       ht_pix     := 200;     { low rez }
  127.       wid_wds    := 20;      { (wid.pix + 15) div 16 }
  128.       flag       := 0;       { device dependent }
  129.       num_planes := 4;       { again, low rez }
  130.     end ;
  131. end;
  132.  
  133. PROCEDURE copy_rect(source, dest : mfdb_ptr ;
  134.                     from_x, from_y,
  135.                     to_x,   to_y,  width, height, mode : integer);
  136.     { using gem raster copy function }
  137.  VAR
  138.    control : Ctrl_Parms ;
  139.    int_in  : Int_In_Parms ;
  140.    int_out : Int_Out_Parms ;
  141.    pts_in  : Pts_In_Parms ;
  142.    pts_out : Pts_Out_Parms ;
  143.  
  144.    PROCEDURE VDI_Call( cmd, sub_cmd : integer ; nints, npts : integer ;
  145.                       VAR ctrl : Ctrl_Parms ;
  146.                       VAR int_in : Int_In_Parms ; VAR int_out : Int_Out_Parms ;
  147.                       VAR pts_in : Pts_In_Parms ; VAR pts_out : Pts_Out_Parms ;
  148.                       translate : boolean ) ;
  149.       EXTERNAL ;
  150. begin
  151.        { put source MFDB address in control array }
  152.    control.source_addr := source ;
  153.        { and same for destination MFDB }
  154.    control.dest_addr   := dest ;
  155.  
  156.    int_in[0] := mode;      { mode }
  157.  
  158.         { set the points for src and dest }
  159.    pts_in[0] := from_x ;
  160.    pts_in[1] := from_y ;
  161.    pts_in[2] := from_x + width  -1 ;
  162.    pts_in[3] := from_y + height -1 ;
  163.  
  164.    pts_in[4] := to_x ;
  165.    pts_in[5] := to_y ;
  166.    pts_in[6] := to_x + width  -1 ;
  167.    pts_in[7] := to_y + height -1 ;
  168.  
  169.    VDI_Call( 109, 0, 1, 8, control, int_in, int_out, pts_in, pts_out, false);
  170.  
  171. end;
  172.  
  173. Procedure flip_screens ;
  174.  var
  175.    tempscreen : ptr_screen;
  176.  begin
  177.     Tempscreen     := Visible_Screen;
  178.     Visible_Screen := Build_Screen;
  179.     Build_Screen   := Tempscreen;
  180.     init_mfdb ( build_mfdb, build_screen ) ;
  181.     Setscreen ( Build_Screen, Visible_Screen, -1 );
  182.  end;
  183.  
  184. function alloc_Screen : ptr_screen;
  185. VAR
  186.   Scr_junk  :
  187.     RECORD
  188.     CASE integer OF
  189.       0 : (scr_i   : long_integer ) ;
  190.       1 : (scr_big : scr_def_ptr ) ;
  191.       2 : (scr_adr : ptr_screen ) ;
  192.   end;
  193. begin
  194.    WITH Scr_junk DO
  195.     begin
  196.      NEW(Scr_big);                { allocates 32512 bytes }
  197.      IF Scr_i MOD 256 <> 0 THEN   { adjust its address to be on a 256 boundry }
  198.         scr_i := scr_i + (256 - (scr_i MOD 256)); {to become a screen address }
  199.     end;
  200.    alloc_Screen := scr_junk.scr_adr;  { return it as a pointer }
  201. end;
  202.  
  203. Function Load_Screen ( def_path : path_name;
  204.                        var  screen_mem : ptr_screen;
  205.                        var colors : c_pallet) :boolean;
  206.  var
  207.    f : degas_file;
  208.    x : integer;
  209.    filename : path_name;
  210.    t : boolean;
  211. begin
  212.    filename := '';
  213.    t := get_in_file(def_path,filename);
  214.    set_mouse(M_Bee);
  215.    reset( f, filename );
  216.    with f^ do
  217.     begin
  218.       colors := pal ;
  219.       screen_mem^ := scr;
  220.     end;
  221.    load_screen := true;
  222.    set_mouse(M_Arrow);
  223. end;
  224.  
  225. function limit ( position, size, edge : integer ): integer;
  226. begin
  227.    if position > ( edge - size ) then
  228.       position := ( edge - size ) ;
  229.    limit := position;
  230. end;
  231.  
  232. Procedure event_loop;
  233.  var
  234.    dummy     : integer ;
  235.    quit_flag : boolean;
  236.    prior_x, prior_y,
  237.    mouse_x, mouse_y,
  238.    event     : integer;
  239.    msg       : message_buffer;
  240. begin
  241.  prior_x := -1;
  242.  prior_y := -1;
  243.  repeat
  244.     event := Get_Event(E_Button|E_Timer,
  245.                      1,1,1,             (* left button down      *)
  246.                      0,                 (* timer *)
  247.                      False,0,0,0,0,
  248.                      False,0,0,0,0,
  249.                      msg,
  250.                      dummy,             (* Key pressed           *)
  251.                      dummy,dummy,       (* Not used              *)
  252.                      mouse_x,mouse_y,
  253.                      dummy
  254.                      );
  255.     mouse_x := limit ( mouse_x, sprite_w, 320 );
  256.     mouse_y := limit ( mouse_y, sprite_h, 200 );
  257.     if ( mouse_x <> prior_x ) or ( mouse_y <> prior_y ) then
  258.     begin
  259.        { The sequence of events is
  260.          1) position sprite; 2) flip_screens; 3) clean_up (new) build_screen
  261.          A wait for vertical sync is necessary between 2) & 3) so that
  262.          the (new) build_screen is not visible before we clean it up. }
  263.  
  264.        { 1). copy the sprite to the build screen not touching visible screen}
  265.        copy_rect ( sprite_mfdb, build_mfdb, 0, 0, mouse_x, mouse_y,
  266.                   sprite_w, sprite_h, 3 );
  267.        { 2). }
  268.        flip_screens;
  269.  
  270.        wait_vsync;     { see commentry }
  271.  
  272.        { 3). clean up prior screen }
  273.        { put the original screen ( now hidden ) back together }
  274.        if prior_x <> -1 then
  275.           copy_rect ( field_mfdb, build_mfdb, prior_x, prior_y,
  276.                     prior_x, prior_y,
  277.                     sprite_w, sprite_h, 3 ) ;
  278.  
  279.        { rotate the sprite locations }
  280.        prior_x := mouse_x;
  281.        prior_y := mouse_y ;
  282.     end;
  283.     quit_flag := (event & E_Button) <> 0 ;
  284.  until Quit_flag ;
  285. end;
  286.  
  287. begin
  288.  if Init_gem >= 0 then
  289.  begin
  290.     if getrez <> 0 then
  291.        dummy := do_alert('[3][ | LOW REZ ONLY ][ OK ]',1)
  292.     else
  293.     begin
  294.        { save the original screen loactions }
  295.        orig_phy_screen := physbase ;
  296.        orig_log_screen := logbase ;
  297.  
  298.        init_mouse ;
  299.        set_mouse ( M_Bee );
  300.  
  301.        {fill a screen with a degas picture }
  302.        field_screen := alloc_screen;
  303.        init_mfdb ( field_mfdb, field_screen ) ;
  304.        if load_screen ('A:\*.PI1', field_screen, Intro_pallet ) then ;
  305.  
  306.        {copy it to a changing copy }
  307.        copy_screen := alloc_screen ;
  308.        copy_screen^ := field_screen^;  {should this be a blit move?}
  309.  
  310.        {once more to the working screen}
  311.        build_screen := alloc_screen;
  312.        init_mfdb ( build_mfdb, build_screen ) ;
  313.        build_screen^ := field_screen^;
  314.  
  315.        sprite_screen := alloc_screen ;
  316.        init_mfdb ( sprite_mfdb, sprite_screen ) ;
  317.        if load_screen ('A:\*.SPT', sprite_screen, orig_pallet ) then ;
  318.  
  319.        {set up for swapping}
  320.        hide_mouse;
  321.        set_colors ( intro_pallet ) ;
  322.        visible_screen := copy_screen;
  323.      { build_screen := build_screen ;  }
  324.        flip_screens;
  325.        draw_string ( 30,60,'screen 0');    { DDT }
  326.        flip_screens;                       { DDT }
  327.        draw_string ( 30,60,'SCREEN 1');    { DDT }
  328.  
  329.        event_loop;
  330.  
  331.        { put screens back }
  332.        show_mouse ;
  333.        setscreen (orig_log_screen, orig_phy_screen, -1 ) ;
  334.     end  ;
  335.     exit_gem;
  336.  end;
  337. end.
  338.