mapmaker.pas 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. Program MapMaker;
  2. uses Exec, graphics, Intuition, Utility;
  3. {$I tagutils.inc}
  4. {
  5. Patrick Quaid.
  6. This program just draws a blocky map from straight overhead,
  7. then repeatedly splits each block into four parts and adjusts the
  8. elevation of each of the parts until it gets down to one pixel per
  9. block. It ends up looking something like a terrain map. It's kind
  10. of a fractal thing, but not too much. Some program a long time ago
  11. inspired this, but I apologize for forgetting which one. As I
  12. recall, that program was derived from Chris Gray's sc.
  13. Once upon a time I was thinking about writing an overblown
  14. strategic conquest game, and this was the first stab at a map
  15. maker. The maps it produces look nifty, but have no sense of
  16. geology so they're really not too useful for a game.
  17. When the map is finished, press the left button inside the
  18. window somewhere and the program will go away.
  19. }
  20. {
  21. Changed the source to 2.0+.
  22. 12 May 1998.
  23. Translated to FPC. This was one of the first
  24. program I tried with fpc, just to check that
  25. the amiga units worked.
  26. 08 Aug 1998.
  27. [email protected]
  28. }
  29. const
  30. MinX = 0;
  31. MaxX = 320;
  32. MinY = 0;
  33. MaxY = 200;
  34. type
  35. MapArray = array [MinX .. MaxX - 1, MinY .. MaxY - 1] of Longint;
  36. VAR
  37. average,x,y,
  38. nextx,nexty,count1,
  39. skip,level : Longint;
  40. rp : pRastPort;
  41. vp : Pointer;
  42. s : pScreen;
  43. w : pWindow;
  44. m : pMessage;
  45. Map : MapArray;
  46. Quit : Boolean;
  47. i : Longint;
  48. thetags : Array[0..12] of tTagItem;
  49. Function FixX(x : Longint): Longint;
  50. begin
  51. if x < 0 then
  52. FixX := x + MaxX
  53. else if x >= MaxX then
  54. FixX := x mod MaxX
  55. else
  56. FixX := x;
  57. end;
  58. Function FixY(y : Longint) : Longint;
  59. begin
  60. if x < 0 then
  61. FixY := y + MaxY
  62. else if x >= MaxY then
  63. FixY := y mod MaxY
  64. else
  65. FixY := y;
  66. end;
  67. Procedure DrawMap;
  68. begin
  69. if skip = 1 then begin
  70. for x := MinX to MaxX - 1 do begin
  71. for y := MinY to MaxY - 1 DO begin
  72. if Map[x,y] < 100 then begin
  73. SetAPen(rp, 0);
  74. i := WritePixel(rp, x, y)
  75. end else begin
  76. average := (Map[x,y] - 100) DIV 6 + 1;
  77. if average > 15 then
  78. average := 15;
  79. SetAPen(rp, average);
  80. i := WritePixel(rp, x, y)
  81. end
  82. end
  83. end
  84. end else begin
  85. x := MinX;
  86. while x < MaxX do begin
  87. y := MinY;
  88. while y < MaxY do begin
  89. if Map[x,y] < 100 then begin
  90. SetAPen(rp, 0);
  91. RectFill(rp,x,y,x + skip - 1,y + skip - 1)
  92. end else begin
  93. average := (Map[x,y] - 100) DIV 6 + 1;
  94. if average > 15 then
  95. average := 15;
  96. SetAPen(rp,average);
  97. RectFill(rp,x,y,x + skip - 1,y + skip - 1);
  98. end;
  99. y := y + skip;
  100. end;
  101. x := x + skip;
  102. end;
  103. end;
  104. end;
  105. Function Min(x,y : Longint) : Longint;
  106. begin
  107. if x < y then
  108. Min := x
  109. else
  110. Min := y;
  111. end;
  112. Function Max(x,y : Longint) : Longint;
  113. begin
  114. if x > y then
  115. Max := x
  116. else
  117. Max := y;
  118. end;
  119. Function Height(x,y : Longint) : Longint;
  120. begin
  121. Height := Map[x,y] div 32;
  122. end;
  123. Procedure ChangeDelta(var d : Longint);
  124. begin
  125. case Random(100) of
  126. 51..75 : if d < 1 then
  127. Inc(d);
  128. 76..100 : if d > -1 then
  129. Dec(d);
  130. end;
  131. end;
  132. Procedure MakeRivers;
  133. var
  134. i : Longint;
  135. x,y,
  136. dx,dy : Longint;
  137. OK : Boolean;
  138. LastHeight : Longint;
  139. count1 : Longint;
  140. cx,cy : Longint;
  141. Search : Longint;
  142. CheckHeight : Longint;
  143. begin
  144. SetAPen(rp, 16);
  145. for cx := 0 to 319 do begin
  146. for cy := 0 to 199 do begin
  147. if (Map[cx,cy] > 153) and (Map[cx,cy] < 162) and
  148. (Random(100) < 3) then begin
  149. x := cx;
  150. y := cy;
  151. dx := 0;
  152. dy := 0;
  153. while (dx = 0) and (dy = 0) do begin
  154. dx := Random(2) - 1;
  155. dy := Random(2) - 1;
  156. end;
  157. OK := True;
  158. count1 := 0;
  159. while OK do begin
  160. LastHeight := Map[x,y]; { Height(x,y); }
  161. Map[x,y] := 0;
  162. i := WritePixel(rp, x, y);
  163. CheckHeight := -6;
  164. Search := 0;
  165. repeat
  166. repeat
  167. ChangeDelta(dx);
  168. ChangeDelta(dy);
  169. until (dx <> 0) or (dy <> 0);
  170. Inc(Search);
  171. if (Map[FixX(x + dx), FixY(y + dy)] > 0) and
  172. { (Height(FixX(x + dx), FixY(y + dy)) < CheckHeight) then begin }
  173. (Map[FixX(x + dx), FixY(y + dy)] < (LastHeight + CheckHeight)) then begin
  174. x := FixX(x + dx);
  175. y := FixY(y + dy);
  176. Search := 0;
  177. end else if Search > 200 then begin
  178. if CheckHeight < 6 then begin
  179. Inc(CheckHeight,2);
  180. Search := 1;
  181. end else begin
  182. Search := 0;
  183. OK := False;
  184. end;
  185. end;
  186. until Search = 0;
  187. Inc(count1);
  188. if count1 > 150 then
  189. OK := False;
  190. if Map[x,y] < 100 then
  191. OK := False;
  192. end;
  193. end;
  194. end;
  195. end;
  196. end;
  197. Procedure MakeMap;
  198. begin
  199. rp:= w^.RPort;
  200. vp:= ViewPortAddress(w);
  201. SetRGB4(vp, 0, 0, 0, 12); { Ocean Blue }
  202. SetRGB4(vp, 1, 1, 1, 0);
  203. SetRGB4(vp, 2, 0, 3, 0);
  204. SetRGB4(vp, 3, 0, 4, 0); { Dark Green }
  205. SetRGB4(vp, 4, 0, 5, 0);
  206. SetRGB4(vp, 5, 1, 6, 0);
  207. SetRGB4(vp, 6, 2, 8, 0); { Medium Green }
  208. SetRGB4(vp, 7, 4, 10, 0);
  209. SetRGB4(vp, 8, 6, 10, 0);
  210. SetRGB4(vp, 9, 9, 9, 0); { Brown }
  211. SetRGB4(vp, 10, 8, 8, 0);
  212. SetRGB4(vp, 11, 7, 7, 0); { Dark Brown }
  213. SetRGB4(vp, 12, 10, 10, 0); { Dark Grey }
  214. SetRGB4(vp, 13, 10, 10, 10);
  215. SetRGB4(vp, 14, 12, 12, 12);
  216. SetRGB4(vp, 15, 14, 14, 15); { White }
  217. SetRGB4(vp, 16, 0, 0, 10); { River blue }
  218. Randomize; { Seed the Random Number Generator }
  219. level := 7;
  220. skip := 16;
  221. y := MinY;
  222. while y < MaxY do begin
  223. x := MinX;
  224. while x < MaxX do begin
  225. Map[x,y] := Random(220);
  226. x := x + skip;
  227. end;
  228. y := y + skip;
  229. end;
  230. DrawMap;
  231. for level := 2 to 5 do begin
  232. skip := skip DIV 2;
  233. y := MinY;
  234. while y < MaxY do begin
  235. if (y MOD (2*skip)) = 0 then
  236. nexty := skip * 2
  237. else
  238. nexty:=skip;
  239. x := MinX;
  240. while x < MaxX do begin
  241. if (x MOD (2*skip)) = 0 then
  242. nextx := skip * 2
  243. else
  244. nextx := skip;
  245. if (nextx = skip * 2) AND (nexty = skip * 2) then begin
  246. average := Map[x,y] * 5;
  247. count1 := 9;
  248. end else begin
  249. average := 0;
  250. count1 := 4;
  251. end;
  252. if (nextx = skip * 2) then begin
  253. average := average + Map[x,FixY(y - skip)];
  254. average := average + Map[x,FixY(y + nexty)];
  255. count1 := count1 + 2;
  256. end;
  257. if (nexty = skip * 2) then begin
  258. average := average + Map[FixX(x - skip),y];
  259. average := average + Map[FixX(x + nextx),y];
  260. count1 := count1 + 2;
  261. end;
  262. average := average + Map[FixX(x-skip),FixY(y-skip)]
  263. + Map[FixX(x-nextx),FixY(y+nexty)]
  264. + Map[FixX(x+skip),FixY(y-skip)]
  265. + Map[FixX(x+nextx),FixY(y+nexty)];
  266. average := (average DIV count1) +
  267. (Random(4) - 2) * (9 - level);
  268. case Average of
  269. 150..255 : Average := Average + 2;
  270. 100..149 : Inc(Average);
  271. else
  272. Average := Average - 3;
  273. end;
  274. if average < 0 then
  275. average := 0;
  276. if average > 220 then
  277. average := 220;
  278. Map[x,y] := average;
  279. x := x + skip;
  280. end;
  281. m := GetMsg(w^.UserPort);
  282. if m <> Nil then begin
  283. Quit := True;
  284. Exit;
  285. end;
  286. y := y + skip;
  287. end;
  288. DrawMap;
  289. end;
  290. MakeRivers;
  291. end;
  292. begin
  293. GfxBase := OpenLibrary(GRAPHICSNAME,0);
  294. if GfxBase <> nil then begin
  295. thetags[0] := TagItem(SA_Left, 0);
  296. thetags[1] := TagItem(SA_Top, 0);
  297. thetags[2] := TagItem(SA_Width, 320);
  298. thetags[3] := TagItem(SA_Height, 200);
  299. thetags[4] := TagItem(SA_Depth, 5);
  300. thetags[5] := TagItem(SA_DetailPen, 3);
  301. thetags[6] := TagItem(SA_BlockPen, 2);
  302. thetags[7] := TagItem(SA_Type, CUSTOMSCREEN_f);
  303. thetags[8].ti_Tag := TAG_END;
  304. s := OpenScreenTagList(NIL,@thetags);
  305. if s <> NIL then begin
  306. thetags[0] := TagItem(WA_IDCMP, IDCMP_MOUSEBUTTONS);
  307. thetags[1] := TagItem(WA_Left, MinX);
  308. thetags[2] := TagItem(WA_Top, MinY);
  309. thetags[3] := TagItem(WA_Width, MaxX);
  310. thetags[4] := TagItem(WA_Height, MaxY);
  311. thetags[5] := TagItem(WA_MinWidth, 50);
  312. thetags[6] := TagItem(WA_MinHeight, 20);
  313. thetags[7] := TagItem(WA_Borderless, 1);
  314. thetags[8] := TagItem(WA_BackDrop, 1);
  315. thetags[9] := TagItem(WA_SmartRefresh, 1);
  316. thetags[10] := TagItem(WA_Activate, 1);
  317. thetags[11] := TagItem(WA_CustomScreen, longint(s));
  318. thetags[12].ti_Tag := TAG_END;
  319. w := OpenWindowTagList(NIL,@thetags);
  320. IF w <> NIL THEN begin
  321. Quit := False;
  322. ShowTitle(s, 0);
  323. MakeMap;
  324. if not Quit then
  325. m := WaitPort(w^.UserPort);
  326. Forbid;
  327. repeat
  328. m := GetMsg(w^.UserPort);
  329. until m = nil;
  330. CloseWindow(w);
  331. Permit;
  332. end else
  333. writeln('Could not open the window.');
  334. CloseScreen(s);
  335. end else
  336. writeln('Could not open the screen.');
  337. CloseLibrary(GfxBase);
  338. end else writeln('no graphics.library');
  339. end.