home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* GRAFFITI.PAS *)
- (* Blockgrafiken (nicht nur) für Turbo-Editoren *)
- (* (c) 1990 O. Großklaus & TOOLBOX *)
- (* ------------------------------------------------------ *)
- {$M 4096,0,655360} { Heap wird durch TSR-Unit plattgemacht }
- {$R- No RangeCheck }
- {$S- No StackCheck }
- {$D- No Debug Info }
- {$B- Boolean complete }
- PROGRAM Graffiti;
-
- USES
- Dos, { Standard DOS-Unit }
- Crt, { Standard CRT-Unit }
- txTsr; { angepaßte TSR-Unit, ausgehend von toolbox 5'90 }
-
- CONST
- GrashID = 1; { Kennung }
- ZmitALT = ' Zeichnen mit <Alt>+JKIM'; { Aktivierung }
- LogoSize = 16; { Logogröße }
-
- Logo : ARRAY [1..LogoSize] OF STRING [54] = (
- ('╔════════════════════════════════════════════════════╗'),
- ('║ GRAFFITI ║'),
- ('║ Zeichnen von Blockgrafiken mit "Cursorbewegungen" ║'),
- ('║ ┌─────────────────────────────────────────┐ ║'),
- ('║ │ <Alt>+<T> schaltet zwischen │ und ║ um. │ ║'),
- ('║ └───────╥─────────────────────────╥───────┘ ║'),
- ('║ ║' +ZmitALT+ ' ║ ║'),
- ('║ ╚═════════════════════════╝ ║'),
- ('╠═════════ A C H T U N G - A C H T U N G ! ══════════╣'),
- ('║ - Nur für Turbo- und kompatible Editoren. ║'),
- ('║ - Vor Gebrauch Platz schaffen (Leerzeile/Text). ║'),
- ('║ - Will ein Zeichen nicht passen, nicht verzweifeln.║'),
- ('║ Dieses Zeichen gibt es dann wirklich nicht... ║'),
- ('║ - Immer schön im 25-Zeilen-Modus bleiben! ║'),
- ('║ - Keine "harten" Tabulatoren im Text! ║'),
- ('╚════════════════════════════════════════════════════╝'));
-
- Single = 1;
- Double = 2;
- All = 0;
- DrawMode : BOOLEAN = TRUE;
- DoubleMode : BOOLEAN = FALSE;
- LeftRight = TRUE;
- UpDown = FALSE;
- CLeft = 75;
- Cup = 72;
- CDown = 80;
- InsertToggle : WORD = 82;
- HotKeyLeft : WORD = $2400; { ALT - J }
- HotKeyRight : WORD = $2500; { ALT - K }
- HotKeyUp : WORD = $1700; { ALT - I }
- HotKeyDown : WORD = $3200; { ALT - M }
- HotKeyToggle : WORD = $1400; { ALT - T }
-
- VAR
- Direct : BOOLEAN; { Richtung LeftRight/UpDown }
- I : BYTE;
- Ok : BOOLEAN; { Installation ok ? }
-
- (* ---------------------------------------------------- *)
- (* Cursorbewegungen auf dem Bildschirm, nicht im Editor *)
-
- PROCEDURE CMoveRight;
- BEGIN
- GotoXY(WhereX+1, WhereY);
- END;
-
- PROCEDURE CMoveLeft;
- BEGIN
- GotoXY(WhereX-1, WhereY);
- END;
-
- PROCEDURE CMoveUp;
- BEGIN
- GotoXY(WhereX, WhereY-1);
- END;
-
- PROCEDURE CMoveDown;
- BEGIN
- GotoXY(WhereX, WhereY+1);
- END;
-
- PROCEDURE Beep;
- BEGIN
- Sound(7000); Delay(1); NoSound;
- END;
-
- FUNCTION CPosOk : BOOLEAN; (* Cursorposition überprüfen *)
- VAR
- Xp, Yp : BYTE;
- BEGIN
- Xp := WhereX;
- Yp := WhereY;
- CPosOk := ((Xp > 1) AND (Xp < 80) AND
- (Yp > 1) AND (Yp <25 ));
- END;
-
- FUNCTION GetScrnChar : CHAR;
- VAR
- Regs : Registers;
- BEGIN
- Regs.ah := 08;
- Regs.bh := 0;
- Intr($10, Regs);
- GetScrnChar := CHAR(Regs.al);
- END;
-
- PROCEDURE PutChar(ch : CHAR; First : BOOLEAN);
- VAR
- Regs : Registers;
- BEGIN
- IF First THEN
- IF DrawMode = DoubleMode THEN
- IF Direct = UpDown THEN ch := '║' { #186 }
- ELSE ch := '═' { #205 }
- ELSE IF Direct = UpDown THEN ch := '│' { #179 }
- ELSE ch := '─'; { #196 }
- Regs.ah := $0A;
- Regs.al := Ord(ch);
- Regs.bh := 00;
- Regs.cx := 01;
- Intr($10, Regs);
- END;
-
- PROCEDURE CharBuffer(ch : CHAR);
- VAR
- Regs : Registers;
- BEGIN
- Regs.ah := 05;
- Regs.cl := Ord(ch);
- Regs.ch := 00;
- Intr($16, Regs);
- END;
-
- PROCEDURE MoveC(C : BYTE);
- VAR
- Regs : Registers;
- BEGIN
- Regs.ah := 05;
- Regs.cl := 0;
- Regs.ch := C;
- Intr($16, Regs);
- END;
-
- PROCEDURE RepLast;
- (* letzte Cursorposition reparieren *)
- CONST
- LeftSingleNipple : SET OF CHAR =
- ['┤','╢','╖','╜','┐','┴','┬','─','┼','╨','╥','╫','┘'];
- LeftDoubleNipple : SET OF CHAR =
- ['╡','╕','╣','╗','╝','╛','╩','╦','═','╬','╧','╤','╪'];
- RightSingleNipple : SET OF CHAR =
- ['└','┴','┬','├','─','┼','╟','╨','╥','╙','╓','╫','┌'];
- RightDoubleNipple : SET OF CHAR =
- ['╞','╚','╔','╩','╦','═','╬','╧','╤','╘','╒','╪','╠'];
- UpSingleNipple : SET OF CHAR =
- ['│','┤','╡','╛','└','┴','├','┼','╞','╧','╘','╪','┘'];
- UpDoubleNipple : SET OF CHAR =
- ['╢','╣','║','╜','╟','╚','╩','╠','╬','╨','╙','╫','╝'];
- DownSingleNipple : SET OF CHAR =
- ['│','┤','╡','╕','┐','┬','├','┼','╞','╤','╒','╪','┌'];
- DownDoubleNipple : SET OF CHAR =
- ['╢','╖','╣','║','╗','╟','╔','╦','╠','╬','╥','╓','╫'];
-
- (* Zuordnungstabelle *)
- Tabelle : ARRAY [0..256] OF CHAR = ( ' ',
- { 1 2 3 4 5 6 7 8 9 10}
- ' ',' ','└',' ','│','┌','├',' ','┘','─', {00}
- '┴','┐','┤','┬','┼',' ',' ','╙',' ',' ', {10}
- ' ',' ',' ','╜',' ','╨',' ',' ',' ',' ', {20}
- ' ',' ','╘',' ',' ','╒','╞',' ',' ',' ', {30}
- ' ',' ',' ',' ',' ',' ',' ','╚',' ',' ', {40}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', {50}
- ' ',' ',' ',' ',' ','╓',' ',' ',' ',' ', {60}
- ' ','╖',' ','╥',' ',' ',' ',' ',' ','║', {70}
- ' ','╟',' ',' ',' ',' ',' ','╢',' ','╫', {80}
- ' ',' ',' ',' ',' ','╔',' ',' ',' ',' ', {90}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', {100}
- ' ','╠',' ',' ',' ',' ',' ',' ',' ',' ', {110}
- ' ',' ',' ',' ',' ',' ',' ',' ','╛',' ', {120}
- ' ','╕','╡',' ',' ',' ',' ',' ',' ',' ', {130}
- ' ',' ',' ','╝',' ',' ',' ',' ',' ',' ', {140}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ','═', {150}
- '╧',' ',' ','╤','╪',' ',' ',' ',' ',' ', {160}
- ' ',' ',' ',' ',' ','╩',' ',' ',' ',' ', {170}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', {180}
- ' ','╗',' ',' ',' ',' ',' ',' ',' ',' ', {190}
- ' ',' ',' ',' ',' ',' ',' ','╣',' ',' ', {200}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', {210}
- ' ',' ',' ','╦',' ',' ',' ',' ',' ',' ', {220}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ','╬', {230}
- ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', {240}
- ' ',' ',' ',' ',' ',' '); {250}
- VAR
- Lc, { linkes Zeichen }
- Rc, { rechtes Zeichen }
- Uc, { oberes Zeichen }
- Dc : CHAR; { unteres Zeichen }
- AktLeftNipple, { linker Nippel }
- AktRightNipple, { rechter Nippel }
- AktUpNipple, { oberer Nippel }
- AktDownNipple : BYTE; { unterer Nippel }
- X, Y : BYTE; { Screenposition }
-
- FUNCTION GetChar(X, Y : BYTE) : CHAR;
- VAR
- OldX, OldY : BYTE;
- BEGIN
- OldX := WhereX; { Alte Position speichern }
- OldY := WhereY;
- GotoXY(X,Y); { x, y einstellen }
- GetChar := GetScrnChar; { Zeichen lesen }
- GotoXY(OldX, OldY); { wieder zurückgehen }
- END;
-
- {┌─────────────────────────────────────────────────────┐}
- {│Aktuelles Zeichen ermitteln: │}
- {│ │}
- {│ Single Double │}
- {│┌──┬──┬──┬──╥──┬──┬──┬──┐ │}
- {││ 1│ 2│ 4│ 8║10│20│40│80│HEX BYTE │}
- {│└─┬┴─┬┴─┬┴─┬╨─┬┴─┬┴─┬┴─┬┘ │}
- {│ │ │ │ │ │ │ │ └─ Nippel links │}
- {│ │ │ │ │ │ │ └──── Nippel unten │}
- {│ │ │ │ │ │ └─────── Nippel rechts │}
- {│ │ │ │ │ └────────── Nippel hoch │}
- {│ │ │ │ └───────────── Nippel links │}
- {│ │ │ └──────────────── Nippel unten │}
- {│ │ └─────────────────── Nippel rechts │}
- {│ └────────────────────── Nippel hoch │}
- {│ │}
- {└─────────────────────────────────────────────────────┘}
-
- PROCEDURE GetAktChar(ModeGet : BYTE);
- BEGIN
- AktLeftNipple := 0;
- AktRightNipple := 0;
- AktUpNipple := 0;
- AktDownNipple := 0;
- IF ((ModeGet = All) OR (ModeGet = Single)) THEN BEGIN
- IF Lc IN RightSingleNipple THEN AktLeftNipple := 8;
- IF Rc IN LeftSingleNipple THEN AktRightNipple := 2;
- IF Uc IN DownSingleNipple THEN AktUpNipple := 1;
- IF Dc IN UpSingleNipple THEN AktDownNipple := 4;
- END;
- IF ((ModeGet = All) OR (ModeGet = Double)) THEN BEGIN
- IF Lc IN RightDoubleNipple THEN AktLeftNipple := 128;
- IF Rc IN LeftDoubleNipple THEN AktRightNipple := 32;
- IF Uc IN DownDoubleNipple THEN AktUpNipple := 16;
- IF Dc IN UpDoubleNipple THEN AktDownNipple := 64;
- END;
- END;
-
- FUNCTION CalcChar : CHAR; (* Zeichen ermitteln *)
- VAR
- Dummy : CHAR;
- BEGIN
- Lc := GetChar(X-1, Y); { Umgebung einlesen }
- Rc := GetChar(X+1, Y); { Umgebung einlesen }
- Uc := GetChar(X, Y-1); { Umgebung einlesen }
- Dc := GetChar(X, Y+1); { Umgebung einlesen }
- IF DrawMode = DoubleMode THEN { Default setzen }
-
- IF Direct = UpDown THEN CalcChar := '║' { #186 }
- ELSE CalcChar := '═' { #205 }
- ELSE
- IF Direct = UpDown THEN CalcChar := '│' { #176 }
- ELSE CalcChar := '─'; { #197 }
-
- GetAktChar(All); { Aktuelles Zeichen ermitteln }
- Dummy := Tabelle[AktLeftNipple + AktRightNipple +
- AktUpNipple + AktDownNipple];
-
- IF Dummy = ' ' THEN BEGIN
- IF DrawMode = DoubleMode THEN GetAktChar(Double)
- ELSE GetAktChar(Single);
- Dummy := Tabelle[AktLeftNipple + AktRightNipple +
- AktUpNipple + AktDownNipple];
- END;
- IF Dummy <> ' ' THEN
- CalcChar := Dummy; { Zeichen gefunden }
- END;
-
- BEGIN
- X := WhereX;
- Y := WhereY;
- PutChar(CalcChar, FALSE);
- END;
-
- FUNCTION BufferEmpty : BOOLEAN;
- VAR
- Head : WORD ABSOLUTE $0:$41A; { Tastaturpuffer Anfang }
- Tail : WORD ABSOLUTE $0:$41C; { Tastaturbuffer Ende }
- BEGIN
- BufferEmpty := (Head = Tail); { Leer : Anfang = Ende }
- END;
-
- FUNCTION EditorIsInInsert : BOOLEAN;
- (* Editor in OVERWRITE schalten (nur für Turbo Pascal! *)
- VAR
- Zeile : STRING [6];
- Mode : BYTE ABSOLUTE $40:$49;
- ScreenBase : WORD;
- i : BYTE;
- BEGIN
- IF Mode = 7 THEN ScreenBase := $B000
- ELSE ScreenBase := $B800;
- Zeile[0] := #6;
- FOR i := 0 TO 5 DO
- Zeile[i+1] := CHAR(Ptr(ScreenBase, $D2+i*2)^);
-
- IF Zeile = '══════' THEN { Turbo-Fenster mit Rahmen }
- FOR i := 0 TO 5 DO
- Zeile[i+1] := CHAR(Ptr(ScreenBase, $174+i*2)^);
- EditorIsInInsert := (Zeile = 'Insert');
- END;
-
- {$F+}
- PROCEDURE PopupLeft;
- (* HotKey-Entry *)
- BEGIN
- IF EditorIsInInsert THEN MoveC(InsertToggle);
- IF NOT BufferEmpty THEN Exit;
- IF NOT CPosOk THEN
- Beep
- ELSE BEGIN
- Direct := LeftRight;
- CMoveLeft; PutChar(' ', TRUE); CMoveRight;
- RepLast;
- CharBuffer(GetScrnChar);
- CMoveLeft; MoveC(CLeft); MoveC(CLeft);
- RepLast;
- CharBuffer(GetScrnChar);
- MoveC(CLeft);
- END;
- END;
-
- PROCEDURE PopupRight;
- BEGIN
- IF EditorIsInInsert THEN MoveC(InsertToggle);
- IF NOT BufferEmpty THEN Exit;
- IF NOT CPosOk THEN
- Beep
- ELSE BEGIN
- Direct := LeftRight;
- CMoveRight; PutChar(' ', TRUE); CMoveLeft;
- RepLast;
- CharBuffer(GetScrnChar);
- CMoveRight;
- RepLast;
- CharBuffer(GetScrnChar);
- MoveC(CLeft);
- END;
- END;
-
- PROCEDURE PopupDown;
- BEGIN
- IF EditorIsInInsert THEN MoveC(InsertToggle);
- IF NOT BufferEmpty THEN Exit;
- IF NOT CPosOk THEN
- Beep
- ELSE BEGIN
- Direct := UpDown;
- CMoveDown; PutChar(' ', TRUE); CMoveUp;
- RepLast;
- CharBuffer(GetScrnChar);
- MoveC(CLeft); MoveC(CDown); CMoveDown;
- RepLast;
- CharBuffer(GetScrnChar); MoveC(CLeft);
- END;
- END;
-
- PROCEDURE PopupUp;
- BEGIN
- IF EditorIsInInsert THEN MoveC(InsertToggle);
- IF NOT BufferEmpty THEN Exit;
- IF NOT CPosOk THEN
- Beep
- ELSE BEGIN
- Direct := UpDown;
- CMoveUp; PutChar(' ', TRUE); CMoveDown;
- RepLast;
- CharBuffer(GetScrnChar);
- MoveC(CLeft); MoveC(Cup); CMoveUp;
- RepLast;
- CharBuffer(GetScrnChar); MoveC(CLeft);
- END;
- END;
-
- PROCEDURE ToggleDraw;
- BEGIN
- DrawMode := NOT DrawMode;
- END;
- {$F-}
-
- BEGIN
- Ok := TRUE;
- IF ParamCount = 0 THEN BEGIN
- ClrScr;
- TextBackground(Red);
- FOR I := 1 TO LogoSize DO BEGIN
- Write(' '); { 13 Blanks }
- Write(Logo[I]);
- WriteLn(' '); { 13 Blanks }
- END;
- TextBackground(Black);
- END;
- IF AlreadyLoaded(GrashID) THEN
- WriteLn('Bereits geladen')
- ELSE BEGIN { Hotkey-Routinen inst. }
-
- Ok := Ok AND PopUpInstalled(@ToggleDraw,
- HotKeyToggle, 0, 1);
- Ok := Ok AND PopUpInstalled(@PopupLeft,
- HotkeyLeft, 0, 2);
- Ok := Ok AND PopUpInstalled(@PopupRight,
- HotkeyRight, 0, 3);
- Ok := Ok AND PopUpInstalled(@PopupUp,
- HotkeyUp, 0, 4);
- Ok := Ok AND PopUpInstalled(@PopupDown,
- HotkeyDown, 0, 5);
- IF Ok THEN
- MakeResident(GrashID)
- ELSE
- WriteLn('Fehler: Konnte nicht installiert werden');
- END;
- END.
- (* ------------------------------------------------------ *)
- (* Ende von GRAFFITI.PAS *)
-
-