view draw_inputs.pde @ 7:c848a6133cfc

Fix many calculations (divisions) that assume integer variable division semantics by truncating to int(). Also add two helper functions chop2(v) and chop8(v) and use them where appropriate.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 03 Jul 2018 22:17:48 +0300
parents a1261cd4c676
children 72407a4d9539
line wrap: on
line source

// Collect all that "reads" the virtual image in some way or other
// plus other passive manipulations

int odd(int v) {
    if ((v | 1) == v) return 1;
    return 0;
}

int even(int v) {
    if (v >> 1 == v) return 1;
    return 0;
}

float getangel(float xx, float yy) {
    float ang = degrees(atan2(xx, -yy));
    if (ang < 0) return 360 + ang;
    return ang;
}

int zxcolor(int col) {
    //something that allows different zx brightness colors treated logically as the same
    //i.e. bright red and dark red the same. handy for brush transparency
    if (g_britemode == 0) return col;
    if (col > 7) return col - 8;
    return col;
}

//the "slow" call to mark "dirty block"
void updatepoint(int xx, int yy) {
    if (yy < 0 || xx < 0 || xx >= X || yy >= Y) return;
    xx = int(xx / 8);
    yy = int(yy / 8);
    int ad = xx + yy * MX;
    g_redo[ad] = byte(0); //block update
    g_remdo[ad] = byte(1); //block update
}

int getmultibrush(int x1, int y1) {

    //returns the multicolor color on point x1,y1 at brush

    int ad, looks, mmc;
    if (g_multic == 2) return g_brush[1024 + x1 + y1 * X];

    ad = 1024 + x1 + y1 * X;
    looks = 65536 + int(x1 / 8) + int(y1 / 8) * MX;
    mmc = g_brush[ad] + g_brush[ad + 1] * 2;
    switch (mmc) {
        case 0:
            return g_map[1];
        case 1:
            return g_brush[looks];
        case 2:
            return g_brush[looks + 1000];
        case 3:
            if (machine == PLUS4M) return int(g_map[2]);
            return g_brush[looks + 2000];
    }
    return g_brush[ad] + g_brush[ad + 1] * 2;
}

int getmultic(int x1, int y1, int mode) //mode 0=screen 1=brush
{

    //returns the multicolor color on point x1,y1

    int ad, looks, mmc, source1, source2;

    if (g_multic == 2) {
        looks = 1024 + x1 + y1 * X;
        if (mode == 0) return g_map[looks];
        if (mode == 1) return g_brush[looks];
    }
    x1 = chop2(x1);
    ad = 1024 + x1 + y1 * X;
    source1 = 0;
    source2 = 0;
    looks = 65536 + int(x1 / 8) + int(y1 / 8) * MX;
    if (mode == 0) {
        source1 = g_map[ad];
        source2 = g_map[ad + 1];
    }
    if (mode == 1) {
        source1 = g_brush[ad];
        source2 = g_brush[ad + 1];
    }
    mmc = source1 + source2 * 2;
    //source1=0
    //source2=+1
    //00=zeroc =0
    //01=color1=2
    //10=color2=1
    //11=color3=3

    if (mode == 0) {
        switch (mmc) {
            case 0:
                return g_map[1];
            case 1:
                return g_map[looks];
            case 2:
                return g_map[looks + 1000];
            case 3:
                if (machine == PLUS4M) return int(g_map[2]);
                return g_map[looks + 2000];
        }
    }
    if (mode == 1) {
        switch (mmc) {
            case 0:
                return g_map[1];
            case 1:
                return g_brush[looks];
            case 2:
                return g_brush[looks + 1000];
            case 3:
                if (machine == PLUS4M) return int(g_map[2]);
                return g_brush[looks + 2000];
        }
    }
    return source1 + source2;
}

int getattra(int xx, int yy, int mode) //mode foreground backround
{
    //returns the internal foreground / background color on point xx,yy
    int xv, yv, val;
    if (g_multic == 2) {
        if (mode == 0) return getmultic(xx, yy, 0);
        return g_backg;
    }
    if (g_multic == 1) {
        if (mode == 0) return getmultic(xx, yy, 0);
        return g_map[1]; // was 0?
    }
    xx = int(xx / 8);
    yv = int(yy / 8);
    int ad = 65536 + xx + yy * MX;
    if (mode == 0) {
        val = g_map[ad];
        if (g_britemode == 1 && val == 8) return 0;
        return val;
    }
    //  if(mode==1)
    val = g_map[ad + (MX * MY) * 8];
    if (g_britemode == 1 && val == 8) return 0;
    return val;
}

