|
|
1.1 ! root 1: #define bool int ! 2: #define true 1 ! 3: #define false 0 ! 4: ! 5: #define NOHIT -1 ! 6: ! 7: #define I_NULL -1 ! 8: #define I_OR 0 ! 9: #define I_STORE 1 ! 10: #define I_CLR 2 ! 11: #define I_XOR 3 ! 12: #define I_AND 4 ! 13: ! 14: #include "jerq.h" ! 15: #include <stdio.h> ! 16: ! 17: #define SPACING 24 ! 18: ! 19: #define sgn(x) ((x)<0 ? -1 : (x)==0 ? 0 : 1) ! 20: ! 21: int XSIZE = 50, YSIZE = 50; ! 22: ! 23: int horsize(r) ! 24: Rectangle r; ! 25: { ! 26: return(r.corner.x - r.origin.x); ! 27: } ! 28: ! 29: int versize(r) ! 30: Rectangle r; ! 31: { ! 32: return(r.corner.y - r.origin.y); ! 33: } ! 34: ! 35: extern Texture *(imenu[]); ! 36: ! 37: int lasthitx = 0, lasthity = 0; ! 38: #define SRC_ID 0 ! 39: #define SRC_CLR 1 ! 40: char *blitsrctext[] = ! 41: {"src := src","src := 0",NULL}; ! 42: ! 43: #define DST_STORE 0 ! 44: #define DST_OR 1 ! 45: #define DST_XOR 2 ! 46: #define DST_AND 3 ! 47: #define DST_CLR 4 ! 48: ! 49: char *blitdsttext[] = ! 50: {"dst := src","dst := src or dst","dst := src xor dst","dst := src and dst","dst := 0",NULL}; ! 51: ! 52: Menu blitsrcmenu = {blitsrctext}; ! 53: Menu blitdstmenu = {blitdsttext}; ! 54: ! 55: short Cmove_bits[] = { ! 56: 0x0000, 0x0000, 0x00C0, 0x00E0, ! 57: 0x00F0, 0x7FF8, 0x7FDC, 0x600E, ! 58: 0x6007, 0x600E, 0x7FDC, 0x7FF8, ! 59: 0x00F0, 0x00E0, 0x00C0, 0x0000, ! 60: }; ! 61: Texture Cmove; ! 62: ! 63: short Ccopy_bits[] = { ! 64: 0x0000, 0x7FE0, 0x4020, 0x4020, ! 65: 0x473F, 0x4FA1, 0x4DA1, 0x4C39, ! 66: 0x4FBD, 0x472D, 0x4021, 0x403D, ! 67: 0x7FF9, 0x0201, 0x0201, 0x03FF, ! 68: }; ! 69: Texture Ccopy; ! 70: ! 71: short Cerase_bits[] = { ! 72: 0x03FE, 0x0556, 0x0556, 0x0AAE, ! 73: 0x0AAE, 0x1FFC, 0x101C, 0x2028, ! 74: 0x2028, 0x4050, 0x4050, 0xFFA0, ! 75: 0x80A0, 0x80C0, 0x80C0, 0xFF80, ! 76: }; ! 77: Texture Cerase; ! 78: ! 79: short Cinvert_bits[] = { ! 80: 0x0000, 0x0000, 0x07C0, 0x07C0, ! 81: 0x07C0, 0x07C0, 0x07C0, 0x783C, ! 82: 0x783C, 0x783C, 0x07C0, 0x07C0, ! 83: 0x07C0, 0x07C0, 0x07C0, 0x0000, ! 84: }; ! 85: Texture Cinvert; ! 86: ! 87: short Cblit_bits[] = { ! 88: 0x0000, 0x7FE0, 0x4020, 0x4020, ! 89: 0x403F, 0x4021, 0x4021, 0x4021, ! 90: 0x4021, 0x4021, 0x4021, 0x4021, ! 91: 0x7FE1, 0x0201, 0x0201, 0x03FF, ! 92: }; ! 93: Texture Cblit; ! 94: ! 95: short Creflx_bits[] = { ! 96: 0x0000, 0x0000, 0x7FFE, 0x8001, ! 97: 0x8011, 0xC033, 0xBC5D, 0x8781, ! 98: 0x8501, 0x8501, 0x4482, 0x3C5C, ! 99: 0x0030, 0x0010, 0x0000, 0x0000, ! 100: }; ! 101: Texture Creflx; ! 102: ! 103: short Crefly_bits[] = { ! 104: 0x03F8, 0x0424, 0x0844, 0x0844, ! 105: 0x0844, 0x0FC4, 0x0084, 0x0384, ! 106: 0x0484, 0x0844, 0x1024, 0x3874, ! 107: 0x0844, 0x0844, 0x0424, 0x03F8, ! 108: }; ! 109: Texture Crefly; ! 110: ! 111: short Crotplus_bits[] = { ! 112: 0x0000, 0x0000, 0x3FE0, 0x2010, ! 113: 0x2008, 0x2008, 0x2008, 0x3F08, ! 114: 0x0108, 0x0108, 0x070E, 0x0204, ! 115: 0x0108, 0x0090, 0x0060, 0x0000, ! 116: }; ! 117: Texture Crotplus; ! 118: ! 119: short Crotminus_bits[] = { ! 120: 0x0000, 0x0400, 0x0C00, 0x17F0, ! 121: 0x2008, 0x4004, 0x4004, 0x2004, ! 122: 0x1784, 0x0C84, 0x0484, 0x0084, ! 123: 0x0084, 0x00FC, 0x0000, 0x0000, ! 124: }; ! 125: Texture Crotminus; ! 126: ! 127: short Cshearx_bits[] = { ! 128: 0x0000, 0x0000, 0x0000, 0x0000, ! 129: 0x0000, 0x03FF, 0x0000, 0x0FFC, ! 130: 0x0000, 0x3FF0, 0x0000, 0xFFC0, ! 131: 0x0000, 0x0000, 0x0000, 0x0000, ! 132: }; ! 133: Texture Cshearx; ! 134: ! 135: short Csheary_bits[] = { ! 136: 0x0800, 0x0800, 0x0A00, 0x0A00, ! 137: 0x0A80, 0x0A80, 0x0AA0, 0x0AA0, ! 138: 0x0AA0, 0x0AA0, 0x02A0, 0x02A0, ! 139: 0x00A0, 0x00A0, 0x0020, 0x0020, ! 140: }; ! 141: Texture Csheary; ! 142: ! 143: short Cstretch_bits[] = { ! 144: 0x0000, 0x7CAA, 0x7CAA, 0x7CAA, ! 145: 0x7CAA, 0x7CAA, 0x0000, 0x0000, ! 146: 0x7CAA, 0x0000, 0x7CAA, 0x0000, ! 147: 0x7CAA, 0x0000, 0x7CAA, 0x0000, ! 148: }; ! 149: Texture Cstretch; ! 150: ! 151: short Ctexture_bits[] = { ! 152: 0x4000, 0x7000, 0xE000, 0x2000, ! 153: 0x0444, 0x0777, 0x0EEE, 0x0222, ! 154: 0x0444, 0x0777, 0x0EEE, 0x0222, ! 155: 0x0444, 0x0777, 0x0EEE, 0x0222, ! 156: }; ! 157: Texture Ctexture; ! 158: ! 159: short Cgrid_bits[] = { ! 160: 0x4040, 0xFFFF, 0x4040, 0x4444, ! 161: 0x4040, 0x5555, 0x4040, 0x4444, ! 162: 0x4040, 0xFFFF, 0x4040, 0x4444, ! 163: 0x4040, 0x5555, 0x4040, 0x4444, ! 164: }; ! 165: Texture Cgrid; ! 166: ! 167: short Ccursor_bits[] = { ! 168: 0x0000, 0x0000, 0x03E0, 0x17F0, ! 169: 0x3FF0, 0x5FFE, 0xFFF1, 0x0421, ! 170: 0x0002, 0x00FC, 0x0100, 0x0080, ! 171: 0x0040, 0x0080, 0x0000, 0x0000, ! 172: }; ! 173: Texture Ccursor; ! 174: ! 175: short Cread_bits[] = { ! 176: 0x0000, 0x0FFE, 0x1FFA, 0x1811, ! 177: 0x0021, 0x8021, 0xC061, 0xC1F1, ! 178: 0x622A, 0x3414, 0x1810, 0x0810, ! 179: 0x0420, 0x03C0, 0x0000, 0x0000, ! 180: }; ! 181: Texture Cread; ! 182: ! 183: short Cwrite_bits[] = { ! 184: 0xF000, 0xFC00, 0x6B00, 0x3580, ! 185: 0x12C0, 0x1960, 0x0CA0, 0x06B0, ! 186: 0x0250, 0x0358, 0x01A8, 0x00D8, ! 187: 0x0074, 0x101C, 0xBB06, 0xEEFB, ! 188: }; ! 189: Texture Cwrite; ! 190: ! 191: short Cresize_bits[] = { ! 192: 0xFF54, 0x8100, 0x8104, 0x8100, ! 193: 0x8104, 0x8100, 0x8104, 0xFF00, ! 194: 0x0004, 0x8000, 0x0014, 0x8038, ! 195: 0x001D, 0xAAAF, 0x0007, 0x000F, ! 196: }; ! 197: Texture Cresize; ! 198: ! 199: short Chelp_bits[] = { ! 200: 0x0000, 0x0000, 0x0000, 0x0000, ! 201: 0xE0E0, 0x6060, 0x7F7E, 0x7DFF, ! 202: 0x6FFB, 0x6C7B, 0x6FFE, 0xFFF8, ! 203: 0x003C, 0x0000, 0x0000, 0x0000, ! 204: }; ! 205: Texture Chelp; ! 206: ! 207: short Cundo_bits[] = { ! 208: 0x001C, 0x0022, 0x0041, 0x0081, ! 209: 0x0101, 0x0282, 0x0544, 0x0AA8, ! 210: 0x1550, 0x22A0, 0x4140, 0x8080, ! 211: 0x8100, 0x8200, 0x4400, 0x3800, ! 212: }; ! 213: Texture Cundo; ! 214: ! 215: short white_bits[] = { ! 216: 0x0000, 0x0000, 0x0000, 0x0000, ! 217: 0x0000, 0x0000, 0x0000, 0x0000, ! 218: 0x0000, 0x0000, 0x0000, 0x0000, ! 219: 0x0000, 0x0000, 0x0000, 0x0000, ! 220: }; ! 221: Cursor white; ! 222: Texture whiteT; ! 223: ! 224: short menucursor_bits[] = { ! 225: 0xFFC0, 0x8040, 0x8040, 0x8040, ! 226: 0xFFC0, 0xFFC0, 0xFE00, 0xFEF0, ! 227: 0x80E0, 0x80F0, 0x80B8, 0xFE1C, ! 228: 0x800E, 0x8047, 0x8042, 0xFFC0, ! 229: }; ! 230: Cursor menucursor; ! 231: Texture menucursorT; ! 232: ! 233: short sweepcursor_bits[] = { ! 234: 0x43FF, 0xE001, 0x7001, 0x3801, ! 235: 0x1D01, 0x0F01, 0x8701, 0x8F01, ! 236: 0x8001, 0x8001, 0x8001, 0x8001, ! 237: 0x8001, 0x8001, 0x8001, 0xFFFF, ! 238: }; ! 239: Cursor sweepcursor; ! 240: Texture sweepcursorT; ! 241: ! 242: short sweeportrack_bits[] = { ! 243: 0x43FF, 0xE001, 0x70FD, 0x3805, ! 244: 0x1D05, 0x0F05, 0x8705, 0x8F05, ! 245: 0xA005, 0xA005, 0xA005, 0xA005, ! 246: 0xA005, 0xBFFD, 0x8001, 0xFFFF, ! 247: }; ! 248: Cursor sweeportrack; ! 249: Texture sweeportrackT; ! 250: ! 251: short clock_bits[] = { ! 252: 0x03C0, 0x3420, 0x37E0, 0x13C0, ! 253: 0x17F0, 0x1828, 0x2054, 0x20D4, ! 254: 0x418A, 0x430A, 0x430A, 0x418A, ! 255: 0x2094, 0x201C, 0x787E, 0x67F6, ! 256: }; ! 257: Cursor clock; ! 258: Texture clockT; ! 259: ! 260: short deadmouse_bits[] = { ! 261: 0x0000, 0x0000, 0x0008, 0x0004, ! 262: 0x0082, 0x0441, 0xFFE1, 0x5FF1, ! 263: 0x3FFE, 0x17F0, 0x03E0, 0x0000, ! 264: 0x0000, 0x0000, 0x0000, 0x0000, ! 265: }; ! 266: Cursor deadmouse; ! 267: Texture deadmouseT; ! 268: ! 269: initicons() ! 270: { ! 271: Cmove = ToTexture(Cmove_bits); ! 272: Ccopy = ToTexture(Ccopy_bits); ! 273: Cerase = ToTexture(Cerase_bits); ! 274: Cinvert = ToTexture(Cinvert_bits); ! 275: Cblit = ToTexture(Cblit_bits); ! 276: Creflx = ToTexture(Creflx_bits); ! 277: Crefly = ToTexture(Crefly_bits); ! 278: Crotplus = ToTexture(Crotplus_bits); ! 279: Crotminus = ToTexture(Crotminus_bits); ! 280: Cshearx = ToTexture(Cshearx_bits); ! 281: Csheary = ToTexture(Csheary_bits); ! 282: Cstretch = ToTexture(Cstretch_bits); ! 283: Ctexture = ToTexture(Ctexture_bits); ! 284: Cgrid = ToTexture(Cgrid_bits); ! 285: Ccursor = ToTexture(Ccursor_bits); ! 286: Cread = ToTexture(Cread_bits); ! 287: Cwrite = ToTexture(Cwrite_bits); ! 288: Cresize = ToTexture(Cresize_bits); ! 289: Chelp = ToTexture(Chelp_bits); ! 290: Cundo = ToTexture(Cundo_bits); ! 291: whiteT = ToTexture(white_bits); ! 292: white = ToCursor(white_bits, white_bits, 7, 7); ! 293: menucursorT = ToTexture(menucursor_bits); ! 294: menucursor = ToCursor(menucursor_bits, menucursor_bits, 7, 7); ! 295: sweepcursorT = ToTexture(sweepcursor_bits); ! 296: sweepcursor = ToCursor(sweepcursor_bits, sweepcursor_bits, 7, 7); ! 297: sweeportrackT = ToTexture(sweeportrack_bits); ! 298: sweeportrack = ToCursor(sweeportrack_bits, sweeportrack_bits, 7, 7); ! 299: clockT = ToTexture(clock_bits); ! 300: clock = ToCursor(clock_bits, clock_bits, 7, 7); ! 301: deadmouseT = ToTexture(deadmouse_bits); ! 302: deadmouse = ToCursor(deadmouse_bits, deadmouse_bits, 7, 7); ! 303: } ! 304: ! 305: #define MOVE 0 ! 306: #define COPY 1 ! 307: #define INVERT 2 ! 308: #define ERASE 3 ! 309: ! 310: #define REFLECTX 5 ! 311: #define REFLECTY 6 ! 312: #define ROTATEPLUS 7 ! 313: #define ROTATEMINUS 8 ! 314: ! 315: #define SHEARX 10 ! 316: #define SHEARY 11 ! 317: #define STRETCH 12 ! 318: #define TEXTURE 13 ! 319: ! 320: #define READ 15 ! 321: #define GRID 16 ! 322: #define RESIZE 17 ! 323: #define WRITE 18 ! 324: ! 325: #define BLIT 20 ! 326: #define PICK 21 ! 327: #define HELP 22 ! 328: #define UNDO 23 ! 329: ! 330: Texture *(imenu[]) = ! 331: {&Cmove,&Ccopy,&Cinvert,&Cerase,0, ! 332: &Creflx,&Crefly,&Crotplus,&Crotminus,0, ! 333: &Cshearx,&Csheary,&Cstretch,&Ctexture,0, ! 334: &Cread,&Cgrid,&Cresize,&Cwrite,0, ! 335: &Cblit,&Ccursor,&Chelp,&Cundo,0, ! 336: 0,0,0,0 ! 337: }; ! 338: ! 339: ! 340: char exa[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; ! 341: char buf[100],FNAME[50]; ! 342: Point nullpoint, point16x16; ! 343: Rectangle icon, ICON, sweep, outl, nullrect, rect16x16; ! 344: int Xsize,Ysize; ! 345: int Xblocks,Yblocks; ! 346: int modx,divx,mody,divy; ! 347: ! 348: flipring(p) ! 349: Point p; ! 350: { ! 351: outline(&display,raddp(Rect(1,1,SPACING-2,SPACING-2),p)); ! 352: outline(&display,raddp(Rect(2,2,SPACING-3,SPACING-3),p)); ! 353: } ! 354: ! 355: drawimenu(xicons,yicons,r) ! 356: Rectangle r; ! 357: { ! 358: Bitmap *textr; ! 359: int i,j; ! 360: rectf(&display,r,F_CLR); ! 361: outline(&display,Rpt(r.origin,sub(r.corner,Pt(1,1)))); ! 362: textr = balloc(Rect(0,0,16,16)); ! 363: if (textr == ((Bitmap *) 0)) return(0); ! 364: for (j=0; j<yicons; j++) { ! 365: for (i=0; i<xicons; i++) { ! 366: texture(textr,textr->rect,imenu[j*(xicons+1)+i],F_STORE); ! 367: bitblt(textr,textr->rect, ! 368: &display, ! 369: add(r.origin,Pt(i*SPACING+(SPACING-16)/2,j*SPACING+(SPACING-16)/2)), ! 370: F_OR); ! 371: } ! 372: } ! 373: bfree(textr); ! 374: } ! 375: ! 376: Point imenuhit() ! 377: { ! 378: Bitmap *offscreen; ! 379: Point ms,valley,diff,result,menudrift; ! 380: Rectangle menurect; ! 381: Cursor *oldcursor; ! 382: int i,j,hitx,hity, ohitx,ohity; ! 383: int xicons,yicons; ! 384: oldcursor = cursswitch(&white); ! 385: xicons = 0; ! 386: for (j=0; imenu[xicons*j]; j++) { ! 387: for (i=0; imenu[xicons*j+i]; i++); ! 388: i++; ! 389: xicons = i; ! 390: } ! 391: xicons -= 1; ! 392: yicons = j; ! 393: /* while (!button3()) wait(MOUSE); */ ! 394: ms = mouse.xy; ! 395: menurect = raddp(Rect(0,0,SPACING*xicons,SPACING*yicons),ms); ! 396: menurect = rsubp(menurect,Pt(SPACING*lasthitx,SPACING*lasthity)); ! 397: menudrift.x = min(menurect.corner.x,Drect.corner.x); ! 398: menudrift.y = min(menurect.corner.y,Drect.corner.y); ! 399: menudrift = sub(menudrift,menurect.corner); ! 400: menurect = raddp(menurect,menudrift); cursset(ms=add(ms,menudrift)); ! 401: menudrift.x = max(menurect.origin.x,Drect.origin.x); ! 402: menudrift.y = max(menurect.origin.y,Drect.origin.y); ! 403: menudrift = sub(menudrift,menurect.origin); ! 404: menurect = raddp(menurect,menudrift); cursset(add(ms,menudrift)); ! 405: offscreen = balloc(menurect); ! 406: if (offscreen != ((Bitmap *) 0)) { ! 407: bitblt(&display,menurect,offscreen,offscreen->rect.origin,F_STORE); ! 408: } ! 409: drawimenu(xicons,yicons,menurect); ! 410: hitx = hity = -1; ! 411: while (button3()) { ! 412: jnap(1); ! 413: ms = mouse.xy; ! 414: ohitx = hitx; ohity = hity; ! 415: if (ptinrect(ms,menurect)) { ! 416: lasthitx = hitx = (ms.x-menurect.origin.x)/SPACING; ! 417: lasthity = hity = (ms.y-menurect.origin.y)/SPACING; ! 418: } else hitx = hity = -1; ! 419: if (hitx == -1) { ! 420: if (ohitx != -1) { ! 421: flipring(valley); ! 422: cursswitch(oldcursor); ! 423: } ! 424: continue; ! 425: } ! 426: if (ohitx == -1) { ! 427: cursswitch(&white); ! 428: valley = add(menurect.origin,Pt(SPACING*hitx,SPACING*hity)); ! 429: flipring(valley); ! 430: } else if (ohitx != hitx || ohity != hity){ ! 431: flipring(valley); ! 432: valley = add(menurect.origin,Pt(SPACING*hitx,SPACING*hity)); ! 433: flipring(valley); ! 434: } ! 435: } ! 436: if (offscreen != ((Bitmap *) 0)) { ! 437: bitblt(offscreen,offscreen->rect,&display,menurect.origin,F_STORE); ! 438: bfree(offscreen); ! 439: } ! 440: result.x = hitx; ! 441: result.y = hity; ! 442: cursswitch(oldcursor); ! 443: return(result); ! 444: } ! 445: ! 446: Rectangle canonrect(p1, p2) ! 447: Point p1, p2; ! 448: { ! 449: Rectangle r; ! 450: r.origin.x = min(p1.x, p2.x); ! 451: r.origin.y = min(p1.y, p2.y); ! 452: r.corner.x = max(p1.x, p2.x); ! 453: r.corner.y = max(p1.y, p2.y); ! 454: return(r); ! 455: } ! 456: ! 457: int pttopt(p,q) ! 458: /* manhattan topology distance between two points */ ! 459: Point p,q; ! 460: { ! 461: return(abs(p.x-q.x)+abs(p.y-q.y)); ! 462: } ! 463: ! 464: Point nearestcorner(r,p) ! 465: Rectangle r; ! 466: Point p; ! 467: { ! 468: int mindist,dist; ! 469: Point minq,q; ! 470: q = r.origin; ! 471: mindist = pttopt(p,q); minq = q; ! 472: q.x = r.origin.x; q.y = r.corner.y; ! 473: if ((dist = pttopt(p,q))<mindist) {mindist = dist; minq = q;} ! 474: q = r.corner; ! 475: if ((dist = pttopt(p,q))<mindist) {mindist = dist; minq = q;} ! 476: q.x = r.corner.x; q.y = r.origin.y; ! 477: if ((dist = pttopt(p,q))<mindist) {mindist = dist; minq = q;} ! 478: return(minq); ! 479: } ! 480: ! 481: outline(b,r) ! 482: Bitmap *b; ! 483: Rectangle r; ! 484: { ! 485: rectf(b,Rect(r.origin.x,r.origin.y,r.origin.x+1,r.corner.y),F_XOR); ! 486: rectf(b,Rect(r.origin.x,r.corner.y,r.corner.x,r.corner.y+1),F_XOR); ! 487: rectf(b,Rect(r.corner.x,r.origin.y+1,r.corner.x+1,r.corner.y+1),F_XOR); ! 488: rectf(b,Rect(r.origin.x+1,r.origin.y,r.corner.x+1,r.origin.y+1),F_XOR); ! 489: } ! 490: ! 491: Border(r) ! 492: Rectangle r; ! 493: { ! 494: outline(&display,inset(r,1)); ! 495: outline(&display,inset(r,-1)); ! 496: } ! 497: ! 498: Rectangle sweeprect() ! 499: { ! 500: Rectangle r; ! 501: Point p1, p2; ! 502: Cursor *oldcursor; ! 503: oldcursor = cursswitch(&sweepcursor); ! 504: while (!button123()) wait(MOUSE); ! 505: p1=mouse.xy; ! 506: p2=p1; ! 507: r=canonrect(p1, p2); ! 508: outline(&display,r); ! 509: for(; button3(); nap(2)){ ! 510: outline(&display,r); ! 511: p2=mouse.xy; ! 512: r=canonrect(p1, p2); ! 513: outline(&display,r); ! 514: } ! 515: outline(&display,r); ! 516: cursswitch(oldcursor); ! 517: return r; ! 518: } ! 519: ! 520: bool getr(cliprect,sweep) ! 521: Rectangle cliprect; ! 522: Rectangle *sweep; ! 523: { ! 524: int j; ! 525: *sweep = sweeprect(); ! 526: return(rectclip(sweep,cliprect)); ! 527: } ! 528: ! 529: Point IconPoint(p) ! 530: /* convert screen coord to icon coord */ ! 531: Point p; ! 532: { ! 533: p.x = (p.x+Xsize-modx)/Xsize - divx - 1; ! 534: p.y = (p.y+Ysize-mody)/Ysize - divy - 1; ! 535: return(p); ! 536: } ! 537: ! 538: short IconCoordX(x) ! 539: short x; ! 540: { ! 541: return((x+Xsize-modx)/Xsize - divx - 1); ! 542: } ! 543: ! 544: short IconCoordY(y) ! 545: short y; ! 546: { ! 547: return((y+Ysize-mody)/Ysize - divy - 1); ! 548: } ! 549: ! 550: Point ScreenPoint(p) ! 551: /* convert icon coord to screen coord */ ! 552: Point p; ! 553: { ! 554: p.x = p.x*Xsize + ICON.origin.x; ! 555: p.y = p.y*Ysize + ICON.origin.y; ! 556: return(p); ! 557: } ! 558: ! 559: short ScreenCoordX(x) ! 560: short x; ! 561: { ! 562: return(x*Xsize + ICON.origin.x); ! 563: } ! 564: ! 565: short ScreenCoordY(y) ! 566: short y; ! 567: { ! 568: return(y*Ysize + ICON.origin.y); ! 569: } ! 570: ! 571: ! 572: Rectangle IconRect(r) ! 573: /* convert a screen rectangle to the biggest totally contained icon rectangle */ ! 574: Rectangle r; ! 575: { ! 576: r.origin = IconPoint(add(r.origin,Pt(Xsize-1,Ysize-1))); ! 577: r.corner = IconPoint(r.corner); ! 578: if (horsize(r)<0) r.origin.x = r.corner.x; ! 579: if (versize(r)<0) r.origin.y = r.corner.y; ! 580: return(r); ! 581: } ! 582: ! 583: Rectangle TrackBorder(r,buttonup) ! 584: /* tracks a rectangle "r" (in icon coords) and returns it as it is ! 585: at the end of tracking, clipped to the icon */ ! 586: Rectangle r; ! 587: bool buttonup; ! 588: { ! 589: Point newP, oldP; ! 590: Cursor *oldcursor; ! 591: oldcursor = cursswitch(&white); ! 592: outl.origin = nullpoint; ! 593: outl.corner.x = horsize(r)*Xsize; ! 594: outl.corner.y = versize(r)*Ysize; ! 595: newP = ScreenPoint(r.origin); ! 596: while (buttonup?(button123()):(!button123())) ! 597: wait(MOUSE); ! 598: cursset(newP); ! 599: oldP = newP; ! 600: Border(raddp(outl,newP)); ! 601: while (buttonup?(!button123()):(button123())) { ! 602: wait(MOUSE); ! 603: newP = ScreenPoint(IconPoint(mouse.xy)); ! 604: if (!eqpt(newP,oldP)) { ! 605: Border(raddp(outl,oldP)); ! 606: Border(raddp(outl,newP)); ! 607: oldP = newP; ! 608: } ! 609: } ! 610: Border(raddp(outl,newP)); ! 611: cursswitch(oldcursor); ! 612: return(IconRect(raddp(outl,newP))); ! 613: } ! 614: ! 615: bool SweepIconRect(r) ! 616: Rectangle *r; ! 617: { ! 618: Point p; ! 619: if (!getr(ICON,&sweep)) return(false); ! 620: *r = IconRect(sweep); ! 621: if ((horsize(*r)==0) || (versize(*r)==0)) return(false); ! 622: return(true); ! 623: } ! 624: ! 625: int GetIconRect(r) ! 626: /* returns: 0 if no rectangle is provided; ! 627: 2 if button2 is used (tracking a 16x16 rectangle); ! 628: 3 if button3 is used (sweeping a rectangle); ! 629: if a rectangle is provided, r returns it in icon coordinates */ ! 630: Rectangle *r; ! 631: { ! 632: int result; ! 633: Cursor *oldcursor; ! 634: oldcursor = cursswitch(&sweeportrack); ! 635: while (!button123()) wait(MOUSE); ! 636: if (button3()) { ! 637: if (SweepIconRect(r)) result = 3; ! 638: else result = 0; ! 639: } else if (button2()) { ! 640: *r = TrackBorder(raddp(rect16x16,add(IconPoint(mouse.xy),Pt(1,1))),false); ! 641: result = 2; ! 642: } else {while(button1())jnap(1); result = 0;} ! 643: cursswitch(oldcursor); ! 644: return(result); ! 645: } ! 646: ! 647: bool GetIconPoint(p) ! 648: Point *p; ! 649: { ! 650: Rectangle r; ! 651: r = TrackBorder(raddp(Rect(0,0,1,1),IconPoint(mouse.xy)),true); ! 652: while (button123())jnap(1); ! 653: *p = r.origin; ! 654: return((horsize(r) == 1) && (versize(r) == 1)); ! 655: } ! 656: ! 657: Bitmap *bittester; ! 658: ! 659: bool bitmapbit(b,p) ! 660: Bitmap *b; ! 661: Point p; ! 662: { ! 663: if (!(ptinrect(p,b->rect))) return(false); ! 664: return (getpoint(b,p)); ! 665: } ! 666: ! 667: char getnibble(b,p) ! 668: Bitmap *b; ! 669: Point p; ! 670: { ! 671: int nibble; ! 672: nibble = 8*bitmapbit(b,p) + 4*bitmapbit(b,Pt(p.x+1,p.y)) + ! 673: 2*bitmapbit(b,Pt(p.x+2,p.y)) + bitmapbit(b,Pt(p.x+3,p.y)); ! 674: return(exa[nibble]); ! 675: } ! 676: ! 677: putnibble(ch,b,clipr,p) ! 678: int ch; ! 679: Bitmap *b; ! 680: Rectangle clipr; ! 681: Point p; ! 682: { ! 683: int nibble, mask; ! 684: if (ch<'0') return; ! 685: if (ch<='9') nibble = ch - '0'; ! 686: else if (ch<='F') nibble = 10 + (ch - 'A'); ! 687: else nibble = 10 + (ch - 'a'); ! 688: if (nibble != 0) ! 689: for (mask = 0x10; mask >>= 1; p.x++) ! 690: if ((mask & nibble) && ptinrect(p, clipr)) ! 691: point(b, p, F_OR); ! 692: } ! 693: ! 694: Bitmap *Source, *Undo; ! 695: ! 696: FlipOntoScreen(p) ! 697: Point p; ! 698: { ! 699: Rectangle ICONp; ! 700: if (!ptinrect(p,Source->rect)) return(0); ! 701: point(&display,add(icon.origin,p),F_XOR); ! 702: ICONp.origin = add(Pt(p.x*Xsize,p.y*Ysize),ICON.origin); ! 703: ICONp.corner = add(Pt((p.x+1)*Xsize,(p.y+1)*Ysize),ICON.origin); ! 704: if ((ICONp.origin.x > icon.corner.x) || ! 705: (ICONp.origin.y > icon.corner.y)) ! 706: rectf(&display,ICONp,F_XOR); ! 707: } ! 708: ! 709: bool geticonpoint(p) ! 710: Point p; ! 711: { ! 712: if (!ptinrect(p,Source->rect)) return(false); ! 713: return(bitmapbit(Source,p)); ! 714: } ! 715: ! 716: flipiconpoint(p) ! 717: Point p; ! 718: { ! 719: point(Source,p,F_XOR); ! 720: FlipOntoScreen(p); ! 721: } ! 722: ! 723: IconOp(bit,p,op) ! 724: bool bit; ! 725: Point p; ! 726: int op; ! 727: { ! 728: if ((p.x>=0) && (p.x<Xblocks) && (p.y>=0) && (p.y<Yblocks)) ! 729: switch (op) { ! 730: case I_STORE: ! 731: if (geticonpoint(p) != bit) flipiconpoint(p); ! 732: break; ! 733: case I_CLR: ! 734: if (geticonpoint(p)) flipiconpoint(p); ! 735: break; ! 736: case I_OR: ! 737: if (bit && !geticonpoint(p)) flipiconpoint(p); ! 738: break; ! 739: case I_XOR: ! 740: if (bit) flipiconpoint(p); ! 741: break; ! 742: case I_AND: ! 743: if (!bit && geticonpoint(p)) flipiconpoint(p); ! 744: break; ! 745: } ! 746: } ! 747: ! 748: IconBitBlit(from,to,clip,srccode,dstcode) ! 749: Rectangle from; /* icon coords */ ! 750: Point to; /* icon coords */ ! 751: Rectangle clip; /* icon coords */ ! 752: int srccode,dstcode; ! 753: { ! 754: Rectangle region; ! 755: int dx,dy,di,dj,i,j; ! 756: int left,up; ! 757: bool bit; ! 758: dx = to.x - from.origin.x; ! 759: dy = to.y - from.origin.y; ! 760: left = dx<0; ! 761: up = dy<0; ! 762: di = (left?1:-1); ! 763: dj = (up?1:-1); ! 764: region = from; ! 765: if (!rectclip(®ion,raddp(clip,sub(from.origin,to)))) ! 766: region = nullrect; ! 767: for (j=(up?from.origin.y:from.corner.y-1); ! 768: up?(j<from.corner.y):(j>=from.origin.y); j+=dj) { ! 769: wait(CPU); ! 770: for (i=(left?from.origin.x:from.corner.x-1); ! 771: left?(i<from.corner.x):(i>=from.origin.x); i+=di) { ! 772: bit = geticonpoint(Pt(i,j)); ! 773: IconOp(false,Pt(i,j),srccode); ! 774: if (ptinrect(Pt(i,j),region)) IconOp(bit,Pt(i+dx,j+dy),dstcode); ! 775: } ! 776: } ! 777: } ! 778: ! 779: horshear(b,r,dx,top) ! 780: Bitmap *b; ! 781: Rectangle r; ! 782: int dx; ! 783: bool top; ! 784: { ! 785: int i,j,hsize,vsize,shift; ! 786: bool bit,dir; ! 787: hsize = horsize(r); ! 788: vsize = versize(r); ! 789: dir = (dx>0); ! 790: for (j=0; j<vsize; j++) { ! 791: wait(CPU); ! 792: shift = top ? vsize-j-1 : j; ! 793: bitblt(b,Rect(r.origin.x,r.origin.y+j,r.corner.x,r.origin.y+j+1), ! 794: b,Pt(r.origin.x+muldiv(shift,dx,vsize),r.origin.y+j), ! 795: F_STORE); ! 796: } ! 797: } ! 798: ! 799: vershear(b,r,dy,lft) ! 800: Bitmap *b; ! 801: Rectangle r; ! 802: int dy; ! 803: bool lft; ! 804: { ! 805: int i,j,hsize,vsize,shift; ! 806: bool bit,dir; ! 807: hsize = horsize(r); ! 808: vsize = versize(r); ! 809: dir = (dy>0); ! 810: for (i=0; i<hsize; i++) { ! 811: wait(CPU); ! 812: shift = lft ? hsize-i-1 : i; ! 813: bitblt(b,Rect(r.origin.x+i,r.origin.y,r.origin.x+i+1,r.corner.y), ! 814: b,Pt(r.origin.x+i,r.origin.y+muldiv(shift,dy,hsize)), ! 815: F_STORE); ! 816: } ! 817: } ! 818: ! 819: OpRotPlus() ! 820: { ! 821: int vsize,hsize,size; ! 822: Rectangle r,rbuf; ! 823: Bitmap *buffer; ! 824: if (GetIconRect(&r)==0) return(0); ! 825: hsize = horsize(r); vsize = versize(r); size = hsize+vsize; ! 826: buffer = balloc(Rect(0,0,size,size)); ! 827: if (buffer == ((Bitmap *) 0)) return(0); ! 828: rectf(buffer,buffer->rect,F_CLR); ! 829: rbuf = rsubp(r,r.origin); ! 830: SaveForUndo(); ! 831: cursswitch(&clock); ! 832: bitblt(&display,raddp(r,icon.origin),buffer,rbuf.origin,F_XOR); ! 833: horshear(buffer,rbuf,vsize,true); ! 834: vershear(buffer, ! 835: Rect(rbuf.origin.x,rbuf.origin.y,rbuf.corner.x+vsize,rbuf.corner.y), ! 836: size,false); ! 837: horshear(buffer, ! 838: Rect(rbuf.origin.x,rbuf.corner.y-1, ! 839: rbuf.corner.x+vsize,rbuf.corner.y+hsize-1), ! 840: -hsize,false); ! 841: Erase(r); ! 842: OrOntoPicture(buffer, ! 843: Rect(rbuf.origin.x,rbuf.corner.y-1, ! 844: rbuf.origin.x+vsize,rbuf.corner.y+hsize-1), ! 845: add(r.origin,sub(Pt(hsize/2,vsize/2),Pt(vsize/2,hsize/2)))); ! 846: cursswitch((Cursor *) 0); ! 847: bfree(buffer); ! 848: } ! 849: ! 850: OpRotMinus() ! 851: { ! 852: int vsize,hsize,size; ! 853: Rectangle r,rbuf; ! 854: Bitmap *buffer; ! 855: if (GetIconRect(&r)==0) return(0); ! 856: hsize = horsize(r); vsize = versize(r); size = hsize+vsize; ! 857: buffer = balloc(Rect(0,0,size,size)); ! 858: if (buffer == ((Bitmap *) 0)) return(0); ! 859: rectf(buffer,buffer->rect,F_CLR); ! 860: rbuf = raddp(r,sub(Pt(vsize,0),r.origin)); ! 861: SaveForUndo(); ! 862: cursswitch(&clock); ! 863: bitblt(&display,raddp(r,icon.origin),buffer,rbuf.origin,F_XOR); ! 864: horshear(buffer,rbuf,-vsize,true); ! 865: vershear(buffer, ! 866: Rect(rbuf.origin.x-vsize,rbuf.origin.y,rbuf.corner.x,rbuf.corner.y), ! 867: size,true); ! 868: horshear(buffer, ! 869: Rect(rbuf.origin.x-vsize,rbuf.corner.y-1, ! 870: rbuf.corner.x,rbuf.corner.y+hsize-1), ! 871: hsize,false); ! 872: Erase(r); ! 873: OrOntoPicture(buffer, ! 874: Rect(rbuf.corner.x-vsize,rbuf.corner.y-1, ! 875: rbuf.corner.x,rbuf.corner.y+hsize-1), ! 876: add(r.origin,sub(Pt(hsize/2,vsize/2),Pt(vsize/2,hsize/2)))); ! 877: cursswitch((Cursor *) 0); ! 878: bfree(buffer); ! 879: } ! 880: ! 881: OpReflY() ! 882: { ! 883: Rectangle r; ! 884: int i,j; ! 885: bool bit1,bit2; ! 886: if (GetIconRect(&r)==0) return(0); ! 887: SaveForUndo(); ! 888: cursswitch(&clock); ! 889: for (i=r.origin.x; i<r.corner.x; i+=1) { ! 890: wait(CPU); ! 891: for (j=0; j<(versize(r)/2); j+=1) { ! 892: bit1 = geticonpoint(Pt(i,r.origin.y+j)); ! 893: bit2 = geticonpoint(Pt(i,r.corner.y-1-j)); ! 894: IconOp(bit1,Pt(i,r.corner.y-1-j),I_STORE); ! 895: IconOp(bit2,Pt(i,r.origin.y+j),I_STORE); ! 896: } ! 897: } ! 898: cursswitch((Cursor *) 0); ! 899: } ! 900: ! 901: OpReflX() ! 902: { ! 903: Rectangle r; ! 904: int i,j; ! 905: bool bit1,bit2; ! 906: if (GetIconRect(&r)==0) return(0); ! 907: SaveForUndo(); ! 908: cursswitch(&clock); ! 909: for (i=0; i<(horsize(r)/2); i+=1) { ! 910: wait(CPU); ! 911: for (j=r.origin.y; j<r.corner.y; j+=1) { ! 912: bit1 = geticonpoint(Pt(r.origin.x+i,j)); ! 913: bit2 = geticonpoint(Pt(r.corner.x-1-i,j)); ! 914: IconOp(bit1,Pt(r.corner.x-1-i,j),I_STORE); ! 915: IconOp(bit2,Pt(r.origin.x+i,j),I_STORE); ! 916: } ! 917: } ! 918: cursswitch((Cursor *) 0); ! 919: } ! 920: ! 921: OpBlit(srcop,dstop) ! 922: int srcop,dstop; ! 923: { ! 924: Rectangle r, r1; ! 925: Point p; ! 926: if (GetIconRect(&r)==0) return(0); ! 927: r1 = TrackBorder(r,true); ! 928: p = r1.origin; ! 929: if (button23()) { ! 930: while (button23())jnap(1); ! 931: SaveForUndo(); ! 932: cursswitch(&clock); ! 933: IconBitBlit(r,p,Rect(0,0,Xblocks,Yblocks),srcop,dstop); ! 934: cursswitch((Cursor *) 0); ! 935: } else while (button1())jnap(1); ! 936: } ! 937: ! 938: ! 939: OpGeneralBlit() ! 940: { ! 941: int srcop, dstop; ! 942: cursswitch(&menucursor); ! 943: while (!button123()) wait(MOUSE); ! 944: cursswitch((Cursor *) 0); ! 945: if (!button3()) return(0); ! 946: switch (menuhit(&blitsrcmenu,3)) { ! 947: case NOHIT: ! 948: srcop = I_NULL; ! 949: break; ! 950: case SRC_ID: ! 951: srcop = I_OR; ! 952: break; ! 953: case SRC_CLR: ! 954: srcop = I_CLR; ! 955: break; ! 956: } ! 957: if (srcop==I_NULL) {cursswitch((Cursor *) 0); return(0);} ! 958: cursswitch(&menucursor); ! 959: while (!button123()) wait(MOUSE); ! 960: cursswitch((Cursor *) 0); ! 961: if (!button3()) return(0); ! 962: switch (menuhit(&blitdstmenu,3)) { ! 963: case NOHIT: ! 964: dstop = I_NULL; ! 965: break; ! 966: case DST_STORE: ! 967: dstop = I_STORE; ! 968: break; ! 969: case DST_OR: ! 970: dstop = I_OR; ! 971: break; ! 972: case DST_XOR: ! 973: dstop = I_XOR; ! 974: break; ! 975: case DST_AND: ! 976: dstop = I_AND; ! 977: break; ! 978: case DST_CLR: ! 979: dstop = I_CLR; ! 980: break; ! 981: } ! 982: if (dstop==I_NULL) {cursswitch((Cursor *) 0); return(0);} ! 983: OpBlit(srcop,dstop); ! 984: } ! 985: ! 986: Erase(r) ! 987: Rectangle r; ! 988: { ! 989: int i,j; ! 990: for (j = r.origin.y ; j < r.corner.y ; j++) { ! 991: wait(CPU); ! 992: for (i = r.origin.x ; i < r.corner.x ; i++) { ! 993: if (geticonpoint(Pt(i,j)) == true) flipiconpoint(Pt(i,j)); ! 994: } ! 995: } ! 996: } ! 997: ! 998: OpErase() ! 999: { ! 1000: Rectangle r; ! 1001: if (GetIconRect(&r)==0) return(0); ! 1002: SaveForUndo(); ! 1003: cursswitch(&clock); ! 1004: Erase(r); ! 1005: cursswitch((Cursor *)0); ! 1006: } ! 1007: ! 1008: OpInvert() ! 1009: { ! 1010: Rectangle r; ! 1011: int i,j; ! 1012: if (GetIconRect(&r)==0) return(0); ! 1013: SaveForUndo(); ! 1014: cursswitch(&clock); ! 1015: for (j = r.origin.y ; j < r.corner.y ; j++) { ! 1016: wait(CPU); ! 1017: for (i = r.origin.x ; i < r.corner.x ; i++) { ! 1018: flipiconpoint(Pt(i,j)); ! 1019: } ! 1020: } ! 1021: cursswitch((Cursor *)0); ! 1022: } ! 1023: ! 1024: getstr(s,p) ! 1025: char *s; ! 1026: Point p; ! 1027: { ! 1028: char c,*t; ! 1029: static char str[]="x"; ! 1030: t = s; ! 1031: for (;;) { ! 1032: wait(KBD); ! 1033: if (((c=kbdchar()) == '\r') || (c == '\n')) { ! 1034: *s = '\0'; ! 1035: return; ! 1036: } ! 1037: if (c == '\b') { ! 1038: if (s>t) { ! 1039: str[0] = *(--s); ! 1040: string(&defont,str,&display,(p = sub(p,Pt(9,0))),F_XOR); ! 1041: } ! 1042: } else if ((c >= '!') && (c <= '~')) { ! 1043: if (s-t<50) { ! 1044: *s++ = (str[0] = c); ! 1045: p = string(&defont,str,&display,p,F_XOR); ! 1046: } ! 1047: } ! 1048: } ! 1049: } ! 1050: ! 1051: GetFNAME() ! 1052: { ! 1053: Point p; ! 1054: Bitmap *b; ! 1055: cursswitch(&deadmouse); ! 1056: b = balloc(Rpt(Drect.origin,Pt(Drect.corner.x,Drect.origin.y+18))); ! 1057: if (b!=0) { ! 1058: bitblt(&display,b->rect,b,Drect.origin,F_STORE); ! 1059: rectf(&display,b->rect,F_CLR); ! 1060: outline(&display,inset(b->rect,1)); ! 1061: } ! 1062: p = string(&defont,"File: ",&display,add(Drect.origin,Pt(10,3)),F_XOR); ! 1063: getstr(FNAME,p); ! 1064: p = string(&defont,"File: ",&display,add(Drect.origin,Pt(10,3)),F_XOR); ! 1065: string(&defont,FNAME,&display,p,F_XOR); ! 1066: if (b!=0) { ! 1067: bitblt(b,b->rect,&display,Drect.origin,F_STORE); ! 1068: bfree(b); ! 1069: } ! 1070: cursswitch((Cursor *) 0); ! 1071: } ! 1072: ! 1073: Bitmap *pickupmap; ! 1074: ! 1075: PickUpCursor() ! 1076: { ! 1077: /* ! 1078: Cursor *oldcursor; ! 1079: Cursor pickuptexture; ! 1080: Rectangle r; ! 1081: int i; ! 1082: r = TrackBorder(raddp(rect16x16,IconPoint(mouse.xy)),true); ! 1083: r = raddp(r,icon.origin); ! 1084: bitblt(&display,r,pickupmap,Pt(0,0),F_STORE); ! 1085: for (i=0; i<16; i++) pickuptexture.bits[i] = (short)(pickupmap->base[i]>>16); ! 1086: oldcursor = cursswitch(&pickuptexture); ! 1087: while (button123())jnap(1); ! 1088: while (!button123())jnap(1); ! 1089: while (button123())jnap(1); ! 1090: cursswitch(oldcursor); ! 1091: */ ! 1092: } ! 1093: ! 1094: char SFbuffer[100]; ! 1095: char *SFlist[] = { /* Where to look */ ! 1096: "", /* Look in local directory first */ ! 1097: "/usr/jerq/icon/16x16/", /* Ick! "/usr/jerq/icon" should be a parameter */ ! 1098: "/usr/jerq/icon/texture/", ! 1099: "/usr/jerq/icon/large/", ! 1100: "/usr/jerq/icon/face48/", ! 1101: (char *) 0 ! 1102: }; ! 1103: ! 1104: FILE *SearchFile(filename,mode,filefound) ! 1105: char *filename, *mode, **filefound; ! 1106: { ! 1107: FILE *fp; ! 1108: char **sf = SFlist; ! 1109: int namez = strlen(filename); ! 1110: *filefound = SFbuffer; ! 1111: fp = (FILE *) 0; ! 1112: for (; (fp == (FILE *) 0) && (*sf != (char *) 0); sf++) { ! 1113: if ((strlen(*sf) + namez) < sizeof(SFbuffer)) { ! 1114: strcpy(SFbuffer, *sf); ! 1115: strcat(SFbuffer, filename); ! 1116: fp = fopen(SFbuffer, mode); ! 1117: } ! 1118: } ! 1119: return(fp); ! 1120: } ! 1121: ! 1122: Rectangle OpLoad(bitmap,filename) ! 1123: Bitmap *bitmap; ! 1124: char *filename; ! 1125: { ! 1126: FILE *fp; ! 1127: Rectangle rect; ! 1128: Cursor *oldcursor; ! 1129: char *filefound; ! 1130: int ch,i,j; ! 1131: int xsize,ysize; ! 1132: rect = bitmap->rect; ! 1133: oldcursor = cursswitch(&clock); ! 1134: fp = SearchFile(filename,"r",&filefound); ! 1135: if (fp == ((FILE *) 0)) {cursswitch((Cursor *) 0); return(nullrect);} ! 1136: ch = getc(fp); ! 1137: if (ch=='0') { ! 1138: i = rect.origin.x; j = rect.origin.y; ! 1139: xsize = 0; ! 1140: for (;;) { ! 1141: getc(fp); /* 'x' */ ! 1142: putnibble(getc(fp),bitmap,rect,Pt(i,j)); i+=4; ! 1143: putnibble(getc(fp),bitmap,rect,Pt(i,j)); i+=4; ! 1144: putnibble(getc(fp),bitmap,rect,Pt(i,j)); i+=4; ! 1145: putnibble(getc(fp),bitmap,rect,Pt(i,j)); i+=4; ! 1146: getc(fp); /* ',' */ ! 1147: while ((ch = getc(fp))==' '); /* '0' or '\n' */ ! 1148: if (ch=='\n') { ! 1149: xsize = max(xsize,i-rect.origin.x); ! 1150: i = rect.origin.x; ! 1151: j++; ! 1152: ch = getc(fp); /* '0' */ ! 1153: } else if (ch == EOF) break; ! 1154: } ! 1155: ysize = j-rect.origin.y; ! 1156: } else { ! 1157: while ((ch!='{')&&(ch!=EOF)) ch=getc(fp); ! 1158: for (j=rect.origin.y; j<rect.origin.y+16; j++) { ! 1159: while (((ch=getc(fp))!='x')&&(ch!='X')&&(ch!=EOF)) {}; ! 1160: putnibble(getc(fp),bitmap,rect,Pt(rect.origin.x,j)); ! 1161: putnibble(getc(fp),bitmap,rect,Pt(rect.origin.x+4,j)); ! 1162: putnibble(getc(fp),bitmap,rect,Pt(rect.origin.x+8,j)); ! 1163: putnibble(getc(fp),bitmap,rect,Pt(rect.origin.x+12,j)); ! 1164: } ! 1165: xsize = ysize = 16; ! 1166: } ! 1167: fclose(fp); ! 1168: rect.origin.x = 0; rect.origin.y = 0; ! 1169: rect.corner.x = xsize; rect.corner.y = ysize; ! 1170: cursswitch(oldcursor); ! 1171: return(rect); ! 1172: } ! 1173: ! 1174: OpRead() ! 1175: { ! 1176: Rectangle rect, r1; ! 1177: Bitmap *buffer; ! 1178: Point p; ! 1179: GetFNAME(); ! 1180: if (!FNAME[0]) return(0); ! 1181: buffer = balloc(Source->rect); ! 1182: if (buffer == ((Bitmap *) 0)) {cursswitch((Cursor *) 0); return(0);} ! 1183: rectf(buffer,buffer->rect,F_CLR); ! 1184: rect = OpLoad(buffer,FNAME); ! 1185: if (!eqrect(rect,nullrect)) { ! 1186: SaveForUndo(); ! 1187: r1 = TrackBorder(raddp(rect,IconPoint(mouse.xy)),true); ! 1188: p = r1.origin; ! 1189: while (button3())jnap(1); ! 1190: cursswitch(&clock); ! 1191: OrOntoPicture(buffer,rect,p); ! 1192: cursswitch((Cursor *)0); ! 1193: } ! 1194: bfree(buffer); ! 1195: } ! 1196: ! 1197: #ifdef BSD ! 1198: #define BUFSIZE BUFSIZ ! 1199: #endif BSD ! 1200: char buffer[BUFSIZE]; ! 1201: char *bufend; ! 1202: ! 1203: bclear() ! 1204: { ! 1205: bufend = buffer; ! 1206: } ! 1207: ! 1208: bsend(fp) ! 1209: FILE *fp; ! 1210: { ! 1211: *bufend = '\0'; ! 1212: fputs(buffer,fp); ! 1213: bclear(); ! 1214: } ! 1215: ! 1216: bputc(c,fp) ! 1217: char c; ! 1218: FILE *fp; ! 1219: { ! 1220: if (bufend >= buffer+BUFSIZE-3) bsend(fp); ! 1221: *bufend++ = c; ! 1222: } ! 1223: ! 1224: OpWrite() ! 1225: { ! 1226: FILE *fp; ! 1227: Rectangle r; ! 1228: Point p; ! 1229: int i,j,butt; ! 1230: butt = GetIconRect(&r); ! 1231: if (butt==0) return(0); ! 1232: if (butt==3) { ! 1233: GetFNAME(); ! 1234: if (!FNAME[0]) return(0); ! 1235: fp = fopen(FNAME,"w"); ! 1236: if (fp == ((FILE *) 0)) return(0); ! 1237: rectf(&display,Drect,F_XOR); ! 1238: bclear(); ! 1239: for (j = r.origin.y; j<r.corner.y; j++) { ! 1240: for (i=r.origin.x; i<r.corner.x; i+=16) { ! 1241: bputc('0',fp);bputc('x',fp); ! 1242: bputc(getnibble(Source,Pt(i,j)),fp); ! 1243: bputc(getnibble(Source,Pt(i+4,j)),fp); ! 1244: bputc(getnibble(Source,Pt(i+8,j)),fp); ! 1245: bputc(getnibble(Source,Pt(i+12,j)),fp); ! 1246: bputc(',',fp); ! 1247: } ! 1248: bputc('\n',fp); ! 1249: bsend(fp); ! 1250: } ! 1251: fclose(fp); ! 1252: rectf(&display,Drect,F_XOR); ! 1253: } else if (butt==2) { ! 1254: GetFNAME(); ! 1255: if (!FNAME[0]) return(0); ! 1256: fp = fopen(FNAME,"w"); ! 1257: if (fp == ((FILE *) 0)) return(0); ! 1258: rectf(&display,Drect,F_XOR); ! 1259: fputs("Texture ",fp); fputs(FNAME,fp); fputs(" = {\n",fp); ! 1260: j = r.origin.y; i = r.origin.x; ! 1261: bclear(); ! 1262: while (j < r.corner.y) { ! 1263: if (((j-r.origin.y)%4) == 0) bputc('\t',fp); ! 1264: bputc(' ',fp);bputc('0',fp);bputc('x',fp); ! 1265: bputc(getnibble(Source,Pt(i,j)),fp); ! 1266: bputc(getnibble(Source,Pt(i+4,j)),fp); ! 1267: bputc(getnibble(Source,Pt(i+8,j)),fp); ! 1268: bputc(getnibble(Source,Pt(i+12,j)),fp); ! 1269: bputc(',',fp); ! 1270: if (((j-r.origin.y)%4) == 3) bputc('\n',fp); ! 1271: j = j+1; ! 1272: bsend(fp); ! 1273: } ! 1274: fputs("};\n",fp); ! 1275: fclose(fp); ! 1276: rectf(&display,Drect,F_XOR); ! 1277: } ! 1278: ! 1279: } ! 1280: ! 1281: OpTexture() ! 1282: { ! 1283: Bitmap *buffer,*buffer1; ! 1284: Rectangle source,dest; ! 1285: Point target; ! 1286: int repx,repy,i,j,hsize,vsize; ! 1287: if (GetIconRect(&source)==0) return(0); ! 1288: if (GetIconRect(&dest)==0) return(0); ! 1289: hsize = horsize(source); ! 1290: vsize = versize(source); ! 1291: if ((hsize==0) || (vsize==0)) return(0); ! 1292: buffer = balloc(source); ! 1293: if (buffer == ((Bitmap *) 0)) return(0); ! 1294: buffer1 = balloc(source); ! 1295: if (buffer1 == ((Bitmap *) 0)) {bfree(buffer); return(0);} ! 1296: SaveForUndo(); ! 1297: cursswitch(&clock); ! 1298: bitblt(&display,raddp(source,icon.origin),buffer,buffer->rect.origin,F_STORE); ! 1299: repx = horsize(dest)/hsize; ! 1300: repy = versize(dest)/vsize; ! 1301: for (j=0; j<=repy; j++) ! 1302: for (i=0; i<=repx; i++) { ! 1303: bitblt(buffer,buffer->rect,buffer1,buffer1->rect.origin,F_STORE); ! 1304: OrOntoPictureClipped(buffer1, ! 1305: buffer1->rect,add(dest.origin,Pt(i*hsize,j*vsize)),dest); ! 1306: } ! 1307: cursswitch((Cursor *) 0); ! 1308: bfree(buffer); ! 1309: bfree(buffer1); ! 1310: } ! 1311: ! 1312: int GridSwitch=0; ! 1313: ! 1314: OpGrid() ! 1315: { ! 1316: if ((GridSwitch%2)==0) DrawFineGrid(); else DrawCoarseGrid(); ! 1317: GridSwitch = (GridSwitch+1)%4; ! 1318: } ! 1319: ! 1320: OpResize() ! 1321: { ! 1322: Point p; ! 1323: Rectangle r; ! 1324: Bitmap *NewSource, *NewUndo; ! 1325: Cursor *oldcursor; ! 1326: bool doit; ! 1327: oldcursor = cursswitch(&clock); ! 1328: p=mouse.xy; ! 1329: r=canonrect(icon.origin,p); ! 1330: outline(&display,r); ! 1331: for(; !button123(); nap(2)){ ! 1332: outline(&display,r); ! 1333: p=mouse.xy; ! 1334: r=canonrect(icon.origin,p); ! 1335: outline(&display,r); ! 1336: } ! 1337: doit = button3(); ! 1338: outline(&display,r); ! 1339: cursswitch(oldcursor); ! 1340: while (button123())jnap(1); ! 1341: if (!doit) return(0); ! 1342: if (!rectclip(&r,Rpt(icon.origin,ICON.corner))) return(0); ! 1343: r = rsubp(r,icon.origin); ! 1344: NewSource = balloc(r); if (NewSource==0) return(0); ! 1345: NewUndo = balloc(r); if (NewUndo==0) {bfree(NewSource); return(0);} ! 1346: rectf(NewSource,NewSource->rect,F_CLR); ! 1347: rectf(NewUndo,NewUndo->rect,F_CLR); ! 1348: bitblt(Source,Source->rect,NewSource,NewSource->rect.origin,F_XOR); ! 1349: bitblt(Undo,Undo->rect,NewUndo,NewUndo->rect.origin,F_XOR); ! 1350: bfree(Source); bfree(Undo); ! 1351: Source = NewSource; Undo = NewUndo; ! 1352: rectf(&display,Drect,F_CLR); ! 1353: XSIZE = horsize(r); YSIZE = versize(r); ! 1354: Redraw(); ! 1355: } ! 1356: ! 1357: ! 1358: HorShear(r,dx,top) ! 1359: Rectangle r; ! 1360: int dx; ! 1361: bool top; ! 1362: { ! 1363: int j,vsize,shift; ! 1364: vsize = versize(r); ! 1365: for (j=0; j<vsize; j++) { ! 1366: shift = top ? vsize-j-1 : j; ! 1367: IconBitBlit(Rect(r.origin.x,r.origin.y+j,r.corner.x,r.origin.y+j+1), ! 1368: Pt(r.origin.x+muldiv(shift,dx,vsize),r.origin.y+j), ! 1369: Rect(0,0,Xblocks,Yblocks), ! 1370: I_CLR,I_OR); ! 1371: } ! 1372: } ! 1373: ! 1374: VerShear(r,dy,lft) ! 1375: Rectangle r; ! 1376: int dy; ! 1377: bool lft; ! 1378: { ! 1379: int i,hsize,shift; ! 1380: hsize = horsize(r); ! 1381: for (i=0; i<hsize; i++) { ! 1382: shift = lft ? hsize-i-1 : i; ! 1383: IconBitBlit(Rect(r.origin.x+i,r.origin.y,r.origin.x+i+1,r.corner.y), ! 1384: Pt(r.origin.x+i,r.origin.y+muldiv(shift,dy,hsize)), ! 1385: Rect(0,0,Xblocks,Yblocks), ! 1386: I_CLR,I_OR); ! 1387: } ! 1388: } ! 1389: ! 1390: OpHorShear() ! 1391: { ! 1392: Rectangle r; ! 1393: int dx; ! 1394: bool top; ! 1395: Point p,nearcorner; ! 1396: if (GetIconRect(&r)==0) return(0); ! 1397: if ((horsize(r)==0) || (versize(r)==0)) return(0); ! 1398: if (!GetIconPoint(&p)) return(0); ! 1399: SaveForUndo(); ! 1400: cursswitch(&clock); ! 1401: nearcorner = nearestcorner(r,p); ! 1402: dx = p.x - nearcorner.x; ! 1403: top = (nearcorner.y == r.origin.y); ! 1404: HorShear(r,dx,top); ! 1405: cursswitch((Cursor *) 0); ! 1406: } ! 1407: ! 1408: OpVerShear() ! 1409: { ! 1410: Rectangle r; ! 1411: int dy; ! 1412: bool lft; ! 1413: Point p,nearcorner; ! 1414: if (GetIconRect(&r)==0) return(0); ! 1415: if ((horsize(r)==0) || (versize(r)==0)) return(0); ! 1416: if (!GetIconPoint(&p)) return(0); ! 1417: SaveForUndo(); ! 1418: cursswitch(&clock); ! 1419: nearcorner = nearestcorner(r,p); ! 1420: dy = p.y - nearcorner.y; ! 1421: lft = (nearcorner.x == r.origin.x); ! 1422: VerShear(r,dy,lft); ! 1423: cursswitch((Cursor *) 0); ! 1424: } ! 1425: ! 1426: Stretch(sb,sr,db,dr,op) ! 1427: Bitmap *sb,*db; ! 1428: Rectangle sr,dr; ! 1429: Code op; ! 1430: { ! 1431: int i,j,shsize,svsize,dhsize,dvsize; ! 1432: shsize = horsize(sr); ! 1433: svsize = versize(sr); ! 1434: dhsize = horsize(dr); ! 1435: dvsize = versize(dr); ! 1436: for (j=0; j<svsize; j++) { ! 1437: wait(CPU); ! 1438: for (i=0; i<shsize; i++) { ! 1439: bitblt(sb, ! 1440: Rect(sr.origin.x+i,sr.origin.y+j,sr.origin.x+i+1,sr.origin.y+j+1), ! 1441: db, ! 1442: Pt(dr.origin.x+muldiv(dhsize,i,shsize), ! 1443: dr.origin.y+muldiv(dvsize,j,svsize)), ! 1444: op); ! 1445: } ! 1446: } ! 1447: } ! 1448: ! 1449: OpStretch() ! 1450: { ! 1451: Bitmap *buffer; ! 1452: Rectangle source,dest; ! 1453: if (GetIconRect(&source)==0) return(0); ! 1454: if ((horsize(source)==0) || (versize(source)==0)) return(0); ! 1455: if (GetIconRect(&dest)==0) return(0); ! 1456: if ((horsize(dest)==0) || (versize(dest)==0)) return(0); ! 1457: buffer = balloc(dest); ! 1458: if (buffer == ((Bitmap *) 0)) return(0); ! 1459: SaveForUndo(); ! 1460: cursswitch(&clock); ! 1461: rectf(buffer,buffer->rect,F_CLR); ! 1462: Stretch(&display,raddp(source,icon.origin),buffer,buffer->rect,F_XOR); ! 1463: IconBitBlit(source,source.origin,Rect(0,0,0,0),F_CLR,F_CLR); ! 1464: OrOntoPictureClipped(buffer,buffer->rect,dest.origin,dest); ! 1465: cursswitch((Cursor *) 0); ! 1466: bfree(buffer); ! 1467: } ! 1468: ! 1469: DrawHorGridLine(p,op) ! 1470: Point p; ! 1471: Code op; ! 1472: { ! 1473: if ((p.y < icon.corner.y+2) && (p.x < icon.corner.x+2)) ! 1474: p.x = ScreenCoordX(IconCoordX(icon.corner.x+Xsize)); ! 1475: rectf(&display,Rpt(p,Pt(ICON.corner.x,p.y+1)),op); ! 1476: } ! 1477: ! 1478: DrawVerGridLine(p,op) ! 1479: Point p; ! 1480: Code op; ! 1481: { ! 1482: if ((p.x < icon.corner.x+2) && (p.y < icon.corner.y+2)) ! 1483: p.y = ScreenCoordY(IconCoordY(icon.corner.y+Ysize)); ! 1484: rectf(&display,Rpt(p,Pt(p.x+1,ICON.corner.y)),op); ! 1485: } ! 1486: ! 1487: DrawGridBorder() ! 1488: { ! 1489: DrawHorGridLine(ICON.origin,F_OR); ! 1490: DrawHorGridLine(add(ICON.origin,Pt(0,Yblocks*Ysize)),F_OR); ! 1491: DrawVerGridLine(ICON.origin,F_OR); ! 1492: DrawVerGridLine(add(ICON.origin,Pt(Xblocks*Xsize,0)),F_OR); ! 1493: point(&display,ICON.corner,F_OR); ! 1494: } ! 1495: ! 1496: DrawFineGrid() ! 1497: { ! 1498: register int i,j; ! 1499: for (j=1; j<Yblocks; j++) DrawHorGridLine(add(ICON.origin,Pt(0,j*Ysize)),F_XOR); ! 1500: for (i=1; i<Xblocks; i++) DrawVerGridLine(add(ICON.origin,Pt(i*Xsize,0)),F_XOR); ! 1501: } ! 1502: ! 1503: DrawCoarseGrid() ! 1504: { ! 1505: Point p; ! 1506: register int i,j; ! 1507: for (j=0; j<=Yblocks; j+=16) ! 1508: DrawHorGridLine(add(ICON.origin,Pt(0,j*Ysize+1)),F_XOR); ! 1509: for (j=8; j<=Yblocks; j+=16) { ! 1510: p=add(ICON.origin,Pt(0,j*Ysize+1)); ! 1511: if ((p.y < icon.corner.y+2) && (p.x < icon.corner.x+2)) ! 1512: p.x = ScreenCoordX(IconCoordX(icon.corner.x+Xsize)); ! 1513: for (i=0; i<=Xblocks*Xsize; i+=2) ! 1514: point(&display,Pt(p.x+i,p.y),F_XOR); ! 1515: } ! 1516: for (i=0; i<=Xblocks; i+=16) ! 1517: DrawVerGridLine(add(ICON.origin,Pt(i*Xsize+1,0)),F_XOR); ! 1518: for (i=8; i<=Xblocks; i+=16) { ! 1519: p=add(ICON.origin,Pt(i*Xsize+1,0)); ! 1520: if ((p.x < icon.corner.x+2) && (p.y < icon.corner.y+2)) ! 1521: p.y = ScreenCoordY(IconCoordY(icon.corner.y+Ysize)); ! 1522: for (j=0; j<=Yblocks*Ysize; j+=2) ! 1523: point(&display,Pt(p.x,p.y+j),F_XOR); ! 1524: } ! 1525: } ! 1526: ! 1527: Bitmap *HelpBuffer, *HelpTexture; ! 1528: ! 1529: helpline(i,icon,str) ! 1530: int i; ! 1531: Texture *icon; ! 1532: char *str; ! 1533: { ! 1534: texture(HelpTexture,HelpTexture->rect,icon,F_STORE); ! 1535: bitblt(HelpTexture,HelpTexture->rect,HelpBuffer,Pt(2,2+16*i),F_XOR); ! 1536: string(&defont,str,HelpBuffer,Pt(2+32,2+16*i),F_XOR); ! 1537: } ! 1538: ! 1539: HelpSorry() ! 1540: { ! 1541: string(&defont,"Not enough space on blit", ! 1542: &display,add(icon.corner,Pt(15,-20)),F_XOR); ! 1543: } ! 1544: ! 1545: Help() ! 1546: { ! 1547: HelpBuffer = balloc(Rect(0,0,302,482)); ! 1548: HelpTexture = balloc(Rect(0,0,16,16)); ! 1549: if ((HelpBuffer==0) || (HelpTexture==0)) { ! 1550: HelpSorry(); ! 1551: while (!button123()) wait(MOUSE); ! 1552: HelpSorry(); ! 1553: while (button123())jnap(1); ! 1554: return(0); ! 1555: } ! 1556: rectf(HelpBuffer,HelpBuffer->rect,F_CLR); ! 1557: outline(HelpBuffer,Rpt(HelpBuffer->rect.origin,sub(HelpBuffer->rect.corner,Pt(1,1)))); ! 1558: helpline(0,&whiteT,"left button: draw"); ! 1559: helpline(1,&whiteT,"middle button: erase"); ! 1560: helpline(2,&whiteT,""); ! 1561: helpline(3,&Cmove,"move region"); ! 1562: helpline(4,&Ccopy,"copy region"); ! 1563: helpline(5,&Cinvert,"invert region"); ! 1564: helpline(6,&Cerase,"erase region"); ! 1565: helpline(7,&Creflx,"reflect x region"); ! 1566: helpline(8,&Crefly,"reflect y region"); ! 1567: helpline(9,&Crotplus,"rotate + region"); ! 1568: helpline(10,&Crotminus,"rotate - region"); ! 1569: helpline(11,&Cshearx,"shear x region"); ! 1570: helpline(12,&Csheary,"shear y region"); ! 1571: helpline(13,&Cstretch,"stretch region"); ! 1572: helpline(14,&Ctexture,"texture region"); ! 1573: helpline(15,&Cread,"read file"); ! 1574: helpline(16,&Cgrid,"background grids"); ! 1575: helpline(17,&Cresize,"resize drawing area"); ! 1576: helpline(18,&Cwrite,"write file"); ! 1577: helpline(19,&Cblit,"bitblit region"); ! 1578: helpline(20,&Ccursor,"pick cursor icon"); ! 1579: helpline(21,&Chelp,"(press a button to continue)"); ! 1580: helpline(22,&Cundo,"undo last operation"); ! 1581: helpline(23,&whiteT,""); ! 1582: helpline(24,&clockT,"wait"); ! 1583: helpline(25,&deadmouseT,"mouse inactive"); ! 1584: helpline(26,&menucursorT, "menu on right button"); ! 1585: helpline(27,&sweepcursorT,"sweep rect (right button)"); ! 1586: helpline(28,&sweeportrackT,"sweep rect (right button) or"); ! 1587: helpline(29,&whiteT,"get 16x16 frame (middle butt)"); ! 1588: screenswap(HelpBuffer,HelpBuffer->rect,raddp(HelpBuffer->rect,Drect.origin)); ! 1589: while (!button123())jnap(1); ! 1590: screenswap(HelpBuffer,HelpBuffer->rect,raddp(HelpBuffer->rect,Drect.origin)); ! 1591: while (button123())jnap(1); ! 1592: bfree(HelpBuffer); ! 1593: bfree(HelpTexture); ! 1594: } ! 1595: ! 1596: SaveForUndo() ! 1597: { ! 1598: bitblt(Source,Source->rect,Undo,Undo->rect.origin,F_STORE); ! 1599: } ! 1600: ! 1601: OpUndo() ! 1602: { ! 1603: Rectangle r; ! 1604: int hsize,vsize,i,j; ! 1605: bool bit; ! 1606: Cursor *oldcursor; ! 1607: oldcursor = cursswitch(&clock); ! 1608: r = Source->rect; ! 1609: bitblt(Undo,r,Source,r.origin,F_XOR); ! 1610: XorOntoScreen(Source,r,r.origin); ! 1611: bitblt(Source,r,Undo,r.origin,F_XOR); ! 1612: bitblt(Undo,r,Source,r.origin,F_XOR); ! 1613: cursswitch(oldcursor); ! 1614: } ! 1615: ! 1616: XorOntoScreen(b,r,p) ! 1617: Bitmap *b; ! 1618: Rectangle r; ! 1619: Point p; ! 1620: { ! 1621: int i,j,h,v; ! 1622: h = horsize(r); v = versize(r); ! 1623: for(j=0; j<h; j++) { ! 1624: wait(CPU); ! 1625: for (i=0; i<v; i++) { ! 1626: if (bitmapbit(b,add(r.origin,Pt(j,i)))) ! 1627: FlipOntoScreen(add(p,Pt(j,i))); ! 1628: } ! 1629: } ! 1630: } ! 1631: ! 1632: XorOntoPicture(b,r,p) ! 1633: Bitmap *b; ! 1634: Rectangle r; ! 1635: Point p; ! 1636: { ! 1637: XorOntoScreen(b,r,p); ! 1638: bitblt(b,r,Source,p,F_XOR); ! 1639: } ! 1640: ! 1641: OrOntoPicture(b,r,p) ! 1642: Bitmap *b; ! 1643: Rectangle r; ! 1644: Point p; ! 1645: /* Scrambles the contents of b */ ! 1646: { ! 1647: rectf(b,r,F_XOR); ! 1648: bitblt(Source,raddp(rsubp(r,r.origin),p),b,r.origin,F_OR); ! 1649: rectf(b,r,F_XOR); ! 1650: XorOntoPicture(b,r,p); ! 1651: } ! 1652: ! 1653: OrOntoPictureClipped(b,r,p,clip) ! 1654: Bitmap *b; ! 1655: Rectangle r; ! 1656: Point p; ! 1657: Rectangle clip; ! 1658: { ! 1659: if (!rectclip(&r,rsubp(clip,sub(p,r.origin)))) r = nullrect; ! 1660: OrOntoPicture(b,r,p); ! 1661: } ! 1662: ! 1663: bool FirstTime = true; ! 1664: ! 1665: Redraw() ! 1666: { ! 1667: Xblocks = XSIZE; ! 1668: Yblocks = YSIZE; ! 1669: ! 1670: Xsize = (horsize(Drect)-1)/Xblocks; ! 1671: Ysize = (versize(Drect)-1)/Yblocks; ! 1672: ! 1673: if (Xsize==0) Xsize = 1; ! 1674: if (Ysize==0) Ysize = 1; ! 1675: ! 1676: Ysize = (Xsize = (Xsize<Ysize)?Xsize:Ysize); ! 1677: ! 1678: icon.origin = add(Drect.origin,Pt(2,2)); ! 1679: icon.corner = add(icon.origin,Pt(Xblocks,Yblocks)); ! 1680: ! 1681: ICON.origin = sub(Drect.corner,Pt(1+Xsize*Xblocks,1+Ysize*Yblocks)); ! 1682: ICON.corner = add(ICON.origin,Pt(Xsize*Xblocks,Ysize*Yblocks)); ! 1683: modx = ICON.origin.x % Xsize; ! 1684: divx = ICON.origin.x / Xsize; ! 1685: mody = ICON.origin.y % Ysize; ! 1686: divy = ICON.origin.y / Ysize; ! 1687: ! 1688: rectf(&display, Drect, F_CLR); ! 1689: DrawGridBorder(); ! 1690: outline(&display,inset(Rpt(icon.origin,add(icon.corner,Pt(-1,-1))),-2)); ! 1691: if ((GridSwitch==1)||(GridSwitch==2)) DrawFineGrid(); ! 1692: if ((GridSwitch==2)||(GridSwitch==3)) DrawCoarseGrid(); ! 1693: ! 1694: if (FirstTime) FirstTime = false; ! 1695: else { ! 1696: cursswitch(&clock); ! 1697: XorOntoScreen(Source,Source->rect,Source->rect.origin); ! 1698: cursswitch((Cursor *)0); ! 1699: } ! 1700: } ! 1701: ! 1702: Icon() ! 1703: { ! 1704: Bitmap *b; ! 1705: Point p,cur,hit; ! 1706: int i,j; ! 1707: ! 1708: Redraw(); ! 1709: ! 1710: cur.x = 0; cur.y = 0; ! 1711: ! 1712: for (;;) { ! 1713: wait(MOUSE); ! 1714: if (P->state&RESHAPED) return(0); ! 1715: if (button1()) { ! 1716: SaveForUndo(); ! 1717: while(button1()) { ! 1718: if (ptinrect((p=mouse.xy),ICON)) { ! 1719: p = sub(p,ICON.origin); ! 1720: cur.x = p.x/Xsize; ! 1721: cur.y = p.y/Ysize; ! 1722: if (geticonpoint(cur) == false) flipiconpoint(cur); ! 1723: } ! 1724: wait(MOUSE); ! 1725: } ! 1726: } else if (button2()) { ! 1727: SaveForUndo(); ! 1728: while(button2()) { ! 1729: if (ptinrect((p=mouse.xy),ICON)) { ! 1730: p = sub(p,ICON.origin); ! 1731: cur.x = p.x/Xsize; ! 1732: cur.y = p.y/Ysize; ! 1733: if (geticonpoint(cur) == true) flipiconpoint(cur); ! 1734: } ! 1735: wait(MOUSE); ! 1736: } ! 1737: } ! 1738: if (button3()) { ! 1739: hit = imenuhit(imenu); ! 1740: switch (5*hit.y+hit.x) { ! 1741: case BLIT: OpGeneralBlit(); break; ! 1742: case MOVE: OpBlit(I_CLR,I_OR); break; ! 1743: case COPY: OpBlit(I_OR,I_OR); break; ! 1744: case ERASE: OpErase(); break; ! 1745: case INVERT: OpInvert(); break; ! 1746: case REFLECTX: OpReflX(); break; ! 1747: case REFLECTY: OpReflY(); break; ! 1748: case ROTATEPLUS: OpRotPlus(); break; ! 1749: case ROTATEMINUS: OpRotMinus(); break; ! 1750: case SHEARX: OpHorShear(); break; ! 1751: case SHEARY: OpVerShear(); break; ! 1752: case STRETCH: OpStretch(); break; ! 1753: case TEXTURE: OpTexture(); break; ! 1754: case GRID: OpGrid(); break; ! 1755: case PICK: PickUpCursor(); break; ! 1756: case READ: OpRead(); break; ! 1757: case WRITE: OpWrite(); break; ! 1758: case RESIZE: OpResize(); break; ! 1759: case HELP: Help(); break; ! 1760: case UNDO: OpUndo(); break; ! 1761: } ! 1762: } ! 1763: } ! 1764: } ! 1765: ! 1766: ! 1767: main(argc,argv) ! 1768: char *argv[]; ! 1769: { ! 1770: request(MOUSE|SEND|KBD); ! 1771: mousemotion(); ! 1772: initdisplay(argc, argv); ! 1773: initicons(); ! 1774: ! 1775: nullpoint.x = 0; ! 1776: nullpoint.y = 0; ! 1777: point16x16.x = 16; ! 1778: point16x16.y = 16; ! 1779: nullrect.origin = nullpoint; ! 1780: nullrect.corner = nullpoint; ! 1781: rect16x16.origin = nullpoint; ! 1782: rect16x16.corner = point16x16; ! 1783: ! 1784: bittester = balloc(Rect(0,0,1,1)); ! 1785: pickupmap = balloc(Rect(0,0,16,16)); ! 1786: Source = balloc(Rect(0,0,XSIZE,YSIZE)); ! 1787: if (Source == ((Bitmap *) 0)) exit(); ! 1788: rectf(Source,Source->rect,F_CLR); ! 1789: Undo = balloc(Rect(0,0,XSIZE,YSIZE)); ! 1790: if (Undo == ((Bitmap *) 0)) exit(); ! 1791: rectf(Undo,Undo->rect,F_CLR); ! 1792: ! 1793: do { ! 1794: P->state&=~RESHAPED; ! 1795: Icon(); ! 1796: } while (P->state&RESHAPED); ! 1797: ! 1798: exit(); ! 1799: ! 1800: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.