Showing posts with label Experimentation. Show all posts
Showing posts with label Experimentation. Show all posts

Wednesday, October 7, 2015

Curves

So what have I been work on lately, for some time now I have been working again, so less hours to experiment and work on things, actually feel the need turn off the computer sometimes.

Anyway, I'm a geek and geeks can't turn off the computer for too long before curiosity takes over.

Lately I have been investigating curves, I know what you are thinking, and It's not that, I'm not stupid, I know to keep my distance.

I'm talking about other types of curves, or mathematically draw curved lines.

Now you thinking maybe taking about y=(x*scalefactor)^2, or y=sin(x)*scalefactor.
No formulas like that only draws curves in y direction, you can't have diagonal curve, or curve between two random coordinates, using formulas like that.

So there is a video from Steven Wittens, on youtube, that I really enjoyed.

https://www.youtube.com/watch?v=Zkx1aKv2z8o&index=6&list=WL

Bezier curves!!!!

So way on earth is curves important, well you draw thing in paint program save image use that, no need to know how it was done, but realize the paint tools use curves.

Even the fonts I use for this text I have written, uses some curve, SVG image or vector images, use curves, flash videos, and lots of other things.

So the best way to play around with curves is a editor, or program you drag curves around, and this what I did, soon I complete the program, as simple toy.



So way not use library someone else has made, way spend this amount of time on something you get for free, well what is fun in that, coding is about figuring things out, and play with things, learn something, the most fun I have had is maybe programs I did not complete. Just experimenting on things.

So why don't you work on mplayer, well the answer is I need a break from mplayer, and it has become work, coding should be fun, so this way I doing this I guess.

Sunday, April 14, 2013

AGA/OCS (planar) vs 8BIT CLUT (chunky)

Friday after work, and yester day I did some experimentation, people keep on saying how great AGA and OCS are for demos, is this really true? Does planar really have a advantage over 8bit CLUT chunky graphics. I think it does not, its just that planar modes, makes easier to do layering, and graphic card does the rest, so my experiment was simple implement some sort of layering in 8bit CLUT, should not be too hard.

So here is my main code, not so complicated.

#include <stdlib.h>
#include <stdio.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/Picasso96API.h>
#include "chunky_plains.h"

int main()
{
    struct chunky_plains *cp;
    struct Screen *src = NULL;
    struct Window *win;
    struct RenderInfo ri;
    int err;
    void *tmp;
    PLANEPTR ptr;
    BPTR bmlock;
    int x,y;
    int n,anim;
    ULONG bpr;

    src = p96OpenScreenTags(
        P96SA_DisplayID, 0x50051000,
        P96SA_Title, (ULONG) "666",
        P96SA_Quiet, TRUE,
        P96SA_NoMemory, TRUE,
        P96SA_NoSprite, TRUE,
        P96SA_Exclusive, TRUE,
        TAG_END    );

    if ( src )
    {
        win = OpenWindowTags(NULL,
            WA_Left, 0, WA_Top, 0,
            WA_Width, 640, WA_Height, 480,
            WA_NoCareRefresh, TRUE,
            WA_Borderless, TRUE,
            WA_Activate, TRUE,
            WA_RMBTrap, TRUE,
            WA_ReportMouse, TRUE,
            WA_CustomScreen, (ULONG) src,
            TAG_END
        );

        if (src)
        {
            SetRGB32( &src -> ViewPort ,0,0xFFFFFFFF,0,0);

            for (y=0;y<255;y++)
            {
                SetRGB32( &src -> ViewPort ,1,y * 0x01010101, (255-y)* 0x01010101,y*0x01010101);
            }

            printf("Bitmap %x\n",src -> BitMap);
            printf("BytesPerRow %d\n", src -> BitMap.BytesPerRow);
            printf("Rows %d\n", src -> BitMap.Rows);

        }
 
        Delay(20);

        if (err = alloc_cunky_plains(win -> RPort -> BitMap, 4,4,0,0,0,0,0,0, 320,200,&cp))
        {
            printf("error code: %d\n",err);
        }
        else
        {

            for (y=0;y<255;y++)
            {
                for (x=0;x<255;x++)
                {
                    set_color(cp,0, (y^x) & 8 ? (x & 3) : (y & 3) , x ,y );
                }
            }
            Delay(100);
            for (anim = 0; anim < 5; anim++)
            for (n=0;n<32;n++)
            {
                for (y=0;y<255;y++)
                {
                    for (x=0;x<255;x++)
                    {
                        set_color(cp,1, (y^(x+n)) & 16 ? 2 : 0 , x ,y );
                    }
                }
                Delay(1);
            }
            Delay(100);

            for (anim = 0; anim < 100; anim++)
            {
                scroll(cp,0,50,50,100,100,0,1);
                scroll(cp,1,50,50,100,100,1,0);
                Delay(2);
            }
            Delay(100);

            free_chunky_plains(cp);
        }
      
        Delay(100);

        CloseWindow(win);
        p96CloseScreen(src);
    }
}