int getabsa(int xx, int yy, int mode) //mode 0=screen 1=brush
{
    // returns the visible colour on point xx,yy
    int sad, ssap, ad, val;
    int chek;
    val = 0;
    sad = 1024 + xx + yy * X;
    ad = 65536 + int(xx / 8) + yy * MX;
    chek = int(g_map[sad]);
    if (chek == 100 || chek == 200) return chek;

    if (mode == 0) {
        ssap = int(g_map[sad]);
    } else {
        ssap = int(g_brush[sad]);
    }

    if (ssap == 1) {
        if (mode == 0) {
            val = g_map[ad];
        } else {
            val = g_brush[ad];
        }
        if (g_britemode == 1 && val == 8) return 0;
        return val;
    }
    if (ssap == 0) {
        if (mode == 0) {
            val = g_map[ad + (MX * MY) * 8];
        } else {
            val = g_brush[ad + (MX * MY) * 8];;
        }
        if (g_britemode == 1 && val == 8) return 0;
        return val;
    }
    return g_map[sad];
}

//the most accessible way to get a color index from a point
int easygetcolor(int xx, int yy) {
    if (yy < 0 || xx < 0 || xx >= X || yy >= Y) return 0;
    if (g_multic > 0) return getmultic(xx, yy, 0);
    if (g_multic == 0) return getabsa(xx, yy, 0);
    return 0;
}

void infersize() {
    int xx, yy, cp, molox, okay;
    int bx, by;
    storeparameters();
    xx = 0;
    molox = 1;
    okay = 0;
    if (g_multic == 1 || g_hzoomer == 2) molox = 2;
    cp = easygetcolor(0, 0);
    for (xx = 0; xx < X; xx = xx + molox) {
        if (easygetcolor(xx, 0) == cp && okay == 0) {
            g_animx = xx;
        } else {
            okay = 1;
        }
    }
    okay = 0;
    for (yy = 0; yy < Y; yy++) {
        if (easygetcolor(0, yy) == cp && okay == 0) {
            g_animy = yy;
        } else {
            okay = 1;
        }
    }

    g_animx = g_animx + molox;
    g_animy = g_animy + 1;
    if (g_animx > 63 || g_animy > 63 || g_animx <= 2 || g_animy <= 2) {
        message("BAD SIZE|See manual");
        restoreparameters();
        g_data[int('n')] = 0;
        return;
    }
    int boldsourcex = g_bsourcex;
    int boldsourcey = g_bsourcey;
    int boldsourcex2 = g_bsourcex2;
    int boldsourcey2 = g_bsourcey2;

    g_bsourcex = g_animx;
    g_bsourcey = 0;
    g_bsourcex2 = g_animx + g_animx - molox;
    g_bsourcey2 = g_animy - 1;
    g_animframes = 0;
    g_animno = 1;
    int raamit = -1;
    for (yy = 0; yy <= Y; yy = yy + g_animy) {
        for (xx = 0; xx <= X; xx = xx + g_animx) {
            okay = 1;
            for (bx = 0; bx < g_animx; bx = bx + molox) {
                for (by = 0; by < g_animy; by++) {
                    if (easygetcolor(xx + bx, yy + by) != cp) okay = 0;
                }
            }
            if (okay == 1 && g_animframes <= 1) g_animframes = raamit;
            if (xx + g_animx < X || xx + g_animx == X) raamit++;
        }
    }
    if (g_animframes <= 0) {
        message("BAD BOOKEND|See manual");
        restoreparameters();
        g_data[int('n')] = 0;
        g_bsourcex = boldsourcex;
        g_bsourcey = boldsourcey;
        g_bsourcex2 = boldsourcex2;
        g_bsourcey2 = boldsourcey2;
        return;
    }
    message("Play Brush|" + g_animx + " x " + g_animy + "|" + g_animframes + " frames");
}

void animbrush_do() {
    int bx, by;
    int horisize;
    int molox = 1;
    if (g_multic == 1) molox = 2;
    horisize = int(X / g_animx);
    g_animno = g_animno + 1;
    if (g_animno > g_animframes) g_animno = 1;
    by = int(g_animno / horisize);
    bx = g_animno - (by * horisize);
    g_bsourcex = bx * g_animx;
    g_bsourcey = by * g_animy;
    g_bsourcex2 = g_bsourcex + g_animx - molox;
    g_bsourcey2 = g_bsourcey + g_animy - 1;
}

void set_fixed_raster(int set) {
    for (int i = 0; i < 64; i++) {
        g_fixedraster[i] = g_rasterpatterns[set * 64 + i];
    }
}

int get_raster(int xx, int yy) {
    int molox = 1;
    if (g_multic == 1 || g_hzoomer == 2) molox = 2;
    xx = xx + g_raster_offset_x * molox;
    yy = yy + g_raster_offset_y;
    if (g_multic == 1 || g_hzoomer == 2) {
        xx = int(xx / 2);
    }
    int mx = chop8(xx);
    int my = chop8(yy);
    xx = xx - mx;
    yy = yy - my;
    return g_fixedraster[xx + yy * 8];
}

void refreshpalette() {
    //relevant for alterable palettes, such as amiga or cpc
    if (g_palsteps == 0) return;
    for (int i = 0; i < g_maxcolors; i++) {
        makecolor(i, int(g_map[256 + i * 3]), int(g_map[256 + i * 3 + 1]), int(g_map[256 + i * 3 + 2]));
    }
}