Bladeren bron

Module Int added

Arthur Yefimov 4 jaren geleden
bovenliggende
commit
5282bace5d
11 gewijzigde bestanden met toevoegingen van 256 en 41 verwijderingen
  1. 153 0
      Programs/Life2Print.Mod
  2. 2 1
      data/bin/link_console.bat
  3. 1 0
      data/bin/link_console.sh
  4. 2 1
      data/bin/link_graph.bat
  5. 1 0
      data/bin/link_graph.sh
  6. 16 31
      src/Graph.Mod
  7. 57 0
      src/Int.Mod
  8. 7 4
      src/Makefile_linux
  9. 7 4
      src/Makefile_win32
  10. 7 0
      src/SDL2.Mod
  11. 3 0
      src/SDL2.h0

+ 153 - 0
Programs/Life2Print.Mod

@@ -0,0 +1,153 @@
+MODULE Life2Print;
+(*This program saves screenshots of the Game of Life in PNG files.*)
+IMPORT G := Graph, Int, Str := Strings;
+CONST maxW = 60*8; maxH = 33*8;
+  cellSize = 2;
+  initial = 0.2;
+TYPE
+  Field = ARRAY maxH, maxW OF INTEGER;
+VAR
+  S: G.Bitmap;
+  W, H: INTEGER; (* Real width and height of field in cells *)
+  m, m2: Field; (* m2 is a temporary copy of m *)
+  x0, y0: INTEGER; (* Field offset on screen in pixels *)
+  colors: ARRAY 9 OF INTEGER; (* Color constants: black, red etc. *)
+
+  saved: ARRAY 3 OF INTEGER; (* Saved neighbour colors *)
+  nofcolors: INTEGER; (* Number of saved neighbour colors *)
+  fileno: INTEGER;
+
+PROCEDURE Print;
+VAR s: ARRAY 256 OF CHAR;
+BEGIN s := 'shot';
+  Int.Append(fileno, s);
+  Str.Append('.png', s);
+  IF G.SavePng(S, s) THEN END;
+  INC(fileno)
+END Print;
+
+PROCEDURE Save(y, x: INTEGER);
+BEGIN
+  IF nofcolors < LEN(saved) THEN
+    saved[nofcolors] := m2[y, x];
+    INC(nofcolors)
+  END
+END Save;
+
+PROCEDURE GetColor(): INTEGER;
+VAR c: INTEGER;
+BEGIN
+  IF saved[0] = saved[1] THEN c := saved[0]
+  ELSIF saved[0] = saved[2] THEN c := saved[0]
+  ELSIF saved[1] = saved[2] THEN c := saved[1]
+  ELSE c := saved[G.Random(3)]
+  END;
+  RETURN c
+END GetColor;
+
+PROCEDURE Neighbours(x, y: INTEGER): INTEGER;
+VAR n: INTEGER;
+BEGIN
+  n := 0;
+  nofcolors := 0;
+  IF y # 0 THEN
+    IF m2[y - 1, x] # 0 THEN INC(n); Save(y - 1, x) END;
+    IF (x # 0) & (m2[y - 1, x - 1] # 0) THEN INC(n); Save(y - 1, x - 1) END;
+    IF (x # W - 1) & (m2[y - 1, x + 1] # 0) THEN INC(n); Save(y - 1, x + 1) END
+  END;
+  IF (x # 0) & (m2[y, x - 1] # 0) THEN INC(n); Save(y, x - 1) END;
+  IF (x # W - 1) & (m2[y, x + 1] # 0) THEN INC(n); Save(y, x + 1) END;
+  IF y # H - 1 THEN
+    IF m2[y + 1, x] # 0 THEN INC(n); Save(y + 1, x) END;
+    IF (x # 0) & (m2[y + 1, x - 1] # 0) THEN INC(n); Save(y + 1, x - 1) END;
+    IF (x # W - 1) & (m2[y + 1, x + 1] # 0) THEN INC(n); Save(y + 1, x + 1) END
+  END;
+  RETURN n
+END Neighbours;
+
+PROCEDURE Live;
+VAR x, y, n, c: INTEGER;
+BEGIN
+  m2 := m;
+  FOR y := 0 TO H - 1 DO
+    FOR x := 0 TO W - 1 DO
+      n := Neighbours(x, y);
+      IF n = 3 THEN
+        m[y, x] := GetColor()
+      ELSIF n # 2 THEN
+        m[y, x] := 0
+      END
+    END
+  END
+END Live;
+
+PROCEDURE DrawCell(x, y: INTEGER);
+VAR xx, yy, c: INTEGER;
+BEGIN
+  xx := x0 + x * cellSize;
+  yy := y0 + y * cellSize;
+  c := colors[m[y, x]];
+  G.RectFill(S, xx, yy, xx + cellSize - 1, yy + cellSize - 1, c)
+END DrawCell;
+
+PROCEDURE Draw;
+VAR x, y: INTEGER;
+BEGIN
+  FOR y := 0 TO H - 1 DO
+    FOR x := 0 TO W - 1 DO
+      DrawCell(x, y)
+    END
+  END;
+  G.Flip
+END Draw;
+
+PROCEDURE Run;
+BEGIN
+  REPEAT
+    Draw;
+    Live;
+    Print
+  UNTIL G.KeyPressed()
+END Run;
+
+PROCEDURE Init;
+VAR x, y: INTEGER;
+BEGIN
+  G.Settings(800, 300, {G.sharpPixels, G.spread(*, G.fullscreen*)});
+  S := G.Init();
+
+  W := S.w DIV cellSize;
+  H := S.h DIV cellSize;
+  IF W >= maxW THEN W := maxW - 1 END;
+  IF H >= maxH THEN H := maxH - 1 END;
+
+  colors[0] := G.MakeCol(10, 10, 10);
+  colors[1] := G.MakeCol(240, 0, 0);
+  colors[2] := G.MakeCol(230, 230, 230);
+  colors[3] := G.MakeCol(0, 100, 255);
+  colors[4] := G.MakeCol(0, 230, 0);
+  colors[5] := G.MakeCol(255, 255, 0);
+  colors[6] := G.MakeCol(230, 0, 230);
+  colors[7] := G.MakeCol(150, 80, 0);
+  colors[8] := G.MakeCol(255, 150, 0);
+
+  fileno := 1;
+
+  FOR y := 0 TO H - 1 DO
+    FOR x := 0 TO W - 1 DO
+      IF G.Uniform() < initial THEN
+        m[y, x] := G.Random(8) + 1
+      ELSE
+        m[y, x] := 0
+      END
+    END
+  END;
+  x0 := (S.w - cellSize * W) DIV 2;
+  y0 := (S.h - cellSize * H) DIV 2
+END Init;
+
+BEGIN
+  Init;
+  Run;
+  G.Close
+END Life2Print.

+ 2 - 1
data/bin/link_console.bat

@@ -24,6 +24,7 @@ ECHO ON
 gcc -fPIC -g -I "%CURDIR%voc\C\include"^
  -o %ONAME%.exe %ONAME%.o^
  %ARGS%^
+ "%CURDIR%voc/lib/Int.o"^
  -L"%CURDIR%voc\lib" -lvoc-OC -lmingw32
 @SET RETCODE=%ERRORLEVEL%
-@EXIT /b %RETCODE%
+@EXIT /b %RETCODE%

+ 1 - 0
data/bin/link_console.sh

@@ -12,6 +12,7 @@ shift
 $CC -fPIC -g -I $VOCDIR/C/include \
   -o $ONAME $ONAME.o \
   $@ \
+  $VOCDIR/lib/Int.o \
   $VOCDIR/lib/libvoc-OC.a
 retcode=$?
 cd ..

+ 2 - 1
data/bin/link_graph.bat

@@ -26,8 +26,9 @@ gcc -fPIC -g -I "%CURDIR%voc/C/include"^
  %ARGS%^
  "%CURDIR%voc/lib/Graph.o"^
  "%CURDIR%voc/lib/SDL2.o"^
+ "%CURDIR%voc/lib/Int.o"^
  -L"%CURDIR%voc/lib" -lvoc-OC^
  -w -Wl,-subsystem,windows -lmingw32^
  -lSDL2main -lSDL2 -lSDL2_image
 @SET RETCODE=%ERRORLEVEL%
-@EXIT /b %RETCODE%
+@EXIT /b %RETCODE%

+ 1 - 0
data/bin/link_graph.sh

@@ -13,6 +13,7 @@ $CC -fPIC -g -I $VOCDIR/C/include \
   -o $ONAME $ONAME.o \
   $@ \
   $VOCDIR/lib/Graph.o $VOCDIR/lib/SDL2.o \
+  $VOCDIR/lib/Int.o \
   $VOCDIR/lib/libvoc-OC.a \
   $SDL2Opts -lSDL2_image
 retcode=$?

+ 16 - 31
src/Graph.Mod

@@ -304,36 +304,6 @@ VAR
 
 PROCEDURE -AAIncludeSDL2h0 '#include "SDL2.h0"';
 
-(* C Macros *)
-
-PROCEDURE LoadBmp(filename: ARRAY OF CHAR): SDL.Surface;
-BEGIN
-  RETURN SDL.LoadBmpRW(SDL.RWFromFile(filename, 'rb'), 1)
-END LoadBmp;
-
-(* Misc *)
-
-PROCEDURE Str*(n: INTEGER; VAR s: ARRAY OF CHAR);
-BEGIN
-  (*IntStr.IntToStr(n, s)*)
-  s[0] := '4'; s[1] := '2'; s[2] := 0X (*!FIXME*)
-END Str;
-
-PROCEDURE Val*(s: ARRAY OF CHAR): INTEGER;
-VAR n: INTEGER; (*res: IntStr.ConvResults;*)
-BEGIN
-  (*IntStr.StrToInt(s, n, res);
-  IF res # IntStr.strAllRight THEN n := 0 END;
-  RETURN n*)
-  RETURN 42 (*!FIXME*)
-END Val;
-
-PROCEDURE AppendN*(n: INTEGER; VAR s: ARRAY OF CHAR);
-VAR sn: ARRAY 30 OF CHAR;
-BEGIN
-  (*Str(n, sn); S.Append(sn, s) !FIXME *)
-END AppendN;
-
 (* General *)
 
 PROCEDURE GetError*(VAR s: ARRAY OF CHAR);
@@ -648,13 +618,28 @@ END DestroyBitmap;
 
 PROCEDURE LoadBitmap*(filename: ARRAY OF CHAR): Bitmap;
 VAR bmp: Bitmap;
-BEGIN        (* LoadBmp(filename) for BMP-only *)
+BEGIN
   NEW(bmp); bmp.surface := SDL.ImgLoad(filename);
   IF bmp.surface = NIL THEN bmp := NIL
   ELSE bmp.w := bmp.surface.w; bmp.h := bmp.surface.h END;
   RETURN bmp
 END LoadBitmap;
 
+PROCEDURE SaveBmp*(bmp: Bitmap; filename: ARRAY OF CHAR): BOOLEAN;
+BEGIN
+  RETURN SDL.SaveBmpRW(bmp.surface, SDL.RWFromFile(filename, 'wb'), 1) = 0
+END SaveBmp;
+
+PROCEDURE SavePng*(bmp: Bitmap; filename: ARRAY OF CHAR): BOOLEAN;
+BEGIN
+  RETURN SDL.ImgSavePng(bmp.surface, filename) = 0
+END SavePng;
+
+PROCEDURE SaveJpg*(bmp: Bitmap; filename: ARRAY OF CHAR): BOOLEAN;
+BEGIN
+  RETURN SDL.ImgSaveJpg(bmp.surface, filename) = 0
+END SaveJpg;
+
 PROCEDURE Blit*(src, dest: Bitmap; sx, sy, sw, sh, dx, dy: INTEGER);
 VAR a, b: SDL.Rect;
 BEGIN a.x := sx; a.y := sy; a.w := sw; a.h := sh;

+ 57 - 0
src/Int.Mod

@@ -0,0 +1,57 @@
+MODULE Int;
+IMPORT Strings;
+
+PROCEDURE Str*(n: INTEGER; VAR s: ARRAY OF CHAR);
+VAR i, j: INTEGER; tmp: CHAR; neg: BOOLEAN;
+BEGIN
+  IF n = 0 THEN
+    s[0] := '0'; i := 1
+  ELSE i := 0; neg := n < 0; 
+    IF neg THEN n := -n END;
+    WHILE (n > 0) & (i < LEN(s) - 1) DO
+      s[i] := CHR(ORD('0') + n MOD 10);
+      n := n DIV 10; INC(i)
+    END;
+    IF neg & (i < LEN(s) - 1) THEN s[i] := '-'; INC(i) END
+  END;
+  s[i] := 0X; j := 0; DEC(i);
+  WHILE j < i DO
+    tmp := s[j]; s[j] := s[i]; s[i] := tmp;
+    INC(j); DEC(i)
+  END
+END Str;
+
+PROCEDURE Val*(int: LONGINT; VAR str: ARRAY OF CHAR);
+CONST maxLength = 11;
+VAR
+  b: ARRAY maxLength + 1 OF CHAR;
+  s, e: INTEGER;
+  h: CHAR;
+BEGIN
+  IF int = MIN(LONGINT) THEN b := '-2147483648'; e := 11
+  ELSE
+    IF int < 0 THEN b[0] := '-'; int := -int; s := 1 ELSE s := 0 END;
+    e := s; (* 's' holds starting position of string *)
+    REPEAT
+      b[e] := CHR(int MOD 10 + ORD('0'));
+      int := int DIV 10;
+      INC(e)
+    UNTIL int = 0;
+    b[e] := 0X;
+
+    DEC(e);
+    WHILE s < e DO
+      h := str[s]; str[s] := str[e]; str[e] := h;
+      INC(s); DEC(e)
+    END
+  END;
+  COPY(b, str)
+END Val;
+
+PROCEDURE Append*(n: INTEGER; VAR s: ARRAY OF CHAR);
+VAR sn: ARRAY 30 OF CHAR;
+BEGIN
+  Str(n, sn); Strings.Append(sn, s)
+END Append;
+
+END Int.

+ 7 - 4
src/Makefile_linux

@@ -20,7 +20,7 @@ fo: ../$(PROG)
 		mv $(PROG) ..
 
 $(PROG).o: $(PROG).Mod EditorText.sym Terminal.sym OV.sym \
-		Editor.sym Term.sym Graph.sym SDL2.sym
+		Editor.sym Term.sym Graph.sym SDL2.sym Int.sym
 	$(VOC) -OC -cesF -m $(PROG).Mod
 
 OV.sym: OV.Mod Terminal.sym Graph.sym
@@ -47,6 +47,9 @@ term/term.o: term/term_$(OS).c
 Graph.sym: Graph.Mod SDL2.sym
 	$(VOC) -OC -cesF Graph.Mod
 
+Int.sym: Int.Mod
+	$(VOC) -OC -cesF Int.Mod
+
 SDL2.sym: SDL2.Mod
 	$(VOC) -OC -cesF SDL2.Mod
 
@@ -84,8 +87,8 @@ voc:
 	make -C ../data/bin/voc full
 
 install:
-	cp Graph.sym SDL2.sym $(VOCDIR)/C/sym
-	cp Graph.h SDL2.h SDL2.h0 $(VOCDIR)/C/include
-	cp Graph.o SDL2.o $(VOCDIR)/lib
+	cp Graph.sym SDL2.sym Int.sym $(VOCDIR)/C/sym
+	cp Graph.h SDL2.h SDL2.h0 Int.h $(VOCDIR)/C/include
+	cp Graph.o SDL2.o Int.o $(VOCDIR)/lib
 	mkdir -p ../bin
 

+ 7 - 4
src/Makefile_win32

@@ -20,7 +20,7 @@ fo: ../$(PROG).exe
 		mv $(PROG).exe ..
 
 $(PROG).o: $(PROG).Mod EditorText.sym Terminal.sym OV.sym \
-		Editor.sym Term.sym Graph.sym SDL2.sym
+		Editor.sym Term.sym Graph.sym SDL2.sym Int.sym
 	$(VOC) -OC -cesF -m $(PROG).Mod
 
 OV.sym: OV.Mod Terminal.sym Graph.sym
@@ -47,6 +47,9 @@ term/term.o: term/term_$(OS).c
 Graph.sym: Graph.Mod SDL2.sym
 	$(VOC) -OC -cesF Graph.Mod
 
+Int.sym: Int.Mod
+	$(VOC) -OC -cesF Int.Mod
+
 SDL2.sym: SDL2.Mod
 	$(VOC) -OC -cesF SDL2.Mod
 
@@ -68,7 +71,7 @@ voc:
 	make -C ../data/bin/voc full
 
 install:
-	cp Graph.sym SDL2.sym $(VOCDIR)/C/sym
-	cp Graph.h SDL2.h SDL2.h0 $(VOCDIR)/C/include
-	cp Graph.o SDL2.o $(VOCDIR)/lib
+	cp Graph.sym SDL2.sym Int.sym $(VOCDIR)/C/sym
+	cp Graph.h SDL2.h SDL2.h0 Int.h $(VOCDIR)/C/include
+	cp Graph.o SDL2.o Int.o $(VOCDIR)/lib
 	mkdir -p ../bin

+ 7 - 0
src/SDL2.Mod

@@ -333,6 +333,9 @@ PROCEDURE -RWFromFile*(fname, mode: ARRAY OF CHAR): SYSTEM.PTR
     "SDL_RWFromFile(fname, mode)";
 PROCEDURE -LoadBmpRW*(src: SYSTEM.PTR; freeSrc: INTEGER): Surface
     "(void *)SDL_LoadBMP_RW(src, freeSrc)";
+PROCEDURE -SaveBmpRW*(surface: Surface; src: SYSTEM.PTR;
+    freeSrc: INTEGER): INTEGER
+    "(int)SDL_SaveBMP_RW(surface, src, freeSrc)";
 
 (* SDL Image Addon *)
 
@@ -340,6 +343,10 @@ PROCEDURE -ImgInit*(flags: SET): SET "IMG_Init(flags)";
 PROCEDURE -ImgQuit* "IMG_Quit()";
 PROCEDURE -ImgLoad*(file: ARRAY OF CHAR): Surface
     "(void *)IMG_Load(file)";
+PROCEDURE -ImgSavePng*(surface: Surface; file: ARRAY OF CHAR): INTEGER
+    "(int)IMG_SavePNG(surface, file)";
+PROCEDURE -ImgSaveJpg*(surface: Surface; file: ARRAY OF CHAR): INTEGER
+    "(int)IMG_SaveJPG(surface, file)";
 
 (* Renderer *)
 

+ 3 - 0
src/SDL2.h0

@@ -33,9 +33,12 @@ extern UINT32 SDL_GetWindowFlags(void *);
 extern void SDL_GetWindowSize(void *, void *, void *);
 extern int IMG_Init(int);
 extern void *IMG_Load(void *);
+extern int IMG_SavePNG(void *, void *);
+extern int IMG_SaveJPG(void *, void *);
 extern void IMG_Quit(void);
 extern int SDL_Init(UINT32);
 extern void *SDL_LoadBMP_RW(void *, int);
+extern int SDL_SaveBMP_RW(void *, void *, int);
 extern int SDL_LockSurface(void *);
 extern UINT32 SDL_MapRGB(void *, UINT8, UINT8, UINT8);
 extern int SDL_PollEvent(void *);