home *** CD-ROM | disk | FTP | other *** search
- {$UNDEF test}
-
- {$IFDEF test}
- {$A+,B-,D+,E-,F-,G-,I+,L+,N-,O-,R+,S+,V+,X-}
- {$M 16384,0,655360}
- {$ELSE}
- {$A+,B-,D+,E-,F-,G-,I-,L+,N-,O-,R-,S-,V-,X-}
- {$M 16384,150000,655360}
- {$ENDIF}
-
- PROGRAM MakeSprite;
- {Zweck : Erstellung von *.COD und *.PIC Dateien für ANIVGA }
- {Autor : Kai Rohrbacher }
- {Sprache : TurboPascal 6.0 }
- {Datum : Juli 1992 }
- {Anmerkung: Hat manchmal Probleme bei der Mausinitialisierung - keine}
- { Ahnung warum!}
-
- {Erweiterungen um ein Tool:}
- { ein Event dafür definieren}
- { in "ToolTyp" mitaufnehmen }
- { in "Menu[]" aufnehmen (vor dem Sentineleintrag natürlich)}
- { DrawTool* Routine für Icondarstellung einfügen (inkl. FORWARD)}
- { DrawWorkArea* Routine einführen, die Objekt löschen, zeichnen & speichern kann}
- { Tooltyp in ClearOldObject(), DrawNewObject() und StoreObject() einfügen}
- { in WorkAreaAction() 2x einfügen: temporäres Objekt zeichnen, Objekt abschließen}
- { in SelectNewTool() und ShowActualTool() einfügen}
- { im Hauptprogramm bei Event-Abfrage berücksichtigen}
- { Wenn es den Inhalt der Workarea ändert, dann WorkAreaMaxUsedX|Y ändern}
-
- USES Dos,Graph,crt,DATWAHL,Eingabe;
- const Titel1='MakeSprite V2.0 (c) - by Kai Rohrbacher';
- GetMaxX=639;
- GetMaxY=399; {da Graph.GetMaxY hier noch nicht zur Verfügung steht!}
- Menumax=10; {Anzahl Einträge im Hauptmenu}
- WorkBreite=320; {Breite der Workarea}
- WorkHoehe=200;
- WorkStartX= 4; WorkEndX=WorkStartX+Pred(WorkBreite);
- WorkStartY=35; WorkEndY=WorkStartY+Pred(WorkHoehe);
- PaletteX=WorkStartX+WorkBreite+4; {Koord. für Palette}
- PaletteY=30;
- PalHoehe=15; {Abmessungen einer Palettenkachel}
- PalBreite=18;
- MeldungX=390; MeldungY=GetMaxY-95;{Koordinaten für Meldungen}
- InfoX=WorkStartX; {dto., für Sprite-Info}
- InfoY=WorkEndy+10;
- ToolsX=10; ToolsY=WorkEndY+65; {dto., für Toolboxen }
- zoom:BYTE=2; {Vergrößerungsfaktor}
- StartVirtualX:INTEGER=0; {Verschiebung des Workarea-Inhaltes}
- StartVirtualY:INTEGER=0;
- MenuStartX=2; MenuStartY=GetMaxY-20; {Menu-Startkoordinaten}
-
- CursorMaxX=11; {max. Abmessungen des Mauscursors}
- CursorMaxY=13;
- MausMinX=0; {Koordinatenbereich für Maus}
- MausMinY=20;
- MausMaxX=GetMaxX-CursorMaxX;
- MausMaxY=GetMaxY-CursorMaxY;
-
- MaxSpriteBreite=316; {sollte Vielfaches von 4 sein}
- MaxSpriteHoehe =200;
- Datenbytes=MaxSpriteHoehe*Succ(Pred(MaxSpriteBreite) div 4)*4;
-
- Kopf=50; {Größe des folgenden Spriteheaders in Bytes (ohne Data-Feld):}
- VID640x400x256=1;
- transparent=0; {Farbe für durchsichtig = 0 per Definition!}
-
- TYPE spritetyp= record case Integer of
- 0:(
- Zeiger_auf_Plane:Array[0..3] OF Word; {Diese...}
- Breite_in_4er_Gruppen:WORD; {...Daten}
- Hoehe_in_Zeilen:WORD; {...brauchen}
- Translate:Array[1..4] OF Byte; {...alles}
- SpriteLength:WORD;
- Dummy:Array[1..10] OF Word; {...zusammen}
- Kennung:ARRAY[1..2] OF CHAR;
- Version:BYTE;
- Modus:BYTE;
- ZeigerL,ZeigerR,ZeigerO,ZeigerU:Word; {"Kopf" Bytes!}
- Data:Array[1..Datenbytes
- +(WorkBreite*2)*2
- +(WorkHoehe *2)*2] OF Byte;
- );
- 1:(
- readin:Array[0..(Datenbytes-1) {max. Größe der Planedaten}
- +(WorkBreite*2)*2 {dto., Y-Grenzen (2 Wort-Tabellen)}
- +(WorkHoehe *2)*2 {dto., X-Gr. (auch Worteinträge)}
- +Kopf] OF Byte; {Zeiger am Anfang, immer!}
- )
- END;
- {Datentyp zur Repräsentation der WorkArea; Achtung: WorkArea[y,x],}
- {nicht WorkArea[x,y]!}
- WorkAreatyp= record case Integer of
- 0:(data:ARRAY[0..WorkBreite*WorkHoehe-1] OF BYTE);
- 1:(feld:ARRAY[0..WorkHoehe-1,0..WorkBreite-1] OF BYTE);
- END;
-
- Farbeck=RECORD
- x1,y1,x2,y2:Integer;
- END;
-
- BildTyp=(cod,pic,none);
- ActionTyp=(clear,draw,store);
-
- ToolTyp=(Punkt,Rechteck,Ellipse_,FRechteck,FEllipse,Linie,FuellEimer,Kopie);
- ObjektTyp=RECORD
- stage:BYTE;
- StartX,StartY,LastX,LastY:INTEGER;
- actX,actY:INTEGER; {Hilfskoordinaten, nur für "Kopie"-Tool}
- Typ:ToolTyp;
- Aligned:BOOLEAN;
- END;
- ButtonStringTyp=STRING[8]; {Meldung in Clickboxen}
-
- CONST aktuellesTool:ToolTyp=Punkt; {aktuell gewähltes Tool}
- aktuelleFarbe:BYTE=White; {aktuelle Zeichenfarbe }
- Objekt:ObjektTyp=(
- stage:0; {Objekt noch nicht begonnen, Rest uninteressant!}
- StartX:0; StartY:0; LastX:0; LastY:0;
- actX:0; actY:0;
- Typ:Punkt;
- Aligned:FALSE
- );
-
- VAR CRTAddress, {Adresse des CRT-Ports, $3B4/$3D4 fuer monochrom/Farbe}
- StatusReg:WORD; {dto., fuer Statusregister, $3BA/$3DA}
- Shift:BOOLEAN; {gibt wieder, ob während Auswertung Shift gedrückt war}
- BestWhite, {Beste Näherungen der angeg. Farben}
- BestBlack,
- BestCyan,
- BestLightGray,
- BestDarkGray:BYTE;
-
- {---------Menu-Felder---------}
- CONST EventNone=0; {gar nix}
- EventError=1; {Fehler }
- EventQuit=2; {Programm vielleicht beenden}
- EventScrollLeft=3; {Scroll nach links }
- EventScrollRight=4; {Scroll nach rechts}
- EventScrollUp=5; {Scroll nach oben }
- EventScrollDown=6; {Scroll nach unten }
- EventZoomin=7; {Workareainhalt vergrößern}
- EventZoomout=8; {dto., verkleinern}
- EventHelp=9; {Hilfe}
- EventLadeSprite=10; {Sprite laden}
- EventLadePalette=11; {Palette laden}
- EventResetColors=12; {Defaultpalette}
- EventLadeHintergrund=13; {Hintergrundbild laden}
- EventMapPalette=14; {Workareainhalt auf Palette matchen}
- EventMapToBIOSPalette=15; {dto., aber auf Standardfarbenpalette}
- EventInWorkArea=16; {Maus in Workarea}
- EventMouseMoved=17; {Maus wurde bewegt}
- EventSelectColor=18; {Farbe wird ausgewählt}
- EventToolPixel=19; {Tool für Punkte selektiert}
- EventToolLine=20; {dto., für Linien}
- EventToolRectangle=21; {dto., für Quadrate+Rechtecke}
- EventToolEllipse=22; {dto., für Kreise+Ellipsen}
- EventToolBar=23; {dto., für ausgefüllte Quadrate+Rechtecke}
- EventToolDisc=24; {dto., für ausgefüllte Kreise+Ellipsen}
- EventToolFill=25; {dto., für Füllfunktion}
- EventToolCopy=26; {dto., für Ausschnittskopien}
- EventBlinkColor=27; {Eine Farbe blinken lassen}
- EventChangeColor=28; {Farbe austauschen}
- EventShowBorder=29; {Spritegrenzen zeigen}
- EventSpeichereSprite=30; {Sprite abspeichern}
- EventSpeichereHintergrund=31;{Hintergrund abspeichern}
- EventSpeicherePalette=32; {Palette abspeichern}
- EventRotateLeft=33; {Workareainhalt um 1 nach links rotieren}
- EventRotateRight=34; {dto., rechts}
- EventRotateUp=35; {dto., nach oben}
- EventRotateDown=36; {dto., nach unten}
- EventMirrorHorizontal=37; {horizontal spiegeln}
- EventMirrorVertical=38; {vertikal spiegeln}
- EventObenLinks=39; {verschiebt Sprite soweit wie möglich links hoch}
- EventEraseWorkarea=40; {Workarea vollständig löschen}
- EventEndProgram=41; {Programm tatsächlich beenden}
-
- VAR globalI:BYTE;
-
- TYPE DrawBox=PROCEDURE;
- box=RECORD {Datentyp für ein Menufeld:}
- x1,y1, {obere linke Boxecke}
- x2,y2:WORD; {untere rechte Ecke }
- Name1,Name2:STRING[8]; {Beschriftung 1.+2.Zeile}
- Show :DrawBox; {Routine zum anzeigen des Icons}
- Event:BYTE; {zurückzugebender Wert}
- Click:BOOLEAN; {muß Maus geclickt werden für Event?}
- Paint:BOOLEAN; {Flag, ob Box zu zeichnen ist}
- END;
- boxes=ARRAY[1..32] OF box; {alle Menufelder zusammen}
-
- PROCEDURE Dummy; FAR; BEGIN END;
- PROCEDURE DrawToolPixels; FAR; FORWARD;
- PROCEDURE DrawToolLines; FAR; FORWARD;
- PROCEDURE DrawToolRectangles; FAR; FORWARD;
- PROCEDURE DrawToolEllipses; FAR; FORWARD;
- PROCEDURE DrawToolBars; FAR; FORWARD;
- PROCEDURE DrawToolDiscs; FAR; FORWARD;
- PROCEDURE DrawToolFill; FAR; FORWARD;
- PROCEDURE DrawToolCopy; FAR; FORWARD;
-
- PROCEDURE DrawFunctionkey; FAR; FORWARD;
- PROCEDURE DrawBoxBorders; FAR; FORWARD;
- PROCEDURE DrawBoxBlinkColor; FAR; FORWARD;
- PROCEDURE DrawBoxChangeColor; FAR; FORWARD;
- PROCEDURE DrawBoxRotateLeft; FAR; FORWARD;
- PROCEDURE DrawBoxRotateRight; FAR; FORWARD;
- PROCEDURE DrawBoxRotateUp; FAR; FORWARD;
- PROCEDURE DrawBoxRotateDown; FAR; FORWARD;
- PROCEDURE DrawBoxMirrorHorizontal; FAR; FORWARD;
- PROCEDURE DrawBoxMirrorVertical; FAR; FORWARD;
- PROCEDURE DrawBoxObenLinks; FAR; FORWARD;
-
- CONST ToolBoxWidth=45;
- BoxWidth=63;
- Menu:boxes=(
- {F1} (x1:MenuStartX+ 0*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 0*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Help'; Name2:'';
- Show :DrawFunctionkey;
- Event:EventHelp;
- Click:TRUE;
- Paint:TRUE),
- {F2} (x1:MenuStartX+ 1*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 1*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Save';Name2:'*.COD';
- Show :DrawFunctionkey;
- Event:EventSpeichereSprite;
- Click:TRUE;
- Paint:TRUE),
- {F3} (x1:MenuStartX+ 2*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 2*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Load';Name2:'*.COD';
- Show :DrawFunctionkey;
- Event:EventLadeSprite;
- Click:TRUE;
- Paint:TRUE),
- {F4} (x1:MenuStartX+ 3*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 3*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Save';Name2:'*.PAL';
- Show :DrawFunctionkey;
- Event:EventSpeicherePalette;
- Click:TRUE;
- Paint:TRUE),
- {F5} (x1:MenuStartX+ 4*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 4*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Load';Name2:'*.PAL';
- Show :DrawFunctionkey;
- Event:EventLadePalette;
- Click:TRUE;
- Paint:TRUE),
- {F6} (x1:MenuStartX+ 5*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 5*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Save';Name2:'*.PIC';
- Show :DrawFunctionkey;
- Event:EventSpeichereHintergrund;
- Click:TRUE;
- Paint:TRUE),
- {F7} (x1:MenuStartX+ 6*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 6*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Load';Name2:'*.PIC';
- Show :DrawFunctionkey;
- Event:EventLadeHintergrund;
- Click:TRUE;
- Paint:TRUE),
- {F8} (x1:MenuStartX+ 7*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 7*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'Clear';Name2:'Screen';
- Show :DrawFunctionkey;
- Event:EventEraseWorkarea;
- Click:TRUE;
- Paint:TRUE),
- {F9} (x1:MenuStartX+ 8*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 8*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'MapPal';Name2:'to Pal';
- Show :DrawFunctionkey;
- Event:EventMapPalette;
- Click:TRUE;
- Paint:TRUE),
- {F10} (x1:MenuStartX+ 9*BoxWidth+8-1; y1:MenuStartY-1;
- x2:MenuStartX+ 9*BoxWidth+8+BoxWidth-14; y2:MenuStartY+18;
- Name1:'QUIT';Name2:'';
- Show :DrawFunctionkey;
- Event:EventQuit;
- Click:TRUE;
- Paint:TRUE),
-
- {Jetzt die Toolboxen:}
- {Punkte:}
- (x1:ToolsX+0*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+1*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawToolPixels;
- Event:EventToolPixel;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Linien:}
- (x1:ToolsX+1*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+2*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawToolLines;
- Event:EventToolLine;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Rechtecke&Quadrate:}
- (x1:ToolsX+2*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+3*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawToolRectangles;
- Event:EventToolRectangle;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Kreise&Ellipsen:}
- (x1:ToolsX+3*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+4*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawToolEllipses;
- Event:EventToolEllipse;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Fülltool:}
- (x1:ToolsX+0*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+1*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawToolFill;
- Event:EventToolFill;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {ausgefüllte Rechtecke&Quadrate:}
- (x1:ToolsX+2*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+3*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawToolBars;
- Event:EventToolBar;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {ausgefüllte Kreise&Ellipsen:}
- (x1:ToolsX+3*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+4*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawToolDiscs;
- Event:EventToolDisc;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Kopie anfertigen:}
- (x1:ToolsX+1*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+2*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawToolCopy;
- Event:EventToolCopy;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
-
- {---Jetzt die Funktionsbuttons---}
-
- {Grenzen anzeigen:}
- (x1:ToolsX+8*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+9*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawBoxBorders;
- Event:EventShowBorder;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Farbe blinken lassen:}
- (x1:ToolsX+4*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+5*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawBoxBlinkColor;
- Event:EventBlinkColor;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Farben austauschen:}
- (x1:ToolsX+4*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+5*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawBoxChangeColor;
- Event:EventChangeColor;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt um 1 Spalte nach links rotieren:}
- (x1:ToolsX+5*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+6*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawBoxRotateLeft;
- Event:EventRotateLeft;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt um 1 Spalte nach rechts rotieren:}
- (x1:ToolsX+6*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+7*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawBoxRotateRight;
- Event:EventRotateRight;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt um 1 Spalte nach oben rotieren:}
- (x1:ToolsX+5*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+6*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawBoxRotateUp;
- Event:EventRotateUp;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt um 1 Spalte nach unten rotieren:}
- (x1:ToolsX+6*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+7*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawBoxRotateDown;
- Event:EventRotateDown;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt horizontal spiegeln:}
- (x1:ToolsX+7*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+8*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawBoxMirrorHorizontal;
- Event:EventMirrorHorizontal;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt vertikal spiegeln:}
- (x1:ToolsX+7*ToolBoxWidth; y1:ToolsY+37;
- x2:ToolsX+8*ToolBoxWidth-5; y2:ToolsY+37+32;
- Name1:'';Name2:'';
- Show :DrawBoxMirrorVertical;
- Event:EventMirrorVertical;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workareainhalt nach links oben schieben:}
- (x1:ToolsX+8*ToolBoxWidth; y1:ToolsY;
- x2:ToolsX+9*ToolBoxWidth-5; y2:ToolsY+32;
- Name1:'';Name2:'';
- Show :DrawBoxObenLinks;
- Event:EventObenLinks;
- Click:TRUE; {Anclicken nötig}
- Paint:TRUE), {wird gezeichnet}
-
- {Workarea kann auch als "Menubox" realisiert werden:}
- (x1:WorkStartX; y1:WorkStartY;
- x2:WorkEndX; y2:WorkEndY;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventInWorkArea;
- Click:FALSE; {kein Anclicken nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Palettenbereich kann auch als "Menubox" realisiert werden:}
- (x1:PaletteX+25; y1:PaletteY+10;
- x2:PaletteX+25+16*PalBreite-3; y2:PaletteY+10+16*PalHoehe-3;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventSelectColor;
- Click:TRUE; {Anclicken nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {gesamter Mausbereich kann auch als "Menubox" realisiert werden:}
- (x1:MausMinX; y1:MausMinY;
- x2:MausMaxX; y2:MausMaxY;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventMouseMoved;
- Click:FALSE; {kein Anclicken nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Sentinelwert, da x1>x2!}
- (x1:1; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNone;
- Click:TRUE;
- Paint:TRUE)
- );
-
- VAR event:BYTE;
-
- {Für alle folgenden Draw* -Routinen gilt: beim Aufruf steht in "globalI" }
- {der Index der darzustellenden Menubox und diese ist wirklich zu zeichnen}
-
- PROCEDURE DrawBasicBox;
- {zeichnet eine "nackte" Box}
- BEGIN
- WITH Menu[globalI] DO
- BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
- END;
- END;
-
- PROCEDURE DrawToolPixels;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(x1+4,y1+4,x1+4+2,y1+4+2);
- Bar(x1+8,y1+15,x1+8+2,y1+15+2);
- Bar(x1+5,y2-9,x1+5+2,y2-9+2);
- Bar(x2-8,y2-7,x2-8+2,y2-7+2);
- Bar(x1+17,y2-13,x1+17+2,y2-13+2);
- Bar(x2-15,y1+8,x2-15+2,y1+8+2);
- SetFillStyle(SolidFill,BestCyan);
- Bar(x1+9,y1+4,x1+9+2,y1+4+2);
- Bar(x1+15,y1+5,x1+15+2,y1+5+2);
- Bar(x2-5,y2-9,x2-5+2,y2-9+2);
- Bar(x2-13,y2-6,x2-13+2,y2-6+2);
- Bar(x2-12,y1+12,x2-12+2,y1+12+2);
- END;
- END;
-
- PROCEDURE DrawToolLines;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetLineStyle(SolidLn,0,ThickWidth);
- SetColor(BestBlack);
- Line(x1+4,y2-8,x2-4,y1+12);
- SetColor(BestDarkGray);
- Line(x1+8,y1+5,x2-6,y2-7);
- SetColor(BestCyan);
- Line(x1+4,y1+5,x1+10,y2-3);
- SetLineStyle(SolidLn,0,NormWidth);
- END;
- END;
-
- PROCEDURE DrawToolRectangles;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(x1+ 4,y1+12,x1+20,y1+13);
- Bar(x1+20,y1+12,x1+21,y1+27);
- Bar(x1+20,y1+27,x1+ 4,y1+26);
- Bar(x1+ 4,y1+27,x1+ 5,y1+12);
-
- SetFillStyle(SolidFill,BestCyan);
- Bar(x1+ 8,y1+11,x1+ 9,y1+ 6);
- Bar(x1+ 8,y1+ 6,x2- 4,y1+ 7);
- Bar(x2- 4,y1+ 6,x2- 5,y2-12);
- Bar(x2- 4,y2-12,x1+22,y2-13);
- END;
- END;
-
- PROCEDURE DrawToolEllipses;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestCyan);
- Ellipse(x1+22,y1+14,273,160,13,6);
- Ellipse(x1+22,y1+14,273,160,14,7);
- SetColor(BestBlack);
- Circle(x1+13,y2-13, 8);
- Circle(x1+13,y2-13, 8+1);
- END;
- END;
-
- PROCEDURE DrawToolBars;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetFillStyle(SolidFill,BestCyan);
- Bar(x1+ 8,y1+ 6,x2- 4,y2-13);
- SetFillStyle(SolidFill,BestBlack);
- Bar(x1+ 4,y1+12,x1+20,y1+27);
- END;
- END;
-
- PROCEDURE DrawToolDiscs;
- VAR i:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestCyan);
- SetFillStyle(SolidFill,BestBlack);
- FOR i:=1 TO 7 DO
- Ellipse(x1+22,y1+14,273,160,7+i,i);
- Line(x1+22-14,y1+14,x1+22+14,y1+14);
- SetColor(BestBlack);
- PieSlice(x1+13,y2-13,0,360, 8);
- PieSlice(x1+13,y2-13,0,360, 8+1);
- END;
- END;
-
- PROCEDURE DrawToolFill;
- CONST width=7;
- height=12;
- VAR i,tx,ty:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- tx:=x1+11; ty:=y1+16;
- SetColor(BestWhite);
- FOR i:=1 TO width DO Line(tx+i,ty-i,tx+height+i,ty+height-i);
- SetColor(BestBlack);
- Line(tx+0,ty-0,tx+succ(width),ty-succ(width));
- SetLineStyle(SolidLn,0,ThickWidth);
- Line(tx+0,ty-0,tx+height-1,ty+height-1);
- Line(tx+succ(width),ty-succ(width),
- tx+height+width,ty+height-succ(width)-1);
- Line(tx+height,ty+height-1,tx+height+width,ty+height-succ(width));
- SetLineStyle(SolidLn,0,NormWidth);
- Circle(tx +width+1, ty,2);
- Line(tx +width+1,ty,tx +width+1,ty-10);
- Line(tx +width+7,ty-3,tx +width+7,ty-10-3);
- Line(tx +width+1,ty-10,tx +width+7,ty-10-3);
- SetColor(BestCyan);
- Line(tx,ty-2,tx,ty+height);
- Line(tx-1,ty-1,tx-1,ty+height-2);
- Line(tx-1,ty+2,tx-1,ty+height-4);
- Line(tx-1,ty-1,tx+1,ty-2);
- END;
- END;
-
- PROCEDURE DrawToolCopy;
- CONST
- IconMaxX=23;
- IconMaxY=21;
- dx=10; dy=3;
- s=Black;
- w=White;
- c=Cyan;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|2|2|2|2}
- {0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3}
-
- (t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,s,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,s,c,c,c,c,s,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,c,c,s,s,c,c,s,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,c,s,t,t,s,c,s,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,c,s,t,t,s,c,s,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,c,s,t,s,c,s,t,s,s,s,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,c,s,s,c,s,t,s,c,c,c,s,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,s,c,c,s,t,s,c,s,s,c,c,s),
- (t,t,t,t,t,t,t,t,t,t,t,t,s,w,s,t,s,c,s,t,t,s,c,s),
- (t,t,t,t,t,t,t,t,t,t,t,t,s,w,s,s,c,s,t,t,t,s,c,s),
- (t,t,t,t,t,t,t,t,t,t,s,s,w,w,w,w,c,s,s,s,s,c,c,s),
- (t,t,t,t,t,t,t,t,s,s,w,w,s,w,s,s,s,c,c,c,c,c,s,t),
- (t,t,t,t,t,t,s,s,w,w,w,w,w,s,s,t,t,s,s,s,s,s,t,t),
- (t,t,t,t,s,s,w,w,w,w,s,w,w,s,t,t,t,t,t,t,t,t,t,t),
- (t,t,s,s,w,w,w,w,w,s,w,w,s,t,t,t,t,t,t,t,t,t,t,t),
- (t,s,w,w,w,w,w,s,s,w,w,w,s,t,t,t,t,t,t,t,t,t,t,t),
- (s,w,w,w,w,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (s,w,w,s,s,t,t,s,w,w,w,s,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,s,s,t,t,t,t,s,w,w,s,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,s,w,w,w,s,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,s,w,w,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,s,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestCyan);
- Rectangle(x1+dx-6,y1+dy+16,x1+dx+16,y1+dy+26);
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx,y1+y+dy,BestBlack);
- w:PutPixel(x1+x+dx,y1+y+dy,BestWhite);
- c:PutPixel(x1+x+dx,y1+y+dy,BestCyan);
- END;
- END;
- END;
-
- {Folgende Menuboxen sind keine "Tools" in obigem Sinne, sondern Funktions-}
- {buttons:}
-
- PROCEDURE DrawFunctionkey;
- VAR s:STRING[3];
- BEGIN
- WITH Menu[globalI] DO
- BEGIN
- SetFillStyle(SolidFill,BestCyan);
- IF (x1<x2) AND (Paint) THEN
- BEGIN
- SetColor(BestWhite);
- OutTextXY(x1-8,y1+1,'F');
- STR(globalI MOD 10,s);
- OutTextXY(x1-8,y1+1+10,s);
- Bar(x1,y1,x2,y2);
- SetColor(BestBlack);
- OutTextXY(x1+1,y1+1,Name1);
- OutTextXY(x1+1,y1+1+10,Name2);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxBorders;
- CONST
- IconMaxX=35;
- IconMaxY=26;
- dx=3; dy=3;
- s=Black;
- w=White;
- c=Cyan;
- d=DarkGray;
- g=LightGray;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|2|2|2|2|2|2|2|2|2|2|3|3|3|3|3|3}
- {0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5}
-
- (t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,s,s,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,s,s,c,c,c,c,c,c,g,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,s,c,c,w,w,w,w,w,c,c,c,g,s,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,s,c,c,w,w,c,c,c,c,c,c,c,c,d,s,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,s,c,w,w,c,g,d,d,d,g,c,c,c,g,s,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,s,c,w,w,c,g,d,s,s,s,d,g,c,c,c,d,s,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,s,c,w,w,c,g,s,t,t,t,s,d,c,c,c,d,s,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,s,g,c,c,g,d,s,t,t,t,t,s,c,c,c,d,s,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,s,d,d,d,s,t,t,t,t,t,s,c,c,c,d,s,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,s,t,t,t,s,s,s,t,t,t,t,t,t,s,c,c,c,d,s,t,t,t,t,s,t,t,t,t,t,t),
- (t,t,t,t,t,s,s,t,t,t,t,t,t,t,t,t,t,s,s,c,c,c,g,d,s,t,t,t,t,s,s,t,t,t,t,t),
- (t,t,t,t,s,w,s,s,s,s,t,t,t,t,t,t,s,c,c,c,c,c,d,s,t,t,s,s,s,s,w,s,t,t,t,t),
- (t,t,t,s,w,w,w,w,w,s,t,t,t,t,t,s,c,c,c,c,c,g,d,s,t,t,s,w,w,w,w,w,s,t,t,t),
- (t,t,s,w,w,w,w,w,w,s,t,t,t,t,s,c,c,w,c,c,g,d,s,t,t,t,s,w,w,w,w,w,w,s,t,t),
- (t,s,w,w,w,w,w,w,w,s,t,t,t,s,c,c,w,c,c,g,d,s,t,t,t,t,s,w,w,w,w,w,w,w,s,t),
- (t,t,s,w,w,w,w,w,w,s,t,t,t,s,c,w,w,c,g,d,s,t,t,t,t,t,s,w,w,w,w,w,w,s,t,t),
- (t,t,t,s,w,w,w,w,w,s,t,t,t,s,c,w,c,g,d,s,t,t,t,t,t,t,s,w,w,w,w,w,s,t,t,t),
- (t,t,t,t,s,w,s,s,s,s,t,t,t,s,c,c,c,c,d,s,t,t,t,t,t,t,s,s,s,s,w,s,t,t,t,t),
- (t,t,t,t,t,s,s,t,t,t,t,t,t,s,g,c,c,g,d,s,t,t,t,t,t,t,t,t,t,s,s,t,t,t,t,t),
- (t,t,t,t,t,t,s,t,t,t,t,t,t,t,s,d,d,d,s,t,t,t,t,t,t,t,t,t,t,s,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,c,c,g,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,c,w,c,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,g,c,g,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx,y1+y+dy,BestBlack);
- w:PutPixel(x1+x+dx,y1+y+dy,BestWhite);
- c:PutPixel(x1+x+dx,y1+y+dy,BestCyan);
- d:PutPixel(x1+x+dx,y1+y+dy,BestDarkGray);
- g:PutPixel(x1+x+dx,y1+y+dy,BestLightGray);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxBlinkColor;
- CONST
- IconMaxX=35;
- IconMaxY=16;
- dx=2; dy=8;
- s=Black;
- w=White;
- d=DarkGray;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|2|2|2|2|2|2|2|2|2|2|3|3|3|3|3|3}
- {0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5}
-
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,t,t,t,t,t,t,s,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,t,t,t,t,s,t,t,t,t,s,t,t,t,t,t,s,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,s,t,t,t,t,t,t,t,t,t,t,t,t,t,s,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,s,t,t,t,s,s,s,s,s,t,t,t,s,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,s,t,t,t,t,t,t,t,t,s,s,w,w,w,w,w,s,s,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,s,s,t,t,t,t,t,t,t,s,w,s,s,w,w,w,w,s,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,s,s,s,s,w,s,t,t,s,t,t,s,w,s,s,w,w,w,w,w,w,s,t,t,t,t,s,s),
- (t,d,d,d,d,d,d,t,s,w,w,w,w,w,s,t,t,s,t,s,w,s,s,w,w,w,w,w,w,s,t,t,s,s,t,t),
- (t,d,d,d,d,d,d,t,s,w,w,w,w,w,w,s,t,t,t,t,s,w,w,w,w,w,w,w,s,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,s,w,w,w,w,w,w,w,s,t,t,t,s,w,w,w,w,w,w,w,s,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,s,w,w,w,w,w,w,s,t,t,s,t,t,s,w,w,w,w,w,s,t,t,s,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,s,w,w,w,w,w,s,t,s,s,t,t,t,t,s,s,s,w,s,t,t,t,t,s,s,t,t,t),
- (t,d,d,d,d,d,d,t,s,s,s,s,w,s,t,t,t,t,t,t,t,t,s,w,w,s,s,t,t,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,s,s,t,t,t,t,t,t,t,t,t,s,s,s,s,s,t,t,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,s,t,t,t,t,t,t,t,t,t,t,s,s,s,w,s,t,t,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,w,w,s,s,t,t,t,t,t,t,t,t,t),
- (t,d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,s,s,s,t,t,t,t,t,t,t,t,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx,y1+y+dy,BestBlack);
- w:PutPixel(x1+x+dx,y1+y+dy,BestWhite);
- d:PutPixel(x1+x+dx,y1+y+dy,BestDarkGray);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxChangeColor;
- CONST
- IconMaxX=26;
- IconMaxY=16;
- dx=7; dy=8;
- s=Black;
- w=White;
- d=DarkGray;
- c=Cyan;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|2|2|2|2|2|2|2|2|2|2|3|3|3|3|3|3}
- {0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5}
-
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t),
- (d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,s,t,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,s,s,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,s,s,s,w,s,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,w,w,w,w,w,s,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,w,w,w,w,w,w,s,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,w,w,w,w,w,w,w,s,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,w,w,w,w,w,w,s,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,w,w,w,w,w,s,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,s,s,s,s,w,s,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,s,s,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,s,t,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,c,c,c,c,c,c),
- (d,d,d,d,d,d,t,t,t,t,t,t,t,t,t,t,t,t,t,t,t,c,c,c,c,c,c)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx,y1+y+dy,BestBlack);
- w:PutPixel(x1+x+dx,y1+y+dy,BestWhite);
- d:PutPixel(x1+x+dx,y1+y+dy,BestDarkGray);
- c:PutPixel(x1+x+dx,y1+y+dy,BestCyan);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxRotateLeft;
- VAR miX,miY:INTEGER;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- miX:=(x1+x2) SHR 1; miY:=(y1+y2) SHR 1;
- Ellipse(miX,miY, 0,360, 13,5);
- Ellipse(miX,miY, 0,360, 13-1,5-1);
- Line(miX-3,miY+4,miX+3,miY+4-3);
- Line(miX-2,miY+4,miX+4,miY+4-3);
- Line(miX-3,miY+5,miX+3,miY+5+3);
- Line(miX-2,miY+5,miX+4,miY+5+3);
- END;
- END;
-
- PROCEDURE DrawBoxRotateRight;
- VAR miX,miY:INTEGER;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- miX:=(x1+x2) SHR 1; miY:=(y1+y2) SHR 1;
- Ellipse(miX,miY, 0,360, 13,5);
- Ellipse(miX,miY, 0,360, 13-1,5-1);
- Line(miX-3,miY+4-3,miX+3,miY+4);
- Line(miX-2,miY+4-3,miX+4,miY+4);
- Line(miX-3,miY+5+3,miX+3,miY+5);
- Line(miX-2,miY+5+3,miX+4,miY+5);
- END;
- END;
-
- PROCEDURE DrawBoxRotateUp;
- VAR miX,miY:INTEGER;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- miX:=(x1+x2) SHR 1; miY:=(y1+y2) SHR 1;
- Ellipse((x1+x2) SHR 1,(y1+y2) SHR 1, 0,360, 7,12);
- Ellipse((x1+x2) SHR 1,(y1+y2) SHR 1, 0,360, 7-1,12-1);
- Line(miX-7-4,miY+3,miX-7-1,miY-2);
- Line(miX-7-4,miY+2,miX-7-1,miY-1);
- Line(miX-7+5,miY+3,miX-7+2,miY-2);
- Line(miX-7+5,miY+2,miX-7+2,miY-1);
- END;
- END;
-
- PROCEDURE DrawBoxRotateDown;
- VAR miX,miY:INTEGER;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- miX:=(x1+x2) SHR 1; miY:=(y1+y2) SHR 1;
- Ellipse((x1+x2) SHR 1,(y1+y2) SHR 1, 0,360, 7,12);
- Ellipse((x1+x2) SHR 1,(y1+y2) SHR 1, 0,360, 7-1,12-1);
- Line(miX-7-4,miY-2,miX-7-1,miY+3);
- Line(miX-7-4,miY-1,miX-7-1,miY+2);
- Line(miX-7+5,miY-2,miX-7+2,miY+3);
- Line(miX-7+5,miY-1,miX-7+2,miY+2);
- END;
- END;
-
- PROCEDURE DrawBoxMirrorHorizontal;
- CONST
- IconMaxX=25;
- IconMaxY=8;
- dx=7; dy=3;
- s=Black;
- w=White;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|2|2|2|2|2|2}
- {0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5}
-
- (t,s,t,t,t,t,s,t,t,t,t,t,t,t,t,t,s,t,t,t,t,s,t,t,t,t),
- (s,s,t,t,t,t,s,s,t,t,t,t,t,t,t,s,s,t,t,t,t,s,s,t,t,t),
- (w,s,s,s,s,s,s,w,s,t,t,t,t,t,s,w,s,s,s,s,s,s,w,s,t,t),
- (w,w,w,w,w,w,w,w,w,s,t,t,t,s,w,w,w,w,w,w,w,w,w,w,s,t),
- (w,w,w,w,w,w,w,w,w,w,s,t,s,w,w,w,w,w,w,w,w,w,w,w,w,s),
- (w,w,w,w,w,w,w,w,w,s,t,t,t,s,w,w,w,w,w,w,w,w,w,w,s,t),
- (w,s,s,s,s,s,s,w,s,t,t,t,t,t,s,w,s,s,s,s,s,s,w,s,t,t),
- (s,s,t,t,t,t,s,s,t,t,t,t,t,t,t,s,s,t,t,t,t,s,s,t,t,t),
- (t,s,t,t,t,t,s,t,t,t,t,t,t,t,t,t,s,t,t,t,t,s,t,t,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- Line(x1+dx,y1+dy+9,x1+dx+19,y1+dy);
- Line(x1+dx,y1+dy+9+18,x1+dx+19,y1+dy+18);
- Line(x1+dx,y1+dy+9,x1+dx,y1+dy+9+18);
- Line(x1+dx+19,y1+dy,x1+dx+19,y1+dy+18);
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx+1,y1+y+dy+9,BestBlack);
- w:PutPixel(x1+x+dx+1,y1+y+dy+9,BestWhite);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxMirrorVertical;
- CONST
- IconMaxX=8;
- IconMaxY=21;
- dx=4; dy=5;
- s=Black;
- w=White;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|1|2|3|4|5|6|7|8}
-
- (t,t,t,t,s,t,t,t,t),
- (t,t,t,s,w,s,t,t,t),
- (t,t,s,w,w,w,s,t,t),
- (t,s,w,w,w,w,w,s,t),
- (s,s,s,w,w,w,s,s,s),
- (t,t,s,w,w,w,s,t,t),
- (t,t,s,w,w,w,s,t,t),
- (t,t,s,w,w,w,s,t,t),
- (t,t,s,w,w,w,s,t,t),
- (s,s,s,w,w,w,s,s,s),
- (t,s,w,w,w,w,w,s,t),
- (t,t,s,w,w,w,s,t,t),
- (t,t,t,s,w,s,t,t,t),
- (t,t,t,t,s,t,t,t,t),
- (t,t,t,t,t,t,t,t,t),
- (t,t,t,t,s,t,t,t,t),
- (t,t,t,s,w,s,t,t,t),
- (t,t,s,w,w,w,s,t,t),
- (t,s,w,w,w,w,w,s,t),
- (s,s,s,w,w,w,s,s,s),
- (t,t,s,w,w,w,s,t,t),
- (t,t,s,w,w,w,s,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- Line(x1+dx+11,y1+dy+11,x1+dx+32,y1+dy+11);
- Line(x1+dx,y1+dy+22,x1+dx+21,y1+dy+22);
- Line(x1+dx,y1+dy+22,x1+dx+11,y1+dy+11);
- Line(x1+dx+21,y1+dy+22,x1+dx+32,y1+dy+11);
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx+12,y1+y+dy,BestBlack);
- w:PutPixel(x1+x+dx+12,y1+y+dy,BestWhite);
- END;
- END;
- END;
-
- PROCEDURE DrawBoxObenLinks;
- CONST
- IconMaxX=7;
- IconMaxY=6;
- dx=4; dy=3;
- s=Black;
- w=White;
- t=255; {transparent}
- IconBorder:ARRAY[0..IconMaxY,0..IconMaxX] OF BYTE=
- (
- {0|1|2|3|4|5|6|7}
-
- (s,s,s,s,s,s,s,t),
- (s,w,w,w,w,s,t,t),
- (s,w,w,w,w,w,s,t),
- (s,w,w,w,w,w,w,s),
- (s,s,w,w,w,w,s,t),
- (s,t,s,w,w,s,t,t),
- (t,t,t,s,s,t,t,t)
- );
- VAR x,y:WORD;
- BEGIN
- DrawBasicBox;
- WITH Menu[globalI] DO
- BEGIN
- SetColor(BestBlack);
- Line(x1+dx,y1+dy,x1+dx+30,y1+dy);
- Line(x1+dx,y1+dy,x1+dx,y1+dy+25);
- Rectangle(x1+dx+3,y1+dy+3,x1+dx+3+9,y1+dy+3+8);
- Rectangle(x1+dx+3+18,y1+dy+3+15,x1+dx+3+18+9,y1+dy+3+15+8);
- FOR y:=0 TO IconMaxY DO
- FOR x:=0 TO IconMaxX DO
- CASE IconBorder[y,x] OF
- t:BEGIN END;
- s:PutPixel(x1+x+dx+14,y1+y+dy+12,BestBlack);
- w:PutPixel(x1+x+dx+14,y1+y+dy+12,BestWhite);
- END;
- END;
- END;
-
- {----------Maus-Routinen----------}
- CONST MouseMoved=1;
- LeftButtonPressed=2;
- LeftButtonReleased=4;
- RightButtonPressed=8;
- RightButtonReleased=16;
- w=White;
- b=Black;
- t=255; {durchsichtig}
- SuppressMouse:BOOLEAN=FALSE;
- TYPE MausCursor=RECORD
- data:ARRAY[0..CursorMaxY,0..CursorMaxX] OF BYTE;
- hotX,hotY:BYTE;
- END;
-
- CONST CursorPfeil:MausCursor=
- ( data:(
- (w,b,t,t,t,t,t,t,t,t,t,t),
- (w,w,b,t,t,t,t,t,t,t,t,t),
- (w,w,w,w,b,t,t,t,t,t,t,t),
- (w,w,w,w,w,b,t,t,t,t,t,t),
- (w,w,w,w,w,w,w,b,t,t,t,t),
- (w,w,w,w,w,w,w,w,b,t,t,t),
- (w,w,w,w,w,w,w,w,w,w,b,t),
- (w,w,w,w,w,w,w,w,w,w,w,b),
- (w,w,w,t,w,w,w,b,t,t,t,t),
- (w,w,t,t,t,w,w,w,b,t,t,t),
- (t,t,t,t,t,w,w,w,b,t,t,t),
- (t,t,t,t,t,t,w,w,w,b,t,t),
- (t,t,t,t,t,t,w,w,w,b,t,t),
- (t,t,t,t,t,t,t,w,w,t,t,t));
- hotx:0; hoty:0);
-
- CursorKreuz:MausCursor=
- ( data:(
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (w,w,w,t,t,t,w,w,w,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,w,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t),
- (t,t,t,t,t,t,t,t,t,t,t,t));
- hotx:4; hoty:4);
-
- VAR Aufrufmaske,Maustasten:WORD;
- MausX,MausY,MausAbsX,MausAbsY:INTEGER;
- mouseX2,mouseY2:INTEGER; {interne Mauskoordinaten}
- MouseMemSize:WORD; {Größe des MouseMem-Speichers}
- oldMouse:RECORD
- MouseMem:POINTER; {Speicher für Mauscursordaten}
- oldX,oldY:WORD; {alte Mauskoordinaten}
- END;
- MouseUpdate:BOOLEAN;
- LeftButton,RightButton:BOOLEAN;
- regs:REGISTERS;
-
- FUNCTION min(a,b:INTEGER):INTEGER;
- BEGIN
- IF a<=b THEN min:=a ELSE min:=b
- END;
-
- FUNCTION max(a,b:INTEGER):INTEGER;
- BEGIN
- IF a>=b THEN max:=a ELSE max:=b
- END;
-
- FUNCTION min3(a,b,c:INTEGER):INTEGER;
- BEGIN
- min3:=min(a,min(b,c))
- END;
-
- FUNCTION max3(a,b,c:INTEGER):INTEGER;
- BEGIN
- max3:=max(a,max(b,c))
- END;
-
- FUNCTION InWorkArea:BOOLEAN;
- { in: MausX,MausY = momentane Mauskoordinaten}
- { WorkStartX|Y, WorkEndX|Y = Koord. der Workarea}
- {out: TRUE|FALSE, wenn Mauscursor in Workarea}
- BEGIN
- InWorkArea:=(WorkStartX<=MausX) AND (MausX<=WorkEndX) AND
- (WorkStartY<=MausY) AND (MausY<=WorkEndY)
- END;
-
- FUNCTION MouseEvent(VAR menu):BYTE;
- { in: MausX,MausY = aktuelle Mausposition}
- { LeftButton, RightButton = TRUE, wenn Mausbutton gedrückt}
- { Shift = TRUE, falls Shifttaste während des Mausclicks gedrückt }
- { worden ist}
- { menu = Array vom Typ "boxes", das die Menuboxkoordinaten enthält}
- { EventNone = Rückgabewert, falls Maus in keinem der Felder steht }
- {out: Der Index desjenigen "menu"-Eintrages, in dem die Maus steht; }
- { sollte dies keiner sein, so wird "EventNone"=0 zurückgegeben }
- {rem: Das Ende der Menueinträge muß durch einen Eintrag mit x1>x2 an- }
- { gegeben werden!}
- VAR i:BYTE;
- a:boxes ABSOLUTE menu;
- BEGIN
- i:=1;
- WHILE (a[i].x1<=a[i].x2) DO
- BEGIN
- WITH a[i] DO
- IF (x1<=MausX) AND (MausX<=x2) AND (y1<=MausY) AND (MausY<=y2)
- AND ( (NOT click) OR (LeftButton OR RightButton) )
- THEN BEGIN
- IF NOT Shift THEN MouseEvent:=Event
- ELSE CASE Event OF
- EventMapPalette :MouseEvent:=EventMapToBIOSPalette;
- EventLadePalette:MouseEvent:=EventResetColors;
- else MouseEvent:=Event
- END;
-
- exit
- END
- ELSE INC(i)
- END;
- MouseEvent:=EventNone;
- END;
-
- PROCEDURE DrawMaus(VAR Cursor:MausCursor);
- { in: Cursor = aktueller, anzuzeigender Mauscursor}
- { MausX,MausY = Koordinaten für Mauscursor}
- { oldMouse.MouseMem^ = Platz für Grafikausschnitt unter Mauscursor}
- {out: oldMouse.* = gerettete Grafikdaten}
- {rem: Der Speicherplatz MouseMem^ muß bereits reserviert worden sein }
- { Obwohl die Routine "Cursor" nicht verändert, wird als VAR-Para- }
- { meter übergeben, da dann nur ein Zeiger übergeben wird!}
- VAR i,j,xr,yr:WORD;
- BEGIN
- WITH Cursor DO
- BEGIN
- xr:=max(MausX-hotx,0); yr:=max(MausY-hoty,0); {nur Onscreen-Teile retten!}
- GetImage(xr,yr,xr+CursorMaxX,yr+CursorMaxY,oldMouse.MouseMem^);
- oldMouse.oldx:=xr; oldMouse.oldY:=yr;
- FOR i:=0 TO CursorMaxX DO
- FOR j:=0 TO CursorMaxY DO
- IF data[j,i]=Black THEN PutPixel(xr+i,yr+j,BestBlack)
- ELSE IF data[j,i]=White THEN PutPixel(xr+i,yr+j,BestWhite)
- END;
- END;
-
- PROCEDURE UnDrawMaus;
- { in: oldMouse.* = zu restaurierende Grafikdaten}
- BEGIN
- WITH oldMouse DO PutImage(oldX,oldY,MouseMem^,NormalPut)
- END;
-
- FUNCTION MouseInstalled : Boolean;
- { in: - }
- {out: TRUE|FALSE für: Maus gefunden/nicht gefunden}
- VAR INT33h:POINTER;
- BEGIN
- GetIntVec($33,INT33h);
- IF (BYTE(INT33h^)=$CF) OR (LONGINT(INT33h)=0)
- THEN MouseInstalled:=FALSE {nur IRET oder Nullpointer}
- ELSE BEGIN {INT33h führt nicht ins Nirwana, trau dich!}
- WRITELN(10);
- (* regs.ax := 0; {Ja hallo, gibt's hier ne Maus im System?}
- Intr($33,regs);
- MouseInstalled:=(regs.ax=$FFFF); *)
- ASM
- PUSHF
- CLI
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,0
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- STI
- POPF
-
- CMP AX,$FFFF
- JNE @noMouse
- MOV @Result,TRUE
- JMP @done
- @noMouse:
- MOV @Result,FALSE
- @done:
- END;
- WRITELN(9);
- END;
- END;
-
- PROCEDURE DisableMouse;
- inline($B0/<BYTE(TRUE)/ {MOV AL,TRUE}
- $A2/SuppressMouse); {MOV SuppressMouse,AL}
-
- PROCEDURE EnableMouse;
- inline($B0/<BYTE(FALSE)/ {MOV AL,FALSE}
- $A2/SuppressMouse); {MOV SuppressMouse,AL}
-
- PROCEDURE ClearMouse;
- BEGIN
- MouseUpdate:=FALSE; LeftButton:=FALSE; RightButton:=FALSE;
- EnableMouse;
- END;
-
- {$S-}
- PROCEDURE MouseCallBack; FAR;
- { in: mouseX2,mouseY2 = alte Mauskoordinaten}
- { SuppressMouse = TRUE falls Mausereignis ignoriert werden soll}
- { MausMinX,MausMinY = minimal zulässige Mauskoordinaten}
- { MausMaxX,MausMaxY = maximal zulässige Mauskoordinaten}
- {out: Falls SuppressMouse=FALSE war, wurden folgende Variablen neugesetzt:}
- { MouseUpdate = TRUE}
- { MPressed = TRUE, falls linker Button gedrückt}
- { Shift = TRUE, falls eine der Shifttasten gedrückt wurde}
- { MausX,MausY = aktuelle Mauskoordinaten}
- { SuppressMouse = TRUE}
- {rem: Diese Prozedur entspricht einer Interrupt-Service-Routine, die}
- { immer dann aufgerufen wird, wenn eine der bei ihrer Initialisierung}
- { angegebenen Aufrufbedingungen erfüllt ist}
- { MouseUpdate = TRUE impliziert SuppressMouse:=TRUE, d.h.: die weitere}
- { Aktualisierung von Mausdaten ist solange gesperrt, bis die alten }
- { verarbeitet wurden und die Maus mit "EnableMouse()" wieder freige- }
- { geben wird!}
- BEGIN
- ASM
- pushf
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
- mov bp,SEG @DATA
- mov DS,bp
-
- CMP SuppressMouse,TRUE {soll Maus überhaupt behandelt werden?}
- JE @quit
-
- MOV AufrufMaske,AX
- MOV MausTasten,BX
- MOV MausX,CX
- MOV MausY,DX
- MOV MausAbsX,SI
- MOV MausAbsY,DI
-
- MOV MouseUpdate,TRUE
- MOV DX,AX
- AND AX,LeftButtonPressed
- JE @noLeftButton
- MOV LeftButton,TRUE
- @noLeftButton:
- AND DX,RightButtonPressed
- JE @noRightButton
- MOV RightButton,TRUE
- @noRightButton:
-
- XOR AX,AX {Shift-Status der Tastatur auslesen:}
- MOV ES,AX {steht in mem[$40:$17] in den untersten 2 Bits}
- MOV SI,417h
- MOV AL,ES:[SI]
- AND AL,3
- JE @noShift
- MOV Shift,TRUE
- JMP @L1
- @noShift:
- MOV Shift,FALSE
-
- @L1:
- MOV AX,11
- INT 33h {Koordinatenänderung einlesen}
- MOV AX,mouseX2 {und Mauskoordinaten aktualisieren}
- ADD AX,CX
- CMP AX,MausMinX*2 {mouseX2:=max(MausMinX*2,mouseX2)}
- JGE @noSmall1
- MOV AX,MausMinX*2
- @noSmall1:
- CMP AX,MausMaxX*2 {mouseX2:=min(MausMaxX*2,mouseX2)}
- JLE @noBig1
- MOV AX,MausMaxX*2
- @noBig1:
- MOV mouseX2,AX
- SHR AX,1 {dem doofen Treiber doch noch eine Auflösung}
- MOV MausX,AX {von 640x400 Punkten abringen}
-
- MOV AX,mouseY2
- ADD AX,DX
- CMP AX,MausMinY*2 {mouseY2:=max(MausMinY*2,mouseY2)}
- JGE @noSmall2
- MOV AX,MausMinY*2
- @noSmall2:
- CMP AX,MausMaxY*2 {mouseY2:=min(MausMaxY*2,mouseY2)}
- JLE @noBig2
- MOV AX,MausMaxY*2
- @noBig2:
- MOV mouseY2,AX
- SHR AX,1
- MOV MausY,AX
-
- MOV SuppressMouse,TRUE
-
- @quit:
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- popf
- END;
- END;
- {$S+}
-
- PROCEDURE PushAll;
- INLINE(
- $9C/ { PUSHF }
- $50/ { PUSH AX }
- $53/ { PUSH BX }
- $51/ { PUSH CX }
- $52/ { PUSH DX }
- $56/ { PUSH SI }
- $57/ { PUSH DI }
- $55/ { PUSH BP }
- $06/ { PUSH ES }
- $1E); { PUSH DS }
-
- PROCEDURE PopAll;
- INLINE(
- $1F/ { POP DS }
- $07/ { POP ES }
- $5D/ { POP BP }
- $5F/ { POP DI }
- $5E/ { POP SI }
- $5A/ { POP DX }
- $59/ { POP CX }
- $5B/ { POP BX }
- $58/ { POP AX }
- $9D); { POPF }
-
- PROCEDURE initmouse;
- { in: MausMaxX,MausMaxY = max. zulässige Mausbildschirmkoordinaten}
- { MausCallBack = Maus-Event-Handler (FAR-Prozedur!) }
- {out: mouseX|Y2=MausMinX|Y*2, MausX|Y=MausMinX|Y}
- { Koordinatenbereich für Maus wurde entsprechend initialisert }
- { MausCallBack wird bei jeder Mausbewegung/Buttonbetätigung gerufen}
- { Maus ist "abgeschaltet" und muß erst mit "EnableMouse" aktiviert }
- { werden}
- {rem: Vorhandensein einer Maus muß vorher geprüft worden sein}
- { Koordinatenbereich wird verdoppelt, um Maustreiber eine echte }
- { Auflösung 0..MausMaxX,0..MausMaxY in Einerschritten abzuringen}
- BEGIN
- writeln(8);
-
- DisableMouse;
- mouseX2:=MausMinX*2; mouseY2:=MausMinY*2;
- MausX:=mouseX2 SHR 1; MausY:=mouseY2 SHR 1;
- MouseUpdate:=FALSE; LeftButton:=FALSE; RightButton:=FALSE;
-
- writeln(7);
-
- ASM (* regs.ax := 0; Intr($33,regs); {Maustreiber initialisieren} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,0
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
-
- writeln(6);
-
- ASM (* regs.ax := 2; Intr($33,regs); {Cursor aus} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,2
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
- writeln(5);
-
- ASM (* regs.ax := 4; regs.cx := 0; regs.dx := 0; *)
- (* Intr($33,regs); {Maus in die obere linke Ecke setzen...} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,4
- mov cx,0
- mov dx,0
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
- Writeln(4);
-
- ASM (* regs.ax := 7; regs.cx := 0; regs.dx := MausMaxX*2; *)
- (* Intr($33,regs); {x-Koordinatenbereich definieren} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,7
- mov cx,0
- mov dx,MausMaxX*2
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
- Writeln(3);
-
- ASM (* regs.ax := 8; regs.cx := 0; regs.dx := MausMaxY*2; *)
- (* Intr($33,regs); {y-Koordinatenbereich definieren} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,8
- mov cx,0
- mov dx,MausMaxY*2
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
- writeln(2);
-
- ASM (* regs.ax := 12; *)
- (* regs.cx := MouseMoved OR LeftButtonPressed OR RightButtonPressed; *)
- (* regs.es := seg(MouseCallBack); regs.dx := ofs(MouseCallBack); *)
- (* intr($33,regs); {Eigenen ISR installieren} *)
- PUSHF
- CLI
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH BP
- PUSH ES
- PUSH DS
-
- mov ax,12
- mov cx,MouseMoved OR LeftButtonPressed OR RightButtonPressed
- mov dx,SEG MouseCallBack
- mov es,dx
- mov dx,OFFSET MouseCallBack
- int 33h
-
- POP DS
- POP ES
- POP BP
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- STI
- POPF
- END;
-
- writeln(1);
- END;
-
- {------- noch ein paar Popup-Boxen definieren: --------}
- CONST ButtonWidth=(SizeOf(ButtonStringTyp)-1)*8; {Länge einer Textbox}
- EventOk=100;
- abfrage:ARRAY[1..2] OF box=(
- {"Ok"-Box:}
- (x1:0; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventOk;
- Click:TRUE; {Anclicken nötig}
- Paint:FALSE), {zeichnen tun wir selber!}
-
- {Sentinelwert, da x1>x2!}
- (x1:1; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNone;
- Click:TRUE;
- Paint:TRUE)
- );
-
- {-------------------}
-
- EventYes=101;
- EventNo=102;
- alternative:ARRAY[1..3] OF box=(
- {"Ja"/"Nein"-Box:}
- {"Ja"-Box:}
- (x1:0; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventYes;
- Click:TRUE; {Anclicken nötig}
- Paint:FALSE), {zeichnen tun wir selber!}
-
- {"Nein"-Box:}
- (x1:0; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNo;
- Click:TRUE;
- Paint:FALSE),
-
- {Sentinelwert, da x1>x2!}
- (x1:1; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNone;
- Click:TRUE;
- Paint:TRUE)
- );
-
- {-------------------}
- EventCancel=103;
- FarbenWahl:ARRAY[1..4] OF box=(
- {Cancel/Workarea/Palettenbereich-Abfrage:}
-
- {"Nein"-Box:}
- (x1:0; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventCancel;
- Click:TRUE;
- Paint:FALSE),
-
- {Workarea:}
- (x1:WorkStartX; y1:WorkStartY;
- x2:WorkEndX; y2:WorkEndY;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventInWorkArea;
- Click:FALSE; {Anclicken nicht nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Palettenbereich:}
- (x1:PaletteX+25; y1:PaletteY+10;
- x2:PaletteX+25+16*PalBreite-3; y2:PaletteY+10+16*PalHoehe-3;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventSelectColor;
- Click:TRUE; {Anclicken nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Sentinelwert, da x1>x2!}
- (x1:1; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNone;
- Click:TRUE;
- Paint:TRUE)
- );
- {-------------------}
-
- VAR oldGraph:pointer;
- oldGraphSize:WORD;
-
- PROCEDURE DrawOkBox(x1,y1,x2,y2:WORD; Text1:ButtonStringTyp;
- s1,s2,s3:STRING; VAR menu);
- { in: s1|s2|s3 = auszugebende Strings}
- { Text1 = beschriftung für anzuzeigenden Button}
- { x1,y1 = linke obere Ecke der Meldungsbox (absolute Koord.) }
- { x2,y2 = rechte untere Ecke der Meldungsbox (absolute Koord.)}
- { menu = auszugebende Menubox}
- {out: oldGraph^ = alter Inhalt unter Meldebox}
- { oldGraphSize = deren Größe}
- { menu = um Koordinaten erweiterte Menubox (=für }
- { AskOkBox() vorbereitet}
- {rem: Grafikmodus muß bereits aktiv sein!}
- { Length(s1|s2|s3)*8 >= x2-x1+1 !}
- { Der Meldungsboxbereich muß kleiner als 64K sein!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- VAR BoxBreite,BoxHoehe,disx,disy:INTEGER;
- x,y:WORD;
- mymenu:ARRAY[1..10] OF box ABSOLUTE menu;
- BEGIN
- {alte Grafik sichern:}
- oldGraphSize:=ImageSize(x1,y1,x2,y2);
- GetMem(oldGraph,oldGraphSize);
- GetImage(x1,y1,x2,y2,oldGraph^);
-
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
-
- BoxBreite:=Succ(x2-x1); BoxHoehe:=Succ(y2-y1);
- SetColor(BestBlack);
- y:=y1+10;
- IF s1<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s1) SHL 3)) SHR 1,y,s1);
- INC(y,10);
- END;
- IF s2<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s2) SHL 3)) SHR 1,y,s2);
- INC(y,10);
- END;
- IF s3<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s3) SHL 3)) SHR 1,y,s3);
- INC(y,10);
- END;
-
- disx:=(BoxBreite-ButtonWidth) DIV 2;
- disy:=(BoxHoehe-(y-y1)) DIV 4;
- mymenu[1].x1:=x1+disx; mymenu[1].y1:=y+disy;
- mymenu[1].x2:=x2-disx; mymenu[1].y2:=y2-disy;
-
- {Jetzt die Box einzeichnen:}
- y:=y+disy + ((y2-disy)-(y+disy)-8) SHR 1; {für's zentrieren des Textes...}
- WITH mymenu[1] DO
- BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
- OutTextXY(x1+ (ButtonWidth-(Length(Text1) SHL 3)) SHR 1,y,Text1);
- END;
- END;
-
- PROCEDURE AskOkBox(x1,y1:WORD; VAR menu);
- { in: menu = komplett ausgefüllte Menubox}
- { oldGraph^ = alte Grafikdaten}
- { oldGraphSize = deren Größe }
- {out: Event = aufgetretenes Event }
- {rem: Maus wird freigegeben, um lokales Menu bearbeiten zu können!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- VAR mymenu:ARRAY[1..10] OF box ABSOLUTE menu;
- BEGIN;
- DrawMaus(CursorPfeil);
- Event:=EventNone;
-
- {Maus freigeben:}
- ClearMouse;
-
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- Event:=MouseEvent(mymenu);
- IF (Event=EventNone)
- THEN BEGIN {das war nichts, nochmal!}
- DrawMaus(CursorPfeil);
- ClearMouse;
- END;
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(x1,y1,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
- END;
-
- PROCEDURE OkBox(x1,y1,x2,y2:WORD; Text1:ButtonStringTyp;
- s1,s2,s3:STRING; VAR menu);
- { in: s1|s2|s3 = auszugebende Strings}
- { x1,y1 = linke obere Ecke der Meldungsbox (absolute Koord.) }
- { x2,y2 = rechte untere Ecke der Meldungsbox (absolute Koord.)}
- { Text1 = Beschriftung für auszugebenden Button}
- { menu = auszugebende Ok-Box}
- {out: (In menu wurden die Koordinaten verändert, was aber ohne Bedeutung}
- { sein sollte, da die übergebenen Menus eh nur für diesen Zweck ge- }
- { dacht sind)}
- { Event = aufgetretenes Event}
- {rem: Grafikmodus muß bereits aktiv sein!}
- { Length(s1|s2|s3)*8 >= x2-x1+1 !}
- { Maus wird freigegeben, um lokales Menu bearbeiten zu können!}
- { Der Meldungsboxbereich muß kleiner als 64K sein!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- BEGIN
- DrawOkBox(x1,y1,x2,y2,Text1,s1,s2,s3,menu);
- AskOkBox(x1,y1,menu);
- END;
-
- PROCEDURE DrawFirstOfTwoBoxes(x1,y1,x2,y2:WORD;
- Text1,Text2:ButtonStringTyp;
- s1,s2,s3:STRING;
- VAR menu);
- { in: s1|s2|s3 = auszugebende Strings}
- { Text1|2 = Beschriftung der beiden Buttons}
- { x1,y1 = linke obere Ecke der Meldungsbox (absolute Koord.) }
- { x2,y2 = rechte untere Ecke der Meldungsbox (absolute Koord.)}
- { menu = auszugebndes Menu}
- {out: TRUE|FALSE für erste|zweite Box angeclickt}
- { menu = um Koordinaten erweitertes Menu}
- {rem: Grafikmodus muß bereits aktiv sein!}
- { Length(s1|s2|s3)*8 >= x2-x1+1 !}
- { Maus wird freigegeben, um lokales Menu bearbeiten zu können!}
- { Der Meldungsboxbereich muß kleiner als 64K sein!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- VAR BoxBreite,BoxHoehe,disx,disy:INTEGER;
- x,y:WORD;
- mymenu:ARRAY[1..10] OF box ABSOLUTE menu;
- BEGIN
- {alte Grafik sichern:}
- oldGraphSize:=ImageSize(x1,y1,x2,y2);
- GetMem(oldGraph,oldGraphSize);
- GetImage(x1,y1,x2,y2,oldGraph^);
-
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
-
- BoxBreite:=Succ(x2-x1); BoxHoehe:=Succ(y2-y1);
- SetColor(BestBlack);
- y:=y1+10;
- IF s1<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s1) SHL 3)) SHR 1,y,s1);
- INC(y,10);
- END;
- IF s2<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s2) SHL 3)) SHR 1,y,s2);
- INC(y,10);
- END;
- IF s3<>''
- THEN BEGIN
- OutTextXY(x1+ (BoxBreite -(Length(s3) SHL 3)) SHR 1,y,s3);
- INC(y,10);
- END;
-
- disx:=(BoxBreite-(ButtonWidth SHL 1)) DIV 3;
- disy:=(BoxHoehe-(y-y1)) DIV 4;
- mymenu[1].x1:=x1+disx; mymenu[1].y1:=y+disy;
- mymenu[1].x2:=x1+disx+ButtonWidth; mymenu[1].y2:=y2-disy;
-
- mymenu[2].x1:=x2-disx-ButtonWidth; mymenu[2].y1:=y+disy;
- mymenu[2].x2:=x2-disx; mymenu[2].y2:=y2-disy;
-
- {Jetzt die beiden Boxen einzeichnen:}
- y:=y+disy + ((y2-disy)-(y+disy)-8) SHR 1; {für's zentrieren des Textes...}
- WITH mymenu[1] DO
- BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
- OutTextXY(x1+ (ButtonWidth-(Length(Text1) SHL 3)) SHR 1,y,Text1);
- END;
-
- WITH mymenu[2] DO
- BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
- OutTextXY(x1+ (ButtonWidth-(Length(Text2) SHL 3)) SHR 1,y,Text2);
- END;
-
- DrawMaus(CursorPfeil);
- {Maus freigeben:}
- ClearMouse;
- END;
-
- FUNCTION AskFirstOfTwoBoxes(x1,y1:WORD; Text1,Text2:ButtonStringTyp;
- VAR menu):BOOLEAN;
- { in: menu = komplett ausgefüllte Menubox}
- { oldGraph^ = alte Grafikdaten}
- { oldGraphSize = deren Größe }
- {out: Event = aufgetretenes Event }
- {rem: Maus wird freigegeben, um lokales Menu bearbeiten zu können!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- VAR ch:CHAR;
- mymenu:ARRAY[1..10] OF box ABSOLUTE menu;
- BEGIN
- Event:=EventNone;
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- Event:=MouseEvent(mymenu);
- IF (Event=EventNone)
- THEN BEGIN {das war nichts, nochmal!}
- DrawMaus(CursorPfeil);
- ClearMouse;
- END;
- END
- ELSE IF (KeyPressed) AND (Upcase(Text1[1])<>Upcase(Text2[1])) THEN
- BEGIN
- WHILE KeyPressed DO ch:=Upcase(ReadKey);
- IF ch=Upcase(Text1[1]) THEN Event:=mymenu[1].Event
- ELSE IF ch=Upcase(Text2[1]) THEN Event:=mymenu[2].Event;
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(x1,y1,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
-
- AskFirstOfTwoBoxes:=Event=EventYes
- END;
-
- FUNCTION FirstOfTwoBoxes(x1,y1,x2,y2:WORD;
- Text1,Text2:ButtonStringTyp;
- s1,s2,s3:STRING;
- VAR menu):BOOLEAN;
- { in: s1|s2|s3 = auszugebende Strings}
- { Text1|2 = Beschriftung der beiden Buttons}
- { x1,y1 = linke obere Ecke der Meldungsbox (absolute Koord.) }
- { x2,y2 = rechte untere Ecke der Meldungsbox (absolute Koord.)}
- { menu = auszugebendes Menu}
- {out: TRUE|FALSE für erste|zweite Box angeclickt}
- { (In "menu" wurden die Koordinaten verändert, was aber keine }
- { Probleme verursachen sollte, da die übergebenen Menus eh nur}
- { für diesen Zweck gedacht sind)}
- { Event = aufgetretenes Event}
- {rem: Grafikmodus muß bereits aktiv sein!}
- { Length(s1|s2|s3)*8 >= x2-x1+1 !}
- { Maus wird freigegeben, um lokales Menu bearbeiten zu können!}
- { Der Meldungsboxbereich muß kleiner als 64K sein!}
- { Das Menu darf höchstens aus 10 Boxen bestehen}
- BEGIN
- DrawFirstOfTwoBoxes(x1,y1,x2,y2,Text1,Text2,s1,s2,s3,menu);
- FirstOfTwoBoxes:=AskFirstOfTwoBoxes(x1,y1,Text1,Text2,menu);
- END;
-
- {-----Hintergrundbildspeicher: -----------}
- CONST XMAX=319; {Abmessungen einer Hintergrunddatei}
- YMAX=199;
- LINESIZE=(XMAX+1) DIV 4; {Groesse einer Zeile=80 Bytes}
- PAGESIZE=(YMAX+1)*LINESIZE; {200 Zeilen zu je 320/4 Bytes}
- TYPE bitmap=ARRAY[0..PAGESIZE-1] OF BYTE;
- bitmapPtr=^bitmap;
- bild=ARRAY[0..3] OF bitmapPtr;
- VAR WorkArea:^WorkAreatyp;
- CONST WorkAreaMaxUsedX:INTEGER=0; {Hilfsvariablen für schnelleres Zeichnen:}
- WorkAreaMaxUsedY:INTEGER=0; {welches sind die Extremkoord. des Bildes}
-
- {-----Fehlerbehandlung: ------------------}
- CONST {Fehlercodes des Animationspaketes: }
- ErrNone=0;
- ErrNotEnoughMemory=1;
- ErrFileIO=2;
- ErrInvalidSpriteNumber=3;
- ErrNoSprite=4;
- ErrInvalidPageNumber=5;
- ErrNoVGA=6;
- ErrNoPicture=7;
- ErrInvalidPercentage=8;
- ErrNoTile=9;
- ErrInvalidTileNumber=10;
- ErrInvalidCoordinates=11;
- ErrBackgroundToBig=12;
- ErrInvalidMode=13;
- ErrInvalidSpriteLoadNumber=14;
- ErrNoPalette=15;
- ErrPaletteWontFit=16;
-
- Error:BYTE=ErrNone;
-
- FUNCTION GetErrorMessage:STRING;
- { in: Error = Nummer des aufgetretenen Fehlers}
- {out: den Fehler in Worten}
- BEGIN
- CASE Error OF
- ErrNone:GetErrorMessage:='No Error';
- ErrNotEnoughMemory:GetErrorMessage:='Not enough memory available on heap';
- ErrFileIO:GetErrorMessage:='I/O-error with file';
- ErrInvalidSpriteNumber:GetErrorMessage:='Invalid sprite number used';
- ErrNoSprite:GetErrorMessage:='No (or corrupted) sprite file';
- ErrInvalidPageNumber:GetErrorMessage:='Invalid page number used';
- ErrNoVGA:GetErrorMessage:='No VGA-card found';
- ErrNoPicture:GetErrorMessage:='No (or corrupted) picture file';
- ErrInvalidPercentage:GetErrorMessage:='Percentage value must be 0..100';
- ErrNoTile:GetErrorMessage:='No (or corrupted) tile/sprite file';
- ErrInvalidTileNumber:GetErrorMessage:='Invalid tile number used';
- ErrInvalidCoordinates:GetErrorMessage:='Invalid coordinates used';
- ErrBackgroundToBig:GetErrorMessage:='Background too big for tile-buffer';
- ErrInvalidMode:GetErrorMessage:='Only STATIC or SCROLLING allowed here';
- ErrInvalidSpriteLoadNumber:GetErrorMessage:='Invalid spriteload number used';
- ErrNoPalette:GetErrorMessage:='No (or corrupted) palette file';
- ErrPaletteWontFit:GetErrorMessage:='Palette indexes must be <256';
- ELSE GetErrorMessage:='Unknown error';
- END;
- END;
-
- {-----Palette: --------------------------}
- TYPE PaletteEntry=RECORD red,green,blue:BYTE END;
- BigPalette=ARRAY[0..255] OF PaletteEntry;
- PalettePtr=^BigPalette;
- SmallPalette=ARRAY[0..15] OF BYTE;
- CONST DefaultColors:BigPalette= {Defaultfarben-Palette; erste 16-Farben}
- ( {sind identisch zu 16-Farbmodi-Farben! }
- (red: 0; green: 0; blue: 0), {Black}
- (red: 0; green: 0; blue: 42), {Blue }
- (red: 0; green: 42; blue: 0), {Green}
- (red: 0; green: 42; blue: 42), {Cyan }
- (red: 42; green: 0; blue: 0), {Red }
- (red: 42; green: 0; blue: 42), {Magenta }
- (red: 42; green: 21; blue: 0), {Brown}
- (red: 42; green: 42; blue: 42), {LightGray }
- (red: 21; green: 21; blue: 21), {DarkGray }
- (red: 21; green: 21; blue: 63), {LightBlue }
- (red: 21; green: 63; blue: 21), {LightGreen}
- (red: 21; green: 63; blue: 63), {LightCyan }
- (red: 63; green: 21; blue: 21), {LightRed }
- (red: 63; green: 21; blue: 63), {LightMagenta}
- (red: 63; green: 63; blue: 21), {Yellow}
- (red: 63; green: 63; blue: 63), {White }
- (red: 0; green: 0; blue: 0),
- (red: 5; green: 5; blue: 5),
- (red: 8; green: 8; blue: 8),
- (red: 11; green: 11; blue: 11),
- (red: 14; green: 14; blue: 14),
- (red: 17; green: 17; blue: 17),
- (red: 20; green: 20; blue: 20),
- (red: 24; green: 24; blue: 24),
- (red: 28; green: 28; blue: 28),
- (red: 32; green: 32; blue: 32),
- (red: 36; green: 36; blue: 36),
- (red: 40; green: 40; blue: 40),
- (red: 45; green: 45; blue: 45),
- (red: 50; green: 50; blue: 50),
- (red: 56; green: 56; blue: 56),
- (red: 63; green: 63; blue: 63),
- (red: 0; green: 0; blue: 63),
- (red: 16; green: 0; blue: 63),
- (red: 31; green: 0; blue: 63),
- (red: 47; green: 0; blue: 63),
- (red: 63; green: 0; blue: 63),
- (red: 63; green: 0; blue: 47),
- (red: 63; green: 0; blue: 31),
- (red: 63; green: 0; blue: 16),
- (red: 63; green: 0; blue: 0),
- (red: 63; green: 16; blue: 0),
- (red: 63; green: 31; blue: 0),
- (red: 63; green: 47; blue: 0),
- (red: 63; green: 63; blue: 0),
- (red: 47; green: 63; blue: 0),
- (red: 31; green: 63; blue: 0),
- (red: 16; green: 63; blue: 0),
- (red: 0; green: 63; blue: 0),
- (red: 0; green: 63; blue: 16),
- (red: 0; green: 63; blue: 31),
- (red: 0; green: 63; blue: 47),
- (red: 0; green: 63; blue: 63),
- (red: 0; green: 47; blue: 63),
- (red: 0; green: 31; blue: 63),
- (red: 0; green: 16; blue: 63),
- (red: 31; green: 31; blue: 63),
- (red: 39; green: 31; blue: 63),
- (red: 47; green: 31; blue: 63),
- (red: 55; green: 31; blue: 63),
- (red: 63; green: 31; blue: 63),
- (red: 63; green: 31; blue: 55),
- (red: 63; green: 31; blue: 47),
- (red: 63; green: 31; blue: 39),
- (red: 63; green: 31; blue: 31),
- (red: 63; green: 39; blue: 31),
- (red: 63; green: 47; blue: 31),
- (red: 63; green: 55; blue: 31),
- (red: 63; green: 63; blue: 31),
- (red: 55; green: 63; blue: 31),
- (red: 47; green: 63; blue: 31),
- (red: 39; green: 63; blue: 31),
- (red: 31; green: 63; blue: 31),
- (red: 31; green: 63; blue: 39),
- (red: 31; green: 63; blue: 47),
- (red: 31; green: 63; blue: 55),
- (red: 31; green: 63; blue: 63),
- (red: 31; green: 55; blue: 63),
- (red: 31; green: 47; blue: 63),
- (red: 31; green: 39; blue: 63),
- (red: 45; green: 45; blue: 63),
- (red: 49; green: 45; blue: 63),
- (red: 54; green: 45; blue: 63),
- (red: 58; green: 45; blue: 63),
- (red: 63; green: 45; blue: 63),
- (red: 63; green: 45; blue: 58),
- (red: 63; green: 45; blue: 54),
- (red: 63; green: 45; blue: 49),
- (red: 63; green: 45; blue: 45),
- (red: 63; green: 49; blue: 45),
- (red: 63; green: 54; blue: 45),
- (red: 63; green: 58; blue: 45),
- (red: 63; green: 63; blue: 45),
- (red: 58; green: 63; blue: 45),
- (red: 54; green: 63; blue: 45),
- (red: 49; green: 63; blue: 45),
- (red: 45; green: 63; blue: 45),
- (red: 45; green: 63; blue: 49),
- (red: 45; green: 63; blue: 54),
- (red: 45; green: 63; blue: 58),
- (red: 45; green: 63; blue: 63),
- (red: 45; green: 58; blue: 63),
- (red: 45; green: 54; blue: 63),
- (red: 45; green: 49; blue: 63),
- (red: 0; green: 0; blue: 28),
- (red: 7; green: 0; blue: 28),
- (red: 14; green: 0; blue: 28),
- (red: 21; green: 0; blue: 28),
- (red: 28; green: 0; blue: 28),
- (red: 28; green: 0; blue: 21),
- (red: 28; green: 0; blue: 14),
- (red: 28; green: 0; blue: 7),
- (red: 28; green: 0; blue: 0),
- (red: 28; green: 7; blue: 0),
- (red: 28; green: 14; blue: 0),
- (red: 28; green: 21; blue: 0),
- (red: 28; green: 28; blue: 0),
- (red: 21; green: 28; blue: 0),
- (red: 14; green: 28; blue: 0),
- (red: 7; green: 28; blue: 0),
- (red: 0; green: 28; blue: 0),
- (red: 0; green: 28; blue: 7),
- (red: 0; green: 28; blue: 14),
- (red: 0; green: 28; blue: 21),
- (red: 0; green: 28; blue: 28),
- (red: 0; green: 21; blue: 28),
- (red: 0; green: 14; blue: 28),
- (red: 0; green: 7; blue: 28),
- (red: 14; green: 14; blue: 28),
- (red: 17; green: 14; blue: 28),
- (red: 21; green: 14; blue: 28),
- (red: 24; green: 14; blue: 28),
- (red: 28; green: 14; blue: 28),
- (red: 28; green: 14; blue: 24),
- (red: 28; green: 14; blue: 21),
- (red: 28; green: 14; blue: 17),
- (red: 28; green: 14; blue: 14),
- (red: 28; green: 17; blue: 14),
- (red: 28; green: 21; blue: 14),
- (red: 28; green: 24; blue: 14),
- (red: 28; green: 28; blue: 14),
- (red: 24; green: 28; blue: 14),
- (red: 21; green: 28; blue: 14),
- (red: 17; green: 28; blue: 14),
- (red: 14; green: 28; blue: 14),
- (red: 14; green: 28; blue: 17),
- (red: 14; green: 28; blue: 21),
- (red: 14; green: 28; blue: 24),
- (red: 14; green: 28; blue: 28),
- (red: 14; green: 24; blue: 28),
- (red: 14; green: 21; blue: 28),
- (red: 14; green: 17; blue: 28),
- (red: 20; green: 20; blue: 28),
- (red: 22; green: 20; blue: 28),
- (red: 24; green: 20; blue: 28),
- (red: 26; green: 20; blue: 28),
- (red: 28; green: 20; blue: 28),
- (red: 28; green: 20; blue: 26),
- (red: 28; green: 20; blue: 24),
- (red: 28; green: 20; blue: 22),
- (red: 28; green: 20; blue: 20),
- (red: 28; green: 22; blue: 20),
- (red: 28; green: 24; blue: 20),
- (red: 28; green: 26; blue: 20),
- (red: 28; green: 28; blue: 20),
- (red: 26; green: 28; blue: 20),
- (red: 24; green: 28; blue: 20),
- (red: 22; green: 28; blue: 20),
- (red: 20; green: 28; blue: 20),
- (red: 20; green: 28; blue: 22),
- (red: 20; green: 28; blue: 24),
- (red: 20; green: 28; blue: 26),
- (red: 20; green: 28; blue: 28),
- (red: 20; green: 26; blue: 28),
- (red: 20; green: 24; blue: 28),
- (red: 20; green: 22; blue: 28),
- (red: 0; green: 0; blue: 16),
- (red: 4; green: 0; blue: 16),
- (red: 8; green: 0; blue: 16),
- (red: 12; green: 0; blue: 16),
- (red: 16; green: 0; blue: 16),
- (red: 16; green: 0; blue: 12),
- (red: 16; green: 0; blue: 8),
- (red: 16; green: 0; blue: 4),
- (red: 16; green: 0; blue: 0),
- (red: 16; green: 4; blue: 0),
- (red: 16; green: 8; blue: 0),
- (red: 16; green: 12; blue: 0),
- (red: 16; green: 16; blue: 0),
- (red: 12; green: 16; blue: 0),
- (red: 8; green: 16; blue: 0),
- (red: 4; green: 16; blue: 0),
- (red: 0; green: 16; blue: 0),
- (red: 0; green: 16; blue: 4),
- (red: 0; green: 16; blue: 8),
- (red: 0; green: 16; blue: 12),
- (red: 0; green: 16; blue: 16),
- (red: 0; green: 12; blue: 16),
- (red: 0; green: 8; blue: 16),
- (red: 0; green: 4; blue: 16),
- (red: 8; green: 8; blue: 16),
- (red: 10; green: 8; blue: 16),
- (red: 12; green: 8; blue: 16),
- (red: 14; green: 8; blue: 16),
- (red: 16; green: 8; blue: 16),
- (red: 16; green: 8; blue: 14),
- (red: 16; green: 8; blue: 12),
- (red: 16; green: 8; blue: 10),
- (red: 16; green: 8; blue: 8),
- (red: 16; green: 10; blue: 8),
- (red: 16; green: 12; blue: 8),
- (red: 16; green: 14; blue: 8),
- (red: 16; green: 16; blue: 8),
- (red: 14; green: 16; blue: 8),
- (red: 12; green: 16; blue: 8),
- (red: 10; green: 16; blue: 8),
- (red: 8; green: 16; blue: 8),
- (red: 8; green: 16; blue: 10),
- (red: 8; green: 16; blue: 12),
- (red: 8; green: 16; blue: 14),
- (red: 8; green: 16; blue: 16),
- (red: 8; green: 14; blue: 16),
- (red: 8; green: 12; blue: 16),
- (red: 8; green: 10; blue: 16),
- (red: 11; green: 11; blue: 16),
- (red: 12; green: 11; blue: 16),
- (red: 13; green: 11; blue: 16),
- (red: 15; green: 11; blue: 16),
- (red: 16; green: 11; blue: 16),
- (red: 16; green: 11; blue: 15),
- (red: 16; green: 11; blue: 13),
- (red: 16; green: 11; blue: 12),
- (red: 16; green: 11; blue: 11),
- (red: 16; green: 12; blue: 11),
- (red: 16; green: 13; blue: 11),
- (red: 16; green: 15; blue: 11),
- (red: 16; green: 16; blue: 11),
- (red: 15; green: 16; blue: 11),
- (red: 13; green: 16; blue: 11),
- (red: 12; green: 16; blue: 11),
- (red: 11; green: 16; blue: 11),
- (red: 11; green: 16; blue: 12),
- (red: 11; green: 16; blue: 13),
- (red: 11; green: 16; blue: 15),
- (red: 11; green: 16; blue: 16),
- (red: 11; green: 15; blue: 16),
- (red: 11; green: 13; blue: 16),
- (red: 11; green: 12; blue: 16),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0),
- (red: 0; green: 0; blue: 0)
- );
- VAR ActualColors, {aktuelle Farben}
- ZielPalette :BigPalette; {Zielfarben für MapPalette(), müssen im}
- {Datensegment liegen!}
-
- FUNCTION PalEqual(p1,p2:BigPalette):BOOLEAN;
- { in: p1,p2 = zu vergleichende Paletten}
- {out: p1=p2 }
- VAR i:WORD;
- flag:BOOLEAN;
- BEGIN
- i:=0;
- REPEAT
- flag:= (p1[i].red =p2[i].red)
- AND (p1[i].green=p2[i].green)
- AND (p1[i].blue =p2[i].blue);
- inc(i);
- UNTIL (i>255) OR (NOT flag);
- PalEqual:=flag
- END;
-
- PROCEDURE GetBigPalette(VAR pal:BigPalette); ASSEMBLER;
- { in: pal = Zeiger auf Palette-Speicher}
- {out: pal = momentan aktueller Inhalt der 256-Farben CLUT}
- ASM
- CLI
- XOR AL,AL
- MOV DX,3C7h
- OUT DX,AL
- LES DI,pal
- MOV CX,768
- MOV DX,3C9h
- @L1:
- IN AL,DX
- STOSB
- LOOP @L1
- STI
- END;
-
- FUNCTION BestFit(Color:BYTE):BYTE; ASSEMBLER;
- { in: Color = Farbnummer des 16 Farbmodus, die approximiert werden soll}
- { ActualColors = gerade gesetzte 256 Farben}
- { DefaultColors= Tabelle der Defaultfarben der 16 (256) Farbmodi}
- {out: Farbnummer, deren Farbe am ehesten der uebergebenen Farbe entspricht}
- {rem: von Defaultcolors werden nur die ersten 16 Eintraege benoetigt, um }
- { die Umsetzung Farbname -> RGB-Tripel machen zu koennen!}
- ASM
- MOV BL,Color
- XOR BH,BH
- MOV SI,BX
- SHL SI,1
- ADD SI,BX
- ADD SI,OFFSET DefaultColors
- MOV BX,[SI]
- MOV DH,[SI+2] {BL/BH/DH = aktuelle Farbe, RGB}
-
- PUSH BP
- MOV DI,65535 {DI=bisher gefundenes minimales Fehlerquadrat}
- MOV CX,255
- MOV SI,OFFSET ActualColors {DS:SI = Zeiger auf aktuelle Farben}
-
- @searchloop:
- MOV AL,BL
- SUB AL,[SI] {Farbdifferenz im Rotanteil}
- IMUL AL {Fehler*quadrat* optimieren}
- MOV BP,AX
-
- MOV AL,BH {dto., Gruenanteil}
- SUB AL,[SI+1]
- IMUL AL
- ADD BP,AX
- JC @noNewMin
-
- MOV AL,DH {dto., Blauanteil}
- SUB AL,[SI+2]
- IMUL AL
- ADD AX,BP
- JC @noNewMin
-
- CMP AX,DI
- JAE @noNewMin
- MOV DI,AX
- MOV DL,CL {100h-DL=bisher optimale Farbe}
- @noNewMin:
- ADD SI,3 {naechste Farbe zum Vergleich}
- LOOP @searchloop
-
- POP BP
-
- MOV AL,DL
- NOT AL {AL:=100h-DL = optimale Farbe}
- XOR AH,AH
- END;
-
- PROCEDURE SetPalette(pal:BigPalette);
- { in: pal = Zeiger auf zu setzende Palette }
- { StatusReg = Statusregister der VGA-Karte}
- {out: Best* = Farbnummern der gerade gesetzten}
- { Palette, die den Fraben am ähnlichsten sind }
- {rem: Palette wurde uebernommen}
- VAR p:PalettePtr;
- BEGIN
- p:=@pal; {Trick, da der Assembler nicht mit dem SS-Segment klarkommt}
- ASM
- mov dx,StatusReg
-
- PUSH DS
- LDS SI,p
-
- CLI
- @WaitNotVSyncLoop:
- in al,dx
- and al,8
- jnz @WaitNotVSyncLoop
- @WaitVSyncLoop:
- in al,dx
- and al,8
- jz @WaitVSyncLoop
-
- MOV DX,3C8h
- XOR AL,AL
- OUT DX,AL
- INC DX
-
- MOV CX,256
- @L1:
- LODSB
- OUT DX,AL
- LODSB
- OUT DX,AL
- LODSB
- OUT DX,AL
- LOOP @L1
-
- STI
- POP DS
- END; {of ASM}
- BestWhite:=BestFit(White);
- BestBlack:=BestFit(Black);
- BestCyan :=BestFit(Cyan);
- BestLightGray:=BestFit(LightGray);
- BestDarkGray:=BestFit(DarkGray);
- END;
-
- PROCEDURE SetPaletteEntry(nr,rot,gruen,blau:BYTE); ASSEMBLER;
- { in: nr = zu setzende Farbe}
- { rot,gruen,blau = deren RGB-Werte (0..63)}
- { StatusReg = Portadresse des VGA-Statusregisters}
- {out: - }
- {rem: Die entsprechende Farbe wurde verändert}
- ASM
- MOV AH,rot
- MOV BL,gruen
- MOV BH,blau
- MOV SI,3C8h
- MOV CL,nr
- MOV DX,StatusReg
-
- CLI
- @WaitNotHSync:
- IN AL,DX
- TEST AL,1
- JNE @WaitNotHSync
- @WaitHSync:
- IN AL,DX
- TEST AL,1
- JE @WaitHSync
-
- MOV DX,SI
- MOV AL,CL
- OUT DX,AL {Farbnr. an 3C8h}
- INC DX
- MOV AL,AH
- OUT DX,AL {rot an 3C9h}
- MOV AL,BL
- OUT DX,AL {gruen auch}
- MOV AL,BH
- OUT DX,AL {blau auch}
- STI
- END;
-
- FUNCTION LoadPalette(name:String; number:BYTE; VAR pal:BigPalette):WORD;
- { in: name = Name des zu ladenden Palette-Files (Typ: "*.PAL" )}
- { number = Nummer, die die erste Farbe aus diesem File bekommen soll }
- { ActualColors = gerade aktuelle Farbpalette}
- {out: Anzahl der aus dem File gelesenen Farben (0 = Fehler trat auf) }
- { pal = aus dem File gelesene Farbpalette, evtl. ergaenzt}
- {rem: Alle nicht ueberschriebenen Farben werden in "pal" auf die Werte der}
- { gerade aktuellen Farben "ActualColors" gesetzt; die Palette wurde }
- { nur geladen, nicht gesetzt!}
- LABEL quitloop;
- VAR len:LONGINT;
- f:File;
- i,count:WORD;
- TempPal:BigPalette;
- flag:BOOLEAN;
- BEGIN
- count:=0; {Zahl der bisher eingelesenen Paletteneinträge}
- assign(f,name);
- {$I-} reset(f,1); {$I+}
- if (ioresult<>0)
- THEN BEGIN {Datei existiert nicht oder nicht unter diesem Pfad}
- Error:=ErrFileIO;
- LoadPalette:=0; exit
- END;
- len:=filesize(f); {Dateilaenge ermitteln}
- if (len mod 3<>0) OR (len>3*256) OR (len<3)
- THEN BEGIN
- Error:=ErrNoPalette;
- goto quitloop;
- END;
- IF len+number*3>3*256
- THEN BEGIN
- Error:=ErrPaletteWontFit;
- goto quitloop;
- END;
-
- TempPal:=ActualColors; {temporaere Palette mit aktuellen Farben vorbesetzen}
- {$I-}
- blockread(f,TempPal[number],len);
- {$I+}
-
- IF (ioresult<>0)
- THEN BEGIN
- Error:=ErrFileIO;
- goto quitloop;
- END;
-
- flag:=FALSE;
- FOR i:=number TO Pred(number+(len DIV 3))
- DO flag:=flag OR (TempPal[i].red>63)
- OR (TempPal[i].green>63)
- OR (TempPal[i].blue>63);
- IF flag
- THEN BEGIN
- Error:=ErrNoPalette;
- goto quitloop;
- END;
-
- {Alles ging gut: Palette zurueckgeben}
- pal:=TempPal;
- count:=len DIV 3;
-
- quitloop: ;
- close(f);
- LoadPalette:=count
- END;
-
- PROCEDURE SavePalette(name:String; VAR pal:BigPalette);
- { in: name = Name des zu ladenden Palette-Files (Typ: "*.PAL" )}
- { pal = (teilweise) abzuspeichernde Farbpalette}
- {out: - }
- {rem: Palette "pal" wurde unter dem Namen "name" auf Disk abgespeichert}
- VAR f:FILE;
- fehler:BYTE;
- BEGIN
- assign(f,name);
- {$I-} rewrite(f,1); {$I+}
- fehler:=IOResult;
- {$I-} blockwrite(f,pal[0],SizeOf(pal)); {$I+}
- fehler:=IOResult OR fehler;
- if (fehler<>0)
- THEN BEGIN {Datei konnte nicht geschrieben werden}
- Error:=ErrFileIO;
- exit
- END;
- END;
-
- PROCEDURE FindVGARegisters; ASSEMBLER;
- { in: - }
- {out: CRTAddress = Adresse des CRT-Ports, $3B4/$3D4 für monochrom/Farbe}
- { StatusReg = dto., für Statusregister, $3BA/$3DA}
- ASM
- MOV DX,3CCh
- IN AL,DX
- TEST AL,1
- MOV DX,3D4h
- JNZ @L1
- MOV DX,3B4h
- @L1:
- MOV CRTAddress,DX
- ADD DX,6
- MOV StatusReg,DX
- END;
-
-
- {---------------------------------------------}
- var n,x,y,button:integer;
- s:String[5];
- Farbplatz:Farbeck;
- ch,ch2:Char;
- buttonzahl,i,j:Integer;
- FarbenStartX,FarbenStartY,FarbenHoehegesamt,
- Koordmeldx,Koordmeldy, {Koordinaten für X/Y-Angabe}
- FilenameStartX,FilenameStartY:Integer; {dto., für Filename}
- PalnameStartX ,PalnameStartY :Integer; {dto., für Filename}
- Filenamelang,Filenamekurz: PathStr; {Dateinamen mit/ohne Pfadangabe}
- Palnamelang ,Palnamekurz : PathStr; {Palettennnamen m/o Pfadangabe }
- Wahl:WORD;
-
-
- PROCEDURE FindWorkAreaMaxUsed;
- { in: Workarea^.* = aktuelle Grafikdaten}
- {out: WorkAreaMaxUsedX|Y = benutzte Extremkoordinaten}
- LABEL break1;
- VAR x,y:INTEGER;
- flag:BOOLEAN;
- BEGIN
- WorkAreaMaxUsedX:=0; WorkAreaMaxUsedY:=0;
-
- {max. benutzte Zeile suchen:}
- FOR y:=WorkHoehe-1 DOWNTO 0 DO
- BEGIN {Zeilen von unten nach oben durchsuchen}
- FOR x:=WorkBreite-1 DOWNTO 0 DO {Spalten von rechts nach links durchsuchen}
- IF Workarea^.feld[y,x]<>transparent
- THEN BEGIN {gesetzten Punkt gefunden!}
- WorkAreaMaxUsedY:=y;
- WorkAreaMaxUsedX:=max(WorkAreaMaxUsedX,x);
- goto break1
- END
- END;
- break1:;
-
- {nun noch max. benutzte Spalte suchen: Zeilen WorkHoehe-1..y sind bereits}
- {durchsucht, deren Maximum steht in WorkAreaMaxUsedX!}
- IF WorkAreaMaxUsedX=WorkBreite-1 THEN exit;
- FOR y:=y-1 DOWNTO 0 DO
- BEGIN
- x:=pred(WorkBreite); {von rechts nach links durchsehen}
- WHILE x>WorkAreaMaxUsedX DO {nur echte neue Maxima suchen!}
- BEGIN
- IF Workarea^.feld[y,x]<>transparent
- THEN WorkAreaMaxUsedX:=max(WorkAreaMaxUsedX,x) {damit terminiert WHILE!}
- ELSE dec(x)
- END;
- END;
-
- END;
-
-
- PROCEDURE ErrBeep;
- BEGIN
- sound(100); delay(300); nosound;
- END;
-
- function DetectVGA256 : Integer; FAR;
- begin
- DetectVGA256 := 0
- end;
-
- PROCEDURE init640x400x256;
- VAR Gd,Gm : integer;
- Fehler : integer;
- Size : LongInt;
- BEGIN
- Gd := InstallUserDriver('SVGA256',@DetectVGA256);
- Gm := VID640x400x256;
- InitGraph(Gd, gm ,'');
- Fehler:=GraphResult;
-
- IF Fehler<>GrOK
- THEN BEGIN
- restorecrtmode;
- WRITELN('*** Error while initializing graphic:');
- CASE Fehler OF
- -2:WRITELN('No graphic card found.');
- -3:WRITELN('Could not find *.BGI-driver.');
- -4:WRITELN('Graphic driver has wrong format.');
- -5:WRITELN('Not enough memory to load graphic driver.');
- else WRITELN('Errorcode: ',Fehler);
- END;
- Halt(1);
- END;
-
- setgraphmode(VID640x400x256);
- Fehler:=GraphResult;
-
- IF Fehler<>0
- THEN BEGIN
- restorecrtmode;
- WRITELN('*** Unknown graphic error (while trying to switch into'+
- ' the 256-color-mode).');
- WRITELN('Errorcode: ',Fehler);
- END
- ELSE BEGIN
- ActualColors:=DefaultColors;
- SetPalette(ActualColors); {aktuelle Farben=Defaultfarben}
- END;
- END;
-
- PROCEDURE Absolute2WorkArea(VAR rx,ry:INTEGER);
- { in: MausX|Y = momentane Mauskoordinaten, innerhalb der Workarea}
- { WorkStartX|Y = Startkoord. der Workarea}
- { StartVirtualX|Y = aktuelle Verschiebung des Workareabeginns}
- { zoom = momentan gesetzter Zoomfaktor}
- {out: rx,ry = Mauskoordinaten relativ bzgl. der Workarea}
- BEGIN
- rx:=(MausX-WorkStartX) DIV zoom +StartVirtualX;
- ry:=(MausY-WorkStartY) DIV zoom +StartVirtualY
- END;
-
- PROCEDURE WorkArea2Absolute(rx,ry:INTEGER; VAR ax,ay:INTEGER);
- { in: rx,ry = umzurechnende Workarea-Koordinaten}
- { WorkStartX|Y = Startkoord. der Workarea}
- { StartVirtualX|Y = aktuelle Verschiebung des Workareabeginns}
- { zoom = momentan gesetzter Zoomfaktor}
- {out: ax,ay = absolute (=Bildschrm-)Koordinaten von rx,ry}
- BEGIN
- ax:=(rx-StartVirtualX)*zoom +WorkStartX;
- ay:=(ry-StartVirtualY)*zoom +WorkStartY;
- END;
-
- PROCEDURE UmrandeWorkarea(xstep,ystep:WORD);
- { in: WorkStartX|Y,WorkEndX|Y = zu umrandendes Rechteck}
- { xstep,ystep = Schrittweite für Markierungen}
- { zoom = aktueller Zoomfaktor}
- {out: - }
- {rem: evtl. alte Markierungen werden mit schwarz gelöscht bevor die neuen}
- { Markierungen in weiß aufgebracht werden}
- VAR i:WORD;
- b:BYTE;
- BEGIN
- b:=BestWhite;
- SetColor(BestBlack);
- Rectangle(WorkStartX-2,WorkStartY-2,WorkEndX+2,WorkEndY+2);
- SetColor(b);
- Rectangle(WorkStartX-1,WorkStartY-1,WorkEndX+1,WorkEndY+1);
-
- i:=WorkStartX + zoom SHR 1;
- WHILE i<=WorkEndX DO
- BEGIN
- putpixel(i,WorkStartY-2,b);
- putpixel(i,WorkEndY +2,b);
- inc(i,xstep*zoom);
- END;
-
- j:=WorkStartY + zoom SHR 1;
- WHILE j<=WorkEndY DO
- BEGIN
- putpixel(WorkStartX-2,j,b);
- putpixel(WorkEndX +2,j,b);
- inc(j,ystep*zoom);
- END;
- END;
-
- PROCEDURE ShowActualTool;
- { in: aktuellesTool = aktuell selektiertes Tool}
- {out: - }
- {rem: aktuelles Tool wurde am Bildschirm ausgegeben}
- VAR s:STRING[40];
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX+WorkBreite-202,InfoY+25,InfoX+WorkBreite-10,InfoY+33);
- CASE aktuellesTool OF
- Punkt: s:='pixel';
- Rechteck: s:='rectangle';
- Ellipse_: s:='ellipse';
- FRechteck: s:='bar';
- FEllipse: s:='disc';
- Linie: s:='line';
- FuellEimer: s:='floodfill';
- Kopie: s:='duplicate';
- else s:='';
- END;
- SetColor(BestWhite);
- OutTextXY(InfoX+WorkBreite-202,InfoY+25,'selected tool: '+s);
- END;
-
- PROCEDURE ShowActualColor;
- { in: aktuelleFarbe = aktuell gewählte Farbe}
- {out: - }
- {rem: aktuelle Zeichenfarbe wurde am Bildschirm ausgegeben}
- VAR s:STRING[3];
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX+WorkBreite-202,InfoY+10,InfoX+WorkBreite-17,InfoY+18);
- Str(aktuelleFarbe:2,s);
- SetColor(BestWhite);
- OutTextXY(InfoX+WorkBreite-202,InfoY+10,'drawing color:');
- SetFillStyle(SolidFill,aktuelleFarbe);
- Str(aktuelleFarbe:3,s);
- Bar(InfoX+WorkBreite-106+24,InfoY+10,InfoX+WorkBreite-106+38,InfoY+18);
- OutTextXY(InfoX+WorkBreite-106+42,InfoY+10,'('+s+')');
- END;
-
- PROCEDURE ShowZoom;
- { in: zoom = aktueller Zoomfaktor}
- {out: - }
- {rem: aktueller Zoomfaktor wurde am Bildschirm ausgegeben}
- { Dies geschieht sowohl numerisch als auch als Skalierung entlang}
- { der Workarea}
- VAR s:STRING[3];
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX+WorkBreite-130,InfoY,InfoX+WorkBreite-57,InfoY+8);
- SetColor(BestWhite);
- Str(zoom:3,s); OutTextXY(InfoX+WorkBreite-130,InfoY,'zoom:'+s);
- UmrandeWorkarea(8,8);
- END;
-
- PROCEDURE ShowOffset;
- { in: StartVirtualX|Y = aktuelle Ausschnittverschiebung}
- {out: - }
- {rem: aktueller Verschiebung wurde am Bildschirm ausgegeben}
- VAR s:STRING[3];
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY+30,InfoX+95,InfoY+48);
- SetColor(BestWhite);
- Str(StartVirtualX:3,s); OutTextXY(InfoX,InfoY+30,'offset X:'+s);
- Str(StartVirtualY:3,s); OutTextXY(InfoX,InfoY+40,'offset Y:'+s);
- END;
-
- PROCEDURE ShowCursorDaten;
- { in: MausX,MausY = aktuelle Mauskoordinaten, innerhalb der Workarea!}
- { zoom = aktueller Zoomfaktor}
- {out: Ausgabe der relativen Mauskoordinaten bzgl. der Workarea am Schirm}
- { und der Farbe unter dem Mauscursor}
- {rem: Dieselben Koordinaten werden im Hauptprogramm nochmals benötigt, }
- { bei einer Änderung dort also auch ändern!}
- VAR relX,relY:INTEGER;
- b:BYTE;
- s:STRING[3];
- BEGIN
- Absolute2WorkArea(relX,relY); {relative Koord. berechnen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- SetColor(BestWhite);
- Str(relX:3,s); OutTextXY(InfoX,InfoY,'X:'+s);
- Str(relY:3,s); OutTextXY(InfoX,InfoY+10,'Y:'+s);
- b:=Workarea^.feld[relY,relX]; {Farbe des Punktes}
- Str(b:3,s);
- OutTextXY(InfoX,InfoY+20,'C:');
- SetFillStyle(SolidFill,b); Bar(InfoX+24,InfoY+20,InfoX+38,InfoY+28);
- OutTextXY(InfoX+42,InfoY+20,'('+s+')');
- END;
-
- PROCEDURE ShowFilename;
- { in: Filename* = relevante Daten/Koordinaten}
- {out: - }
- {rem: Filenamekurz wurde angezeigt}
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(FilenameStartX,FilenameStartY,
- FilenameStartX+12*8,FilenameStartY+7);
- SetColor(BestWhite);
- OutTextXY(FilenameStartX,FilenameStartY,Filenamekurz);
- END;
-
- PROCEDURE UpdateWorkArea(vonX,vonY,bisX,bisY:INTEGER; fill:BOOLEAN);
- { in: vonX|Y, bisX|Y = zu restaurierender Workareaausschnitt in relativen}
- { Koordinaten}
- { StartVirtualX|Y= aktuelle Ausschnittverschiebung}
- { zoom = aktueller Zoomfaktor}
- { WorkAreaMaxUsedX|Y = größte derzeit benutzte Koordinaten}
- { Workarea = Bildschirminhalt}
- { fill = TRUE, falls der nicht spezifizierte Workarea-Inhalt gelöscht}
- { werden soll}
- {out: - }
- {rem: spezifizierter Bildschirminhalt wurde restauriert}
- { vonX<=bisX, vonY<=bisY, d.h.: Punkte müssen geordnet sein!}
- LABEL skipx,skipy;
- VAR x,y,x1,y1,lowX,lowY,highX,highY:INTEGER;
- i:BYTE;
- BEGIN
- IF fill
- THEN BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(WorkStartX,WorkStartY,WorkEndX,WorkEndY);
- END;
-
- lowX :=max(StartVirtualX,vonX);
- highX:=min(WorkAreaMaxUsedX,bisX);
- lowY :=max(StartVirtualY,vonY);
- highY:=min(WorkAreaMaxUsedY,bisY);
- IF zoom=1
- THEN FOR y:=lowY TO highY DO
- FOR x:=lowX TO highX DO
- PutPixel(x-StartVirtualX+WorkStartX,
- y-StartVirtualY+WorkStartY,
- WorkArea^.feld[y,x])
- ELSE BEGIN {Zoomfaktor berücksichtigen}
- FOR y:=lowY TO highY DO
- BEGIN
- FOR x:=lowX TO highX DO
- BEGIN
- x1:=(x -StartVirtualX)*zoom +WorkStartX;
- IF x1>WorkEndx THEN goto skipx;
- y1:=(y -StartVirtualY)*zoom +WorkStartY;
- IF y1>WorkEndY THEN goto skipy;
- SetFillStyle(SolidFill,WorkArea^.feld[y,x]);
- Bar(x1,y1,
- min(x1+pred(zoom),WorkEndX),min(y1+pred(zoom),WorkEndY));
- END; {of FOR x}
- skipx:;
- END; {of FOR y}
- skipy:;
- END; {of ELSE}
- END;
-
- PROCEDURE DrawWorkAreaPixel(X,Y:INTEGER; Farbe:BYTE; Art:ActionTyp;
- check:BOOLEAN);
- { in: X,Y = zu zeichnender Punkt (relative Koord.) }
- { Farbe = Zeichenfarbe }
- { Art = STORE, falls Linie in Workarea[] eingetragen werden soll}
- { DRAW , falls Linie gezeichnet werden soll}
- { CLEAR, falls Linie gelöscht werden soll (dann: Farbe uninteressant)}
- { Check = TRUE, falls WorkAreaMaxUsedX|Y neuberechnet werden sollen}
- { (Zählt eh nur, wenn Art=STORE ist!)}
- { zoom = aktueller Zoomfaktor}
- {out: WorkAreaMaxUsedX|Y = evtl. neue Extremkoordinaten}
- {rem: Es wird explizit geprüft, daß die Punkte onscreen sind!}
- VAR x1,y1:INTEGER;
- BEGIN
- IF (X<StartVirtualX) OR (X>WorkBreite-1) OR (Y<StartVirtualY) OR (Y>WorkHoehe-1) THEN exit;
- IF Art=store
- THEN BEGIN
- Workarea^.feld[y,x]:=Farbe;
- IF Check
- THEN BEGIN
- IF Farbe<>transparent
- THEN BEGIN {benutzte Workarea-Fläche größer geworden?}
- WorkAreaMaxUsedX:=max(X,WorkAreaMaxUsedX);
- WorkAreaMaxUsedY:=max(Y,WorkAreaMaxUsedY);
- END
- ELSE FindWorkAreaMaxUsed;
- END;
- exit
- END;
- IF zoom=1
- THEN BEGIN
- IF Art=draw THEN PutPixel(x-StartVirtualX+WorkStartX,
- y-StartVirtualY+WorkStartY,Farbe)
- ELSE {IF Art=clear THEN} PutPixel(x-StartVirtualX+WorkStartX,
- y-StartVirtualY+WorkStartY,
- Workarea^.feld[y,x])
- END
-
- ELSE BEGIN {Zoomfaktor berücksichtigen}
- x1:=(x -StartVirtualX)*zoom +WorkStartX;
- IF x1>WorkEndx THEN exit;
- y1:=(y -StartVirtualY)*zoom +WorkStartY;
- IF y1>WorkEndY THEN exit;
- IF Art=draw THEN SetFillStyle(SolidFill,Farbe)
- ELSE {IF Art=clear THEN} SetFillStyle(SolidFill,Workarea^.feld[y,x]);
- Bar(x1,y1,min(x1+pred(zoom),WorkEndX),min(y1+pred(zoom),WorkEndY));
- END; {of ELSE}
- END;
-
- PROCEDURE DrawWorkAreaLine(x1,y1,x2,y2:INTEGER; Farbe:BYTE; Art:ActionTyp;
- check:BOOLEAN);
- { in: (x1,y1),(x2,y2) = Start- und Endpunkt der zu zeichnenden Linie,}
- { in relativen (=Workarea-)Koordinaten }
- { Farbe = Zeichenfarbe für Zeile}
- { Art = STORE, falls Linie in Workarea[] eingetragen werden soll}
- { DRAW , falls Linie gezeichnet werden soll}
- { CLEAR, falls Linie gelöscht werden soll (dann: Farbe uninteressant)}
- { Check = TRUE, falls WorkAreaMaxUsedX|Y neuberechnet werden sollen}
- { (Zählt eh nur, wenn Art=STORE ist!)}
- { Workarea = aktuelle Grafikdaten}
- {out: Linie wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: stinknormaler Bresenham-Algorithmus!}
- { Die übergebenen Koordinaten müssen relative Koord. sein!}
- VAR x,y,z,dx,dy,dz,i,maxDelta:INTEGER;
-
- PROCEDURE DrawWorkAreaPixel(X,Y:INTEGER; Farbe:BYTE);
- { in: X,Y = zu zeichnender Punkt (relative Koord.) }
- { Farbe = Zeichenfarbe }
- { zoom = aktueller Zoomfaktor}
- {out: - }
- {rem: Das ist eine etwas schnellere Variante als die gleichnamige obige,}
- { da sie nur _zeichnen_ muß!}
- VAR x1,y1:INTEGER;
- BEGIN
- IF (X<StartVirtualX) OR (X>WorkBreite-1) OR (Y<StartVirtualY) OR (Y>WorkHoehe-1) THEN exit;
- IF zoom=1
- THEN PutPixel(x-StartVirtualX+WorkStartX,y-StartVirtualY+WorkStartY,Farbe)
- ELSE BEGIN {Zoomfaktor berücksichtigen}
- x1:=(x -StartVirtualX)*zoom +WorkStartX;
- IF x1>WorkEndx THEN exit;
- y1:=(y -StartVirtualY)*zoom +WorkStartY;
- IF y1>WorkEndY THEN exit;
- SetFillStyle(SolidFill,Farbe);
- Bar(x1,y1,min(x1+pred(zoom),WorkEndX),min(y1+pred(zoom),WorkEndY));
- END; {of ELSE}
- END;
-
- BEGIN
- dx:=abs(x1-x2); dy:=abs(y1-y2);
- IF x1<x2 {Punkte nach x-Koordinate sortieren}
- THEN BEGIN
- x:=x1; y:=y1;
- IF y>y2 THEN z:=-1 ELSE z:=+1 {Y-Ri. von y zu y2 >0 oder <0 ?}
- END
- ELSE BEGIN
- x:=x2; y:=y2;
- IF y>y1 THEN z:=-1 ELSE z:=+1 {dto.: z=Schrittgröße in Y-Ri. }
- END;
- IF Art=store THEN Workarea^.feld[y,x]:=Farbe {Startpunkt setzen}
- ELSE IF Art=draw THEN DrawWorkAreaPixel(x,y,Farbe) {Startpunkt zeichnen}
- ELSE {IF Art=clear THEN} DrawWorkAreaPixel(x,y,Workarea^.feld[y,x]);
- IF dx>dy THEN maxDelta:=dx ELSE maxDelta:=dy;
- IF (dx=0) OR (dy=0) {horizontale oder vertikale Linie?}
- THEN FOR i:=1 TO maxDelta DO {ja, schneller Sonderfall}
- BEGIN
- IF dx<>0 THEN inc(x) ELSE inc(y,z);
- IF Art=store THEN Workarea^.feld[y,x]:=Farbe
- ELSE IF Art=draw THEN DrawWorkAreaPixel(x,y,Farbe)
- ELSE {IF Art=clear THEN} DrawWorkAreaPixel(x,y,Workarea^.feld[y,x]);
- END
- ELSE BEGIN
- dz:=maxDelta SHR 1;
- FOR i:=1 TO maxDelta DO
- BEGIN
- IF dz<dx THEN BEGIN inc(dz,dy); inc(x,1) END; {horiz. Segment}
- IF dz>=dx THEN BEGIN dec(dz,dx); inc(y,z) END; {vert. Segment}
- IF Art=store THEN Workarea^.feld[y,x]:=Farbe
- ELSE IF Art=draw THEN DrawWorkAreaPixel(x,y,Farbe)
- ELSE {IF Art=clear THEN} DrawWorkAreaPixel(x,y,Workarea^.feld[y,x]);
- END;
- END;
-
- IF (Art=store)
- THEN BEGIN {evtl. neue Extremkoord. setzen}
- IF Check
- THEN BEGIN
- IF (Farbe<>transparent)
- THEN BEGIN
- WorkAreaMaxUsedX:=max(WorkAreaMaxUsedX,max(x1,x2));
- WorkAreaMaxUsedY:=max(WorkAreaMaxUsedY,max(y1,y2))
- END
- ELSE FindWorkAreaMaxUsed;
- END;
- END;
- END;
-
- PROCEDURE DrawWorkAreaRectangle(x1,y1,x2,y2:INTEGER; Farbe:BYTE; Art:ActionTyp);
- { in: (x1,y1),(x2,y2) = Start- und Endpunkt des zu zeichnenden Rechtecks }
- { (oder Quadrats) in relativen (=Workarea-)Koordinaten}
- { Farbe = Zeichenfarbe für Rechteck/Quadrat}
- { Art = STORE, falls Rechteck in Workarea[] eingetragen werden soll}
- { DRAW , falls Rechteck gezeichnet werden soll}
- { CLEAR, falls Rechteck gelöscht werden soll (dann: Farbe uninteressant)}
- { Workarea = aktuelle Grafikdaten}
- {out: Rechteck wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- { Die Entscheidung, ob ein Rechteck oder ein Quadrat gezeichnet wird, wurde}
- { bereits vor dem Aufruf entschieden und geclippt!}
- BEGIN
- DrawWorkAreaLine(x1,y1,x2,y1,Farbe,Art,FALSE); {Rechteck/Quadrat aus Linien}
- DrawWorkAreaLine(x2,y1,x2,y2,Farbe,Art,FALSE); {zusammensetzen}
- DrawWorkAreaLine(x2,y2,x1,y2,Farbe,Art,FALSE);
- DrawWorkAreaLine(x1,y2,x1,y1,Farbe,Art,FALSE);
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END;
-
- PROCEDURE DrawWorkAreaEllipse(x1,y1,x2,y2:INTEGER; Farbe:BYTE; Art:ActionTyp);
- { in: (x1,y1) = Kreismittelpunkt bzw. Ellipsenmittelpunkt}
- { (x2,y2) = Randpunkt des Kreises bzw.: Eckpunkt des der Ellipse umschrie-}
- { benen Rechtecks, so daß Halbachsen a:=|x2-x1|, b:=|y2-y1| sind}
- { Farbe = Zeichenfarbe für Kreis/Ellipse }
- { Art = STORE, falls Kreis/Ellipse in Workarea[] eingetragen werden soll}
- { DRAW , falls Kreis/Ellipse gezeichnet werden soll}
- { CLEAR, falls Kreis/Ellipse gelöscht werden soll (dann: Farbe uninteressant)}
- { Workarea = aktuelle Grafikdaten}
- { Objekt.aligned = TRUE|FALSE für: Kreis|Ellipse}
- {out: Kreis/Ellipse wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- VAR a,b,r,rq,x,y,u1,u2,u3,u4,v1,v2,v3,v4:INTEGER;
- BEGIN
- IF Objekt.aligned
- THEN BEGIN {Kreis}
- rq:=sqr(x2-x1)+sqr(y2-y1);
- r:=TRUNC(sqrt(rq)+1);
- FOR y:=0 TO TRUNC(r/sqrt(2)) DO
- BEGIN
- x:=TRUNC(sqrt(rq-sqr(y)));
- u1:=x1-x; v1:=y1-y;
- u2:=x1+x; v2:=y1+y;
- u3:=x1-y; v3:=y1-x;
- u4:=x1+y; v4:=y1+x;
- DrawWorkAreaPixel(u1,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u1,v2,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v2,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u3,v3,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u3,v4,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u4,v3,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u4,v4,Farbe,Art,FALSE);
- END;
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END
- ELSE BEGIN {Ellipse}
- a:=abs(x2-x1); b:=abs(y2-y1); {Halbachsen berechnen}
- IF (a=0) OR (b=0)
- THEN BEGIN {Sonderfall: Ellipse entartet zum Strich oder Punkt}
- IF a=0
- THEN DrawWorkAreaLine(x1,min(max(y1-(y2-y1),0),WorkHoehe-1),
- x2,y2,Farbe,Art,TRUE)
- ELSE DrawWorkAreaLine(min(max(x1-(x2-x1),0),WorkBreite-1),
- y1,x2,y2,Farbe,Art,TRUE);
- exit;
- END;
- {Punkte in x-Ri. durchgehen und y berechnen}
- FOR x:=0 TO a DO {Ellipsengleichung x²/a² + y²/b² =1}
- BEGIN {nach y auflösen!}
- y:=round(sqrt(1.0-sqr(x/a))*b);
- u1:=x1-x; v1:=y1-y;
- u2:=x1+x; v2:=y1+y;
- DrawWorkAreaPixel(u1,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u1,v2,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v2,Farbe,Art,FALSE);
- END;
- {Punkte in y-Ri. durchgehen und x berechnen}
- FOR y:=0 TO b DO {Ellipsengleichung x²/a² + y²/b² =1}
- BEGIN {nach x auflösen!}
- x:=round(sqrt(1.0-sqr(y/b))*a);
- u1:=x1-x; v1:=y1-y;
- u2:=x1+x; v2:=y1+y;
- DrawWorkAreaPixel(u1,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u1,v2,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v1,Farbe,Art,FALSE);
- DrawWorkAreaPixel(u2,v2,Farbe,Art,FALSE);
- END;
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END;
- END;
-
- PROCEDURE DrawWorkAreaBar(x1,y1,x2,y2:INTEGER; Farbe:BYTE; Art:ActionTyp);
- { in: (x1,y1),(x2,y2) = Start- und Endpunkt des zu zeichnenden ausgefüllten}
- { Rechtecks (oder Quadrats) in relativen (=Workarea-)}
- { Koordinaten}
- { Farbe = Zeichenfarbe für Rechteck/Quadrat}
- { Art = STORE, falls Rechteck in Workarea[] eingetragen werden soll}
- { DRAW , falls Rechteck gezeichnet werden soll}
- { CLEAR, falls Rechteck gelöscht werden soll (dann: Farbe uninteressant)}
- { Workarea = aktuelle Grafikdaten}
- {out: Rechteck wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- { Die Entscheidung, ob ein Rechteck oder ein Quadrat gezeichnet wird, wurde}
- { bereits vor dem Aufruf entschieden und geclippt!}
- VAR y:WORD;
- BEGIN
- FOR y:=min(y1,y2) TO max(y1,y2) DO {Rechteck/Quadrat aus Linien bilden}
- DrawWorkAreaLine(x1,y,x2,y,Farbe,Art,FALSE);
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END;
-
- PROCEDURE DrawWorkAreaDisc(x1,y1,x2,y2:INTEGER; Farbe:BYTE; Art:ActionTyp);
- { in: (x1,y1) = Scheibenmittelpunkt bzw. Ellipsenmittelpunkt}
- { (x2,y2) = Randpunkt der Scheibe bzw.: Eckpunkt des der Ellipse umschrie-}
- { benen Rechtecks, so daß Halbachsen a:=|x2-x1|, b:=|y2-y1| sind}
- { Farbe = Zeichenfarbe für Scheibe/Ellipse }
- { Art = STORE, falls Scheibe/Ellipse in Workarea[] eingetragen werden soll}
- { DRAW , falls Scheibe/Ellipse gezeichnet werden soll}
- { CLEAR, falls Scheibe/Ellipse gelöscht werden soll (dann: Farbe uninteressant)}
- { Workarea = aktuelle Grafikdaten}
- { Objekt.aligned = TRUE|FALSE für: Scheibe|ausgefüllte Ellipse}
- {out: Scheibe/Ellipse wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- VAR a,b,rq,x,y,u1,u2,u3,u4,v1,v2,v3,v4:INTEGER;
- BEGIN
- IF Objekt.aligned
- THEN BEGIN {Scheibe}
- rq:=sqr(x2-x1)+sqr(y2-y1);
- FOR y:=0 TO ROUND(sqrt(rq/2)) DO
- BEGIN
- x:=TRUNC(sqrt(rq-sqr(y)));
- u1:=max(x1-x,0); v1:=max(y1-y,0);
- u2:=min(x1+x,WorkBreite-1); v2:=min(y1+y,WorkHoehe-1);
- u3:=max(x1-y,0); v3:=max(y1-x,0);
- u4:=min(x1+y,WorkBreite-1); v4:=min(y1+x,WorkHoehe-1);
- DrawWorkAreaLine(u1,v1,u2,v1,Farbe,Art,FALSE);
- DrawWorkAreaLine(u1,v2,u2,v2,Farbe,Art,FALSE);
- DrawWorkAreaLine(u3,v3,u4,v3,Farbe,Art,FALSE);
- DrawWorkAreaLine(u3,v4,u4,v4,Farbe,Art,FALSE);
- END;
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END
- ELSE BEGIN {Ellipse}
- a:=abs(x2-x1); b:=abs(y2-y1); {Halbachsen berechnen}
- IF (a=0) OR (b=0)
- THEN BEGIN {Sonderfall: Ellipse entartet zum Strich oder Punkt}
- IF a=0
- THEN DrawWorkAreaLine(x1,min(max(y1-(y2-y1),0),WorkHoehe-1),
- x2,y2,Farbe,Art,TRUE)
- ELSE DrawWorkAreaLine(min(max(x1-(x2-x1),0),WorkBreite-1),
- y1,x2,y2,Farbe,Art,TRUE);
- exit;
- END;
- {Punkte in y-Ri. durchgehen und x berechnen}
- FOR y:=0 TO b DO {Ellipsengleichung x²/a² + y²/b² =1}
- BEGIN {nach x auflösen!}
- x:=trunc(sqrt(1.0-sqr(y/b))*a);
- u1:=max(x1-x,0); v1:=max(y1-y,0);
- u2:=min(x1+x,WorkBreite-1); v2:=min(y1+y,WorkHoehe-1);
- DrawWorkAreaLine(u1,v1,u2,v1,Farbe,Art,FALSE);
- DrawWorkAreaLine(u1,v2,u2,v2,Farbe,Art,FALSE);
- END;
- IF Art=STORE THEN FindWorkAreaMaxUsed;
- END;
- END;
-
- PROCEDURE DrawWorkAreaFill(x1,y1:INTEGER; Farbe:BYTE; Art:ActionTyp);
- { in: (x1,y1) = Startpunkt, von dem aus gefüllt werden soll}
- { Farbe = Füllfarbe}
- { Art = STORE, falls Füllgebiet in Workarea[] eingetragen werden soll}
- { DRAW , falls Füllgebiet gezeichnet werden soll}
- { CLEAR, falls Füllgebiet gelöscht werden soll (dann: Farbe uninteressant)}
- { Workarea = aktuelle Grafikdaten}
- {out: Workarea wurde von (x1,y1) ausgehend "geflutet" _oder_ in Workarea eingetragen}
- { oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=1)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- VAR aufFarbe:BYTE;
- tempArea:^WorkAreaTyp;
-
- PROCEDURE RecursiveFill(x,y:WORD);
- { in: (x,y)=Ausgangspunkt für das Füllen}
- { aufFarbe=Farbe, die überschrieben werden darf}
- { Farbe=Füllfarbe}
- { Art=DRAW oder STORE}
- { tempArea=Kopie der Workarea}
- {out: Alle von (x,y) aus erreichbaren Pixel der Farbe "aufFarbe" wurden}
- { mit der Farbe "Farbe" überschrieben}
- {rem: Der Alg. sucht die längste horizontale Linie, die er durchgehend }
- { zeichnen kann und ruft sich rekursiv für die dadurch entstehenden}
- { oberen und unteren Hälften auf}
- VAR i,StartX,EndX:INTEGER;
- BEGIN
- IF tempArea^.feld[y,x]<>aufFarbe THEN exit; {Abbruch der Rekursion}
- StartX:=x; EndX:=x;
- WHILE (EndX<=WorkBreite-1) AND
- ( (EndX=WorkBreite-1) OR (tempArea^.feld[y,EndX+1]=aufFarbe))
- DO inc(EndX); {boolesche Kurzschlußauswertung wichtig!}
- IF EndX=WorkBreite THEN dec(EndX);
- {damit: EndX=letztes X, das gefüllt werden darf}
- WHILE (StartX>=0) AND
- ( (StartX=0) OR (tempArea^.feld[y,StartX-1]=aufFarbe))
- DO dec(StartX); {boolesche Kurzschlußauswertung wichtig!}
- IF StartX=-1 THEN inc(StartX);
- {damit: StartX=erstes X, das gefüllt werden darf}
-
- DrawWorkAreaLine(StartX,y,EndX,y,Farbe,Art,FALSE); {diese Linie zeichnen}
- FOR i:=StartX TO EndX DO tempArea^.feld[y,i]:=Farbe; {und merken!}
-
- IF y>0 {obere Hälfte abarbeiten}
- THEN FOR i:=StartX TO EndX DO RecursiveFill(i,pred(y));
- IF y<WorkHoehe-1 {untere Hälfte abarbeiten}
- THEN FOR i:=StartX TO EndX DO RecursiveFill(i,succ(y));
- END;
-
- BEGIN
- IF (Art=DRAW) OR (Art=STORE)
- THEN BEGIN
- aufFarbe:=WorkArea^.feld[y1,x1]; {auf welcher Farbe soll gefüllt werden?}
- IF aufFarbe<>Farbe
- THEN BEGIN
- New(tempArea); Move(WorkArea^,tempArea^,SizeOf(WorkArea^));
- RecursiveFill(x1,y1); {na dann mach mal!}
- IF Art=STORE
- THEN BEGIN
- Move(tempArea^,WorkArea^,SizeOf(WorkArea^));
- FindWorkAreaMaxUsed
- END;
- Dispose(tempArea);
- END;
- END
- ELSE {IF Art=CLEAR THEN}
- BEGIN
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- END;
- END;
-
- PROCEDURE DrawWorkAreaCopy(x1,y1,x2,y2,x3,y3:INTEGER; Art:ActionTyp);
- { in: (x1,y1),(x2,y2) = Start- und Endpunkt des zu zeichnenden Bereichs}
- { (x3,y3) = Zielpunkt dafür (nur für stage=2)}
- { (alles in relativen (=Workarea-)Koordinaten) }
- { Art = STORE, falls Bereich in Workarea[] eingetragen werden soll}
- { DRAW , falls Bereich gezeichnet werden soll}
- { CLEAR, falls Bereich gelöscht werden soll }
- { Workarea = aktuelle Grafikdaten }
- { Objekt.stage = aktueller Zustand (1 oder 2)}
- {out: Bereich wurde gezeichnet _oder_ in Workarea eingetragen oder gelöscht}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten (nur wenn Art=STORE)}
- {rem: Die übergebenen Koordinaten müssen relative Koord. sein!}
- { Punkte der Farbe "transparent" werden als durchsichtig behandelt!}
- VAR x,y:WORD;
- farbe:BYTE;
- BEGIN
- IF x1>x2 THEN BEGIN x:=x1; x1:=x2; x2:=x END;
- IF y1>y2 THEN BEGIN y:=y1; y1:=y2; y2:=y END;
- IF (Art=DRAW) OR (Art=CLEAR)
- THEN BEGIN
- IF Objekt.stage=1
- THEN BEGIN {gepunktete Box aufspannen}
- farbe:=BestWhite;
- FOR x:=x1 TO x2 DO
- BEGIN
- DrawWorkAreaPixel(x,y1,farbe,Art,FALSE);
- DrawWorkAreaPixel(x,y2,farbe,Art,FALSE);
- IF farbe=BestWhite
- THEN farbe:=BestBlack
- ELSE farbe:=BestWhite
- END;
- farbe:=BestBlack;
- FOR y:=SUCC(y1) TO PRED(y2) DO
- BEGIN
- DrawWorkAreaPixel(x1,y,farbe,Art,FALSE);
- DrawWorkAreaPixel(x2,y,farbe,Art,FALSE);
- IF farbe=BestWhite
- THEN farbe:=BestBlack
- ELSE farbe:=BestWhite
- END;
- END
- ELSE BEGIN {Bereich (x1,y1)-(x2,y2) nach (x3,y3) kopieren oder löschen}
- FOR y:=y1 TO y2 DO
- FOR x:=x1 TO x2 DO
- IF WorkArea^.feld[y,x]<>transparent
- THEN DrawWorkAreaPixel(x3+(x-x1),y3+(y-y1),
- WorkArea^.feld[y,x],Art,FALSE)
- END;
- END
- ELSE BEGIN {Art=Store (AND stage=2)}
- FOR y:=y1 TO y2 DO
- FOR x:=x1 TO x2 DO
- IF WorkArea^.feld[y,x]<>transparent
- THEN DrawWorkAreaPixel(x3+(x-x1),y3+(y-y1),
- WorkArea^.feld[y,x],STORE,FALSE);
- FindWorkAreaMaxUsed;
- END;
- END;
-
-
- FUNCTION sign(a:INTEGER):INTEGER;
- BEGIN
- IF a<0 THEN sign:=-1
- ELSE IF a>0 THEN sign:=+1
- ELSE sign:=0
- END;
-
- PROCEDURE ClearOldObject;
- { in: Objekt.Typ = zu restaurierender Typ}
- { Objekt.StartX,StartY,LastX,LastY = Start-/Endpunkte der Maus für}
- { dieses Objekt}
- {out: - }
- CONST DontCare=0;
- VAR tempX,tempY:INTEGER;
- BEGIN
- WITH Objekt DO
- BEGIN
- IF stage=0 THEN exit; {kein Objekt begonnen, also nichts zum löschen!}
- CASE Typ OF
- Punkt:DrawWorkAreaPixel(StartX,StartY,DontCare,CLEAR,FALSE);
- Linie:DrawWorkAreaLine(StartX,StartY,LastX,LastY,DontCare,CLEAR,FALSE);
- Rechteck:DrawWorkAreaRectangle(StartX,StartY,LastX,LastY,DontCare,CLEAR);
- Ellipse_:DrawWorkAreaEllipse(StartX,StartY,LastX,LastY,DontCare,CLEAR);
- FRechteck:DrawWorkAreaBar(StartX,StartY,LastX,LastY,DontCare,CLEAR);
- FEllipse:DrawWorkAreaDisc(StartX,StartY,LastX,LastY,DontCare,CLEAR);
- FuellEimer:DrawWorkAreaFill(LastX,LastY,DontCare,CLEAR);
- Kopie:DrawWorkAreaCopy(StartX,StartY,LastX,LastY,actX,actY,CLEAR);
- else ErrBeep;
- END; {of CASE}
- END; {of WITH}
- END;
-
- PROCEDURE DrawNewObject;
- { in: Objekt.Typ = zu zeichnender Typ}
- { Objekt.StartX,StartY,LastX,LastY = Start-/Endpunkte der Maus für}
- { dieses Objekt}
- { Objekt.Farbe = Zeichenfarbe}
- {out: - }
- {rem: Aktuelles Objekt wurde im Bereich der Workarea gezeichnet, ohne }
- { aber in die Workarea[] aufgenommen worden zu sein}
- VAR tempX,tempY:INTEGER;
- BEGIN
- WITH Objekt DO
- BEGIN
- IF stage=0 THEN exit; {kein Objekt begonnen, also nichts zum zeichnen!}
- CASE Typ OF
- Punkt:DrawWorkAreaPixel(StartX,StartY,aktuelleFarbe,DRAW,FALSE);
- Linie:DrawWorkAreaLine(StartX,StartY,LastX,LastY,aktuelleFarbe,DRAW,FALSE);
- Rechteck:DrawWorkAreaRectangle(StartX,StartY,LastX,LastY,aktuelleFarbe,DRAW);
- Ellipse_:DrawWorkAreaEllipse(StartX,StartY,LastX,LastY,aktuelleFarbe,DRAW);
- FRechteck:DrawWorkAreaBar(StartX,StartY,LastX,LastY,aktuelleFarbe,DRAW);
- FEllipse:DrawWorkAreaDisc(StartX,StartY,LastX,LastY,aktuelleFarbe,DRAW);
- FuellEimer:DrawWorkAreaFill(LastX,LastY,aktuelleFarbe,DRAW);
- Kopie:DrawWorkAreaCopy(StartX,StartY,LastX,LastY,actX,actY,DRAW);
- else ErrBeep;
- END; {of CASE}
- END; {of WITH}
- END;
-
- PROCEDURE StoreObject;
- { in: Objekt.Typ = zu zeichnender Typ}
- { Objekt.StartX,StartY,LastX,LastY = Start-/Endpunkte der Maus für}
- { dieses Objekt}
- { Objekt.Farbe = Zeichenfarbe}
- {out: - }
- {rem: Objekt wurde in Workarea[] übernommen; es ist dabei unerheblich,}
- { ob das Objekt auf dem Schirm sichtbar ist oder nicht (natürlich }
- { sollte es sichtbar sein, um den Benutzer nicht zu verwirren, }
- { aber es ist eben nicht zwingend erforderlich)}
- VAR tempX,tempY:INTEGER;
- BEGIN
- WITH Objekt DO
- BEGIN
- CASE Typ OF
- Punkt:DrawWorkAreaPixel(StartX,StartY,aktuelleFarbe,STORE,TRUE);
- Linie:DrawWorkAreaLine(StartX,StartY,LastX,LastY,aktuelleFarbe,STORE,TRUE);
- Rechteck:DrawWorkAreaRectangle(StartX,StartY,LastX,LastY,aktuelleFarbe,STORE);
- Ellipse_:DrawWorkAreaEllipse(StartX,StartY,LastX,LastY,aktuelleFarbe,STORE);
- FRechteck:DrawWorkAreaBar(StartX,StartY,LastX,LastY,aktuelleFarbe,STORE);
- FEllipse:DrawWorkAreaDisc(StartX,StartY,LastX,LastY,aktuelleFarbe,STORE);
- FuellEimer:DrawWorkAreaFill(LastX,LastY,aktuelleFarbe,STORE);
- Kopie:DrawWorkAreaCopy(StartX,StartY,LastX,LastY,actX,actY,STORE);
- else ErrBeep;
- END; {of CASE}
-
- stage:=0; {Objekt beendet}
- END; {of WITH}
- END;
-
- PROCEDURE ShowPalName;
- { in: Palnamekurz = Palettenname}
- { ActualColors = aktuelle Farben}
- {out: - }
- BEGIN
- SetFillStyle(SolidFill,BestBlack);
- Bar(PalnameStartX,PalnameStartY,PalnameStartX+(18 SHL 3),PalnameStartY+8);
- IF PalEqual(ActualColors,DefaultColors)
- THEN BEGIN {Standardpalette}
- SetColor(BestWhite);
- OutTextXY(PalnameStartX,PalnameStartY,'(Default palette)');
- END
- ELSE BEGIN {Palette wurde geladen, also darstellen!}
- SetColor(BestWhite);
- OutTextXY(PalnameStartX,PalnameStartY,Palnamekurz);
- END;
- END;
-
- PROCEDURE RestoreScreen;
- { in: WorkArea = Spritedaten bzw. Bilddaten}
- { WorkAreaMaxUsedX|Y = vom Bild benutzte Extremkoordinaten}
- {out: Grafikbildschirm wurde restauriert}
- VAR s:STRING[5];
-
- PROCEDURE MenuZeigen;
- VAR s:STRING[3];
- BEGIN
- globalI:=1;
- WHILE (menu[globalI].x1<menu[globalI].x2) AND (menu[globalI].Paint) DO
- BEGIN
- menu[globalI].Show;
- INC(globalI)
- END;
- END;
-
- PROCEDURE WorkAreaDarstellen;
- BEGIN
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,FALSE);
- DrawNewObject;
- ShowFilename;
- END;
-
- PROCEDURE PaletteZeigen;
- VAR x,y:WORD;
- s:STRING[3];
- i:BYTE;
- BEGIN
- SetColor(BestWhite);
- FOR i:=0 TO 15 DO
- BEGIN
- STR(i:2,s);
- OutTextXY(PaletteX+25+i*PalBreite,PaletteY,s);
- STR(i*16:3,s);
- OutTextXY(PaletteX,PaletteY+10+3+i*PalHoehe,s);
- END;
- FOR y:=0 TO 15 DO
- BEGIN
- FOR x:=0 TO 15 DO
- BEGIN
- SetFillStyle(SolidFill,y*16+x);
- Bar(PaletteX+25+x*PalBreite,PaletteY+10+y*PalHoehe,
- PaletteX+25+succ(x)*PalBreite-3,PaletteY+10+succ(y)*PalHoehe-3);
- END;
- END;
- END;
-
-
- BEGIN
- SetPalette(ActualColors); {aktuelle Farben wieder einsetzen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(0,0,GetMaxX,GetMaxY);
-
- MenuZeigen;
- PaletteZeigen;
- IF InWorkArea THEN ShowCursorDaten;
-
- UmrandeWorkarea(8,8);
- ShowFileName;
- WorkAreaDarstellen;
-
- ShowZoom;
- ShowActualColor;
- ShowOffset;
- ShowActualTool;
- DrawNewObject;
- ShowPalName;
-
- SetColor(BestWhite);
- SetTextStyle(DefaultFont,HorizDir,2);
- OutTextXY(0,0,Titel1);
- SetTextStyle(DefaultFont,HorizDir,1);
-
- END;
-
- PROCEDURE loescheWorkarea;
- VAR i:Integer;
- BEGIN
- SetColor(BestBlack);
- FOR i:=WorkStartY TO WorkEndY DO line(WorkStartX,i,WorkEndX,i);
- END;
-
- PROCEDURE ladeSprite;
- { in: Workarea^ = alte Grafikdaten (uninteressant, wenn Shift=FALSE)}
- { Shift = TRUE|FALSE für: alten Inhalt überlagern/löschen}
- {out: Filenamelang = gewählter Dateiname mit Pfadangabe}
- { Filenamekurz = dto., nur Name+Extension}
- { WorkArea = Bild der geladenen Datei }
- { WorkAreaMaxUsedX|Y = Extremkoordinaten }
- VAR s,name:String;
- Dirname : DirStr;
- Filename: NameStr;
- Extname : ExtStr;
- fehler:Boolean;
- GrafikBild:Pointer;
- Size,i,offset,vonwo:Word;
- zeile,spalte,startx,endx:INTEGER;
- plane:BYTE;
- sprite:^spritetyp; {Hier steht das eigentliche Sprite drinnen}
-
- FUNCTION Spritedatenlesen(name:String):Boolean;
- { in: "name" ist der vollständige Name des einzulesenden Sprites }
- {out: Die globale Variable "sprite^" enthält die Daten des Sprites }
- { Ist "name" kein 256-Farben-Sprite oder zu groß, um in der }
- { Workarea bearbeitet zu werden, so wird "FALSE" zurückgegeben,}
- { anderenfalls "TRUE" }
- {rem: Das Sprite wird NICHT dargestellt, sondern nur eingelesen! }
- VAR f:file;
- size:longint;
- i,j:Word;
-
- PROCEDURE FehlerMeldung(s:String);
- VAR ch:char;
- BEGIN
- WRITELN(#7);
- WRITE(s+' <any key>');
- ch:=readkey;
- while keypressed do ch:=readkey
- END;
-
- BEGIN
- assign(f,name);
- {$I-}
- reset(f,1); size:=FileSize(f);
- {$I+}
- if ioresult<>0
- THEN BEGIN
- FehlerMeldung('I/O-error while trying to open file!');
- Spritedatenlesen:=false;
- exit
- END;
- if size>SizeOF(sprite^.readin)
- THEN BEGIN
- FehlerMeldung('File too big!');
- close(f);
- Spritedatenlesen:=false;
- exit
- END;
- if size<Kopf
- THEN BEGIN
- FehlerMeldung('File to small to be a sprite file!');
- Spritedatenlesen:=false;
- exit
- END;
-
- blockread(f,sprite^.readin,size);
- close(f); WRITELN;
-
- WITH Sprite^ DO
- BEGIN {Jetzt kommt die Fehlerprüfung:}
- IF (Kennung[1]<>'K') or (Kennung[2]<>'R') {Kennung muss "KR" sein}
- or (SpriteLength<>size) {Groesse muss stimmen}
- or (Zeiger_auf_Plane[1]-Zeiger_auf_Plane[0]<> {Planegröße muß mit}
- Breite_in_4er_Gruppen*Hoehe_in_Zeilen) {Abmessungen übereinstimmen}
- or (ZeigerR-ZeigerL<>Hoehe_in_Zeilen*2) {X-Grenztabellengröße auch}
- or (ZeigerU-ZeigerO<>Breite_in_4er_Gruppen*8) {dto., für Y-Gr.tab.}
- or (Translate[1]<>1) {die 4 Translate-Einträge im Spriteheader}
- or (Translate[2]<>2) {müssen die ersten 4 Zweierpotenzwerte haben}
- or (Translate[3]<>4)
- or (Translate[4]<>8)
- THEN BEGIN
- FehlerMeldung('This is no 256-color-sprite!');
- Spritedatenlesen:=false;
- exit
- END;
-
- IF (Hoehe_in_Zeilen>Workhoehe) or
- (Breite_in_4er_Gruppen*4>WorkBreite)
- THEN BEGIN
- FehlerMeldung('Sprite to big to fit into workarea!');
- Spritedatenlesen:=false;
- exit
- END;
- END;
-
- Spritedatenlesen:=true
- END;
-
- BEGIN
- RestoreCRTMode;
- ClrScr;
-
- name:='*.COD';
- GotoXY(10,4);
- WRITE('Select your *.COD-file to load with the cursor keys,');
- GotoXY(10,5);
- WRITE('PageUP/PageDOWN, HOME/END and CR; <ESC> to cancel:');
- Dateiwahl(10,7,15,name,fehler);
- IF fehler THEN
- BEGIN
- setgraphmode(VID640x400x256);
- RestoreScreen;
- write(#7);
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- '*** I/O-error! ***',
- 'Couldn''t open file/device',name,Abfrage);
- END
- ELSE IF name=''
- THEN BEGIN {nichts ausgewählt (ESC gedrückt)}
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE BEGIN {Spritedaten lesen}
- New(sprite);
- IF Spritedatenlesen(name) {ok, Daten einlesen und prüfen}
- THEN BEGIN
- Filenamelang:=name;
- FSplit(Filenamelang, Dirname, Filename, Extname);
- Filenamekurz:=Filename+Extname;
-
- {Jetzt Spritedaten nach WorkArea decodieren:}
- IF NOT Shift
- THEN FillChar(WorkArea^,SizeOf(WorkArea^),transparent);
- WITH sprite^ DO
- BEGIN
- FOR zeile:=0 TO Pred(Hoehe_in_Zeilen) DO
- BEGIN
- startx:=zeigerL+zeile shl 1;
- endx :=zeigerR+zeile shl 1;
- FOR spalte:=readin[succ(startx)] shl 8 +readin[startx]
- TO readin[succ(endx)] shl 8 +readin[endx] DO
- BEGIN
- plane:=spalte and 3;
- offset:=spalte shr 2 +zeile*Breite_in_4er_Gruppen;
- vonwo:=Zeiger_auf_Plane[plane];
- IF readin[vonwo+offset]<>transparent
- THEN WorkArea^.feld[zeile,spalte]:=readin[vonwo+offset]
- END;
- END;
- (* Folgende Zuweisungen wären zu ungenau, da Sprites *)
- (* in X-Richtung immer als Vielfaches von 4 gespeichert *)
- (* werden: *)
- (*
- WorkAreaMaxUsedX:=min(Breite_in_4er_Gruppen*4-1,XMAX);
- WorkAreaMaxUsedY:=pred(Hoehe_in_Zeilen);
- *)
- FindWorkAreaMaxUsed; (* ...deshalb lieber so! *)
- END;
-
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE BEGIN {keine oder fehlerhafte *.COD-Datei}
- Filenamelang:=''; Filenamekurz:='';
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END;
- Dispose(sprite);
- END;
- END;
-
- PROCEDURE ladePalette;
- { in: -}
- {out: Palnamelang = gewählter Dateiname mit Pfadangabe}
- { Palnamekurz = dto., nur Name+Extension}
- {rem: Ist die geladene Palette gleich der Standardpalette, so werden}
- { Palname* auf '' gesetzt}
- VAR s,name:String;
- Dirname : DirStr;
- Filename: NameStr;
- Extname : ExtStr;
- fehler:Boolean;
- neuPal:BigPalette;
- i:WORD;
-
- PROCEDURE FehlerMeldung(s:String);
- VAR ch:char;
- BEGIN
- WRITELN(#7);
- WRITE(s+' <any key>');
- ch:=readkey;
- while keypressed do ch:=readkey
- END;
-
- BEGIN
- RestoreCRTMode;
- ClrScr;
-
- name:='*.PAL';
- GotoXY(10,4);
- WRITE('Select your *.PAL-file to load with the cursor keys,');
- GotoXY(10,5);
- WRITE('PageUP/PageDOWN, HOME/END and CR; <ESC> to cancel:');
- Dateiwahl(10,7,15,name,fehler);
- IF fehler THEN
- BEGIN
- setgraphmode(VID640x400x256);
- RestoreScreen;
- write(#7);
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- '*** I/O-error! ***',
- 'Couldn''t open file/device',name,Abfrage);
- END
- ELSE IF name=''
- THEN BEGIN {nichts ausgewählt (ESC gedrückt)}
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE IF LoadPalette(name,0,neuPal)<>0 {ok, Daten einlesen und prüfen}
- THEN BEGIN
- Palnamelang:=name;
- FSplit(Palnamelang, Dirname, Filename, Extname);
- Palnamekurz:=Filename+Extname;
-
- setgraphmode(VID640x400x256);
- ActualColors:=neuPal;
- SetPalette(ActualColors);
- IF PalEqual(ActualColors,DefaultColors)
- THEN BEGIN {geladene Palette = Standardpalette?}
- Palnamelang:='';
- Palnamekurz:='';
- END;
- RestoreScreen;
-
- END
- ELSE BEGIN {keine oder fehlerhafte *.PAL-Datei}
- FehlerMeldung('Couldn''t read *.PAL-file!');
- Palnamelang:=''; Palnamekurz:='';
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END;
- END;
-
- FUNCTION SelectZielPalette:BOOLEAN;
- { in: -}
- {out: Palnamelang = gewählter Dateiname mit Pfadangabe}
- { Palnamekurz = dto., nur Name+Extension}
- { ZielPalette = geladene Palette}
- { TRUE|FALSE, falls Palette geladen|nicht geladen wurde}
- {rem: Ist die geladene Palette gleich der Standardpalette, so werden}
- { Palname* auf '' gesetzt}
- VAR s,name:String;
- Dirname : DirStr;
- Filename: NameStr;
- Extname : ExtStr;
- fehler:Boolean;
- neuPal:BigPalette;
- i:WORD;
-
- PROCEDURE FehlerMeldung(s:String);
- VAR ch:char;
- BEGIN
- WRITELN(#7);
- WRITE(s+' <any key>');
- ch:=readkey;
- while keypressed do ch:=readkey
- END;
-
- BEGIN
- RestoreCRTMode;
- ClrScr;
-
- name:='*.PAL';
- GotoXY(10,4);
- WRITE('Select the destination palette to map to with the cursor keys,');
- GotoXY(10,5);
- WRITE('PageUP/PageDOWN, HOME/END and CR; <ESC> to cancel:');
- Dateiwahl(10,7,15,name,fehler);
- IF fehler THEN
- BEGIN
- SelectZielPalette:=FALSE;
- setgraphmode(VID640x400x256);
- RestoreScreen;
- write(#7);
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- '*** I/O-error! ***',
- 'Couldn''t open file/device',name,Abfrage);
- END
- ELSE IF name=''
- THEN BEGIN {nichts ausgewählt (ESC gedrückt)}
- SelectZielPalette:=FALSE;
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE IF LoadPalette(name,0,neuPal)<>0 {ok, Daten einlesen und prüfen}
- THEN BEGIN
- SelectZielPalette:=TRUE;
- Palnamelang:=name;
- FSplit(Palnamelang, Dirname, Filename, Extname);
- Palnamekurz:=Filename+Extname;
- ZielPalette:=neuPal;
-
- IF PalEqual(ActualColors,DefaultColors)
- THEN BEGIN {geladene Palette = Standardpalette?}
- Palnamelang:='';
- Palnamekurz:='';
- END;
-
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE BEGIN {keine oder fehlerhafte *.PAL-Datei}
- SelectZielPalette:=FALSE;
- FehlerMeldung('Couldn''t read *.PAL-file!');
- Palnamelang:=''; Palnamekurz:='';
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END;
- END;
-
- PROCEDURE ladeHintergrund;
- { in: -}
- {out: Filenamelang = gewählter Dateiname mit Pfadangabe}
- { Filenamekurz = dto., nur Name+Extension}
- { WorkArea = Bitmaps der geladenen Datei }
- { WorkAreaMaxUsedX|Y = max. benutzte Koordinaten}
- VAR s,name:String;
- Dirname : DirStr;
- Filename: NameStr;
- Extname : ExtStr;
- fehler:Boolean;
- GrafikBild:Pointer;
- Size,i,t,x,y:Word;
- picture:Bild;
-
- FUNCTION LoadPage(name:STRING):BOOLEAN;
- { in: name = Filename fuer das zu ladende Bild}
- {out: pic = Bitmaps des Bildes }
- { TRUE/FALSE für Bild konnte geladen/nicht geladen werden}
- CONST PICHeader:STRING[3]='PIC'; {Kennung in Bilderdateien}
- VAR f:FILE;
- i:BYTE;
- fehler:BOOLEAN;
- s:STRING[3];
- x,y:WORD;
-
- PROCEDURE FehlerMeldung(s:String);
- VAR ch:char;
- BEGIN
- WRITELN(#7);
- WRITE(s+' <any key>');
- ch:=readkey;
- while keypressed do ch:=readkey
- END;
-
- BEGIN
- {$I-}
- Assign(f,name); fehler:=IOResult<>0;
- Reset(f,1); fehler:=fehler OR (IOResult<>0);
- s[0]:=PICHeader[0];
- BlockRead(f,s[1],Length(PICHeader)); fehler:=fehler OR (IOResult<>0);
- {$I+}
- IF fehler
- THEN BEGIN
- {$I-} Close(f); {$I+}
- Error:=ErrFileIO;
- FehlerMeldung(GetErrorMessage);
- LoadPage:=FALSE;
- exit
- END
- ELSE IF (FileSize(f)<>4*PAGESIZE+Length(PICHeader)) OR (s<>PICHeader)
- THEN BEGIN
- {$I-} Close(f); {$I+}
- Error:=ErrNoPicture;
- FehlerMeldung(GetErrorMessage);
- LoadPage:=FALSE;
- exit
- END;
- FOR i:=0 TO 3 DO
- BEGIN
- {$I-}
- BlockRead(f,picture[i]^,PAGESIZE);
- {$I+}
- fehler:=fehler OR (IOResult<>0);
- END;
- {$I-}
- Close(f);
- {$I+}
- fehler:=fehler OR (IOResult<>0);
- IF fehler THEN Error:=ErrFileIO;
- IF fehler THEN FehlerMeldung(GetErrorMessage);
-
- LoadPage:=Error=ErrNone
- END;
-
- BEGIN
- RestoreCRTMode;
- ClrScr;
-
- name:='*.PIC';
- GotoXY(10,4);
- WRITE('Select your *.PIC-file to load with the cursor keys,');
- GotoXY(10,5);
- WRITE('PageUP/PageDOWN, HOME/END and CR; <ESC> to cancel:');
- Dateiwahl(10,7,15,name,fehler);
- IF fehler THEN
- BEGIN
- setgraphmode(VID640x400x256);
- RestoreScreen;
- write(#7);
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- '*** I/O-error! ***',
- 'Couldn''t open file/device',name,Abfrage);
- END
- ELSE IF name=''
- THEN BEGIN {nichts ausgewählt (ESC gedrückt)}
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE BEGIN {Bild laden}
- FOR i:=0 TO 3 DO New(picture[i]);
-
- IF LoadPage(name) {ok, Daten einlesen und prüfen}
- THEN BEGIN
- Filenamelang:=name;
- FSplit(Filenamelang, Dirname, Filename, Extname);
- Filenamekurz:=Filename+Extname;
- {Bilddaten nach Array WorkArea decodieren:}
- FOR y:=0 TO YMAX DO
- FOR x:=0 TO XMAX SHR 2 DO
- BEGIN
- t:=y*LINESIZE;
- WorkArea^.feld[y,x shl 2+0]:=picture[0]^[t+x];
- WorkArea^.feld[y,x shl 2+1]:=picture[1]^[t+x];
- WorkArea^.feld[y,x shl 2+2]:=picture[2]^[t+x];
- WorkArea^.feld[y,x shl 2+3]:=picture[3]^[t+x]
- END;
-
- FindWorkAreaMaxUsed;
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END
- ELSE BEGIN {keine oder fehlerhafte *.COD-Datei}
- Filenamelang:=''; Filenamekurz:='';
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END;
- FOR i:=0 TO 3 DO Dispose(picture[i]);
- END;
- END;
-
- FUNCTION gueltig(VAR P:EingabeString; Ext:ExtStr):Boolean;
- { in: P = vollständiger Dateiname}
- { Ext = gewünschte Defaultextension, falls P selber keine hat}
- {out: TRUE/FALSE, wenn unter dem angegebenen Namen eine Datei angelegt}
- { werden kann und deren Endung "Ext" ist}
- { P = vollständiger Dateiname, um "Ext" erweitert, wenn keine Ex- }
- { tension angegeben wurde, evtl. Leerzeichen wurden entfernt }
- {rem: Eine schon bestehende Datei gleichen Namens wird überschrieben! }
- { P muß in Großschrift sein!}
- VAR i:Byte;
- D: DirStr;
- N: NameStr;
- E: ExtStr;
-
- FUNCTION eroeffenbar(P:PathStr):Boolean;
- VAR f:file;
- temp:Boolean;
- BEGIN
- assign(f,P);
- {$I-}
- rewrite(f);
- {$I+}
- temp:=ioresult=0;
- if temp THEN close(f);
- eroeffenbar:=temp
- END;
-
- BEGIN
- WHILE (P[1]=' ') DO delete(P,1,1);
- WHILE (P[Length(P)]=' ') DO delete(P,Length(P),1);
-
- FSplit(P, D, N, E);
- IF E='' THEN E:=Ext;
- P := D + N + E;
-
- if (n='') {Kein Namen angegeben?}
- or (pos('*',p)>0) {keine Wildcards erlaubt}
- or (pos('?',p)>0)
- or (pos(':',N+E)>0) {LW-Angaben sind nur im Pfad erlaubt}
- or (E<>Ext) {nur "Ext" als Endung erlaubt}
- or ( (pos(':',D)>0) and (pos(':',D)<>2) ) {":" muß an 2.Position sein}
- or (not eroeffenbar(P))
- THEN BEGIN gueltig:=false; exit END
- ELSE gueltig:=true
- END;
-
-
- PROCEDURE speichereSprite;
- { in: Filenamelang = Defaultwert für Spritenamen}
- { Workarea^ = abzuspeichernde Daten}
- { WorkAreaMaxUsedX|Y = max. benutzte Extremkoordinaten}
- { ActualColors = gerade gesetzte Farben}
- { DefaultColors = Standardfarben des BIOS-256-Farbenmodus}
- {out: Auf Disk wurde der Inhalt der Workarea als Sprite abgelegt }
- { Filename* = neue Filenamen}
- {rem: Falls die Workarea leer war oder <ESC> gedrückt wurde, dann}
- { wurde keine Datei angelegt}
- CONST x1=1; y1=4; x2=80; y2=y1+2; {Koordinaten für Eingabebox}
- VAR temp:EingabeString;
- abbruch:Boolean;
- size:word;
- attr:Byte;
- i:Integer;
- ch:Char;
- oldNamelang,oldNamekurz,
- P: PathStr;
- D: DirStr;
- N: NameStr;
- E: ExtStr;
-
- PROCEDURE schreibe_Daten;
- { in: Filenamelang = Name der zu schreibenden Datei}
- { oldName* = alte Dateinamen}
- {out: Falls Sprite nicht erstellt werden konnte, wurden die alten}
- { Dateinamen für Filename* wieder eingesetzt!}
- {rem: Der Inhalt der Workarea wird in die Datei Filenamelang }
- { geschrieben; der Dateiname wurde bereits auf Eröffenbar-}
- { keit geprüft, ebenso, daß die Workarea nicht leer ist! }
- LABEL quit;
- VAR f:file;
- i,j,offset,Plane_Groesse:WORD;
- Gesamtgroesse:LONGINT;
- temp,p:Byte;
- links,rechts,oben,unten:Integer;
- fertig_li,fertig_re,fertig_ob,fertig_un:Boolean;
- Sprite:^spritetyp; {Hier steht das eigentliche Sprite drinnen}
- s:String[20];
- s1,s2:STRING[5];
- pp:POINTER;
- pplen:WORD;
- BEGIN
- SetColor(BestWhite); s:='just a moment...';
- pplen:=ImageSize(MeldungX+50,MeldungY,
- MeldungX+50+length(s) SHL 3,MeldungY+9);
- GetMem(pp,pplen);
- GetImage(MeldungX+50,MeldungY,
- MeldungX+50+length(s) SHL 3,MeldungY+9,pp^);
- OutTextXY(MeldungX+50,MeldungY,s);
-
- New(Sprite);
- WITH Sprite^ DO
- BEGIN
- Translate[1]:=1; Translate[2]:=2; Translate[3]:=4; Translate[4]:=8;
- Kennung[1]:='K'; Kennung[2]:='R';
- Version:=1;
- Modus:=0;
- FOR i:=1 TO 10 DO dummy[i]:=0; {Dummywerte auf 0 setzen}
- Hoehe_in_Zeilen:=Succ(WorkAreaMaxUsedY); {Y-Werte reichen von 0..MaxY}
- Breite_in_4er_Gruppen:=Succ(WorkAreaMaxUsedX shr 2); {0..3->1, 4..7->2, ...}
- {Anzahl Bytes pro Plane:}
- Plane_Groesse:=Hoehe_in_Zeilen*Breite_in_4er_Gruppen;
-
- {Indizes für Grenz- & Planedaten:}
- ZeigerL:=Kopf; {Fängt beim 1.Datenbyte an}
- ZeigerR:=ZeigerL+ (Hoehe_in_Zeilen*2);
- ZeigerO:=ZeigerR+ (Hoehe_in_Zeilen*2);
- ZeigerU:=ZeigerO+ (Breite_in_4er_Gruppen*4 *2);
- Zeiger_auf_Plane[0] :=ZeigerU+ (Breite_in_4er_Gruppen*4 *2);
- Zeiger_auf_Plane[1] :=Zeiger_auf_Plane[0]+ Plane_Groesse;
- Zeiger_auf_Plane[2] :=Zeiger_auf_Plane[1]+ Plane_Groesse;
- Zeiger_auf_Plane[3] :=Zeiger_auf_Plane[2]+ Plane_Groesse;
-
- {Das Sprite besteht aus: "Kopf" Bytes an Zeigern & speziellen Infos,}
- {4 Tabellen mit Planedaten, 2 Tabellen mit X-Grenzen (Wörter!), }
- {2 Tabellen mit Y-Grenzen (Wörter, für jeden X-Wert einen!) }
- Gesamtgroesse:=LONGINT(Kopf)+(Plane_Groesse*4)+
- (Hoehe_in_Zeilen*2)*2+
- (Breite_in_4er_Gruppen*4 *2)*2;
-
- IF Gesamtgroesse>SizeOf(SpriteTyp)
- THEN BEGIN
- Str(Gesamtgroesse:5,s1);
- Str(SizeOf(SpriteTyp):5,s2);
- Write(#7);
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- 'Sprite would be to big!',
- '(is:'+s1+', max:'+s2+')','',Abfrage);
- Filenamelang:=oldNamelang; Filenamekurz:=oldNamekurz;
- goto quit;
- END;
-
- SpriteLength:=Gesamtgroesse;
-
- {Jetzt die eigentlichen Spritedaten berechnen:}
- offset:=0;
- FOR j:=0 TO WorkAreaMaxUsedY DO
- FOR i:=0 TO Pred(Breite_in_4er_Gruppen) DO
- BEGIN
- FOR p:=0 TO 3 DO
- Readin[Zeiger_auf_Plane[p]+offset]:=
- Workarea^.feld[j,(i shl 2)+p];
- inc(offset);
- END;
-
- {Nun die X-Grenzdaten für jede Zeile:}
- offset:=0;
- FOR j:=0 TO WorkAreaMaxUsedY DO
- BEGIN
- links:=0;
- rechts:=Pred(Breite_in_4er_Gruppen shl 2);
- fertig_li:=false; fertig_re:=false;
- REPEAT
- if (not fertig_li and (WorkArea^.feld[j,links]=0))
- THEN inc(links) ELSE fertig_li:=true;
- if (not fertig_re and (WorkArea^.feld[j,rechts]=0))
- THEN dec(rechts) ELSE fertig_re:=true;
- if links>rechts THEN BEGIN fertig_li:=true; fertig_re:=true END;
- UNTIL fertig_li and fertig_re;
- if links>rechts
- THEN BEGIN {Leerzeile, Sentinelwerte eintragen}
- readin[ZeigerL+offset]:=lo(+16000);
- readin[Succ(ZeigerL+offset)]:=hi(+16000);
- readin[ZeigerR+offset]:=lo(-16000);
- readin[Succ(ZeigerR+offset)]:=hi(-16000)
- END
- ELSE BEGIN {normale Zeile, Grenzen eintragen}
- readin[ZeigerL+offset]:=lo(links);
- readin[Succ(ZeigerL+offset)]:=hi(links);
- readin[ZeigerR+offset]:=lo(rechts);
- readin[Succ(ZeigerR+offset)]:=hi(rechts)
- END;
- inc(offset,2) {Grenzeinträge sind Wörter!}
- END;
-
- {Dasselbe für die Grenzdaten jeder Spalte:}
- offset:=0;
- FOR i:=0 TO Pred(Breite_in_4er_Gruppen shl 2) DO
- BEGIN
- oben :=0;
- unten:=WorkAreaMaxUsedY;
- fertig_ob:=false; fertig_un:=false;
- REPEAT
- if (not fertig_ob and (Workarea^.feld[oben,i]=0))
- THEN inc(oben) ELSE fertig_ob:=true;
- if (not fertig_un and (Workarea^.feld[unten,i]=0))
- THEN dec(unten) ELSE fertig_un:=true;
- if oben>unten THEN BEGIN fertig_ob:=true; fertig_un:=true END;
- UNTIL fertig_ob and fertig_un;
- if oben>unten
- THEN BEGIN {Leerspalte, Sentinelwerte eintragen}
- readin[ZeigerO+offset]:=lo(+16000);
- readin[Succ(ZeigerO+offset)]:=hi(+16000);
- readin[ZeigerU+offset]:=lo(-16000);
- readin[Succ(ZeigerU+offset)]:=hi(-16000)
- END
- ELSE BEGIN {normale Spalte, Grenzen eintragen}
- readin[ZeigerO+offset]:=lo(oben);
- readin[Succ(ZeigerO+offset)]:=hi(oben);
- readin[ZeigerU+offset]:=lo(unten);
- readin[Succ(ZeigerU+offset)]:=hi(unten)
- END;
- inc(offset,2) {Grenzeinträge sind Wörter!}
- END;
-
- END; {of with}
-
- {Nun die Daten auf Disk schreiben:}
- assign(f,Filenamelang);
- rewrite(f,1);
- blockwrite(f,sprite^.readin,Gesamtgroesse);
- close(f);
- quit:;
- Dispose(Sprite);
- PutImage(MeldungX+50,MeldungY,pp^,NormalPut);
- Dispose(pp);
- ShowFilename;
- END;
-
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {Workarea leer!}
- ErrBeep;
- exit
- END;
-
- {evtl. alten Filenamen aufheben}
- oldNamelang:=Filenamelang; oldNamekurz:=Filenamekurz;
-
- RestoreCRTMode;
- ClrScr;
-
- GotoXY(x1,y1-2);
- WRITE('Please give a name (*.COD) for your sprite file; <ESC> to cancel');
- GotoXY(1,y2+4);
- WRITELN('Use the following keys to edit your input:'); WRITELN;
- WRITELN('HOME/END : move cursor to the start/end of line');
- WRITELN('LEFT/RIGHT : move cursor one char');
- WRITELN('^LEFT/^RIGHT, ^A/^F : move cursor one word');
- WRITELN;
- WRITELN('INS, ^V : toggle insert/overwrite mode');
- WRITELN('UP/DOWN, ^E/^X : review the last (up to 30) input lines');
- WRITELN;
- WRITELN('^T : delete word DEL, ^G : delete char under cursor');
- WRITELN('^K : delete to end of line BSPC,^H : backspace');
- WRITELN('^Y : delete whole input line ESC : cancel input');
- WRITELN;
- WRITELN('F3 : use last input line');
-
- attr:=textattr; textattr:=boxcolor;
- window(x1,y1,x2,y2);
- clrscr;
- window(1,1,80,25);
- Rahmen(x1,y1,x2,y2);
- window(succ(x1),succ(y1),pred(x2),pred(y2));
-
- {Defaultwert für Namen aus Filenamelang bestimmen:}
- IF Filenamelang<>''
- THEN BEGIN {dafür sorgen, daß evtl. Extension '.COD' lautet}
- FSplit(Filenamelang,D,N,E);
- temp:=D+N+'.COD'
- END
- ELSE temp:='';
-
- abbruch:=false; {heißt: behalte die letzten 30 gemachten Eingaben}
- GotoXY(1,1); {= 1.Position in der Eingabetextbox}
- String_eingeben(temp,x2-x1-2,abbruch);
- window(1,1,80,25);
- textattr:=attr;
- IF abbruch
- THEN BEGIN {ESC gedrückt}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- WRITE('You didn''t choose a file! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- END
- ELSE BEGIN {Dateinamen ausprobieren}
- FOR i:=1 TO Length(temp) DO
- CASE temp[i] OF
- 'ä':temp[i]:='Ä';
- 'ö':temp[i]:='Ö';
- 'ü':temp[i]:='Ü'
- ELSE temp[i]:=upcase(temp[i])
- END;
-
- if not gueltig(temp,'.COD')
- THEN BEGIN {ungültiger Dateiname}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- ClrEol; WRITELN('*** Error! Couldn''t open file with name:');
- ClrEol; WRITELN;
- ClrEol; WRITELN(temp);
- ClrEol; WRITELN;
- ClrEol; WRITE('(invalid access path or filename)! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- abbruch:=true; {Ist auch als Abbruch zu bewerten!}
- END
- ELSE BEGIN {gültiger Name, in Filename_* übernehmen}
- P:=temp;
- FSplit(P,D,N,E);
- Filenamelang:=P;
- Filenamekurz:=N+E;
- END;
- END;
-
- setgraphmode(VID640x400x256);
- RestoreScreen;
-
- IF not abbruch
- THEN BEGIN
- schreibe_Daten; {Eigentliche Daten berechnen & schreiben}
- IF NOT PalEqual(ActualColors,DefaultColors)
- THEN OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- 'The active palette differs',
- 'from the standard palette;',
- 'don''t forget to save it!'
- ,Abfrage);
- END;
- END;
-
- PROCEDURE speicherePalette;
- { in: Palnamelang = Defaultwert für Palettedaten}
- {out: Auf Disk wurde der Inhalt der gerade aktuellen Palette "ActualColors"}
- { abgelegt }
- { Palname* = neue Palettennamen}
- {rem: Falls <ESC> gedrückt wurde, dann wurde keine Datei angelegt}
- CONST x1=1; y1=4; x2=80; y2=y1+2; {Koordinaten für Eingabebox}
- VAR temp:EingabeString;
- abbruch:Boolean;
- size:word;
- attr:Byte;
- i:Integer;
- ch:Char;
- oldPalNamelang,oldPalNamekurz,
- P: PathStr;
- D: DirStr;
- N: NameStr;
- E: ExtStr;
-
- BEGIN
- {evtl. alten Filenamen aufheben}
- oldPalNamelang:=Palnamelang; oldPalNamekurz:=Palnamekurz;
-
- RestoreCRTMode;
- ClrScr;
-
- GotoXY(x1,y1-2);
- WRITE('Please give a name (*.PAL) for your palette file; <ESC> to cancel');
- GotoXY(1,y2+4);
- WRITELN('Use the following keys to edit your input:'); WRITELN;
- WRITELN('HOME/END : move cursor to the start/end of line');
- WRITELN('LEFT/RIGHT : move cursor one char');
- WRITELN('^LEFT/^RIGHT, ^A/^F : move cursor one word');
- WRITELN;
- WRITELN('INS, ^V : toggle insert/overwrite mode');
- WRITELN('UP/DOWN, ^E/^X : review the last (up to 30) input lines');
- WRITELN;
- WRITELN('^T : delete word DEL, ^G : delete char under cursor');
- WRITELN('^K : delete to end of line BSPC,^H : backspace');
- WRITELN('^Y : delete whole input line ESC : cancel input');
- WRITELN;
- WRITELN('F3 : use last input line');
-
- attr:=textattr; textattr:=boxcolor;
- window(x1,y1,x2,y2);
- clrscr;
- window(1,1,80,25);
- Rahmen(x1,y1,x2,y2);
- window(succ(x1),succ(y1),pred(x2),pred(y2));
-
- {Defaultwert für Namen aus Palnamelang bestimmen:}
- IF PalNamelang<>''
- THEN BEGIN {dafür sorgen, daß evtl. Extension '.PAL' lautet}
- FSplit(PalNamelang,D,N,E);
- temp:=D+N+'.PAL'
- END
- ELSE temp:='';
-
- abbruch:=false; {heißt: behalte die letzten 30 gemachten Eingaben}
- GotoXY(1,1); {= 1.Position in der Eingabetextbox}
- String_eingeben(temp,x2-x1-2,abbruch);
- window(1,1,80,25);
- textattr:=attr;
- IF abbruch
- THEN BEGIN {ESC gedrückt}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- WRITE('You didn''t choose a file! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- END
- ELSE BEGIN {Dateinamen ausprobieren}
- FOR i:=1 TO Length(temp) DO
- CASE temp[i] OF
- 'ä':temp[i]:='Ä';
- 'ö':temp[i]:='Ö';
- 'ü':temp[i]:='Ü'
- ELSE temp[i]:=upcase(temp[i])
- END;
-
- if not gueltig(temp,'.PAL')
- THEN BEGIN {ungültiger Dateiname}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- ClrEol; WRITELN('*** Error! Couldn''t open file with name:');
- ClrEol; WRITELN;
- ClrEol; WRITELN(temp);
- ClrEol; WRITELN;
- ClrEol; WRITE('(invalid access path or filename)! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- abbruch:=true; {Ist auch als Abbruch zu bewerten!}
- END
- ELSE BEGIN {gültiger Name, in PalName_* übernehmen}
- P:=temp;
- FSplit(P,D,N,E);
- PalNamelang:=P;
- PalNamekurz:=N+E;
- END;
- END;
-
- setgraphmode(VID640x400x256);
- RestoreScreen;
-
- IF not abbruch
- THEN SavePalette(PalNamelang,ActualColors); {Eigentliche Daten schreiben}
- END;
-
-
- PROCEDURE speichereHintergrund;
- { in: Filenamelang = Defaultwert für Hintergrunddaten}
- { Workarea^ = abzuspeichernde Daten}
- { WorkAreaMaxUsedX|Y = max. benutzte Extremkoordinaten}
- { ActualColors = gerade gesetzte Farben}
- { DefaultColors = Standardfarben des BIOS-256-Farbenmodus}
- {out: Auf Disk wurde der Inhalt der Workarea als Bild abgelegt }
- { Filename* = neue Filenamen}
- {rem: Falls die Workarea leer war oder <ESC> gedrückt wurde, dann}
- { wurde keine Datei angelegt}
- CONST x1=1; y1=4; x2=80; y2=y1+2; {Koordinaten für Eingabebox}
- VAR temp:EingabeString;
- abbruch:Boolean;
- size:word;
- attr:Byte;
- i:Integer;
- ch:Char;
- oldNamelang,oldNamekurz,
- P: PathStr;
- D: DirStr;
- N: NameStr;
- E: ExtStr;
-
- PROCEDURE SavePage;
- { in: Filenamelang = Name der zu schreibenden Datei}
- { oldName* = alte Dateinamen}
- { Workarea^.[] = zu schreibende Daten}
- {out: Falls Sprite nicht erstellt werden konnte, wurden die alten}
- { Dateinamen für Filename* wieder eingesetzt!}
- {rem: Der Inhalt der Workarea wird in die Datei Filenamelang }
- { geschrieben; der Dateiname wurde bereits auf Eröffenbar-}
- { keit geprüft, ebenso, daß die Workarea nicht leer ist! }
- CONST PICHeader:STRING[3]='PIC'; {Kennung in Bilderdateien}
- VAR f:file;
- s:String[20];
- i:BYTE;
- t,x,y:WORD;
- picture:Bild;
- pp:POINTER;
- pplen:WORD;
- BEGIN
- SetColor(BestWhite); s:='just a moment...';
- pplen:=ImageSize(MeldungX+50,MeldungY,
- MeldungX+50+length(s) SHL 3,MeldungY+9);
- GetMem(pp,pplen);
- GetImage(MeldungX+50,MeldungY,
- MeldungX+50+length(s) SHL 3,MeldungY+9,pp^);
- OutTextXY(MeldungX+50,MeldungY,s);
-
- Assign(f,Filenamelang);
- Rewrite(f,1);
- BlockWrite(f,PICHeader[1],Length(PICHeader));
-
- {Bilddaten zusammenstellen:}
- FOR i:=0 TO 3 DO New(picture[i]);
- FOR y:=0 TO YMAX DO
- FOR x:=0 TO XMAX SHR 2 DO
- BEGIN
- t:=y*LINESIZE;
- picture[0]^[t+x]:=Workarea^.feld[y,x shl 2 +0];
- picture[1]^[t+x]:=Workarea^.feld[y,x shl 2 +1];
- picture[2]^[t+x]:=Workarea^.feld[y,x shl 2 +2];
- picture[3]^[t+x]:=Workarea^.feld[y,x shl 2 +3];
- END;
- FOR i:=0 TO 3 DO BlockWrite(f,picture[i]^,PAGESIZE);
- Close(f);
-
- FOR i:=0 TO 3 DO Dispose(picture[i]);
- PutImage(MeldungX+50,MeldungY,pp^,NormalPut);
- Dispose(pp);
- ShowFilename;
- END;
-
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {Workarea leer!}
- ErrBeep;
- exit
- END;
-
- {evtl. alten Filenamen aufheben}
- oldNamelang:=Filenamelang; oldNamekurz:=Filenamekurz;
-
- RestoreCRTMode;
- ClrScr;
-
- GotoXY(x1,y1-2);
- WRITE('Please give a name (*.PIC) for your picture file; <ESC> to cancel');
- GotoXY(1,y2+4);
- WRITELN('Use the following keys to edit your input:'); WRITELN;
- WRITELN('HOME/END : move cursor to the start/end of line');
- WRITELN('LEFT/RIGHT : move cursor one char');
- WRITELN('^LEFT/^RIGHT, ^A/^F : move cursor one word');
- WRITELN;
- WRITELN('INS, ^V : toggle insert/overwrite mode');
- WRITELN('UP/DOWN, ^E/^X : review the last (up to 30) input lines');
- WRITELN;
- WRITELN('^T : delete word DEL, ^G : delete char under cursor');
- WRITELN('^K : delete to end of line BSPC,^H : backspace');
- WRITELN('^Y : delete whole input line ESC : cancel input');
- WRITELN;
- WRITELN('F3 : use last input line');
-
- attr:=textattr; textattr:=boxcolor;
- window(x1,y1,x2,y2);
- clrscr;
- window(1,1,80,25);
- Rahmen(x1,y1,x2,y2);
- window(succ(x1),succ(y1),pred(x2),pred(y2));
-
- {Defaultwert für Namen aus Filenamelang bestimmen:}
- IF Filenamelang<>''
- THEN BEGIN {dafür sorgen, daß evtl. Extension '.PIC' lautet}
- FSplit(Filenamelang,D,N,E);
- temp:=D+N+'.PIC'
- END
- ELSE temp:='';
-
- abbruch:=false; {heißt: behalte die letzten 30 gemachten Eingaben}
- GotoXY(1,1); {= 1.Position in der Eingabetextbox}
- String_eingeben(temp,x2-x1-2,abbruch);
- window(1,1,80,25);
- textattr:=attr;
- IF abbruch
- THEN BEGIN {ESC gedrückt}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- WRITE('You didn''t choose a file! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- END
- ELSE BEGIN {Dateinamen ausprobieren}
- FOR i:=1 TO Length(temp) DO
- CASE temp[i] OF
- 'ä':temp[i]:='Ä';
- 'ö':temp[i]:='Ö';
- 'ü':temp[i]:='Ü'
- ELSE temp[i]:=upcase(temp[i])
- END;
-
- if not gueltig(temp,'.PIC')
- THEN BEGIN {ungültiger Dateiname}
- Window(1,y2+1,80,25); ClrScr; Window(1,1,80,25);
- GotoXY(x1,y2+2);
- ClrEol; WRITELN('*** Error! Couldn''t open file with name:');
- ClrEol; WRITELN;
- ClrEol; WRITELN(temp);
- ClrEol; WRITELN;
- ClrEol; WRITE('(invalid access path or filename)! <any key>');
- ch:=readkey; while keypressed do ch:=readkey;
- abbruch:=true; {Ist auch als Abbruch zu bewerten!}
- END
- ELSE BEGIN {gültiger Name, in Filename_* übernehmen}
- P:=temp;
- FSplit(P,D,N,E);
- Filenamelang:=P;
- Filenamekurz:=N+E;
- END;
- END;
-
- setgraphmode(VID640x400x256);
- RestoreScreen;
-
- IF not abbruch
- THEN BEGIN
- SavePage; {Eigentliche Daten berechnen & schreiben}
- IF NOT PalEqual(ActualColors,DefaultColors)
- THEN OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- 'The active palette differs',
- 'from the standard palette;',
- 'don''t forget to save it!'
- ,Abfrage);
- END;
- END;
-
- PROCEDURE ResetColors;
- { in: DefaultColors = zu setzende Standardpalette}
- {out: ActualColors = Standardfarben}
- { Palname* = ''}
- BEGIN
- ActualColors:=DefaultColors;
- Palnamelang:=''; Palnamekurz:=''; {geladene Palette invalidieren}
- RestoreScreen; {neue Farben sichtbar machen, Menufarben & -namen anpassen}
- END;
-
- PROCEDURE init;
- { prüft + initialisiert Maus, reserviert Platz für Mausmaske}
- { initialisiert Grafik, sucht VGA-Karten-spezifische Grafikregister}
- { reserviert Platz für Workarea-Inhalt}
- { initialisiert Grafikbildschirm}
- { initialisiert Variablen: Filename*, Palname*, Farben*, Koordmeld?}
- { Event=EventNone}
- BEGIN
- writeln(11);
- IF NOT MouseInstalled
- THEN BEGIN {Ohne Maus läuft nix!}
- WRITELN(#7+'Error! Couldn''t detect mouse!');
- Halt(1)
- END
- ELSE BEGIN
- SwapVectors;
- initmouse;
- END;
-
- FindVGARegisters;
- init640x400x256;
-
- WITH oldMouse DO
- BEGIN
- MouseMemSize:=ImageSize(0,0,CursorMaxX,CursorMaxY);
- GetMem(MouseMem,MouseMemSize);
- END;
- Event:=EventNone;
-
- New(WorkArea);
- FillChar(WorkArea^,SizeOf(WorkArea^),transparent);
- Filenamelang:=''; Filenamekurz:='';
- Palnamelang:=''; Palnamekurz:='';
- FarbenStartX:=5;
- FarbenHoehegesamt:=20;
- FarbenStartY:=getmaxy-FarbenHoehegesamt-1;
- Koordmeldx:=FarbenStartX+265;
- Koordmeldy:=FarbenStartY-1;
- FilenameStartX:=(WorkEndX-WorkStartX-12*8) div 2+WorkStartX;
- FilenameStartY:=WorkStartY-10;
- PalnameStartX:=(25+15*PalBreite-12*8) div 2 +PaletteX;
- PalnameStartY:=PaletteY-10;
- RestoreScreen;
- END;
-
- PROCEDURE Help;
- VAR ch:CHAR;
- BEGIN
- RestoreCRTMode;
- TextColor(White); TextBackGround(Blue);
- ClrScr;
-
- WRITELN('Help');
- WRITELN('────');
- WRITELN('Besides the functions indicated by the function keys at the'+
- ' lower screen boun-');
- WRITELN('dary, you have the following options:');
- WRITELN;
- WRITELN(' "+", "-" = zoom in/out the workarea');
- WRITELN(' Shift-F3 = load sprite without erasing the workarea previously');
- WRITELN(' Shift-F5 = reset palette to default color palette');
- WRITELN(' Shift-F7 = load picture without erasing the workarea previously');
- WRITELN(' Shift-F9 = remap object''s colors to default color palette');
- WRITELN;
- WRITELN(' Use the cursor keys to scroll the graphic contents around'+
- ' (if it doesn''t fit');
- WRITELN(' on the screen because of zooming); use SHIFT in addition to'+
- ' scroll pixelwise.');
- WRITELN(' Similar, pressing SHIFT while clicking at one of the rotate'+
- ' buttons will');
- WRITELN(' rotate the screen by one pixel only.');
- WRITELN;
- WRITELN(' Hold down SHIFT while clicking in the workarea for aligned'+
- ' objects (circles');
- WRITELN(' instead of ellipses, etc.).');
- WRITELN;
- WRITELN(' Clicking at the "move to origin" button with Shift will scroll'+
- ' the workarea to');
- WRITELN(' point (0,0) instead');
-
- GotoXY(1,25); TextColor(Yellow);
- WRITE('[press any key]');
- WHILE KeyPressed DO ch:=ReadKey;
- ch:=ReadKey;
- WHILE KeyPressed DO ch:=ReadKey;
-
- TextColor(White); TextBackGround(Black);
- setgraphmode(VID640x400x256);
- RestoreScreen;
- END;
-
- PROCEDURE MapPalette;
- { in: ZielPalette = Zielfarben, auf die gemappt werden soll }
- { ActualColors = aktuelle Farben, die gemappt werden sollen}
- { WorkArea = umzumappende Daten}
- {out: WorkArea = neue Grafikdaten, auf DefaultColors approximiert }
- { WorkAreaMaxUsedX|Y = evtl. neue Extremkoordinaten}
- {rem: Die Farben wurden mit einer "Minimum-square-error"-Routine so gut}
- { wie möglich auf die Farben "ZielPalette" abgebildet, wodurch sich}
- { die Daten natürlich ändern!}
- { Grafikmodus muß gesetzt sein!}
- { Routine sollte nur aufgerufen werden, wenn Workarea nicht leer ist!}
- VAR LookUp:ARRAY[0..255] OF BYTE;
-
- FUNCTION MapToDefaultColors(Color:BYTE):BYTE; ASSEMBLER;
- { in: Color = Farbnummer des 256 Farbmodus, die approximiert werden soll}
- { ActualColors = gerade gesetzte 256 Farben}
- { DefaultColors= Tabelle der Defaultfarben der 16 (256) Farbmodi}
- {out: Defaultfarbe des 256 Farbmodus, die am ehesten der uebergebenen }
- { Farbe entspricht}
- ASM
- MOV BL,Color
- XOR BH,BH
- MOV SI,BX
- SHL SI,1
- ADD SI,BX
- ADD SI,OFFSET ActualColors
- MOV BX,[SI]
- MOV DH,[SI+2] {BL/BH/DH = aktuelle Farbe, RGB}
-
- PUSH BP
- MOV DI,65535 {DI=bisher gefundenes minimales Fehlerquadrat}
- MOV CX,255
- MOV SI,OFFSET ZielPalette {DS:SI = Zeiger auf DefaultColors}
-
- @searchloop:
- MOV AL,BL
- SUB AL,[SI] {Farbdifferenz im Rotanteil}
- IMUL AL {Fehler*quadrat* optimieren}
- MOV BP,AX
-
- MOV AL,BH {dto., Gruenanteil}
- SUB AL,[SI+1]
- IMUL AL
- ADD BP,AX
- JC @noNewMin
-
- MOV AL,DH {dto., Blauanteil}
- SUB AL,[SI+2]
- IMUL AL
- ADD AX,BP
- JC @noNewMin
-
- CMP AX,DI
- JAE @noNewMin
- MOV DI,AX
- MOV DL,CL {100h-DL=bisher optimale Farbe}
- @noNewMin:
- ADD SI,3 {naechste Farbe zum Vergleich}
- LOOP @searchloop
-
- POP BP
-
- MOV AL,DL
- NOT AL {AL:=100h-DL = optimale Farbe}
- XOR AH,AH
- END;
-
- BEGIN
- IF PalEqual(ZielPalette,ActualColors)
- THEN BEGIN {aktuelle Farben = Zielfarben, also kein Mapping nötig}
- ErrBeep;
- exit
- END
- ELSE BEGIN
- {Farbumsetztabelle bestimmen:}
- FOR i:=0 TO 255 DO LookUp[i]:=MapToDefaultColors(i);
- {Grafikdaten umsetzen:}
- FOR y:=0 TO YMAX DO
- FOR x:=0 TO XMAX DO
- WorkArea^.feld[y,x]:=LookUp[WorkArea^.feld[y,x]];
- {Änderungen anzeigen: Zielfarben setzen und Grafik zeigen}
- ActualColors:=ZielPalette;
- IF PalEqual(ActualColors,DefaultColors)
- THEN BEGIN {Bei Defaultfarbenpalette dies auch melden}
- Palnamekurz:='';
- Palnamelang:=''
- END;
-
- FindWorkAreaMaxUsed; {evtl. haben sich die Extremkoord. geändert}
- RestoreScreen; {neue Farben sichtbar machen, Menufarben & -namen anpassen}
- END;
- END;
-
- PROCEDURE MapToBIOSPalette;
- { in: ZielPalette = Zielfarben, auf die gemappt werden soll }
- { ActualColors = aktuelle Farben, die gemappt werden sollen}
- { WorkArea = umzumappende Daten}
- {out: WorkArea = neue Grafikdaten, auf DefaultColors approximiert }
- { WorkAreaMaxUSedX|Y = evtl. neue Extremkoordinaten}
- {rem: Die Farben wurden mit einer "Minimum-square-error"-Routine so gut}
- { wie möglich auf die Defaultfarben "DefaultColors" abgebildet, wo-}
- { durch sich die Daten natürlich ändern!}
- { Grafikmodus muß gesetzt sein!}
- BEGIN
- ZielPalette:=DefaultColors;
- MapPalette
- END;
-
- PROCEDURE AdjustMouse;
- { in: MausX,MausY = aktuelle Mauskoordinaten}
- { zoom = aktueller Zoomfaktor}
- { WorkStartX|Y, WorkEndX|Y = WorkArea-Begrenzungen}
- {out: MausX,MausY wurden so justiert, daß sie nur in einem Raster der }
- { Breite und Höhe "zoom" bewegt werden können und dabei so genau }
- { wie möglich in die Mitte eines solchen Rasterpunktes gesetzt }
- { wurden; fiele der so generierte Punkt außerhalb der WorkArea, }
- { so wird ein Kompromiß gefunden, so daß er wieder innerhalb liegt}
- { Vorher wird die Maus bereits so justiert, daß sie nicht aus dem }
- { Raster [0..319,0..199] fällt (ist durch das scrollen möglich)! }
- {rem: Diese Routine sollte nur gerufen werden, wenn MausX|Y innerhalb }
- { der Workarea liegen}
- VAR rx,ry:INTEGER;
- BEGIN
- IF NOT InWorkArea THEN exit;
-
- Absolute2Workarea(rx,ry); {relative Koordinaten ermitteln}
- rx:=min(rx,WorkBreite-1); {diese müssen im Bereich [0..319,0..199]}
- ry:=min(ry,WorkHoehe-1); {liegen!}
- Workarea2Absolute(rx,ry,MausX,MausY); {in absolute Koord. zurückrechnen}
-
- MausX:=MausX-((MausX-WorkStartX) MOD zoom);
- IF MausX+zoom SHR 1>WorkEndX
- THEN BEGIN {Punktmitte wäre außerhalb}
- MausX:=MausX+ (WorkEndX-MausX) SHR 1
- END
- ELSE INC(MausX,zoom SHR 1);
-
- MausY:=MausY-((MausY-WorkStartY) MOD zoom);
- IF MausY+zoom SHR 1>WorkEndY
- THEN BEGIN {Punktmitte wäre außerhalb}
- MausY:=MausY+ (WorkEndY-MausY) SHR 1
- END
- ELSE INC(MausY,zoom SHR 1);
- END;
-
- PROCEDURE SelectColor;
- { in: MausX,MausY = aktuelle Mauskoordinaten, irgendwo im Palettenbereich}
- {out: aktuelleFarbe=gewählte Farbe, falls gültige Farbe angeclickt wurde }
- {rem: aktuelle Farbe wird zugleich im dafür reservierten Feld angezeigt }
- VAR i,j:BYTE;
- BEGIN
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN exit; {knapp daneben ist auch vorbei: zwischen 2 Farben geclickt!}
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN exit; {dto.}
-
- aktuelleFarbe:=j SHL 4 + i; {=j*16+i}
- ShowActualColor
- END;
-
-
- PROCEDURE ScrollLeft(amount:INTEGER);
- BEGIN
- IF StartVirtualX>0
- THEN BEGIN
- StartVirtualX:=max(0,StartVirtualX-amount);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- ShowOffset;
- END
- ELSE ErrBeep
- END;
-
- PROCEDURE ScrollRight(amount:INTEGER);
- BEGIN
- IF StartVirtualX<XMAX
- THEN BEGIN
- StartVirtualX:=min(XMAX,StartVirtualX+amount);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- ShowOffset;
- END
- ELSE ErrBeep
- END;
-
- PROCEDURE ScrollUp(amount:INTEGER);
- BEGIN
- IF StartVirtualY>0
- THEN BEGIN
- StartVirtualY:=max(0,StartVirtualY-amount);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- ShowOffset;
- END
- ELSE ErrBeep
- END;
-
- PROCEDURE ScrollDown(amount:INTEGER);
- BEGIN
- IF StartVirtualY<YMAX
- THEN BEGIN
- StartVirtualY:=min(YMAX,StartVirtualY+amount);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- ShowOffset;
- END
- ELSE ErrBeep
- END;
-
- PROCEDURE GotoUpLeft;
- { in: StartVirtualX|Y = momentaner sichtbarer Beginn der Workarea}
- { WorkAreaMaxUsedX|Y = max. benutzte Koordinaten}
- {out: StartVirtualX|Y = 0}
- {rem: sichtbarer Workarea-Ausschnitt wurde zurückgesetzt auf 0,0 }
- BEGIN
- IF (StartVirtualX<>0) OR (StartVirtualY<>0)
- THEN BEGIN
- StartVirtualX:=0;
- StartVirtualY:=0;
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- ShowOffset;
- END
- END;
-
- PROCEDURE WorkAreaAction;
- { in: Maus befindet sich in WorkArea}
- { MausX|Y = aktuelle Mauskoordinaten (bereits bzgl. Zooming justiert)}
- { LeftButton, RightButton = Mausbuttonzustände}
- { Objekt = aktuelles Zeichenobjekt }
- { aktuelleFarbe = aktuelle Zeichenfarbe}
- { aktuellesTool = aktuelles Tool }
- { Workarea = aktuelle Grafikdaten}
- {out: Workarea = evtl. veränderte Grafikdaten}
- { Objekt = evtl. veränderte Grafikdaten}
- {rem: Maus ist noch abgeschaltet!}
- VAR dx,dy,diff:INTEGER;
- BEGIN
- WITH Objekt DO
- BEGIN
- IF (stage<>0) AND (RightButton)
- THEN BEGIN {Abbruch der begonnenen Aktion}
- ClearOldObject;
- stage:=0; {damit existiert kein Objekt mehr}
- exit
- END;
-
- IF (stage=0) AND (LeftButton) AND (aktuellesTool=Punkt)
- THEN BEGIN {einfachster Fall: einfach einen Punkt setzen}
- Absolute2WorkArea(StartX,StartY); {aktuelle relative Koord. holen}
-
- (* Die folgenden Zeilen wären ein schnellerer (aber konzeptionell *)
- (* unschöner) Ersatz für die Zeilen ab "Typ:=..." bis "StoreObject"*)
- (* (jeweils einschließlich). Dies wäre deshalb möglich, weil einen *)
- (* Punkt zu setzen eine "unteilbare" Aktion darstellt, die nicht *)
- (* über mehrere Hauptprogrammzyklen verschliffen ist! *)
- (*
- Workarea^.feld[StartY,StartX]:=aktuelleFarbe; {Punkt setzen}
- IF aktuelleFarbe<>transparent
- THEN BEGIN {benutzte Workarea-Fläche größer geworden?}
- WorkAreaMaxUsedX:=max(StartX,WorkAreaMaxUsedX);
- WorkAreaMaxUsedY:=max(StartY,WorkAreaMaxUsedY);
- END
- ELSE FindWorkAreaMaxUsed;
- {nur diesen einen (logischen) Punkt auf dem Schirm neuzeichnen:}
- UpdateWorkArea(StartX,StartY,StartX,StartY,FALSE);
- *)
- Stage:=1;
- Typ :=aktuellesTool; {=Punkt}
- DrawNewObject;
- StoreObject;
- exit
- END;
-
- IF (stage<>0) AND (NOT LeftButton)
- THEN BEGIN {temporäres Objekt zeichnen}
- CASE Typ OF
- {Punkt:DrawNewObject}
- Linie:BEGIN
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY); {wo steht der Mauscursor?}
- IF aligned
- THEN BEGIN {nur horiz., vert. oder diagonale Zeilen!}
- dx:=abs(LastX-StartX); dy:=abs(LastY-StartY);
- {Anhand der Steigung entscheiden, was für eine}
- {Ausrichtung erfolgen soll: 0..0.5=horizontal,}
- {0.5..2 = diagonal, 2..?? = vertikal}
- IF dx>2*dy THEN LastY:=StartY {horizontal}
- ELSE IF dy>2*dx THEN LastX:=StartX {vertikal}
- ELSE BEGIN
- {Diagonale, dafür wird aber auch das Vorzeichen}
- {der Steigung benötigt!}
- diff:=min(dx,dy);
- LastX:=StartX+sign(LastX-StartX)*diff;
- LastY:=StartY+sign(LastY-StartY)*diff
- END;
- END;
- DrawNewObject;
- END;
- Rechteck:BEGIN {Quadrate auch!}
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY);
- IF aligned
- THEN BEGIN {Quadrat!}
- dx:=abs(LastX-StartX); dy:=abs(LastY-StartY);
- diff:=min(dx,dy);
- LastX:=StartX+sign(LastX-StartX)*diff;
- LastY:=StartY+sign(LastY-StartY)*diff;
- END;
- DrawNewObject;
- END;
- Ellipse_:BEGIN
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY);
- DrawNewObject;
- END;
- FRechteck:BEGIN {gefüllte Quadrate auch!}
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY);
- IF aligned
- THEN BEGIN {Quadrat!}
- dx:=abs(LastX-StartX); dy:=abs(LastY-StartY);
- diff:=min(dx,dy);
- LastX:=StartX+sign(LastX-StartX)*diff;
- LastY:=StartY+sign(LastY-StartY)*diff;
- END;
- DrawNewObject;
- END;
- FEllipse:BEGIN
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY);
- DrawNewObject;
- END;
- FuellEimer:BEGIN
- ClearOldObject;
- Absolute2WorkArea(LastX,LastY);
- DrawNewObject;
- END;
- Kopie:BEGIN
- ClearOldObject;
- IF stage=1
- THEN Absolute2WorkArea(LastX,LastY)
- ELSE Absolute2WorkArea(actX,actY); {stage=2!}
- DrawNewObject
- END;
- else ErrBeep;
- END; {of CASE}
- END;
-
- {------- neues Objekt beginnen? -------}
-
- IF LeftButton
- THEN BEGIN {Zustandswechsel des Objekts!}
- IF stage=0 THEN
- BEGIN {neues Objekt beginnen}
- stage:=1; {=begonnen, aber noch nicht fertig}
- Absolute2Workarea(StartX,StartY); {Startpunkt merken}
- LastX:=StartX; LastY:=StartY; {Endpunkt = Startpunkt}
- Typ:=aktuellesTool;
- IF Shift THEN aligned:=TRUE ELSE aligned:=FALSE;
-
- {Sonderbehandlung Fülleimer: schon beim ersten Anclicken aktiv!}
- IF Typ=FuellEimer THEN DrawWorkAreaFill(LastX,LastY,aktuelleFarbe,DRAW);
-
- END
- ELSE IF stage=1 THEN
- BEGIN {begonnenes Objekt abschließen?}
- CASE Typ OF
- Linie,
- Rechteck,
- Ellipse_,
- FRechteck,
- FEllipse,
- FuellEimer: StoreObject;
- Kopie: BEGIN
- ClearOldObject;
- stage:=2;
- END;
- END;
- END
- ELSE {IF stage=2 THEN}
- BEGIN {dto.}
- IF Typ=Kopie THEN StoreObject
- END;
- END;
- END; {of WITH}
- END;
-
- PROCEDURE Zoomin;
- { in: zoom = momentaner Vergrößerungsfaktor}
- {out: zoom = neuer Vergrößerungsfaktor }
- {rem: Bildschirminhalt wurde vergrößert }
- CONST MaxZoom=30;
- BEGIN
- IF zoom<MaxZoom
- THEN BEGIN
- inc(zoom);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt wieder auf den Schirm bringen}
- ShowZoom;
- END
- ELSE ErrBeep
- END;
-
- PROCEDURE Zoomout;
- { in: zoom = momentaner Vergrößerungsfaktor}
- {out: zoom = neuer Vergrößerungsfaktor }
- {rem: Bildschirminhalt wurde verkleinert }
- BEGIN
- IF zoom>1
- THEN BEGIN
- dec(zoom);
- {nur Workarea updaten - geht schneller als "RestoreScreen()"!}
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt wieder auf den Schirm bringen}
- ShowZoom;
- END
- ELSE ErrBeep
- END;
-
-
- PROCEDURE SelectNewTool;
- { in: Event=eines der EventTool* Events}
- {out: aktuellesTool = neues, selektiertes Tool}
- BEGIN
- CASE Event OF
- EventToolPixel:BEGIN
- IF aktuellesTool=Punkt THEN exit; {nix zu tun!}
- ClearOldObject; {evtl. altes Objekt löschen}
- Objekt.stage:=0; {intern natürlich auch}
- aktuellesTool:=Punkt;
- ShowActualTool; {neues Tool anzeigen}
- END;
- EventToolLine :BEGIN
- IF aktuellesTool=Linie THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=Linie;
- ShowActualTool;
- END;
- EventToolRectangle:BEGIN
- IF aktuellesTool=Rechteck THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=Rechteck;
- ShowActualTool;
- END;
- EventToolEllipse:BEGIN
- IF aktuellesTool=Ellipse_ THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=Ellipse_;
- ShowActualTool;
- END;
- EventToolBar:BEGIN
- IF aktuellesTool=FRechteck THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=FRechteck;
- ShowActualTool;
- END;
- EventToolDisc: BEGIN
- IF aktuellesTool=FEllipse THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=FEllipse;
- ShowActualTool;
- END;
- EventToolFill: BEGIN
- IF aktuellesTool=FuellEimer THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=FuellEimer;
- ShowActualTool;
- END;
- EventToolCopy: BEGIN
- IF aktuellesTool=Kopie THEN exit;
- ClearOldObject;
- Objekt.stage:=0;
- aktuellesTool:=Kopie;
- ShowActualTool;
- END;
- else ErrBeep;
- END;
- END;
-
- PROCEDURE ShowBorder(Shift:BOOLEAN);
- { in: Workarea = aktuelle Grafikdaten}
- { WorkAreaMaxUsedX|Y = aktuelle Extremkoordinaten}
- { Shift = TRUE für: auch transparentes Spriteinneres blinken lassen}
- {out: - }
- {rem: Grenzdaten wurden blinkend angezeigt}
- TYPE Punkt=Record
- x,y:Word;
- END;
- CONST DontCare=0;
- VAR punkte:Array[1..2*WorkBreite+2*WorkHoehe] OF Punkt;
- Zeilen_Grenze_links,Zeilen_Grenze_rechts:Array[0..WorkHoehe-1] OF INTEGER;
- p_zahl,Anzahl,i,j,k,links,rechts,oben,unten,MinX,MaxX,MinY,MaxY:Integer;
- fertig_li,fertig_re,fertig_ob,fertig_un:Boolean;
- farbe:Byte;
- s1,s2:STRING[5];
-
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {leere Workarea, also nichts da zum anzeigen!}
- ErrBeep; {Ist aber nur notwendiges Kriterium, nicht hinreichend!}
- exit {(Da gesamtes Sprite ja offscreen sein kann!}
- END;
- p_zahl:=0; MaxX:=0; MaxY:=0; MinX:=MaxInt; MinY:=MaxInt;
-
- {Nun die X-Grenzdaten für jede Zeile:}
- FOR j:=0 TO WorkAreaMaxUsedY DO
- BEGIN
- links:=0; rechts:=WorkAreaMaxUsedX;
- fertig_li:=false; fertig_re:=false;
- REPEAT
- if (not fertig_li and (Workarea^.feld[j,links]=transparent))
- THEN inc(links) ELSE fertig_li:=true;
- if (not fertig_re and (Workarea^.feld[j,rechts]=transparent))
- THEN dec(rechts) ELSE fertig_re:=true;
- if links>rechts THEN BEGIN fertig_li:=true; fertig_re:=true END;
- UNTIL fertig_li and fertig_re;
- Zeilen_Grenze_links[j] :=links;
- Zeilen_Grenze_rechts[j]:=rechts;
- if (links<=rechts)
- THEN BEGIN {normale Zeile, Grenzen eintragen}
- inc(p_zahl);
- punkte[p_zahl].x:=links; punkte[p_zahl].y:=j;
- inc(p_zahl);
- punkte[p_zahl].x:=rechts; punkte[p_zahl].y:=j;
- IF links <MinX THEN MinX:=links;
- IF rechts>MaxX THEN MaxX:=rechts
- END;
- END;
-
- IF Shift
- THEN Anzahl:=p_zahl SHR 1; {für Transparentes reichen die Zeilendaten aus!}
-
- {Dasselbe für die Grenzdaten jeder Spalte:}
- FOR i:=0 TO WorkAreaMaxusedX DO
- BEGIN
- oben :=0; unten:=WorkAreaMaxUsedY;
- fertig_ob:=false; fertig_un:=false;
- REPEAT
- if (not fertig_ob and (Workarea^.feld[oben,i]=transparent))
- THEN inc(oben) ELSE fertig_ob:=true;
- if (not fertig_un and (Workarea^.feld[unten,i]=transparent))
- THEN dec(unten) ELSE fertig_un:=true;
- if oben>unten THEN BEGIN fertig_ob:=true; fertig_un:=true END;
- UNTIL fertig_ob and fertig_un;
- if (oben<=unten)
- THEN BEGIN {normale Spalte, Grenzen eintragen}
- inc(p_zahl);
- punkte[p_zahl].x:=i; punkte[p_zahl].y:=oben;
- inc(p_zahl);
- punkte[p_zahl].x:=i; punkte[p_zahl].y:=unten;
- IF oben <MinY THEN MinY:=oben;
- IF unten>MaxY THEN MaxY:=unten
- END;
- END;
-
- IF p_zahl=0
- THEN BEGIN
- ErrBeep;
- exit
- END
-
- ELSE BEGIN {Punkte blinken lassen}
- STR(WorkAreaMaxUsedX:3,s1);
- STR(WorkAreaMaxUsedY:3,s2);
- DrawOkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,'ok',
- 'used width : 0..'+s1,
- 'used height: 0..'+s2,'',Abfrage);
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
-
- i:=0; farbe:=BestWhite;
- REPEAT
- i:=succ(i) mod 100; {Jedes 100. Mal anzeigen reicht}
- delay(10); {*10ms = Blinkfrequenz von 1Hz }
- if i=0 THEN BEGIN
- UndrawMaus;
- IF Shift
- THEN FOR j:=1 TO Anzahl DO
- FOR k:=punkte[j SHL 1-1].x TO punkte[j SHL 1].x DO
- IF Workarea^.feld[punkte[j SHL 1].y,k]=transparent
- THEN DrawWorkAreaPixel(k,punkte[j SHL 1].y,
- farbe,DRAW,FALSE);
- FOR j:=1 TO p_zahl DO
- DrawWorkAreaPixel(punkte[j].x,punkte[j].y,
- farbe,DRAW,FALSE);
- DrawMaus(CursorPfeil);
- if farbe=BestWhite
- THEN farbe:=BestBlack {Farbe alternieren lassen}
- ELSE farbe:=BestWhite
- END;
-
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- Event:=MouseEvent(abfrage);
- IF (Event=EventNone)
- THEN BEGIN {das war nichts, nochmal!}
- DrawMaus(CursorPfeil);
- ClearMouse
- END;
- END;
- UNTIL Event<>EventNone;
- UndrawMaus;
- END;
-
- {alten Inhalt wiederherstellen:}
- IF Shift
- THEN FOR j:=1 TO Anzahl DO
- FOR k:=punkte[j SHL 1-1].x TO punkte[j SHL 1].x DO
- IF Workarea^.feld[punkte[j SHL 1].y,k]=transparent
- THEN DrawWorkAreaPixel(k,punkte[j SHL 1].y,
- DontCare,CLEAR,FALSE);
- FOR j:=1 TO p_zahl DO
- DrawWorkAreaPixel(punkte[j].x,punkte[j].y,
- DontCare,CLEAR,FALSE);
-
- {alte Grafik wiederherstellen:}
- PutImage(MeldungX,MeldungY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
- END;
-
- PROCEDURE BlinkColor;
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = Anfangskoordinaten der Bildschirmanzeige der Workarea}
- { zoom = momentan gesetzter Vergrößerungsfaktor}
- { FarbWahl = Menu für Cancel/Workarea/Palettenbereich-Abfrage}
- { Abfrage = Menu für Ok-Abfrage}
- {out: - }
- {ren: Der Benutzer wird nach einer Farbe gefragt und diese wird blinkend}
- { hervorgehoben}
- LABEL nochmal;
- VAR BlinkFarbe,farbe:BYTE;
- i,j,maxY,maxX:INTEGER;
- outer:BOOLEAN;
- BEGIN
- DrawOkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,
- 'cancel',
- 'Click at the color you want',
- 'to be shown blinking','',
- FarbenWahl);
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- {evtl. Cursordaten löschen:}
- IF NOT InWorkArea
- THEN BEGIN {evtentuelle Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- END;
- Event:=MouseEvent(FarbenWahl);
- IF Event=EventSelectColor
- THEN BEGIN {Maus im Palettenbereich geclickt}
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN BEGIN {zwischen 2 Farben geclickt!}
- ErrBeep;
- Event:=EventNone;
- goto nochmal;
- END;
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN BEGIN {dto.}
- ErrBeep;
- Event:=EventNone;
- goto nochmal;
- END;
- BlinkFarbe:=j SHL 4 + i; {=j*16+i}
- nochmal:;
- END
- ELSE IF Event=EventInWorkArea
- THEN BEGIN {Maus in Workarea geclickt}
- ShowCursorDaten; {zeige an, wo/auf was der Cursor steht}
- IF LeftButton
- THEN BEGIN
- Absolute2WorkArea(i,j);
- BlinkFarbe:=Workarea^.feld[j,i]
- END
- ELSE Event:=EventNone; {Button war nicht gedrückt}
- END;
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- IF Event=EventNone THEN ClearMouse {auf nächstes Mausevent warten}
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(MeldungX,MeldungY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
-
- {Hier: entweder ist Event=EventCancel oder BlinkFarbe ist die selektierte Farbe}
- IF Event=EventCancel THEN exit;
-
-
- DrawOkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,
- 'ok',
- 'Seen enough?','','',
- Abfrage);
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
-
- i:=0; farbe:=BestWhite;
- {berechne "EndVirtualX|Y", d.h.: die max. angezeigten Koordinaten}
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- REPEAT
- i:=succ(i) mod 200; {Jedes 200. Mal anzeigen reicht}
- delay(5); {*5ms = Blinkfrequenz von 1Hz }
- if i=0 THEN BEGIN
- UndrawMaus;
- {Bei langdauernden Aufgaben wäre der Mauscursor längere Zeit}
- {nicht sichtbar; da sich außerhalb der Workarea nichts tut, }
- {können wir ihn aber dort auch während der Aktion sichtbar }
- {machen: }
- outer:=NOT InWorkArea;
- IF outer THEN DrawMaus(CursorPfeil);
- FOR j:=StartVirtualY TO maxY DO
- FOR i:=StartVirtualX TO maxX DO
- IF Workarea^.feld[j,i]=BlinkFarbe
- THEN DrawWorkAreaPixel(i,j,farbe,DRAW,FALSE);
- IF outer THEN UndrawMaus;
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- if farbe=BestWhite
- THEN farbe:=BestBlack {Farbe alternieren lassen}
- ELSE farbe:=BestWhite
- END;
-
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- Event:=MouseEvent(Abfrage);
- IF (Event=EventNone)
- THEN BEGIN {das war nichts, nochmal!}
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- ClearMouse
- END;
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
-
- {alte Grafik wiederherstellen:}
- PutImage(MeldungX,MeldungY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
- END;
-
- PROCEDURE ChangeColor;
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = Anfangskoordinaten der Bildschirmanzeige der Workarea}
- { zoom = momentan gesetzter Vergrößerungsfaktor}
- { FarbWahl = Menu für Cancel/Workarea/Palettenbereich-Abfrage}
- { Abfrage = Menu für Ok-Abfrage}
- {out: Workarae^ neue Grafikdaten}
- {ren: Der Benutzer wird nach zwei Farben gefragt; die erste wird dann gegen}
- { die zweite ersetzt}
- LABEL nochmal1,nochmal2;
- VAR farbe,alteFarbe,neueFarbe:BYTE;
- alteFarbeS:STRING[3];
- i,j,maxY,maxX:INTEGER;
- outer:BOOLEAN;
- BEGIN
- DrawOkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,
- 'cancel',
- 'Click at the color you',
- 'to want to replace','',
- FarbenWahl);
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
-
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- {evtl. Cursordaten löschen:}
- IF NOT InWorkArea
- THEN BEGIN {evtentuelle Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- END;
- Event:=MouseEvent(FarbenWahl);
- IF Event=EventSelectColor
- THEN BEGIN {Maus im Palettenbereich geclickt}
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN BEGIN {zwischen 2 Farben geclickt!}
- ErrBeep;
- Event:=EventNone;
- goto nochmal1;
- END;
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN BEGIN {dto.}
- ErrBeep;
- Event:=EventNone;
- goto nochmal1;
- END;
- alteFarbe:=j SHL 4 + i; {=j*16+i}
- nochmal1:;
- END
- ELSE IF Event=EventInWorkArea
- THEN BEGIN {Maus in Workarea geclickt}
- ShowCursorDaten; {zeige an, wo/auf was der Cursor steht}
- IF LeftButton
- THEN BEGIN
- Absolute2WorkArea(i,j);
- alteFarbe:=Workarea^.feld[j,i]
- END
- ELSE Event:=EventNone;
- END;
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- IF Event=EventNone THEN ClearMouse
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(MeldungX,MeldungY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
-
- {Hier: entweder ist Event=EventCancel oder alteFarbe ist die selektierte Farbe}
- IF Event=EventCancel THEN exit;
-
- STR(alteFarbe:3,alteFarbeS);
- {--------- jetzt dasselbe nochmal, für die neue Farbe: ---------}
- DrawOkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,
- 'cancel',
- 'Now select the new color',
- 'for color '+alteFarbeS,'',
- FarbenWahl);
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
-
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- {evtl. Cursordaten löschen:}
- IF NOT InWorkArea
- THEN BEGIN {evtentuelle Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- END;
- Event:=MouseEvent(FarbenWahl);
- IF Event=EventSelectColor
- THEN BEGIN {Maus im Palettenbereich geclickt}
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN BEGIN {zwischen 2 Farben geclickt!}
- ErrBeep;
- Event:=EventNone;
- goto nochmal2;
- END;
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN BEGIN {dto.}
- ErrBeep;
- Event:=EventNone;
- goto nochmal2;
- END;
- neueFarbe:=j SHL 4 + i; {=j*16+i}
- nochmal2:;
- END
- ELSE IF Event=EventInWorkArea
- THEN BEGIN {Maus in Workarea geclickt}
- ShowCursorDaten; {zeige an, wo/auf was der Cursor steht}
- IF LeftButton
- THEN BEGIN
- Absolute2WorkArea(i,j);
- neueFarbe:=Workarea^.feld[j,i]
- END
- ELSE Event:=EventNone
- END;
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- IF Event=EventNone THEN ClearMouse
- END;
- UNTIL Event<>EventNone;
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(MeldungX,MeldungY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
-
- {Hier: entweder ist Event=EventCancel oder neueFarbe ist die selektierte Farbe}
- IF Event=EventCancel THEN exit;
-
-
- {-------jetzt: alteFarbe=zu ersetzende Farbe, neueFarbe=Ersatz dafür -------}
- IF alteFarbe=neueFarbe
- THEN BEGIN
- ErrBeep;
- OkBox(MeldungX,MeldungY,MeldungX+220,MeldungY+60,
- 'ok',
- 'You chose the same color',
- 'twice, so there is nothing',
- 'to change!',
- Abfrage);
- END
- ELSE BEGIN {Farbe austauschen!}
- FOR j:=0 TO WorkHoehe-1 DO
- FOR i:=0 TO WorkBreite-1 DO
- IF Workarea^.feld[j,i]=alteFarbe THEN Workarea^.feld[j,i]:=neueFarbe;
- IF (alteFarbe=transparent) OR (neueFarbe=transparent)
- THEN FindWorkAreaMaxUSed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
- END;
-
- PROCEDURE PaletteChange;
- { in: MausX,MausY = irgendwo im Palettenbereich}
- {out: - }
- {rem: Die vom Benutzer angewählte Farbe wurde evtl. geändert}
- LABEL nope;
- CONST StartX=MeldungX; {li. obere Ecke der Meldungsbox}
- StartY=MeldungY;
- EndX=StartX+220;
- EndY=StartY+65;
- sx=25; {Größe einer Menubox}
- sy=15;
- ProbeX1=StartX+10; {Koord. für Anzeige der gewählten Farbe}
- ProbeX2=ProbeX1+39;
- ProbeY1=StartY+12;
- ProbeY2=ProbeY1+36;
- EventIncRed=104;
- EventDecRed=105;
- EventIncGreen=106;
- EventDecGreen=107;
- EventIncBlue=108;
- EventDecBlue=109;
- PalMenu:ARRAY[1..11] OF box=(
- {Ok/Cancel/Workarea/Palettenbereich/inc&dec für R,G,B:}
-
- {"Ok"-Box:}
- (x1:StartX+150; y1:StartY+5; x2:StartX+150+55; y2:StartY+5+sy;
- Name1:' ok ';Name2:'';
- Show :Dummy;
- Event:EventYes;
- Click:TRUE;
- Paint:TRUE),
-
- {"Cancel"-Box:}
- (x1:StartX+150; y1:StartY+25; x2:StartX+150+55; y2:StartY+25+sy;
- Name1:'cancel';Name2:'';
- Show :Dummy;
- Event:EventCancel;
- Click:TRUE;
- Paint:TRUE),
-
- {"Rot-"-Box:}
- (x1:StartX+60; y1:StartY+5; x2:StartX+60+sx; y2:StartY+5+sy;
- Name1:'R-';Name2:'';
- Show :Dummy;
- Event:EventDecRed;
- Click:TRUE;
- Paint:TRUE),
-
- {"Rot+"-Box:}
- (x1:StartX+90; y1:StartY+5; x2:StartX+90+sx; y2:StartY+5+sy;
- Name1:'R+';Name2:'';
- Show :Dummy;
- Event:EventIncRed;
- Click:TRUE;
- Paint:TRUE),
-
-
- {"Grün-"-Box:}
- (x1:StartX+60; y1:StartY+25; x2:StartX+60+sx; y2:StartY+25+sy;
- Name1:'G-';Name2:'';
- Show :Dummy;
- Event:EventDecGreen;
- Click:TRUE;
- Paint:TRUE),
-
- {"Grün+"-Box:}
- (x1:StartX+90; y1:StartY+25; x2:StartX+90+sx; y2:StartY+25+sy;
- Name1:'G+';Name2:'';
- Show :Dummy;
- Event:EventIncGreen;
- Click:TRUE;
- Paint:TRUE),
-
-
- {"Blau-"-Box:}
- (x1:StartX+60; y1:StartY+45; x2:StartX+60+sx; y2:StartY+45+sy;
- Name1:'B-';Name2:'';
- Show :Dummy;
- Event:EventDecBlue;
- Click:TRUE;
- Paint:TRUE),
-
- {"Blau+"-Box:}
- (x1:StartX+90; y1:StartY+45; x2:StartX+90+sx; y2:StartY+45+sy;
- Name1:'B+';Name2:'';
- Show :Dummy;
- Event:EventIncBlue;
- Click:TRUE;
- Paint:TRUE),
-
- {Workarea:}
- (x1:WorkStartX; y1:WorkStartY;
- x2:WorkEndX; y2:WorkEndY;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventInWorkArea;
- Click:FALSE; {Anclicken nicht nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Palettenbereich:}
- (x1:PaletteX+25; y1:PaletteY+10;
- x2:PaletteX+25+16*PalBreite-3; y2:PaletteY+10+16*PalHoehe-3;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventSelectColor;
- Click:TRUE; {Anclicken nötig}
- Paint:FALSE), {...wird aber nicht gezeichnet}
-
- {Sentinelwert, da x1>x2!}
- (x1:1; y1:0; x2:0; y2:0;
- Name1:'';Name2:'';
- Show :Dummy;
- Event:EventNone;
- Click:TRUE;
- Paint:FALSE)
- );
-
- VAR FarbeZumAendern,Farbe,temp:BYTE;
- i,j:INTEGER;
- ch:CHAR;
- mymenu:ARRAY[1..10] OF box ABSOLUTE menu;
- ColorName:STRING[5];
- cred,cgreen,cblue,
- oldred,oldgreen,oldblue:BYTE;
- total,change:BOOLEAN;
-
- PROCEDURE zeichneMenu2;
- {rem: zeichnet die veränderlichen Menudinge}
- BEGIN
- SetFillStyle(SolidFill,FarbeZumAendern);
- Bar(ProbeX1+1,ProbeY1+1,ProbeX2-1,ProbeY2-1);
-
- SetFillStyle(SolidFill,BestLightGray);
- Bar(StartX+90+sx+5,StartY+5+4,StartX+90+sx+5+18,StartY+45+4+9);
- SetColor(BestBlack);
- Str(cred :2,s); OutTextXY(StartX+90+sx+5,StartY+5+4,s);
- Str(cgreen:2,s); OutTextXY(StartX+90+sx+5,StartY+25+4,s);
- Str(cblue :2,s); OutTextXY(StartX+90+sx+5,StartY+45+4,s);
- END;
-
- PROCEDURE zeichneMenu1;
- {rem: zeichnet die unveränderlichen _und_ die veränderlichen Menudinge}
- VAR i:INTEGER;
- s:STRING[3];
- BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(StartX,StartY,EndX,EndY);
- SetFillStyle(SolidFill,BestWhite);
- Bar(StartX,StartY,EndX-1,StartY+1);
- Bar(StartX,StartY,StartX+1,EndY-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(StartX,EndY-1,EndX,EndY);
- Bar(EndX-1,StartY,EndX,EndY);
-
- i:=1;
- WHILE PalMenu[i].x1<=PalMenu[i].x2 DO
- BEGIN
- WITH PalMenu[i] DO
- BEGIN
- IF Paint
- THEN BEGIN
- SetFillStyle(SolidFill,BestLightGray);
- Bar(x1,y1,x2,y2);
- SetFillStyle(SolidFill,BestWhite);
- Bar(x1,y1,x2-1,y1+1);
- Bar(x1,y1,x1+1,y2-1);
- SetFillStyle(SolidFill,BestDarkGray);
- Bar(x1,y2-1,x2,y2);
- Bar(x2-1,y1,x2,y2);
- SetColor(BestBlack);
- IF Name1<>'' THEN OutTextXY(x1+5,y1+4,Name1);
- END;
- END; {of WITH}
- inc(i);
- END; {of WHILE}
-
- SetColor(BestBlack);
- Rectangle(ProbeX1,ProbeY1,ProbeX2,ProbeY2);
- SetColor(BestBlack);
- OutTextXY(ProbeX1,ProbeY2+3,ColorName);
-
- zeichneMenu2;
- END;
-
- BEGIN
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN exit; {knapp daneben ist auch vorbei: zwischen 2 Farben geclickt!}
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN exit; {dto.}
-
- FarbeZumAendern:=j SHL 4 + i; {=j*16+i}
- WITH ActualColors[FarbeZumAendern] DO
- BEGIN
- cred:=red; cgreen:=green; cblue:=blue;
- END;
- Str(FarbeZumAendern:3,ColorName); ColorName:='C:'+ColorName;
-
- oldred:=cred; oldgreen:=cgreen; oldblue:=cblue; {alte Farben für "CANCEL"!}
- {alte Grafik sichern:}
- oldGraphSize:=ImageSize(StartX,StartY,EndX,EndY);
- GetMem(oldGraph,oldGraphSize);
- GetImage(StartX,StartY,EndX,EndY,oldGraph^);
-
-
- zeichneMenu1;
-
- DrawMaus(CursorPfeil);
- Event:=EventNone;
- {Maus freigeben:}
- ClearMouse;
-
- total:=FALSE; {wird wahr, wenn min. eine Menufarbe verändert wurde}
- REPEAT
- IF MouseUpdate
- THEN BEGIN
- UndrawMaus;
- IF NOT InWorkArea
- THEN BEGIN {evtentuelle Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- END;
- Event:=MouseEvent(PalMenu);
- IF Event=EventNone THEN Event:=EventMouseMoved;
- END
- ELSE IF (KeyPressed) THEN
- BEGIN
- WHILE KeyPressed DO ch:=Upcase(ReadKey);
- IF ch='O' THEN Event:=EventYes {okay?}
- ELSE IF ch='C' THEN Event:=EventCancel; {cancel?}
- END;
-
- CASE Event OF
- EventIncRed :IF cred <63 THEN Inc(cred);
- EventIncGreen:IF cgreen<63 THEN Inc(cgreen);
- EventIncBlue :IF cblue <63 THEN Inc(cblue);
- EventDecRed :IF cred >0 THEN Dec(cred);
- EventDecGreen:IF cgreen>0 THEN Dec(cgreen);
- EventDecBlue :IF cblue >0 THEN Dec(cblue);
- EventCancel :BEGIN {alte Farben wiederherstellen}
- cred:=oldred; cgreen:=oldgreen; cblue:=oldblue
- END;
- EventSelectColor:
- BEGIN
- i:=(MausX-PaletteX-25) DIV PalBreite;
- IF i<>(MausX-PaletteX-25+3) DIV PalBreite
- THEN goto nope; {knapp daneben ist auch vorbei: zwischen 2 Farben geclickt!}
- j:=(MausY-PaletteY-10) DIV PalHoehe;
- IF j<>(MausY-PaletteY-10+3) DIV PalHoehe
- THEN goto nope; {dto.}
-
- temp:=j SHL 4 + i; {=j*16+i}
- IF temp<>FarbeZumAendern
- THEN WITH ActualColors[temp] DO
- BEGIN {andere Farbe übernehmen}
- cred:=red; cgreen:=green; cblue:=blue
- END
- ELSE ErrBeep;
-
- nope:;
- END;
- EventInWorkArea:
- BEGIN
- ShowCursorDaten; {zeige an, wo/auf was der Cursor steht}
- IF LeftButton
- THEN BEGIN
- Absolute2Workarea(i,j);
- temp:=Workarea^.feld[j,i];
- IF temp<>FarbeZumAendern
- THEN WITH ActualColors[temp] DO
- BEGIN {andere Farbe übernehmen}
- cred:=red; cgreen:=green; cblue:=blue
- END
- ELSE ErrBeep;
- END
- END;
- END;
-
- WITH ActualColors[FarbeZumAendern] DO
- BEGIN
- IF (cred<>red) OR (cgreen<>green) OR (cblue<>blue)
- THEN BEGIN {Farbe wurde verändert}
- SetPaletteEntry(FarbeZumAendern,cred,cgreen,cblue); {sichtbar machen}
- red:=cred; {Änderung in aktueller Farbpalette vermerken}
- green:=cgreen;
- blue:=cblue;
-
- {nun evtl. neue Menufarben berechnen:}
- change:=FALSE;
- temp:=BestFit(White);
- IF temp<>BestWhite THEN BEGIN BestWhite:=temp; change:=TRUE END;
- temp:=BestFit(Black);
- IF temp<>BestBlack THEN BEGIN BestBlack:=temp; change:=TRUE END;
- temp:=BestFit(Cyan);
- IF temp<>BestCyan THEN BEGIN BestCyan:=temp; change:=TRUE END;
- temp:=BestFit(LightGray);
- IF temp<>BestLightGray THEN BEGIN BestLightGray:=temp; change:=TRUE END;
- temp:=BestFit(DarkGray);
- IF temp<>BestDarkGray THEN BEGIN BestDarkGray:=temp; change:=TRUE END;
-
- IF change {falls veränderte Farbe eine der verwendeten}
- THEN zeichneMenu1 {Menufarben ist, dann ein "großes" Update }
- ELSE zeichneMenu2; {durchführen, sonst ein "kleines"}
- total:=total OR change; {für Abschluß merken}
- END;
- END;
-
- IF (Event<>EventNone)
- THEN BEGIN
- IF (Event<>EventYes) AND (Event<>EventCancel)
- THEN Event:=EventNone;
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
- ClearMouse;
- END;
- UNTIL (Event=EventYes) OR (Event=EventCancel);
-
- UndrawMaus;
- {alte Grafik wiederherstellen:}
- PutImage(StartX,StartY,oldGraph^,NormalPut);
- FreeMem(oldGraph,oldGraphSize);
-
- IF PalEqual(ActualColors,DefaultColors)
- THEN BEGIN
- IF Palnamekurz<>''
- THEN BEGIN
- Palnamelang:=''; Palnamekurz:='';
- END;
- END;
- ShowPalName;
- IF total THEN RestoreScreen; {neue Menufarben überall ändern!}
- END;
-
- PROCEDURE RotateLeft(amount:WORD);
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- { amount = #Spalten, um die rotiert werden soll: 1..WorkBreite-1}
- {out: Workarea^ = neue Grafikdaten}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten}
- {rem: Workarea-Inhalt wurde um 1 Spalte nach links rotiert}
- VAR maxX,maxY,y:INTEGER;
- p1,p2:POINTER;
- tempArea:^WorkAreaTyp;
- size:WORD;
- BEGIN
- New(tempArea);
- FOR y:=0 TO WorkHoehe-1 DO
- move(Workarea^.feld[y,0],tempArea^.feld[y,0],amount);
- p1:=@Workarea^.feld[0,amount];
- p2:=@Workarea^.feld[0,0];
- size:=WorkHoehe*WorkBreite -amount;
- ASM
- MOV CX,size
- LES DI,p2
- LDS SI,p1
- CLD
- REP MOVSB
- MOV AX,SEG @DATA
- MOV DS,AX
- END;
- FOR y:=0 TO WorkHoehe-1 DO
- move(tempArea^.feld[y,0],Workarea^.feld[y,WorkBreite-amount],amount);
- Dispose(tempArea);
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE RotateRight(amount:WORD);
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- { amount = #Spalten, um die rotiert werden soll: 1..WorkBreite-1}
- {out: Workarea^ = neue Grafikdaten}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten}
- {rem: Workarea-Inhalt wurde um 1 Spalte nach rechts rotiert}
- VAR maxX,maxY,y:INTEGER;
- p1,p2:POINTER;
- tempArea:^WorkAreaTyp;
- size:WORD;
- BEGIN
- New(tempArea);
- FOR y:=0 TO WorkHoehe-1 DO
- move(Workarea^.feld[y,WorkBreite-amount],tempArea^.feld[y,0],amount);
- p1:=@Workarea^.feld[WorkHoehe-1,WorkBreite-1-amount];
- p2:=@Workarea^.feld[WorkHoehe-1,WorkBreite-1];
- size:=WorkHoehe*WorkBreite -amount;
- ASM
- MOV CX,size
- LES DI,p2
- LDS SI,p1
- STD
- REP MOVSB
- CLD
- MOV AX,SEG @DATA
- MOV DS,AX
- END;
- FOR y:=0 TO WorkHoehe-1 DO
- move(tempArea^.feld[y,0],Workarea^.feld[y,0],amount);
- Dispose(tempArea);
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE RotateUp(amount:WORD);
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- { amount = #Zeilen, um die rotiert werden soll: 1..WorkHoehe-1}
- {out: Workarea^ = neue Grafikdaten}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten}
- {rem: Workarea-Inhalt wurde um 1 Zeile nach oben rotiert}
- VAR maxX,maxY,y:INTEGER;
- p1,p2:POINTER;
- tempArea:^WorkAreaTyp;
- size:WORD;
- BEGIN
- New(tempArea);
- move(Workarea^.feld[0,0],tempArea^.feld[0,0],WorkBreite*amount);
- p1:=@Workarea^.feld[amount,0];
- p2:=@Workarea^.feld[0,0];
- size:=(WorkHoehe-amount)*WorkBreite;
- ASM
- MOV CX,size
- LES DI,p2
- LDS SI,p1
- CLD
- REP MOVSB
- MOV AX,SEG @DATA
- MOV DS,AX
- END;
- move(tempArea^.feld[0,0],Workarea^.feld[WorkHoehe-amount,0],WorkBreite*amount);
- Dispose(tempArea);
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE RotateDown(amount:WORD);
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- { amount = #Zeilen, um die rotiert werden soll: 1..WorkHoehe-1}
- {out: Workarea^ = neue Grafikdaten}
- { WorkAreaMaxUsedX|Y = neue Extremkoordinaten}
- {rem: Workarea-Inhalt wurde um 1 Zeile nach unten rotiert}
- VAR maxX,maxY,y:INTEGER;
- p1,p2:POINTER;
- tempArea:^WorkAreaTyp;
- size:WORD;
- BEGIN
- New(tempArea);
- move(Workarea^.feld[WorkHoehe-amount,0],tempArea^.feld[0,0],WorkBreite*amount);
- p1:=@Workarea^.feld[WorkHoehe-1-amount,WorkBreite-1];
- p2:=@Workarea^.feld[WorkHoehe-1 ,WorkBreite-1];
- size:=(WorkHoehe-amount)*WorkBreite;
- ASM
- MOV CX,size
- LES DI,p2
- LDS SI,p1
- STD
- REP MOVSB
- CLD
- MOV AX,SEG @DATA
- MOV DS,AX
- END;
- move(tempArea^.feld[0,0],Workarea^.feld[0,0],WorkBreite*amount);
- Dispose(tempArea);
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE MirrorHorizontal;
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- {out: Workarea^ = neue Grafikdaten}
- {rem: Inhalt der Workarea wurde horizontal gespiegelt}
- VAR maxX,maxY,x,y:INTEGER;
- temp:BYTE;
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {Workarea leer!}
- ErrBeep;
- exit
- END;
-
- FOR y:=0 TO WorkAreaMaxUsedY DO
- FOR x:=0 TO min(WorkAreaMaxUsedX,(WorkBreite-1) SHR 1) DO
- BEGIN {Punkte einer Zeile austauschen}
- temp:=Workarea^.feld[y,x];
- Workarea^.feld[y,x]:=Workarea^.feld[y,WorkBreite-1-x];
- Workarea^.feld[y,WorkBreite-1-x]:=temp
- END;
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE MirrorVertical;
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- {out: Workarea^ = neue Grafikdaten}
- {rem: Inhalt der Workarea wurde vertikal gespiegelt}
- VAR maxX,maxY,x,y:INTEGER;
- temp:BYTE;
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {Workarea leer!}
- ErrBeep;
- exit
- END;
-
- FOR x:=0 TO WorkAreaMaxUsedX DO
- FOR y:=0 TO min(WorkAreaMaxUsedY,(WorkHoehe-1) SHR 1) DO
- BEGIN {Punkte einer Spalte austauschen}
- temp:=Workarea^.feld[y,x];
- Workarea^.feld[y,x]:=Workarea^.feld[WorkHoehe-1-y,x];
- Workarea^.feld[WorkHoehe-1-y,x]:=temp
- END;
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
- PROCEDURE ObenLinks;
- { in: Workarea^ = aktuelle Grafikdaten}
- { StartVirtualX|Y = aktuelle Anfangskoord. des sichtbaren Ausschnittes}
- { WorkHoehe, WorkBreite = Abmessungen der Workarea}
- { zoom = aktueller Vergrößerungsfaktor}
- {out: Workarea^ = neue Grafikdaten}
- {rem: Inhalt der Workarea wurde soweit wie möglich nach links oben geschoben}
- VAR minX,minY,maxX,maxY,x,y:INTEGER;
- tempArea:^WorkAreaTyp;
- BEGIN
- IF (WorkAreaMaxUsedX=0) AND (WorkAreaMaxUsedY=0) AND
- (Workarea^.feld[0,0]=transparent)
- THEN BEGIN {Workarea leer!}
- ErrBeep;
- exit
- END;
-
- minX:=WorkAreaMaxUsedX;
- FOR y:=WorkAreaMaxUsedY DOWNTO 0 DO
- FOR x:=minX DOWNTO 0 DO
- IF Workarea^.feld[y,x]<>transparent
- THEN minX:=x; {minimales X dieser Zeile bestimmen}
-
- minY:=WorkAreaMaxUsedY;
- FOR x:=WorkAreaMaxUsedX DOWNTO 0 DO
- FOR y:=minY DOWNTO 0 DO
- IF Workarea^.feld[y,x]<>transparent
- THEN minY:=y; {minimales Y dieser Spalte bestimmen}
-
- IF (minX<>0) OR (minY<>0)
- THEN BEGIN {Inhalt hochschieben:}
- New(tempArea);
- Move(WorkArea^,tempArea^,SizeOf(WorkArea^));
- FillChar(WorkArea^,SizeOf(WorkArea^),transparent);
- FOR y:=minY TO WorkAreaMaxUsedY DO
- FOR x:=minX TO WorkAreaMaxUsedX DO
- Workarea^.feld[y-minY,x-minX]:=tempArea^.feld[y,x];
- Dispose(tempArea);
- END;
-
- FindWorkAreaMaxUsed;
- maxY:=min(WorkHoehe-1, StartVirtualY+(WorkHoehe DIV zoom));
- maxX:=min(WorkBreite-1,StartVirtualX+(WorkBreite DIV zoom));
- UpdateWorkArea(StartVirtualX,StartVirtualY,maxX,maxY,TRUE);
- DrawNewObject; {evtl. begonnenes Objet zeigen}
- END;
-
-
- BEGIN
- init;
-
- DrawMaus(CursorPfeil); {...und anzeigen}
- EnableMouse;
-
- repeat
- IF KeyPressed
- THEN BEGIN
- ch:=ReadKey; Shift:=(mem[$0:$417] AND 3)<>0;
- IF ch=#0
- THEN Wahl:=ORD(ReadKey) SHL 8 {Funktionstasten -> >256}
- ELSE Wahl:=ORD(ch);
- CASE Wahl OF
- $4B00: Event:=EventScrollLeft; {"<-" = Scroll nach links }
- $4D00: Event:=EventScrollRight; {"->" = Scroll nach rechts}
- $4800: Event:=EventScrollUp; {UP = Scroll nach oben }
- $5000: Event:=EventScrollDown; {DOWN = Scroll nach unten }
- $2B : Event:=EventZoomin; {"+" = vergrößern}
- $2D : Event:=EventZoomout; {"-" = verkleinern}
- $3B00: Event:=EventHelp; {F1 = Hilfe}
- $3C00: Event:=EventSpeichereSprite; {F2 = Sprite speichern}
- $3D00,
- $5600: Event:=EventLadeSprite; {(Sh-)F3 = Sprite laden}
- $3E00: Event:=EventSpeicherePalette; {F4 = Palette speichern}
- $3F00: Event:=EventLadePalette; {F5 = Palette laden}
- $5800: Event:=EventResetColors; {Sh-F5= Defaultpalette}
- $4000: Event:=EventSpeichereHintergrund;{F6 = Bild speichern}
- $4100: Event:=EventLadeHintergrund; {F7 = Hintergrundbild laden}
- $4200: Event:=EventEraseWorkarea; {F8 = Workarea löschen}
- $4300: BEGIN {F9 = Palette auf Palette mappen }
- IF (WorkAreaMaxUsedX<>0) OR
- (WorkAreaMaxUsedY<>0) {Workarea nicht leer? }
- THEN BEGIN
- IF SelectZielPalette {Zielpalette auswählen}
- THEN Event:=EventMapPalette
- END
- ELSE Event:=EventError
- END;
- $5C00: Event:=EventMapToBIOSPAlette; {Sh-F9 = Palette auf BIOS-Defaultfarben mappen}
- $4400: Event:=EventQuit; {F10 = Beenden}
- else Event:=EventError;
- END;
- END;
-
- IF Event=EventNone {keine Taste gedrückt, aber vielleicht Mausaktion?}
- THEN IF MouseUpdate
- THEN BEGIN {Mausaktion}
- {N.B.: soll ein Event jetzt noch nachträglich "gelöscht" }
- {werden, so muß es auf "EventMouseMoved" gesetzt werden, }
- {nicht aber auf "EventNone", denn es ist ja was mit der }
- {Maus passiert, (sie wurde zumindest bewegt oder geclickt)}
- {Würde man dies ignorieren, so würde die Maus nicht mehr }
- {"enabled" werden!}
- Event:=MouseEvent(menu);
-
- {Folgende Mausaktionen müssen genauer untersucht werden,}
- {ob sie im geg. Kontext zulässig sind:}
- IF Event=EventMapPalette
- THEN BEGIN {Palette auf Palette mappen}
- IF (WorkAreaMaxUsedX<>0) OR
- (WorkAreaMaxUsedY<>0) {Workarea nicht leer? }
- THEN BEGIN
- IF SelectZielPalette {Zielpalette auswählen}
- THEN Event:=EventMapPalette
- END
- ELSE Event:=EventError
- END
- END;
-
- IF Event<>EventNone
- THEN UnDrawMaus; {alten Bildschirminhalt unter Mauscursor restaurieren}
-
- CASE Event OF
- EventScrollLeft : BEGIN
- IF Shift
- THEN ScrollLeft(1)
- ELSE ScrollLeft(max(1,(WorkBreite DIV zoom) SHR 2));
- IF InWorkArea {evtl. geriete die Maus sonst nämlich}
- THEN BEGIN {außerhalb des Bereiches Xε[0..319] }
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventScrollRight: BEGIN
- IF Shift
- THEN ScrollRight(1)
- ELSE ScrollRight(max(1,(WorkBreite DIV zoom) SHR 2));
- IF InWorkArea {evtl. geriete die Maus sonst nämlich}
- THEN BEGIN {außerhalb des Bereiches Xε[0..319] }
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventScrollUp : BEGIN
- IF Shift
- THEN ScrollUp(1)
- ELSE ScrollUp(max(1,(WorkBreite DIV zoom) SHR 2));
- IF InWorkArea {evtl. geriete die Maus sonst nämlich}
- THEN BEGIN {außerhalb des Bereiches Xε[0..319] }
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventScrollDown : BEGIN
- IF Shift
- THEN ScrollDown(1)
- ELSE ScrollDown(max(1,(WorkBreite DIV zoom) SHR 2));
- IF InWorkArea {evtl. geriete die Maus sonst nämlich}
- THEN BEGIN {außerhalb des Bereiches Xε[0..319] }
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventZoomin : BEGIN
- Zoomin;
- IF InWorkArea {zoomen verändert Punktkoord.,}
- THEN BEGIN
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventZoomout : BEGIN
- Zoomout;
- IF InWorkArea {zoomen verändert Punktkoord.,}
- THEN BEGIN
- AdjustMouse; {deshalb Maus nachjustieren}
- ShowCursorDaten
- END;
- END;
- EventHelp : Help;
- EventSpeichereSprite: speichereSprite;
- EventLadeSprite : ladeSprite;
- EventSpeicherePalette: speicherePalette;
- EventLadePalette: ladePalette;
- EventResetColors: ResetColors;
- EventSpeichereHintergrund: SpeichereHintergrund;
- EventLadeHintergrund: ladeHintergrund;
- EventMapPalette:MapPalette;
- EventMapToBIOSPalette:MapToBIOSPalette;
- EventNone:;
- EventError : ErrBeep;
- EventInWorkArea : BEGIN
- AdjustMouse;
- ShowCursorDaten;
- WorkAreaAction; {Aktion innerhalb der Workarea?}
- END;
- EventMouseMoved:;
- EventSelectColor: IF LeftButton
- THEN SelectColor {linker Button = Farbe wählen}
- ELSE PaletteChange; {recher Button = Farbe ändern}
- EventShowBorder : ShowBorder(Shift);
- EventBlinkColor : BlinkColor;
- EventChangeColor: ChangeColor;
- EventRotateLeft : IF Shift
- THEN RotateLeft(1)
- ELSE RotateLeft(max(1,(WorkBreite DIV zoom) SHR 2));
- EventRotateRight: IF Shift
- THEN RotateRight(1)
- ELSE RotateRight(max(1,(WorkBreite DIV zoom) SHR 2));
- EventRotateUp : IF Shift
- THEN RotateUp(1)
- ELSE RotateUp(max(1,(WorkBreite DIV zoom) SHR 2));
- EventRotateDown : IF Shift
- THEN RotateDown(1)
- ELSE RotateDown(max(1,(WorkBreite DIV zoom) SHR 2));
- EventMirrorHorizontal: MirrorHorizontal;
- EventMirrorVertical : MirrorVertical;
- EventObenLinks : IF Shift
- THEN GotoUpLeft {mit Shift: gehe in die linke obere Ecke}
- ELSE ObenLinks; {ohne: verschiebe Inhalt in li. ob. Ecke}
-
- EventToolPixel,
- EventToolLine,
- EventToolRectangle,
- EventToolEllipse,
- EventToolBar,
- EventToolDisc,
- EventToolFill,
- EventToolCopy: SelectNewTool;
-
- EventEraseWorkarea: BEGIN {Bei "Löschen" lieber nochmal rückfragen}
- ErrBeep;
- IF FirstOfTwoBoxes(MeldungX,MeldungY,
- MeldungX+220,MeldungY+60,
- 'yes','no',
- 'DO YOU REALLY WANT',
- 'TO ERASE THE WORKAREA?','',
- alternative)
- THEN BEGIN
- FillChar(WorkArea^,SizeOf(WorkArea^),transparent);
- WorkAreaMaxUsedX:=0; WorkAreaMaxUsedY:=0;
- UpdateWorkArea(StartVirtualX,StartVirtualY,
- WorkAreaMaxUsedX,WorkAreaMaxUsedY,TRUE);
- DrawNewObject; {evtl. Objekt neuzeichnen}
- END;
- Event:=EventMouseMoved;
- END;
-
-
- EventQuit : BEGIN {Bei "Quit" lieber nochmal rückfragen}
- IF FirstOfTwoBoxes(MeldungX,MeldungY,
- MeldungX+220,MeldungY+60,
- 'yes','no',
- '','Really quit?','',
- alternative)
- THEN Event:=EventEndProgram
- ELSE Event:=EventMouseMoved
- END
-
- else ErrBeep;
- END;
-
- IF Event<>EventNone
- THEN BEGIN {Mauszeiger wurde gelöscht, jetzt wieder neuzeichnen}
- IF NOT InWorkArea
- THEN BEGIN {evtentuelle Cursordaten vom Bildschirm löschen}
- SetFillStyle(SolidFill,BestBlack);
- Bar(InfoX,InfoY,InfoX+80,InfoY+29);
- END;
-
- IF (InWorkArea) AND (zoom=1)
- THEN DrawMaus(CursorKreuz)
- ELSE DrawMaus(CursorPfeil);
-
- ClearMouse; {Mausereignis abgearbeitet}
- END;
-
- IF Event<>EventEndProgram THEN Event:=EventNone;
- until Event=EventEndProgram; {Ende = F10 + Bestätigung}
-
- SetPalette(DefaultColors);
- restorecrtmode;
- SwapVectors
- END.
-