home *** CD-ROM | disk | FTP | other *** search
- program politics;
- {===================================================================}
- {|| ||}
- {|| This program demonstrates writing directly to the COLOR ||}
- {|| video memory. It doesn't work with monochrome -- you ain't ||}
- {|| got 16 colors! It also illustrates the removal of "snow" ||}
- {|| accomplished by waiting for the Horizontal Retrace before ||}
- {|| writing to or reading from the video memory. It's a bit ||}
- {|| slower, but not nearly as slow as normal BIOS "write". ||}
- {|| ||}
- {|| The "game" itself is based on a magazine article I ||}
- {|| once read -- who knows where or when. It's interesting how ||}
- {|| fast "like-minded" people form large blocs and eliminate ||}
- {|| the minorities. Interesting? Alarming! ||}
- {|| ||}
- {|| I don't know if POLITICS qualifies as a "cellular ||}
- {|| automata" game or not -- the fact that the changes are ||}
- {|| random may rule it out. Unlike LIFE, it never truly ||}
- {|| stabilizes, though it always reduces to just a few parties. ||}
- {|| (Since a "lost" party never returns, the trend is clearly ||}
- {|| toward simplification) ||}
- {|| ||}
- {|| ENJOY IT! ||}
- {|| ||}
- {|| --- Neil J. Rubenking -- ||}
- {|| ||}
- {|| Technical Assistance : Julius Marx ||}
- {===================================================================}
- {|| SUGGESTIONS FOR "TWEAKERS" ||}
- {|| ||}
- {|| If the 25x50 "resolution" isn't fine enough for you, ||}
- {|| you might try filling the screen with character 223, the ||}
- {|| "top half box". Then you manipulate the foreground and ||}
- {|| background colors separately -- the foreground color will ||}
- {|| appear in the top half, and the background in the bottom. ||}
- {|| Of course, you only get 8 colors, as you can't have a ||}
- {|| "bright" background (can you?). The effect will be that ||}
- {|| of a 50x50 grid of smaller boxes. ||}
- {|| ||}
- {|| Monochrome users might try characters 219, 178, 177, ||}
- {|| and 176. These four in HighVideo and LowVideo, plus the ||}
- {|| black blank, would give you 9 "parties". ||}
- {|| ||}
- {===================================================================}
-
-
- type
- string30 = string[30];
- screen = array[1..25] of array[1..80] of integer;
- ScrPt = ^screen;
- regpack = record ax,bx,cx,dx,bp,si,di,ds,es,flags: integer; end;
- const
- pt : byte = 178; { I like the "quilted" effect these characters give. }
- pt1 : byte = 178; { For a different display, comment out these values }
- pt2 : byte = 178; { and un-comment the next few lines }
- (*
- pt : byte = 5; { Character 5 is the "spade", but it looks kind }
- pt1 : byte = 17; { of like a person. Characters 17 and 16 together }
- pt2 : byte = 16; { form a diamond shape two characters wide }
- *)
- var
- ScreenSeg : integer;
- Freedonia : screen;
- regs : regpack;
- display : scrPt;
- vidMode, numCols, row, col : byte;
- CheatVar, VidOffset : integer ;
-
-
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure Cursor(mode : char);
- {PURPOSE: Turn cursor on and off -- mode 'Y' is ON, 'N' is off.
- Color cursor has 7 scan lines, numbered 0 to 6, from the
- top. Normal cursor is lines 6 & 7. Monochrome is 0 to 13,
- with normal begin 12 & 13. According to Tech Ref, "setting
- bits 5 or 6 will cause erratic blinking or no cursor at all",
- and that's just what we do for NO cursor (48 = 110000b)
- }
- begin
- with regs do
- begin
- AX := 1 shl 8;
- case mode of
- 'Y': if seg(display^) = $B000 then
- CX := (12 shl 8) + 13
- else
- CX := (5 shl 8) + 6;
- 'N': CX := 48 shl 8;
- end;
- Intr($10,regs);
- end;
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure CheckColor;
- {PURPOSE: Sets the pointer "display" to point at the current video memory.
- "VidMode" contains a number from 0 to 7 -- 7 is MONOchrome adapter
- card, the others are color:
- 0 40x25 BW \
- 1 40x25 color \
- 2 80x25 BW \
- 3 80x25 color > all color/graphics modes
- 4 320x200 color /
- 5 320x200 BW /
- 6 640x200 BW /
- "NumCols" is set to the number of text columns on the screen
- }
- begin
- with regs do
- begin
- AX := 15 shl 8;
- intr($10,regs);
- vidmode := AX and $00FF;
- NumCols := AX shr 8;
- end;
- if vidmode = 7 then ScreenSeg := $B000 else ScreenSeg := $B800;
- Display := Ptr(ScreenSeg,$0000)
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure Hail_Freedonia;
- begin
- window(53,1,80,14);
- textColor(LightRed); TextBackground(blue);
- CLrScr;
- write(#4#4#4#4#4#4,' HAIL FREEDONIA ',#4#4#4#4#4#4);
- TextColor(Lightgreen);
- writeLn;
- writeLn(' Freedonia''s citizens');
- writeLn(' belong to 14 different'); { NOTE: I know there are 16 }
- writeLn(' political parties, here'); { colors, not 14, but BLACK }
- writeLn(' symbolized by 14 colors.'); { and DARKGRAY aren't very }
- writeLn(' They are distributed at'); { visible against a black }
- writeLn(' random to start, but at'); { background! }
- writeLn(' each moment, a randomly');
- writeLn(' chosen citizen converts');
- writeLn(' to the party of one of');
- writeLn(' his/her neighbors. ');
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure message(L1,L2,L3,L4 : string30);
- begin
- window(53,16,80,22);
- TextColor(yellow); TextBackground(green);
- ClrScr;
- writeLn(' NEXT EVENT');
- writeLn;
- writeLN(L1);
- writeLn(L2);
- writeLn(L3);
- writeLn(L4);
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure WaitAndPut(R,C:byte; XX : integer);
- {PURPOSE: Wait for retrace, poke in a character}
- begin
- VidOffset := (r-1)*160 + (c-1)*2;
- CheatVar := XX;
- { ^ }
- { | }
- { | }
- {---------------------------------------------}
- { NOTE: As I'm not very fluent in INLINE, }
- { I've defined two GLOBAL variables to }
- { handle some of the value-passing. It }
- { ain't elegant, but it does the job. }
- {---------------------------------------------}
-
- INLINE(
- $A1/CheatVar/ { MOV AX,CheatVar }
- $8B/$1E/VidOffset/ { MOV BX,VidOffset }
- $1E/ {PUSH DS }
- $50/ {PUSH AX }
- $B8/$B800/ { MOV AX,0B800h }
- $8E/$D8/ { MOV DS,AX }
- $BA/$DA/$03/ { MOV DX,03DA }
- $EC/ {IN AL,DX }
- $A8/$01/ {TEST AL,01 }
- $75/$FB/ {Jnz (back to IN AL,DX) }
- $FA/ {CLI }
- $EC/ {IN AL,DX }
- $A8/$01/ {TEST AL,01 }
- $74/$FB/ {Jz (back to IN AL,DX) }
- $58/ {POP AX }
- $89/$07/ { MOV [BX], AX }
- $1F/ {POP DS }
- $FB); { STI }
- end; { procedure WaitAndPUT2(R,C:byte; XX : integer) }
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure WaitAndGet(R,C:byte; VAR XX : integer);
- {PURPOSE: Wait for retrace, read a character}
- begin
- VidOffset := (r-1)*160 + (c-1)*2;
- INLINE(
- $A1/CheatVar/ { MOV AX,CheatVar }
- $8B/$1E/VidOffset/ { MOV BX,VidOffset }
- $1E/ {PUSH DS }
- $B8/$B800/ { MOV AX,0B800h }
- $8E/$D8/ { MOV DS,AX }
- $BA/$DA/$03/ { MOV DX,03DA }
- $EC/ {IN AL,DX }
- $A8/$01/ {TEST AL,01 }
- $75/$FB/ {Jnz (back to IN AL,DX) }
- $FA/ {CLI }
- $EC/ {IN AL,DX }
- $A8/$01/ {TEST AL,01 }
- $74/$FB/ {Jz (back to IN AL,DX) }
- $8B/$07/ { MOV AX, [BX] }
- $1F/ {POP DS }
- $A3/CheatVar/ { MOV CheatVar,AX }
- $FB); { STI }
- XX := CheatVar;
- end; { procedure WaitAndGet(R,C:byte; VAR XX : integer) }
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure initialize(size:byte);
- { PURPOSE: initialize the country of Freedonia with citizens of 14 parties.
- If "size" is 1, Freedonia consists of 25 rows of 50 single-
- character citizens, using character determined by the constant
- "PT". If size is 2, there are 25x25 citizens, made of the
- characters PT1 and PT2.}
- var
- OneSpot : integer;
- {=================================================================}
- function RandomColor:byte;
- var temp : byte;
- begin
- temp := random(15)+1;
- if temp = 8 then temp := randomColor;
- randomColor := temp;
- end;
- {=================================================================}
- begin
- FillChar(Freedonia,SizeOf(FreeDonia),0);
- if size = 1 then
- for row := 1 to 25 do
- for col := 1 to 50 do
- Freedonia[row][col] := pt or (randomColor shl 8)
- else
- for row := 1 to 25 do
- for col := 1 to 25 do
- begin
- OneSpot := (randomColor shl 8);
- Freedonia[row][col*2-1] := OneSpot or pt1;
- Freedonia[row][col*2] := OneSpot or pt2;
- end;
- display^ := Freedonia;
- Hail_Freedonia;
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- procedure ChangeOfHeart(size:byte; wait : boolean);
- {PURPOSE: select a "citizen" at random. Select a direction at random.
- Convert the neighbor in the chosen direction to the same party
- as the chosen citizen. If "wait" is true, demonstrate wait
- for Horizontal Retrace -- otherwise, just whomp the new
- character to the screen.}
-
- var
- dir, changeTo : byte;
- DH : integer;
- begin
- row := random(25) + 1 ;
- col := random(25 * (3-size)) + 1;
- dir := random(8) + 1;
- if wait then
- WaitAndGet(row,col*size,DH)
- else
- DH := display^[row][col*size];
- case dir of
- 1..3: if row > 1 then row := row - 1 else row := 25;
- 6..8: if row < 25 then row := row + 1 else row := 1;
- end;
- case dir of
- 1,4,6: if col > 1 then col := col - 1 else col := (25*(3-size));
- 3,5,8: if col < (25 * (3-size)) then col := col + 1 else col := 1;
- end;
- if size = 1 then
- if wait then WaitAndPut(row,col,DH)
- else display^[row][col] := DH
- else
- begin
- if wait then
- begin
- WaitAndPut(row,2*col-1,(DH and $FF00) or pt1);
- WaitAndPut(row,2*col,(DH and $FF00) or pt2);
- end
- else
- begin
- display^[row][2*col-1] := (DH and $FF00) or pt1;
- display^[row][2*col] := (DH and $FF00) or pt2;
- end;
- end;
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- begin
- ClrScr;
- CHeckColor;
- if VidMode = 7 then
- begin
- writeLn('Sorry, friend. This program only works with COLOR SCREENS.');
- end
- else
- begin
- randomize;
- cursor('N');
- initialize(1);
- message(' Press <return> to start',' conversions. Writing to',
- ' screen memory directly.','');
- read;
- message(' Press <return> to write',' to screen with Horizon-',
- ' tal Retrace check. Its',' slower, but no snow.');
- repeat
- ChangeOfHeart(1,false);
- until keypressed;
- read;
- message(' Press <return> to start',' again with "people" of',
- ' larger size','');
- repeat
- ChangeOfHeart(1,true);
- until keypressed;
- read(Kbd);
- read;
- initialize(2);
- message(' Press <return> to start',' conversions. Writing to',
- ' screen memory directly.','');
- read;
- message(' Press <return> to write',' to screen with Horizon-',
- ' tal Retrace check. Its',' slower, but no snow.');
- repeat
- ChangeOfHeart(2,false);
- until keypressed; read(Kbd);
- read;
- message(' Press <return> to end','','','');
- repeat
- ChangeOfHeart(2,true);
- until keypressed; read(Kbd);
- cursor('Y');
- end;
- end.