Mercurial > hg > forks > multipaint-js
view draw_smart.pde @ 135:72ae62f2036b
Cosmetic cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 08 Aug 2018 11:16:18 +0300 |
parents | f5c32f6470d0 |
children | 12cf30907f26 |
line wrap: on
line source
//all "intelligent" stuff, the color behavior //and flood fills void consistency() { int xx, yy, ad, a, b, x0, y0, x2, y2; int pat, mat, fad, bad, maxxy, mulu, ymax; if (g_multic == 1 || g_multic == 2) return; if (g_attrimode == 0) { mat = 8; mulu = 1; maxxy = Y; ymax = 0; } else { mat = 64; mulu = 8; maxxy = MY; ymax = 7; } for (yy = 0; yy < MY; yy++) for (xx = 0; xx < MX; xx++) { a = getattra(xx * 8, yy * mulu, 0); b = getattra(xx * 8, yy * mulu, 1); if (a == b) { for (y0 = 0; y0 <= ymax; y0++) { for (x0 = 0; x0 <= 7; x0++) { ad = 1024 + (xx * 8) + (yy * X * mulu) + x0 + y0 * X; g_map[ad] = byte(0); } } } pat = 0; for (y0 = 0; y0 <= ymax; y0++) { for (x0 = 0; x0 <= 7; x0++) { ad = 1024 + (xx * 8) + (yy * X * mulu) + x0 + y0 * X; pat = pat + int(g_map[ad]); } } if (pat == mat || pat == 0) { for (y0 = 0; y0 <= ymax; y0++) { fad = 65536 + xx + (yy * mulu + y0) * MX; bad = fad + (MX * MY * 8); if (pat == 0) g_map[fad] = g_map[bad]; if (pat == mat) g_map[bad] = g_map[fad]; } } } } void transchar(int xx, int yy) { int fad, bad, ad, pt, x0, y0; int aa, bb, pp, ya, yb; ya = 0; yb = 0; xx = int(xx / 8); if (g_attrimode == 1) { yy = chop8(yy); ya = 0; yb = 7; } //zx spec etc if (g_attrimode == 0) { ya = 0; yb = 0; } //msx for (y0 = ya; y0 <= yb; y0++) { fad = 65536 + xx + (yy + y0) * MX; bad = fad + (MX * MY * 8); aa = int(g_map[fad]); bb = int(g_map[bad]); g_map[fad] = byte(bb); g_map[bad] = byte(aa); } for (y0 = ya; y0 <= yb; y0++) for (x0 = 0; x0 < 8; x0++) { ad = 1024 + x0 + xx * 8 + (y0 + yy) * X; pp = 1 - int(g_map[ad]); g_map[ad] = byte(pp); } } void prepare_char(int xx, int yy, int farbe) { //changes the char foreg/backg into "favorable" relative to used color //needed in floodfill // currently seems to be same as transchar except this check, // so we'll just call transchar() .. -- ccr if (int(g_map[1024 + xx + yy * X]) == 0 && g_data[int('r')] == 0 && g_data[int('R')] == 0) transchar(xx, yy); } void floodfill_init(int xx, int yy) { for (x = 0; x < X; x++) for (y = 0; y < Y; y++) g_fillmap[1024 + x + y * X] = byte(0); g_fillmap[1024 + xx + yy * X] = byte(100); } boolean floodfill_mc_plop(int npar, int xc, int yc) { int ad = 1024 + xc + yc * X; if (getmultic(xc, yc, 0) == npar && g_fillmap[ad] == 0) { g_fillmap[ad] = byte(100); if (g_pixelw == 2) g_fillmap[ad + 1] = byte(0); return true; } else return false; } void floodfill_mc(int xx, int yy, int mbut) { int x, y, ax, valid, okay, par, npar, zad; par = 0; if (g_pixelw == 2) xx = chop2(xx); if (mbut == LEFT) par = g_farge; else if (mbut == RIGHT) par = g_backg; npar = getmultic(xx, yy, 0); if (npar == par) return; floodfill_init(xx, yy); valid = 0; okay = 0; while (okay == 0) { valid = 0; for (y = 0; y < Y; y++) for (x = 0; x < X; x += g_pixelw) { zad = 1024 + x + y * X; ax = int(g_fillmap[zad]); if (ax >= 100 && ax <= 199) { valid = 1; if (y > 0 && floodfill_mc_plop(npar, x, y - 1)) valid = 1; if (x > g_pixelw && floodfill_mc_plop(npar, x - g_pixelw, y)) valid = 1; if (x < X - 1 - g_pixelw && floodfill_mc_plop(npar, x + g_pixelw, y)) valid = 1; if (y < Y - 1 && floodfill_mc_plop(npar, x, y + 1)) valid = 1; g_fillmap[zad] = byte(200); if (g_pixelw == 2) g_fillmap[zad + 1] = byte(0); } } if (valid == 0) okay = 1; } for (y = 0; y < Y; y++) for (x = 0; x < X; x += g_pixelw) { if (g_fillmap[1024 + x + y * X] == byte(200)) { g_farge = par; mkaveri(x, y, par, 0); makepoint(x, y); } } g_farge = g_ofarge; } boolean floodfill_iq_plop(int npar, int xc, int yc) { int ad = 1024 + xc + yc * X; if (getabsa(xc, yc, 0) == npar && g_fillmap[ad] == 0) { prepare_char(xc, yc, npar); g_fillmap[ad] = byte(100); return true; } else return false; } void floodfill_iq(int xx, int yy, int mbut) { int x, y, ax, ay, valid, okay, par, npar, zad; par = 0; if (mbut == LEFT) par = g_farge; else if (mbut == RIGHT) par = g_backg; npar = getabsa(xx, yy, 0); if (npar == par) return; // Do consistency chec, then get the NEW color under xx,yy consistency(); prepare_char(xx, yy, npar); floodfill_init(xx, yy); valid = 0; okay = 0; while (okay == 0) { valid = 0; for (y = 0; y < Y; y++) for (x = 0; x < X; x++) { zad = 1024 + x + y * X; ax = int(g_fillmap[zad]); if (ax == 100) { valid = 1; if (y > 0 && floodfill_iq_plop(npar, x, y - 1)) valid = 1; if (x > 0 && floodfill_iq_plop(npar, x - 1, y)) valid = 1; if (x < X - 1 && floodfill_iq_plop(npar, x + 1, y)) valid = 1; if (y < Y - 1 && floodfill_iq_plop(npar, x, y + 1)) valid = 1; g_fillmap[zad] = byte(200); } } if (valid == 0) okay = 1; } for (y = 0; y < Y; y++) for (x = 0; x < X; x++) { if (g_fillmap[1024 + x + y * X] == byte(200)) { g_farge = par; makepoint(x, y); } } g_farge = g_ofarge; } //adaptive color helper for low-attribute modes //reasons the background color for each char as you draw //=changed void fixattr(int x, int y, int foreg, int backg) { int bad, cad, miny, maxy; if (g_britemode == 1) { if (foreg == 8 || backg == 8 || foreg == 0 || backg == 0) return; } miny = chop8(y); maxy = y - miny; miny = maxy; y = chop8(y); if (g_attrimode == 1) { miny = 0; maxy = 7; } for (int i = miny; i <= maxy; i++) { bad = 65536 + int(x / 8) + (y + i) * MX; cad = bad + MX * (MY * 8); if (foreg >= 0) { g_map[bad] = byte(foreg); if (foreg >= 8 && g_map[cad] < 8) g_map[cad] = byte(g_map[cad] + 8); if (foreg < 8 && g_map[cad] >= 8) g_map[cad] = byte(g_map[cad] - 8); } if (backg >= 0) { g_map[cad] = byte(backg); if (backg >= 8 && g_map[bad] < 8) g_map[bad] = byte(g_map[bad] + 8); if (backg < 8 && g_map[bad] >= 8) g_map[bad] = byte(g_map[bad] - 8); } } updatepoint(x, y); } //multicolor color behavior //different behavior depending on whether color area already has max colors, //or if forcecolor is pressed. //bit different for C64 and PLUS4M void skaveri(int x, int y, int foreg, int backg) { int mx = int(x / 8); int my = int(y / 8); if (g_control == false) return; int cc = easygetcolor(x, y); mx = mx * 8; my = my * 8; for (int xx = 0; xx <= 7; xx++) { for (int yy = 0; yy <= 7; yy++) { if (easygetcolor(mx + xx, my + yy) == cc) { g_map[1024 + mx + xx + (my + yy) * X] = byte(foreg); } } } updatepoint(x, y); } void mkaveri(int x, int y, int foreg, int backg) { int mx = int(x / 8); int my = int(y / 8); int ad, bad, cad, dad, b0, b1; int f0, f1, f2, f3, free1, free2, free3; int f, order, numb, suffocatelimit; int targetbit0, targetbit1; order = 0; numb = 0; targetbit0 = 0; targetbit1 = 0; suffocatelimit = 7; if (g_multic == 2) return; f = getmultic(x, y, 0); if (g_data[int('d')] == 1 && f != g_backg) return; cad = 65536 + mx + (my * MX); f0 = int(g_map[1]); f1 = int(g_map[cad]); free1 = 1; f2 = int(g_map[cad + 1000]); free2 = 1; f3 = int(g_map[cad + 2000]); free3 = 1; if (machine == PLUS4M) { free3 = 0; suffocatelimit = 3; f3 = int(g_map[2]); } if (foreg == g_map[1] && g_control == false) return; if (foreg != f1 && foreg != f2 && foreg != f3 || g_control == true) { for (int yy = 0; yy <= 7; yy++) { for (int xx = 0; xx <= 3; xx++) { ad = 1024 + (mx * 8 + xx * 2) + (my * 8 + yy) * X; if (g_map[ad] == 0 && g_map[ad + 1] == 0) { //00 = 00 if (f0 == f) order = 4; } if (g_map[ad] == 1 && g_map[ad + 1] == 0) { //01 = 10 numb = numb | 1; free1 = 0; if (f1 == f) order = 1; } if (g_map[ad] == 0 && g_map[ad + 1] == 1) { //02 = 01 numb = numb | 2; free2 = 0; if (f2 == f) order = 2; } if (g_map[ad] == 1 && g_map[ad + 1] == 1) { //03 = 11 if (machine == C64M) { numb = numb | 4; free3 = 0; } if (f3 == f) { order = 3; targetbit0 = 1; targetbit1 = 1; } } } } boolean zoink = false; if (order == 4) zoink = true; if (order == 3 && machine == PLUS4M) zoink = true; if ((zoink || numb != suffocatelimit) && g_control == true) { if (zoink) { //println("foreg:"+foreg+" f0:"+f0+" f1:"+f1+" f2:"+f2+" f3:"+f3+" free1:"+free1+" free2:"+free2+" free3:"+free3); b0 = -1; b1 = -1; if (foreg == f1 && free1 == 0) { b0 = 1; b1 = 0; } if (foreg == f2 && free2 == 0) { b0 = 0; b1 = 1; } if (foreg == f3 && machine == C64M && free3 == 0) { b0 = 1; b1 = 1; } if (foreg == f3 && machine == PLUS4M) { b0 = 1; b1 = 1; } if (free1 == 1) { free2 = 0; free3 = 0; b0 = 1; b1 = 0; g_map[cad] = byte(foreg); } if (free2 == 1) { free3 = 0; b0 = 0; b1 = 1; g_map[cad + 1000] = byte(foreg); } if (free3 == 1) { b0 = 1; b1 = 1; g_map[cad + 2000] = byte(foreg); } for (int yy = 0; yy <= 7; yy++) { for (int xx = 0; xx <= 3; xx++) { ad = 1024 + (mx * 8 + xx * 2) + (my * 8 + yy) * X; if (g_map[ad] == targetbit0 && g_map[ad + 1] == targetbit1) { if (b0 >= 0) { g_map[ad] = byte(b0); g_map[ad + 1] = byte(b1); } } } } } } //if all color positions are filled, we'll just change the existing one if (numb == suffocatelimit || g_control == true) { if (order == 1) { g_map[cad] = byte(foreg); } //10==1 if (order == 2) { g_map[cad + 1000] = byte(foreg); } //01==2 if (order == 3 && machine == C64M) { g_map[cad + 2000] = byte(foreg); } //11==3 } //color redundancy check for (int yy = 0; yy <= 7; yy++) { for (int xx = 0; xx <= 3; xx++) { ad = 1024 + (mx * 8 + xx * 2) + (my * 8 + yy) * X; if (machine == C64M) { if (g_map[cad] == g_map[cad + 2000]) { if (g_map[ad] == 1 && g_map[ad + 1] == 1) { g_map[ad] = 1; g_map[ad + 1] = 0; } } if (g_map[cad + 1000] == g_map[cad + 2000]) { if (g_map[ad] == 1 && g_map[ad + 1] == 1) { g_map[ad] = 0; g_map[ad + 1] = 1; } } } if (g_map[cad] == g_map[cad + 1000]) { if (g_map[ad] == 0 && g_map[ad + 1] == 1) { g_map[ad] = 1; g_map[ad + 1] = 0; } } if (g_map[1] == g_map[cad]) { if (g_map[ad] == 1 && g_map[ad + 1] == 0) { g_map[ad] = 0; g_map[ad + 1] = 0; } } if (g_map[1] == g_map[cad + 1000]) { if (g_map[ad] == 0 && g_map[ad + 1] == 1) { g_map[ad] = 0; g_map[ad + 1] = 0; } } if (machine == PLUS4M) { if (g_map[2] == g_map[cad]) { if (g_map[ad] == 1 && g_map[ad + 1] == 0) { g_map[ad] = 1; g_map[ad + 1] = 1; } } if (g_map[2] == g_map[cad + 1000]) { if (g_map[ad] == 0 && g_map[ad + 1] == 1) { g_map[ad] = 1; g_map[ad + 1] = 1; } } if (g_map[1] == g_map[2]) { if (g_map[ad] == 1 && g_map[ad + 1] == 1) { g_map[ad] = 0; g_map[ad + 1] = 0; } } } if (machine == C64M) { if (g_map[1] == g_map[cad + 2000]) { if (g_map[ad] == 1 && g_map[ad + 1] == 1) { g_map[ad] = 0; g_map[ad + 1] = 0; } } } } } } updatepoint(x, y); } void kaveri(int x, int y, int foreg, int backg) { if (g_multic == 2) return; if (g_multic != 0 || g_hzoomer == 2 || g_data[int('d')] == 1) return; int k_max, maxy, miny, val, ad, bad, cad; int farge0, farge1; int mx = int(x / 8); int my = int(y / 8); if (g_attrimode == 1) { k_max = 64; miny = 0; maxy = 7; } else { k_max = 8; miny = chop8(y); maxy = y - miny; miny = maxy; } if (g_britemode == 1 && foreg == 8) foreg = 0; //check the amount of colors in the area //if there is only one, return & draw "normally" if (!g_control) { val = 0; for (int yy = miny; yy <= maxy; yy++) { ad = 1024 + (mx * 8) + (my * 8 + yy) * X; for (int xx = 0; xx <= 7; xx++) { val = val + g_map[ad + xx]; } } if (val >= k_max || val == 0) return; //check the two colors the color area is made of //if either of the intended color already exists inside the color area, return & draw "normally" bad = 65536 + mx + y * MX; cad = bad + MX * (MY * 8); farge0 = g_map[bad]; //if(g_britemode==1&&farge0==8){farge0=0;} farge1 = g_map[cad]; //if(g_britemode==1&&farge1==8){farge1=0;} if (g_britemode == 1) { if (farge0 < 8) { if (foreg == farge0 + 8) { fixattr(x, y, foreg, -1); return; } } if (farge1 < 8) { if (foreg == farge1 + 8) { fixattr(x, y, -1, foreg); return; } } if (farge0 >= 8) { if (foreg == farge0 - 8) { fixattr(x, y, foreg, -1); return; } } if (farge1 >= 8) { if (foreg == farge1 - 8) { fixattr(x, y, -1, foreg); return; } } } if (foreg == farge0) return; if (foreg == farge1) return; //new IQ: simply change the underlying color into the intended one, return & draw "normally" } int piksuf; int bg, fg; piksuf = getabsa(x, y, 0); if (g_britemode == 1 && piksuf == 8) piksuf = 0; bad = 0; cad = 0; for (int yy = miny; yy <= maxy; yy++) { bad = 65536 + mx + (my * 8) * MX + yy * MX; cad = bad + MX * (MY * 8); fg = g_map[bad]; if (g_britemode == 1 && fg == 8) fg = 0; bg = g_map[cad]; if (g_britemode == 1 && bg == 8) bg = 0; if (piksuf == fg) { g_map[bad] = byte(foreg); if (g_britemode == 1) { if (foreg > 7 && g_map[cad] < 8 && g_map[cad] != 0) { g_map[cad] = byte(g_map[cad] + 8); } if (foreg < 8 && g_map[cad] > 8 && foreg != 0) { g_map[cad] = byte(g_map[cad] - 8); } } } if (piksuf == bg) { g_map[cad] = byte(foreg); if (g_britemode == 1) { if (foreg > 7 && g_map[bad] < 8 && g_map[bad] != 0) { g_map[bad] = byte(g_map[bad] + 8); } if (foreg < 8 && g_map[bad] > 8 && foreg != 0) { g_map[bad] = byte(g_map[bad] - 8); } } } } // if the result is same color, zero the pixel data if (g_map[bad] == g_map[cad]) { for (int yy = miny; yy <= maxy; yy++) { for (int xx = 0; xx <= 7; xx++) { ad = 1024 + (mx * 8 + xx) + (my * 8 + yy) * X; g_map[ad] = byte(0); } } } updatepoint(x, y); } void kaveri_iq(int x, int y, int f1, int f2) { int k_xx, k_yy, k_ad, k_bad, k_ojox, k_ojoy, k_miny, k_maxy, k_xv, k_yv; int k_c1, k_c2, k_v0, k_v1, k_tipping, k_maximum, exist; byte k_p; if (g_multic != 0 || g_hzoomer == 2) return; exist = getabsa(x, y, 0); if (g_britemode == 1) { if (exist == 8) { if (g_farge < 8) { exist = 0; } } if (exist == 0) { if (g_farge > 7) { exist = 0; } } } k_v0 = 0; k_v1 = 0; k_tipping = 4; k_xx = chop8(x); k_yy = k_yy * 8; k_ojox = int(x / 8); k_ojoy = int(y / 8); k_ojox = k_ojox * 8; k_ojoy = k_ojoy * 8; k_miny = (y - k_ojoy); k_maxy = k_miny; k_maximum = 8; if (g_attrimode == 1) { k_miny = 0; k_maxy = 7; k_tipping = 32; k_maximum = 64; } //spectrum&c64 style k_ad = 65536 + k_xx + (k_yy + k_miny) * MX; k_bad = k_ad + MX * (MY * 8); k_c1 = g_map[k_ad]; k_c2 = g_map[k_bad]; if (g_britemode == 1) { if (k_c1 == 8) k_c1 = 0; if (k_c2 == 8) k_c2 = 0; } k_bad = 1024 + k_xx * 8 + k_yy * X; //do we have more 0's or 1's for (k_yv = k_miny; k_yv <= k_maxy; k_yv++) { k_ad = k_bad + k_yv * X; for (k_xv = 0; k_xv <= 7; k_xv++) { if (g_map[k_ad] == 1) { k_v1++; } else { k_v0++; } k_ad++; } } //force color if (g_control) { k_v1 = k_tipping + 1; if (k_c1 == exist) { k_c1 = g_farge; if (k_c1 == 8 && g_britemode == 1) k_c1 = 0; } if (k_c2 == exist) { k_c2 = g_farge; if (k_c2 == 8 && g_britemode == 1) k_c2 = 0; } if (g_britemode == 1) { if (g_farge >= 8) { if (k_c1 <= 7) k_c1 = k_c1 + 8; if (k_c2 <= 7) k_c2 = k_c2 + 8; } if (g_farge <= 7) { if (k_c1 >= 8) k_c1 = k_c1 - 8; if (k_c2 >= 8) k_c2 = k_c2 - 8; } } } if (k_v1 > k_tipping) { for (k_yv = k_miny; k_yv <= k_maxy; k_yv++) { k_ad = 65536 + k_xx + (k_yy + k_yv) * MX; k_bad = k_ad + MX * (MY * 8); g_map[k_ad] = byte(k_c2); g_map[k_bad] = byte(k_c1); } for (k_yv = k_miny; k_yv <= k_maxy; k_yv++) { k_ad = 1024 + k_xx * 8 + (k_yy + k_yv) * X; for (k_xv = 0; k_xv <= 7; k_xv++) { k_p = g_map[k_ad]; g_map[k_ad] = byte(1 - k_p); if (k_c1 == k_c2) g_map[k_ad] = byte(0); k_ad++; } } } updatepoint(x, y); }