As it turns out its easy to do, I think Intel/AMD PC moved to 16bit/32bit so quickly they forgot about 8Bit/6bit graphics, there are lots of cool things you can do whit 8bit graphics like layering, fadein between layers, scroll texts that go top of some image, or having some kind of vector cube in background and some logo on top of it.

People love this tricks and there are people that do make demos whit this effects even today.

Does it make sens today? Retro is in, but it probably look a lot better in OpenGL, using the Z axes, the things you don't have so great control over in OpenGL is things you can do whit the color palette.

To test you need your own "chunky_plains.h" file, so here is the rest of the code.




struct chunky_plains {
    char bits[8];                    // bits on plain
    char index[8];                    // index bit for color
    char mask[8];                    // mask for color value
    char palette[3][8][256];            // hemm...
    int bytes_per_row;                // copy of bitmap bytes per row
    char *data;                    // ptr to the Bitmap memory
    char *f_buffer;                    // buffer so we can do filtering.
    char *n_buffer;                    // buffer so we can do filtering.
};

enum {
    cp_error_no_mem = 0,
    cp_error_too_many_bits
};

void free_chunky_plains(struct chunky_plains *p)
{
    if (p)
    {
        if (p -> f_buffer) FreeVec(p -> f_buffer);
        if (p -> n_buffer) FreeVec(p -> n_buffer);
        FreeVec(p);
    }
}

int alloc_cunky_plains(struct BitMap *bm, char n0,char n1,char n2,char n3,char n4,char n5, char n6,char n7, int w,int h,struct chunky_plains **new_cp)
{
    struct chunky_plains *p;
    int n;
    int cnt;
    int bpr;
    int error_code = 0;

    p = (struct chunky_plains *) AllocVec( sizeof(struct chunky_plains) , MEMF_ANY );

    if (p)
    {
        bpr = p96GetBitMapAttr(  bm, P96BMA_BYTESPERROW);   

        p -> data =  (char *) p96GetBitMapAttr( bm , P96BMA_MEMORY);
        p -> f_buffer = (char *)  AllocVec( bpr * h , MEMF_ANY | MEMF_CLEAR);
        p -> n_buffer = (char *)  AllocVec( bpr * h , MEMF_ANY | MEMF_CLEAR);
        p -> bytes_per_row = bpr;

        p -> bits[0]=n0;
        p -> bits[1]=n1;
        p -> bits[2]=n2;
        p -> bits[3]=n3;
        p -> bits[4]=n4;
        p -> bits[5]=n5;
        p -> bits[6]=n6;
        p -> bits[7]=n7;

        p -> index[0] = 0;

        cnt = 0;
        for (n=1;n<8;n++)
        {
            p -> index[n] = p -> index[n-1] + p -> bits[n-1];

            cnt += p -> bits[n];
        }

        for (n=0;n<8;n++)
        {
            p -> mask[n] = ((1 << p -> bits[n]) -1) << p -> index[n];

            printf("bits %02x mask %02x index %d\n",p -> bits[n] ,p->mask[n], p -> index[n]);
        }

        if (cnt > 8) error_code = cp_error_too_many_bits;
       
        if (!p -> data)    error_code = cp_error_no_mem;
        if (!p -> f_buffer) error_code = cp_error_no_mem;
        if (!p -> n_buffer) error_code = cp_error_no_mem;

    } else {
        error_code = cp_error_no_mem;
    }

    if (error_code)
    {
        free_chunky_plains(p);
        p = NULL;
    }

    *new_cp = p;

    return error_code;
}


void set_color(struct chunky_plains *cp, char number, char color, int x,int y)
{
    char *pixel = &cp -> data[ x + (cp -> bytes_per_row * y)];
    *pixel = (~cp -> mask[number]) &  *pixel | (color << cp -> index[number] );
}

int get_color(struct chunky_plains *cp, char number, char color, int x,int y)
{
    return (cp -> mask[number] &  cp -> data[ x + (cp -> bytes_per_row * y)]) >> cp -> index[number] ;
}

void scroll(struct chunky_plains *cp, int number, int x1,int y1,int x2,int y2, int offset_x, int offset_y )
{
    int fmask = ~ cp -> mask[number];
    int mask = cp -> mask[number];
    int bytes_per_row = cp -> bytes_per_row;
    register int x = 0;
    register int y;
    register int line_offset;
    register int offset;
    register int doffset;

    // we filter out the other plains into the buffer, so we can put it back in.

    for (y =y1;y<=y2;y++)
    {
        line_offset = y *  bytes_per_row;
        for (x=x1;x<=x2;x++)
        {
            offset = line_offset +x;
            cp -> f_buffer[offset] = cp -> data[ offset ] & fmask;
            cp ->n_buffer[offset] = cp -> data[ offset ] & mask;
        }
    }

    for (y =y1;y<=y2;y++)
    {
        line_offset = y * bytes_per_row;
        for (x=x1;x<=x2;x++)
        {
            offset = line_offset +x;

            doffset = (y + offset_y) * bytes_per_row + (x + offset_x);

            cp -> data[ offset ] = cp -> f_buffer[offset] | cp ->n_buffer[ doffset ] ;
        }
    }
}