⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fun.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
字号:
/* Roaming-blobs-on-mars-collect-some-dust-on-a-tropical-island-and-go-pearl-   diving-before-population-goes-out-of-control. *//* Each frame, a background virtual screen is copied to a virtual screen; *//* sprites (well, pixels) are written on that virtual screen; and the *//* virtual screen is copied to video memory. The background is updated as *//* appropriate. This simple animation technique works well for 320x200 *//* because it's so small. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <time.h>#include <vga.h>#include <vgagl.h>/* This can be changed into any 256 color mode. *//* For planar 256 color modes, enable page flipping. *//* Even 16 color modes work (ugly colors). */#define VGAMODE G800x600x256#define USE_PAGEFLIPPING/* #define USE_SMALLOC *//* This is the size of the animated window. */#define MAPWIDTH 800#define MAPHEIGHT 560#define MAXMOVERS 2000#define MAXCITIES 1000#define NUMBEROFCITIES 20#define NUMBEROFMOVERS 1400#define MOVERTHRESHOLD 1400#define MOVERLIFETIME 1000#define COLORTIME 2000#define randomn( n ) (random() % n)#define red(x) (32 + x)#define green(x) (64 + x)#define yellow(x) (96 + x)#define blue(x) (128 + x)#define magenta(x) (160 + x)#define cyan(x) (192 + x)#define white(x) (224 + x)/* Data types */typedef struct {    int x;    int y;} Position;#define STAT_ACTIVE 1typedef struct {    int stat;    int x;    int y;    int vx;    int vy;    int color;    int time;} Mover;typedef struct {    int x;    int y;    int pop;    int hit;} City;/* Global variables */int map[MAPWIDTH][MAPHEIGHT];/* Map encoding i: *//* (0 - 0xffff  Mover number i) *//* 0x10000...   Part of city (i - 0x10000) */Mover mover[MAXMOVERS];int nu_movers = 0;City city[MAXCITIES];int nu_cities = 0;int mytime = 0;			/* used to be "time" but collids w/libc function time() */int pop = 0;int framerate, framecount, frameclock;GraphicsContext *physicalscreen;GraphicsContext *backscreen;GraphicsContext *background;void error(char *s){    printf("%s\n", s);    vga_setmode(TEXT);    exit(0);}void setcustompalette(void){    /* colors 0-31 are a RGB mix (bits 0 and 1 red, 2 green, 3 and 4 blue) */    /* 32-63    black to red */    /* 64-95    black to green */    /* 96-127   black to yellow */    /* 128-159  black to blue */    /* 160-191  black to magenta */    /* 192-223  black to cyan */    /* 224-255  black to white */    Palette pal;    int i;    for (i = 0; i < 256; i++) {	int r, g, b;	r = g = b = 0;	if ((i & 32) > 0)	    r = (i & 31) << 1;	if ((i & 64) > 0)	    g = (i & 31) << 1;	if ((i & 128) > 0)	    b = (i & 31) << 1;	if (i < 32) {	    r = (i & 3) << 4;	/* 2 bits */	    g = (i & 4) << 3;	/* 1 bit */	    b = (i & 24) << 1;	/* 2 bits */	}	pal.color[i].red = r;	pal.color[i].green = g;	pal.color[i].blue = b;    }    gl_setpalette(&pal);}void initfont(void){    void *font;#ifdef USE_SMALLOC    font = smalloc(256 * 8 * 8 * BYTESPERPIXEL);#else    font = malloc(256 * 8 * 8 * BYTESPERPIXEL);#endif    gl_expandfont(8, 8, white(24), gl_font8x8, font);    gl_setfont(8, 8, font);}int fsize(FILE * f){    int oldpos, size;    oldpos = ftell(f);    fseek(f, 0, SEEK_END);    size = ftell(f);    fseek(f, oldpos, SEEK_SET);    return size;}void loadfile(char **buf, char *fname){    FILE *f;    int size;    f = fopen(fname, "rb");    size = fsize(f);    *buf = malloc(size);    fread(*buf, 1, size, f);    fclose(f);}/* Map */void clearmap(void){    int x, y;    for (y = 0; y < MAPHEIGHT; y++)	for (x = 0; x < MAPWIDTH; x++)	    map[x][y] = 0;}Positionfindfreeposition(void){    int x, y;    Position p;    do {	x = randomn(MAPWIDTH);	y = randomn(MAPHEIGHT);    }    while (map[x][y] != 0);    p.x = x;    p.y = y;    return p;}/* Movers */void initmovers(void){    int i;    for (i = 0; i < MAXMOVERS; i++)	mover[i].stat = 0;}int findfreemoverslot(void){    int i;    for (i = 0; i < MAXMOVERS; i++)	if (!(mover[i].stat & STAT_ACTIVE))	    return i;    error("Mover table overflow");    return 0;}void addrandommover(void){    Position p = findfreeposition();    int i = findfreemoverslot();    int c;    mover[i].x = p.x;    mover[i].y = p.y;    do {	mover[i].vx = randomn(3) - 1;	mover[i].vy = randomn(3) - 1;    }    while (mover[i].vx == 0 && mover[i].vy == 0);    mover[i].stat = STAT_ACTIVE;    switch (randomn(4)) {    case 0:	c = blue(20);	break;    case 1:	c = green(20);	break;    case 2:	c = magenta(20);	break;    default:	c = cyan(20);	break;    }    mover[i].time = 0;    mover[i].color = c;    nu_movers++;}void killmover(int i){    mover[i].stat = 0;    nu_movers--;}void drawmover(int i){    gl_setpixel(mover[i].x, mover[i].y, mover[i].color);}/* Cities */void initcities(void){    nu_cities = 0;}void addcity(int x, int y){    int i = nu_cities++;    map[x][y] = i + 0x10000;    city[i].x = x;    city[i].y = y;    city[i].pop = 1;    city[i].hit = 0;}int cityat(int x, int y){    if (map[x][y] >= 0x10000)	return map[x][y] - 0x10000;    else	return -1;}int citycolor(void){    static int colortable[5] =    {yellow(31), blue(31), white(31), green(31), cyan(31)};    return colortable[(mytime / COLORTIME) % 5]	- (mytime % COLORTIME) * 25 / COLORTIME;}void growcity(int cx, int cy, int x, int y, int ct){/* add city unit at (x, y) adjacent to city unit (cx, cy) */    int c;    map[x][y] = ct + 0x10000;    c = citycolor();    gl_setpixel(x, y, c);    city[ct].pop++;    city[ct].hit = 20;    pop++;}/* Main components */void createbackground(void){/* Create fancy dark red background */    int x, y;    for (y = 0; y < MAPHEIGHT; y++)	for (x = 0; x < MAPWIDTH; x++) {	    int i = 0;	    int n = 0;	    int c;	    if (x > 0) {		i += gl_getpixel(x - 1, y) - red(0);		n++;	    }	    if (y > 0) {		i += gl_getpixel(x, y - 1) - red(0);		n++;	    }	    c = (i + randomn(16)) / (n + 1);	    if (c > 9)		c = 9;	    gl_setpixel(x, y, red(0) + c);	}}void drawbackground(void){/* Build up background from map data */    int x, y;    gl_setcontext(background);    gl_clearscreen(0);    createbackground();    for (y = 0; y < MAPHEIGHT; y++)	for (x = 0; x < MAPWIDTH; x++) {	    int c = cityat(x, y);	    if (c != -1)		gl_setpixel(x, y, citycolor());	}}void createcities(void){    int i;    for (i = 0; i < NUMBEROFCITIES; i++) {	Position p = findfreeposition();	addcity(p.x, p.y);    }}void writestat(void){    char s[41];    int i, x, y;    int maxpopcity, maxpop;    sprintf(s, "Pop %7d  Time %7d  Rate %5d.%d", pop, mytime,	    framerate / 10, framerate % 10);    gl_setwritemode(WRITEMODE_OVERWRITE);    gl_write(0, HEIGHT - 8, s);    maxpop = -1;    maxpopcity = 0;    for (i = 0; i < nu_cities; i++)	if (city[i].pop > maxpop) {	    maxpop = city[i].pop;	    maxpopcity = i;	}    gl_enableclipping();    gl_circle(city[maxpopcity].x, city[maxpopcity].y, 10,	      blue(31));    gl_disableclipping();    gl_setwritemode(WRITEMODE_MASKED);    x = city[maxpopcity].x;    y = city[maxpopcity].y;    sprintf(s, "%d", maxpop);    /* clipping */    if (x + strlen(s) * 8 > MAPWIDTH)	x = MAPWIDTH - strlen(s) * 8;    if (y + 8 > MAPHEIGHT)	y = MAPHEIGHT - 8;    gl_write(x, y, s);}void drawscreen(void){    int i;    /* Copy background to backscreen. */    gl_setcontext(background);    gl_copyscreen(backscreen);    /* Now draw the objects in backscreen. */    gl_setcontext(backscreen);    for (i = 0; i < MAXMOVERS; i++)	if (mover[i].stat & STAT_ACTIVE) {	    drawmover(i);	}    writestat();    /* Copy backscreen to physical screen. */    gl_copyscreen(physicalscreen);}void move(void){    int i;    gl_setcontext(background);    for (i = 0; i < MAXMOVERS; i++)	if (mover[i].stat & STAT_ACTIVE) {	    int nx, ny;	    int c;	    if (++mover[i].time == MOVERLIFETIME) {		killmover(i);		continue;	    }	    for (;;) {		nx = mover[i].x + mover[i].vx;		ny = mover[i].y + mover[i].vy;		if (nx < 0 || nx >= MAPWIDTH) {		    mover[i].vx = -mover[i].vx;		    continue;		}		if (ny < 0 || ny >= MAPHEIGHT) {		    mover[i].vy = -mover[i].vy;		    continue;		}		break;	    }	    c = cityat(nx, ny);	    if (c != -1) {	/* found city */		killmover(i);		growcity(nx, ny, mover[i].x, mover[i].y, c);		continue;	/* next mover */	    }	    mover[i].x = nx;	    mover[i].y = ny;	}    if (pop >= MAPWIDTH * MAPHEIGHT * 255 / 256) {	/* start all over again */	printf("fun: new run.\n");	pop = 0;	mytime = 0;	clearmap();	initcities();	createcities();	drawbackground();    }}void createmovers(void){    int i;    for (i = 0; i < NUMBEROFMOVERS; i++)	addrandommover();}int main(void){    vga_init();    clearmap();    initmovers();    createcities();    createmovers();    vga_setmode(VGAMODE);    gl_setcontextvga(VGAMODE);    physicalscreen = gl_allocatecontext();    gl_getcontext(physicalscreen);#ifdef USE_PAGEFLIPPING    /* Try to enable page flipping. */    gl_enablepageflipping(physicalscreen);#endif    setcustompalette();    /* initfont() here caused trouble with planar 256 color modes. */    gl_setcontextvgavirtual(VGAMODE);    backscreen = gl_allocatecontext();    gl_getcontext(backscreen);#ifdef USE_SMALLOC    free(backscreen->vbuf);    backscreen->vbuf = smalloc(BYTEWIDTH * HEIGHT);    gl_setcontext(backscreen);#endif    initfont();    gl_setcontextvgavirtual(VGAMODE);    background = gl_allocatecontext();    gl_getcontext(background);#ifdef USE_SMALLOC    free(background->vbuf);    background->vbuf = smalloc(BYTEWIDTH * HEIGHT);    gl_setcontext(background);#endif    drawbackground();    framerate = 0;    framecount = 0;    frameclock = clock();    for (;;) {	int i;	drawscreen();	move();	for (i = 0; i < 4; i++)	    if (nu_movers < MOVERTHRESHOLD)		addrandommover();	mytime++;	/* Update frame rate every 3 seconds. */	framecount++;	if (clock() - frameclock >= CLOCKS_PER_SEC) {	    framerate = framecount * CLOCKS_PER_SEC / (clock() - frameclock);	    framecount = 0;	    frameclock = clock();	}    }#ifndef USE_SMALLOC    gl_freecontext(backscreen);    gl_freecontext(background);#endif    vga_setmode(TEXT);    exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -