home *** CD-ROM | disk | FTP | other *** search
/ Merciful 5 / Merciful - Disc 5.iso / software / p / pcqpascalv1.2d.lha / Examples / MapMaker.p < prev    next >
Encoding:
Text File  |  1992-02-17  |  8.5 KB  |  402 lines

  1. Program MapMaker;
  2.  
  3. {$I "Include:Exec/Libraries.i"}
  4. {$I "Include:Exec/Interrupts.i"}
  5. {$I "Include:Graphics/Graphics.i"}
  6. {$I "Include:Graphics/Pens.i"}
  7. {$I "Include:Intuition/Intuition.i"}
  8. {$I "Include:Libraries/DOS.i"}
  9. {$I "Include:Graphics/View.i"}
  10. {$I "Include:Utils/Random.i"}
  11.  
  12. {
  13.     This program just draws a blocky map from straight overhead,
  14. then repeatedly splits each block into four parts and adjusts the
  15. elevation of each of the parts until it gets down to one pixel per
  16. block.  It ends up looking something like a terrain map.  It's kind
  17. of a fractal thing, but not too much.  Some program a long time ago
  18. inspired this, but I apologize for forgetting which one.  As I
  19. recall, that program was derived from Chris Gray's sc.
  20.     Once upon a time I was thinking about writing an overblown
  21. strategic conquest game, and this was the first stab at a map
  22. maker.  The maps it produces look nifty, but have no sense of
  23. geology so they're really not too useful for a game.
  24.     When the map is finished, press the left button inside the
  25. window somewhere and the program will go away.
  26. }
  27.  
  28. const
  29.     MinX = 0;
  30.     MaxX = 320;
  31.     MinY = 0;
  32.     MaxY = 200;
  33.  
  34. type
  35.     MapArray = array [MinX .. MaxX - 1, MinY .. MaxY - 1] of Byte;
  36.  
  37. VAR
  38.     average,x,y,
  39.     nextx,nexty,count,
  40.     skip,level      : Short;
  41.     rp            : RastPortPtr;
  42.     vp            : Address;
  43.     s             : Address;
  44.     w             : WindowPtr;
  45.     Seed      : Integer;
  46.     m             : MessagePtr;
  47.     Map           : MapArray;
  48.     Quit      : Boolean;
  49.  
  50.  
  51. Function FixX(x : short): short;
  52. begin
  53.     if x < 0 then
  54.     FixX := x + MaxX
  55.     else if x >= MaxX then
  56.     FixX := x mod MaxX
  57.     else
  58.     FixX := x;
  59. end;
  60.  
  61. Function FixY(y : short) : short;
  62. begin
  63.     if x < 0 then
  64.     FixY := y + MaxY
  65.     else if x >= MaxY then
  66.     FixY := y mod MaxY
  67.     else
  68.     FixY := y;
  69. end;
  70.  
  71. Procedure DrawMap;
  72. begin
  73.     if skip = 1 then begin
  74.     for x := MinX to MaxX - 1 do begin
  75.         for y := MinY to MaxY - 1 DO begin
  76.         if Map[x,y] < 100 then begin
  77.             SetAPen(rp, 0);
  78.             WritePixel(rp, x, y)
  79.         end else begin
  80.             average := (Map[x,y] - 100) DIV 6 + 1;
  81.             if average > 15 then
  82.             average := 15;
  83.             SetAPen(rp, average);
  84.             WritePixel(rp, x, y)
  85.         end
  86.         end
  87.     end
  88.    end else begin
  89.     x := MinX;
  90.     while x < MaxX do begin
  91.         y := MinY;
  92.         while y < MaxY do begin
  93.         if Map[x,y] < 100 then begin
  94.             SetAPen(rp, 0);
  95.             RectFill(rp,x,y,x + skip - 1,y + skip - 1)
  96.         end else begin
  97.             average := (Map[x,y] - 100) DIV 6 + 1;
  98.             if average > 15 then
  99.             average := 15;
  100.             SetAPen(rp,average);
  101.             RectFill(rp,x,y,x + skip - 1,y + skip - 1);
  102.         end;
  103.         y := y + skip;
  104.         end;
  105.         x := x + skip;
  106.     end;
  107.     end;
  108. end;
  109.  
  110. Function OpenTheScreen() : Boolean;
  111. var
  112.     ns : NewScreenPtr;
  113. begin
  114.     new(ns);
  115.     with ns^ do begin
  116.     LeftEdge := 0;
  117.     TopEdge  := 0;
  118.     Width    := 320;
  119.     Height   := 200;
  120.     Depth    := 5;
  121.     DetailPen := 3;
  122.     BlockPen  := 2;
  123.     ViewModes := 0;
  124.     SType     := CUSTOMSCREEN_f;
  125.     Font      := nil;
  126.     DefaultTitle := nil;
  127.     Gadgets   := nil;
  128.     CustomBitMap := nil;
  129.     end;
  130.  
  131.     s := OpenScreen(ns);
  132.     dispose(ns);
  133.     OpenTheScreen := s <> nil;
  134. end;
  135.  
  136. Function OpenTheWindow() : Boolean;
  137. var
  138.     nw : NewWindowPtr;
  139. begin
  140.     new(nw);
  141.     with nw^ do begin
  142.     LeftEdge := MinX;
  143.     TopEdge := MinY;
  144.     Width := MaxX;
  145.     Height := MaxY;
  146.  
  147.     DetailPen := -1;
  148.     BlockPen  := -1;
  149.     IDCMPFlags := MOUSEBUTTONS_f;
  150.     Flags := BORDERLESS + BACKDROP + SMART_REFRESH + ACTIVATE;
  151.     FirstGadget := nil;
  152.     CheckMark := nil;
  153.     Title := nil;
  154.     Screen := s;
  155.     BitMap := nil;
  156.     MinWidth := 50;
  157.     MaxWidth := -1;
  158.     MinHeight := 20;
  159.     MaxHeight := -1;
  160.     WType := CUSTOMSCREEN_f;
  161.     end;
  162.  
  163.     w := OpenWindow(nw);
  164.     dispose(nw);
  165.     OpenTheWindow := w <> nil;
  166. end;
  167.  
  168. Function Min(x,y : Short) : Short;
  169. begin
  170.     if x < y then
  171.     Min := x
  172.     else
  173.     Min := y;
  174. end;
  175.  
  176. Function Max(x,y : Short) : Short;
  177. begin
  178.     if x > y then
  179.     Max := x
  180.     else
  181.     Max := y;
  182. end;
  183.  
  184.  
  185. Function Height(x,y : Short) : Short;
  186. begin
  187.     Height := Map[x,y] div 32;
  188. end;
  189.  
  190. Procedure ChangeDelta(var d : Short);
  191. begin
  192.     case RangeRandom(100) of
  193.       51..75   : if d < 1 then
  194.              Inc(d);
  195.       76..100  : if d > -1 then
  196.              Dec(d);
  197.     end; 
  198. end;
  199.  
  200. Procedure MakeRivers;
  201. var
  202.     i    : Short;
  203.     x,y,
  204.     dx,dy  : Short;
  205.     OK   : Boolean;
  206.     LastHeight : Short;
  207.     Count      : Short;
  208.     cx,cy      : Short;
  209.     Search     : Short;
  210.     CheckHeight : Short;
  211. begin
  212.     SetAPen(rp, 16);
  213.  
  214.     for cx := 0 to 319 do begin
  215.     for cy := 0 to 199 do begin
  216.         if (Map[cx,cy] > 153) and (Map[cx,cy] < 162) and 
  217.            (RangeRandom(100) < 3) then begin
  218.  
  219.         x := cx;
  220.         y := cy;
  221.  
  222.         dx := 0;
  223.         dy := 0;
  224.         while (dx = 0) and (dy = 0) do begin
  225.             dx := RangeRandom(2) - 1;
  226.             dy := RangeRandom(2) - 1;
  227.         end;
  228.  
  229.         OK := True;
  230.  
  231.         Count := 0;
  232.         while OK do begin
  233.             LastHeight := Map[x,y]; { Height(x,y); }
  234.             Map[x,y] := 0;
  235.             WritePixel(rp, x, y);
  236.  
  237.             CheckHeight := -6;
  238.             Search := 0;
  239.             repeat
  240.                 repeat
  241.                 ChangeDelta(dx);
  242.                 ChangeDelta(dy);
  243.                 until (dx <> 0) or (dy <> 0);
  244.             Inc(Search);
  245.             if (Map[FixX(x + dx), FixY(y + dy)] > 0) and
  246.                          {  (Height(FixX(x + dx), FixY(y + dy)) < CheckHeight) then begin }
  247.                (Map[FixX(x + dx), FixY(y + dy)] < (LastHeight + CheckHeight)) then begin
  248.                 x := FixX(x + dx);
  249.                 y := FixY(y + dy);
  250.                 Search := 0;
  251.             end else if Search > 200 then begin
  252.                 if CheckHeight < 6 then begin
  253.                 Inc(CheckHeight,2);
  254.                 Search := 1;
  255.                 end else begin
  256.                 Search := 0;
  257.                 OK := False;
  258.                 end;
  259.             end;
  260.             until Search = 0;
  261.  
  262.             Inc(Count);
  263.             if Count > 150 then
  264.             OK := False;
  265.             if Map[x,y] < 100 then
  266.             OK := False;
  267.         end;
  268.         end;
  269.     end;
  270.     end;
  271. end;
  272.  
  273. Procedure MakeMap;
  274. begin
  275.  
  276.     rp:= w^.RPort;
  277.     vp:= ViewPortAddress(w);
  278.  
  279.     SetRGB4(vp, 0, 0, 0, 12); { Ocean Blue }
  280.     SetRGB4(vp, 1, 1, 1, 0);
  281.     SetRGB4(vp, 2, 0, 3, 0);
  282.     SetRGB4(vp, 3, 0, 4, 0); { Dark Green }
  283.     SetRGB4(vp, 4, 0, 5, 0);
  284.     SetRGB4(vp, 5, 1, 6, 0);
  285.     SetRGB4(vp, 6, 2, 8, 0); { Medium Green }
  286.     SetRGB4(vp, 7, 4, 10, 0);
  287.     SetRGB4(vp, 8, 6, 10, 0);
  288.     SetRGB4(vp, 9, 9, 9, 0); { Brown }
  289.     SetRGB4(vp, 10, 8, 8, 0);
  290.     SetRGB4(vp, 11, 7, 7, 0); { Dark Brown }
  291.     SetRGB4(vp, 12, 10, 10, 0); { Dark Grey }
  292.     SetRGB4(vp, 13, 10, 10, 10);
  293.     SetRGB4(vp, 14, 12, 12, 12);
  294.     SetRGB4(vp, 15, 14, 14, 15); { White }
  295.     SetRGB4(vp, 16, 0, 0, 10);   { River blue }
  296.  
  297.     SelfSeed; { Seed the Random Number Generator }
  298.  
  299.     level := 7;
  300.     skip  := 16;
  301.  
  302.     y := MinY;
  303.     while y < MaxY do begin
  304.     x := MinX;
  305.     while x < MaxX do begin
  306.         Map[x,y] := RangeRandom(220);
  307.         x := x + skip;
  308.     end;
  309.     y := y + skip;
  310.     end;
  311.  
  312.     DrawMap;
  313.  
  314.     for level := 2 to 5 do begin
  315.     skip := skip DIV 2;
  316.     y := MinY;
  317.     while y < MaxY do begin
  318.         if (y MOD (2*skip)) = 0 then
  319.         nexty := skip * 2
  320.         else
  321.         nexty:=skip;
  322.         x := MinX;
  323.         while x < MaxX do begin
  324.         if (x MOD (2*skip)) = 0 then
  325.             nextx := skip * 2
  326.         else
  327.             nextx := skip;
  328.         if (nextx = skip * 2) AND (nexty = skip * 2) then begin
  329.             average := Map[x,y] * 5;
  330.             count := 9;
  331.         end else begin
  332.             average := 0;
  333.             count := 4;
  334.         end;
  335.         if (nextx = skip * 2) then begin
  336.             average := average + Map[x,FixY(y - skip)];
  337.             average := average + Map[x,FixY(y + nexty)];
  338.             count := count + 2;
  339.         end;
  340.         if (nexty = skip * 2) then begin
  341.             average := average + Map[FixX(x - skip),y];
  342.             average := average + Map[FixX(x + nextx),y];
  343.             count := count + 2;
  344.         end;
  345.         average := average + Map[FixX(x-skip),FixY(y-skip)]
  346.                    + Map[FixX(x-nextx),FixY(y+nexty)]
  347.                    + Map[FixX(x+skip),FixY(y-skip)]
  348.                    + Map[FixX(x+nextx),FixY(y+nexty)];
  349.         average := (average DIV count) +
  350.                 (RangeRandom(4) - 2) * (9 - level);
  351.         case Average of
  352.           150..255 : Average := Average + 2;
  353.           100..149 : Inc(Average);
  354.         else
  355.             Average := Average - 3;
  356.         end;
  357.         if average < 0 then
  358.             average := 0;
  359.         if average > 220 then
  360.             average := 220;
  361.         Map[x,y] := average;
  362.  
  363.         x := x + skip;
  364.         end;
  365.         m := GetMsg(w^.UserPort);
  366.         if m <> Nil then begin
  367.         Quit := True;
  368.         return;
  369.         end;
  370.         y := y + skip;
  371.     end;
  372.     DrawMap;
  373.     end;
  374.     MakeRivers;
  375. end;
  376.  
  377. begin
  378.     GfxBase := OpenLibrary("graphics.library", 0);
  379.     if GfxBase <> nil then begin
  380.     if OpenTheScreen() then begin
  381.         if OpenTheWindow() then begin
  382.         Quit := False;
  383.         ShowTitle(s, false);
  384.         MakeMap;
  385.         if not Quit then
  386.             m := WaitPort(w^.UserPort);
  387.         Forbid;
  388.         repeat
  389.             m := GetMsg(w^.UserPort);
  390.         until m = nil;
  391.         CloseWindow(w);
  392.         Permit;
  393.         end else
  394.         writeln('Could not open the window.');
  395.         CloseScreen(s);
  396.     end else
  397.         writeln('Could not open the screen.');
  398.     CloseLibrary(GfxBase);
  399.     end else
  400.     writeln('Could not open graphics.library');
  401. end.
  402.