{ Mouse-Cursor Editor working in VGA graphics mode. Written by Bruce Winterbon, 96 Aug. Various mouse cursors were taken from SWAG code. A mouse-cursor editor written by Olaf Bartelt was also taken from SWAG as a starting point. It was completely rewritten. It needs the usual EGAVGA.BGI file in the same directory, of course.} PROGRAM Graphics_Mouse_Editor; uses Crt,dos,graph,drivers; function hex(v:longint;const w:integer):string; var s:String; i:Integer; const hexc:array[0..15] of char='0123456789ABCDEF'; begin s[0]:=Chr(w); for i:=w downto 1 do begin s[i]:=hexc[v and $F]; v:=v shr 4 end; Hex:=s; end {Hex}; type MCursor=record masks:array[0..31] of word; hsx,hsy:integer; end; const bitMask:array[0..15] of word = ($8000,$4000,$2000,$1000,$800,$400,$200,$100, $80,$40,$20,$10,$8,$4,$2,$1); clr:array[0..3]of integer=(14,12,2,4); cursNum=27; cursorList: array[0..cursNum] of MCursor = ( (Masks:($7FFF,$3FFF,$1FFF,$0FFF,$07FF,$03FF,$01FF,$00FF, {0:black arrow} $007F,$03FF,$03FF,$29FF,$71FF,$F0FF,$FAFF,$F8FF, $8000,$C000,$A000,$9000,$8800,$8400,$8200,$8100, $8780,$8400,$B400,$D200,$8A00,$0900,$0500,$0700);hsx:1;hsy:2), (masks:($9FFF,$8FFF,$87FF,$83FF,$81FF,$80FF,$807F,$803F, {1:white arrow} $801F,$800F,$80FF,$887F,$987F,$FC3F,$FC3F,$FE3F, $0000,$2000,$3000,$3800,$3C00,$3E00,$3F00,$3F80, $3FC0,$3E00,$3600,$2300,$0300,$0180,$0180,$0000);hsx:2;hsy:1), (Masks:($FBEF,$F3E7,$E3E3,$C001,$8000,$C001,$E3E3,$F3E7, {2:mcHArrow} $FBEF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF,$FFFF, $0410,$0C18,$1414,$27F2,$4001,$27F2,$1414,$0C18, $0410,$0000,$0000,$0000,$0000,$0000,$0000,$0000);hsx:8;hsy:4), (Masks:($FFFF,$FBFF,$F1FF,$E0FF,$C07F,$803F,$F1FF,$F1FF, {3:mcVArrow} $F1FF,$F1FF,$F1FF,$803F,$C07F,$E0FF,$F1FF,$FBFF, $0000,$0400,$0A00,$1100,$2080,$7BC0,$0A00,$0A00, $0A00,$0A00,$0A00,$7BC0,$2080,$1100,$0A00,$0400);hsx:5;hsy:8), (Masks:($FFFF,$81FF,$83FF,$83FF,$81FF,$80FF,$B07F,$F83F, {4:mcSlArrow} $FC1F,$FE0F,$FF06,$FF80,$FFC0,$FFE0,$FFE0,$FFC0, $0000,$7E00,$4400,$4400,$4200,$7100,$4880,$0440, $0220,$0110,$0089,$0047,$0021,$0011,$0011,$003F);hsx:8;hsy:8), (Masks:($FFFF,$81C0,$83E0,$83E0,$81C0,$8080,$B006,$F80F, {5:crossed arrows} $FC1F,$F80F,$B006,$8080,$81C0,$83E0,$83E0,$81C0, $0000,$7E3F,$4411,$4411,$4221,$7147,$4889,$0410, $0220,$0410,$4889,$7147,$4221,$4411,$4411,$7E3F);hsx:8;hsy:8), (masks:($f9ff,$f0ff,$e07f,$e07f,$c03f,$c03f,$801f,$801f, {6:up arrow} $000f,$000f,$f0ff,$f0ff,$f0ff,$f0ff,$f0ff,$f0ff, $0000,$0600,$0f00,$0f00,$1f80,$1f80,$3fc0,$3fc0, $7fe0,$0600,$0600,$0600,$0600,$0600,$0600,$0600);hsx:5;hsy:0), (masks:($fe1f,$f01f,$0000,$0000,$0000,$f01f,$fe1f,$ffff, {7:left arrow} $ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff, $0, $c0, $7c0, $7ffe,$7c0, $c0, $0, $0, $0, $0, $0, $0, $0, $0, $0, $0);hsx:1;hsy:3), (Masks:($FFFF,$FE3F,$FE3F,$FE3F,$FE3F,$FE3F,$FE3F,$8000, {8:mcCrossHair} $8000,$8000,$FE3F,$FE3F,$FE3F,$FE3F,$FE3F,$FE3F, $0000,$0140,$0140,$0140,$0140,$0140,$0140,$7E3F, $0000,$7E3F,$0140,$0140,$0140,$0140,$0140,$0140);hsx:8;hsy:8), (Masks:($FFFF,$FFFF,$FFFF,$FFFF,$FE3F,$FE3F,$FE3F,$F007, {9:mcSmallCross} $F007,$F007,$FE3F,$FE3F,$FE3F,$FFFF,$FFFF,$FFFF, $0000,$0000,$0000,$0000,$01C0,$0140,$0140,$0E38, $0808,$0E38,$0140,$0140,$01C0,$0000,$0000,$0000);hsx:8;hsy:8), (Masks:($F01F,$E00F,$C007,$8003,$0441,$0C61,$0381,$0381, {10:circle, centre cross } $0381,$0C61,$0441,$8003,$C007,$E00F,$F01F,$FFFF, $0000,$07C0,$0920,$1110,$2108,$4004,$4004,$783C, $4004,$4004,$2108,$1110,$0920,$07C0,$0000,$0000);hsx:7;hsy:7), (masks:($7e0, $180, $0, $c003,$f00f,$c003,$0, $180, {11:diagonal cross} $7e0, $ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff, $0, $700e,$1c38,$660, $3c0, $660, $1c38,$700e, $0, $0, $0, $0, $0, $0, $0, $0);hsx:7;hsy:4), (masks:($fc3f,$fc3f,$fc3f,$0000,$0000, $0,$fc3f,$fc3f, {12:rectangular cross} $fc3f,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff, $0, $180, $180, $180, $7ffe,$180, $180, $180, $0, $0, $0, $0, $0, $0, $0, $0);hsx:7;hsy:4), (Masks:($FFFF,$0FE1,$07C1,$0381,$8103,$C107,$E00F,$F01F, {13:X} $FC7F,$F01F,$E00F,$C107,$8103,$0381,$07C1,$0FE1, $0000,$C006,$600C,$3018,$1830,$0C60,$0440,$0280, $0100,$0280,$0440,$0C60,$1830,$3018,$600C,$C006);hsx:7;hsy:8), (Masks:($FF7F,$FC1F,$F807,$F803,$F803,$F803,$9801,$0801, {14:mcHand} $0001,$8001,$C001,$E003,$F007,$F80F,$FC0F,$FC0F, $0080,$0360,$0558,$0554,$0554,$0554,$6416,$9402, $8C02,$4402,$2006,$1004,$0808,$0410,$0210,$03F0);hsx:8;hsy:8), (Masks:($F3FF,$E1FF,$E1FF,$E1FF,$E1FF,$E049,$E000,$8000, {15:pointing finger} $0000,$0000,$07FC,$07F8,$9FF9,$8FF1,$C003,$E007, $0C00,$1200,$1200,$1200,$1200,$13B6,$1249,$7249, $9249,$9001,$9001,$8001,$4002,$4002,$2004,$1FF8);hsx:4;hsy:0), (masks:($e1ff,$e1ff,$e1ff,$e1ff,$e1ff,$e000,$e000,$e000, {16:pointing hand} $0, $0, $0, $0, $0, $0, $0, $0, $1e00,$1200,$1200,$1200,$1200,$13ff,$1249,$1249, $f249,$9001,$9001,$9001,$8001,$8001,$8001,$ffff);hsx:4;hsy:0), (Masks:($0000,$0000,$0000,$C003,$E007,$F00F,$F81F,$FC3F, {17:HourGlassMask} $FC3F,$F81F,$F00F,$E007,$C003,$0000,$0000,$0000, $0000,$7FFE,$0000,$1FF8,$0FF0,$0000,$0000,$0000, $0180,$03C0,$07E0,$0E78,$1818,$0000,$7FFE,$0000);hsx:8;hsy:8), (masks:($0, $0, $0, $0, $8001,$c003,$e007,$f00f, {18:hourglass} $e007,$c003,$8001,$0, $0, $0, $0, $ffff, $0, $7ffe,$6006,$300c,$1818,$c30, $660, $3c0, $660, $c30, $1998,$33cc,$67e6,$7ffe,$0, $0);hsx:8;hsy:7), (masks:($0001,$0001,$8003,$C7C7,$E38F,$F11F,$F83F,$FC7F, {19:hourglass} $F83F,$F11F,$E38F,$C7C7,$8003,$0001,$0001,$0000, $0000,$7FFC,$2008,$1010,$0820,$0440,$0280,$0100, $0280,$0440,$0820,$1010,$2008,$7FFC,$0000,$0000);hsx:7;hsy:7), (masks:($ffff,$c003,$8001,$0000, $0, $0, $0, $0, {20:watch} $0000, $0, $0, $0, $0,$8001,$c003,$ffff, $0000, $0,$1ff8,$2004,$4992,$4022,$4042,$518a, $4782,$4002,$4992,$4002,$2004,$1ff8, $0, $0);hsx:8;hsy:8), (masks:($E007,$C003,$8001,$0000,$0000,$0000,$0000,$0000, {21:watch} $0000,$0000,$0000,$0000,$0000,$8001,$C003,$E007, $0000,$1FF8,$318C,$6186,$4012,$4022,$4042,$718C, $718C,$4062,$4032,$4002,$6186,$318C,$1FF8,$0000);hsx:7;hsy:7), (Masks:($8003,$0001,$0001,$1831,$1011,$0001,$0001,$8003, {22:hammer of THOR} $F83F,$F83F,$F83F,$F83F,$F83F,$F83F,$F83F,$F83F, $0000,$3FF8,$4284,$4104,$4284,$4444,$3FF8,$0380, $0380,$0380,$0380,$0380,$0380,$0380,$0380,$0000);hsx:7;hsy:3), (Masks:($FFF0,$FFE0,$FFC0,$FF81,$FF03,$0607,$000F,$001F, {23:check-mark} $803F,$C07F,$E0FF,$F1FF,$FFFF,$FFFF,$FFFF,$FFFF, $0000,$0006,$000C,$0018,$0030,$0060,$70C0,$3980, $1F00,$0E00,$0400,$0000,$0000,$0000,$0000,$0000);hsx:5;hsy:10), (masks:($fff0,$ffe0,$ffc0,$ff81,$ff03,$607, $f, $1f, {24:check mark} $c03f,$f07f,$ffff,$ffff,$ffff,$ffff,$ffff,$ffff, $0, $6, $c, $18, $30, $60, $70c0,$1d80, $700, $0, $0, $0, $0, $0, $0, $0);hsx:6;hsy:8), (Masks:($E10F,$E00F,$F01F,$FC7F,$FC7F,$FC7F,$FC7F,$FC7F, {25:I shape} $FC7F,$FC7F,$FC7F,$FC7F,$F01F,$E00F,$E10F,$FFFF, $0000,$0C60,$0280,$0100,$0100,$0100,$0100,$0100, $0100,$0100,$0100,$0100,$0280,$0C60,$0000,$0000);hsx:7;hsy:7), (Masks:($C003,$8001,$07E0,$0000,$0000,$0000,$0000,$0000, {26:Smiley} $0000,$0000,$0000,$8001,$C003,$C003,$E007,$F81F, $0FF0,$1008,$2004,$4002,$4E72,$4A52,$4E72,$4002, $4992,$581A,$2424,$13C8,$1008,$0C30,$03C0,$0000);hsx:7;hsy:8), (Masks:($F83F,$F83F,$F83F,$F83F,$F83F,$F83F,$F83F,$F83F, {27:sword} $8003,$8003,$8003,$8003,$8003,$F83F,$F01F,$F01F, $0100,$0380,$0380,$0380,$0380,$0380,$0380,$0380, $0380,$3398,$3398,$3FF8,$0380,$0380,$0380,$07C0);hsx:7;hsy:0) ); xb0=10; yb0=10; dxb=20; x0=40; y0=50; dx=10; dy=10; ddx=200; xs=220; ys=420; var cn,l0,l1:integer; mBut,mwx,mwy:integer; dest : text; procedure drawMouseCursor(const x,y,n:integer); var i,j,v:integer; s:string[2]; begin with cursorList[n] do begin for i:=0 to 15 do for j:=0 to 15 do begin v:=0; if (masks[i] and bitmask[j])<>0 then inc(v,1); if (masks[i+16] and bitmask[j])<>0 then inc(v,2); putPixel(x+j,y+i,clr[v]); end; end; str(n,s); setColor(0); outTextXY(x,y+20,s); end; procedure drawBigCursor(const n:integer); var i,j,c,x1,y1,v:integer; begin hideMouse; with cursorList[n] do begin for i:=0 to 15 do for j:=0 to 15 do begin v:=0; x1:=x0+j*dx; y1:=y0+i*dy; if (masks[i] and bitmask[j])<>0 then inc(v,1); if (masks[i+16] and bitmask[j])<>0 then inc(v,2); c:=clr[v and 1]; setFillStyle(1,c); bar(x1,y1,x1+dx-2,y1+dy-2); c:=clr[v and 2]; setFillStyle(1,c); inc(x1,ddx); bar(x1,y1,x1+dx-2,y1+dy-2); c:=clr[v]; setFillStyle(1,c); inc(x1,ddx); bar(x1,y1,x1+dx-2,y1+dy-2); end; c:=1; setFillStyle(1,c); i:=dx div 3; j:=dy div 3; x1:=x0+hsx*dx+i; y1:=y0+hsy*dy+j; bar(x1,y1,x1+i,y1+j); inc(x1,ddx); bar(x1,y1,x1+i,y1+j); inc(x1,ddx); bar(x1,y1,x1+i,y1+j); end; showMouse; end; function locateMouse:integer; {0:nothing; 1:top line; 2:lh box;3:rh box} var xx:integer; begin locateMouse:=0; if (mwy>=yb0) and (mwy<=yb0+15) then begin {bar} xx:=mwx-xb0; if xx<0 then exit; l0:=xx div dxb; if l0>cursNum then exit; if (xx mod dxb)<=15 then locateMouse:=1; end; if (mwy>=y0) and (mwy<=y0+16*dy) then begin {cursors} xx:=mwx-x0; if xx<0 then exit; l0:=xx div ddx; if l0>1 then exit; if (xx mod ddx)<=16*dx then locateMouse:=l0+2; if l0=1 then dec(xx,ddx); {check for hot spot here!!} l0:=(mwy-y0) div dy; l1:=xx div dx; end; end; procedure ChangeMousePointer(n:integer); var r:registers; begin hideMouse; with cursorList[n] do with r do begin ax:=9; bx:=hsx; cx:=hsy; es:=seg(masks); dx:=ofs(masks); end; intr($33,r); showMouse; end; {ChangeMousePointer} procedure checkMouse; assembler; asm mov ax,3 int $33 mov mBut,bx mov mwx,cx mov mwy,dx end; procedure UpdateBigCursor(const i:integer); {i=2,lhs; i=3,rhs} {toggle bit, redraw appropriate parts of figures} var j,c,x1,y1,v:integer; begin hideMouse; with cursorList[cn] do begin { l0=i<=>y,l1=j<=>x} x1:=x0+l1*dx; y1:=y0+l0*dy; if i=2 then masks[l0]:=masks[l0] xor bitmask[l1] else masks[l0+16]:=masks[l0+16] xor bitmask[l1]; v:=0; if (masks[l0] and bitmask[l1])<>0 then inc(v,1); if (masks[l0+16] and bitmask[l1])<>0 then inc(v,2); c:=clr[v and 1]; setFillStyle(1,c); bar(x1,y1,x1+dx-2,y1+dy-2); c:=clr[v and 2]; setFillStyle(1,c); inc(x1,ddx); bar(x1,y1,x1+dx-2,y1+dy-2); c:=clr[v]; setFillStyle(1,c); inc(x1,ddx); bar(x1,y1,x1+dx-2,y1+dy-2); c:=1; setFillStyle(1,c); v:=dx div 3; j:=dy div 3; x1:=x0+hsx*dx+v; y1:=y0+hsy*dy+j; bar(x1,y1,x1+v,y1+j); inc(x1,ddx); bar(x1,y1,x1+v,y1+j); inc(x1,ddx); bar(x1,y1,x1+v,y1+j); end; ChangeMousePointer(cn); showMouse; end; procedure SaveWork(const cn:integer); var s:string; i:integer; begin str(cn,s); writeln(dest,'{case '+s+'}'); write (dest,' (Masks:('); with cursorList[cn] do begin for i:=0 to 31 do begin s:='$'+hex(masks[i],4); write(dest,s); if i<31 then begin write(dest,','); if i mod 8 = 7 then begin writeln(dest); write(dest,' '); end; end; end; str(hsx,s); write(dest,');hsx:'+s); str(hsy,s); writeln(dest,';hsy:'+s+'),'); writeln(dest); end; end; const fname='cursors.dat'; var gd,gm,x,y,n,i,j,k:integer; buttonDown:Boolean; begin repeat if not keypressed then break; i:=ord(readKey); until false; gd:=VGA; gm := VGAHi; initgraph(gd,gm,'d:\turbo\tp\'); { change this as needed !! } setfillstyle(solidfill,white); bar (0,0,getMaxX,getMaxY); SetColor(black); y:=220; outTextxy(0,y,' Screen mask Cursor mask Combination'); y:=450; x:=30; outtextxy(x,y,'Press any non-special key to exit.'); dec(y,12); outtextxy(x,y,'Press to append current cursor data to file "cursors.dat".'); dec(y,12); outtextxy(x,y,'The cursor changes appearance automatically.'); dec(y,12); outtextxy(x,y,'Move hot spot with arrow keys.'); dec(y,12); outTextXY(x,y,'Alter screen and cursor masks by clicking.'); dec(y,12); outTextxy(x,y,'Select starting cursor by clicking on top row.'); setfillstyle(solidfill,black); bar(0,250,getMaxX,350); x:=xb0; y:=yb0; for n:=0 to cursNum do begin drawMouseCursor(x,y,n); inc(x,dxb); end; cn:=0; drawBigCursor(cn); ChangeMousePointer(cn); ShowMouse; buttonDown:=false; assign(dest,fname); {$I-} append(dest); if IOResult<>0 then rewrite(dest); {$I+} repeat checkMouse; if (mBut=0)=buttonDown then begin buttonDown:=not buttonDown; if not buttonDown then begin i:=locateMouse; case i of 1: begin {top line} cn:=l0; drawBigCursor(cn); ChangeMousePointer(l0); end; 2,3: UpdateBigCursor(i); {lh,rh boxes} end;{case} end; end; if keyPressed then begin i:=ord(readkey); if i<>0 then break; i:=ord(readkey); with cursorList[cn] do case i of 60: {F2} saveWork(cn); 72: {up} if hsy>0 then dec(hsy); 75: {left} if hsx>0 then dec(hsx); 77: {right} if hsx<16 then inc(hsx); 80: {down} if hsy<16 then inc(hsy); end; drawBigCursor(cn); end; until false; closegraph; close(Dest); end.