planukit.c

来自「linux 下svgalib编的一个界面程序示例」· C语言 代码 · 共 645 行 · 第 1/2 页

C
645
字号
	palette[(i + 64) * 3 + 1] = 0;	palette[(i + 64) * 3 + 2] = 0;    }    for (i = 0; i < 64; i++) {	palette[(i + 128) * 3 + 0] = 0;	palette[(i + 128) * 3 + 1] = i;	palette[(i + 128) * 3 + 2] = 0;    }    for (i = 0; i < 64; i++) {	palette[(i + 192) * 3 + 0] = 0;	palette[(i + 192) * 3 + 1] = 0;	palette[(i + 192) * 3 + 2] = i;    }    gl_setpalette (&palette);}/*returns 1 if exit key is pressed */int PL_handle_key (TD_Solid * plane){    static float incr = 0.1047198;    int finished = 0;    int c;/*plane->gamma += incr;   plane->beta = -0.5;   plane->render = TD_SOLID;    return 0; *//*---> a screen saver*/    switch (c = getchar ()) {    case 'q':	plane->alpha += incr;	break;    case 'a':	plane->alpha -= incr;	break;    case 'o':	plane->beta += incr;	break;    case 'p':	plane->beta -= incr;	break;    case 'z':	plane->gamma += incr;	break;    case 'x':	plane->gamma -= incr;	break;    case 't':	plane->z_cam += PL_METER;	break;    case 'v':	plane->z_cam -= PL_METER;	break;    case 'g':	plane->x_cam += PL_METER;	break;    case 'f':	plane->x_cam -= PL_METER;	break;    case 'w':	plane->distance += PL_METER;	plane->y_cam += PL_METER;	break;    case 's':	plane->distance -= PL_METER;	plane->y_cam -= PL_METER;	break;    case 'c':	finished = 1;	break;    case 'i':	plane->gamma = 0;	plane->alpha = 0;	plane->beta = 0;	break;    case ' ':	switch (plane->render) {	case TD_MESH:	    plane->render = TD_MESH_AND_SOLID;	    break;	case TD_MESH_AND_SOLID:	    plane->render = TD_SOLID;	    break;	case TD_SOLID:	    plane->render = TD_EDGES_ONLY;	    break;	case TD_EDGES_ONLY:	    plane->render = TD_MESH;	    break;	}	break;    case 'r':	if (plane->option_flags & TDOPTION_FLAT_TRIANGLE)	    plane->option_flags &= 0xFFFFFFFF - TDOPTION_FLAT_TRIANGLE;	else	    plane->option_flags |= TDOPTION_FLAT_TRIANGLE;	break;    case '1':	incr += .01047198;	break;    case '2':	incr -= .01047198;	break;    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':	DENS = c - '2';	PL_init_surfaces (plane);    }    if (incr < 0)	incr = 0;    return (finished);}/*WRITE-PAGE FLIPPING*//*  The following routines redirect the setpage functions to take advantage  of the vga memory: writing graphics functions to one half of the memory  while viewing  the other. This saves us a copyscreen, while costing the extra  time it takes to draw to vga memory instead of linear (i.e. the  virtual screen) memory. vga.c should have the minor modification  that would allow this to be done more simply. The following was the  only way that seemed to work without altering vga.c. We will  call the method "Write-page Flipping", as apposed to "Page Flipping"  where pages are flipped, but writing is done to a virtual screen  which is then copied to the vga memory not being viewed. Write-page  Flipping writes directly to the vga memory not being viewed.  The method even works on my TVGA8900CL/D in 320x200 (though it's not  supposed to), and doesn't work in 640x480 (where it is supposed to)  so I have given both options at startup. Note that Write-page flipping  can only work on linear or paged modes (320x200, 640x480, 800x600,  1024x768) since graphics functions to write directly to planar   modes are not supported by svgalib.*/GraphicsContext physcr, virscr;int winflipping, vgawindow = 0;int Startpage[2];int gmode, chipset;void PL_redraw (TD_Solid * plane){    gl_clearscreen (64);    TD_draw_solid (plane);}void PL_cleanup (TD_Solid * plane){/*this function should free all allocated memory*/    return;}void winpointto (int win){    if (chipset == TVGA8900 && gmode == G320x200x256) {	/*trident has 4 bpp in this mode */	vga_ext_set(VGA_EXT_PAGE_OFFSET, (Startpage[win] * 4) >> 16);    } else {	vga_ext_set(VGA_EXT_PAGE_OFFSET, Startpage[win] >> 16);    }    vga_setpage (0);}void winview (int win){    vga_waitretrace ();    vga_setdisplaystart (Startpage[win] * win);}void winflip (void){    winview (vgawindow);    vgawindow = 1 - vgawindow;    winpointto (vgawindow);}void PL_animate (TD_Solid * plane, void (*PL_redraw_callback) (TD_Solid *),	    int (*PL_key_callback) (TD_Solid *)){    do {	PL_redraw_callback (plane);	if(winflipping) {	    winflip ();	} else {	    gl_setscreenoffset( HEIGHT * WIDTH * currentcontext.flippage );	    gl_copyscreen (&physcr);	}    } while (!(int *) PL_key_callback (plane));}int pl_getchar (void){    int c = 0;    while (c == 0 || c == '\n') {	c = vga_getkey ();    }    if (c >= 'a' && c <= 'z')	c += 'A' - 'a';    return c;}int main (void){    int mode[7] =    {5, 6, 7, 8, 10, 11, 12};    int Winflipping[7] =    {1, 0, 0, 0, 1, 1, 1};    int Winflippages[7] =    {65536, 0, 0, 0, 8 * 65536, 8 * 65536, 16 * 256};    int c, c2;    vga_modeinfo *ginfo;    TD_Solid *plane;/* Note that in this demo, graphics are written to all modes as   virtual modes, so that the triangle routine optimisations will   operate all the time (see triangle.c). */    vga_init ();    if (!(vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_SET) & (1 << VGA_EXT_PAGE_OFFSET))) {	puts("You need at least svgalib 1.2.10 to run this program!\n");	exit(1);    }    do {	printf ("\n256 color modes:\n\n1: 320x200\n2: 320x240\n3: 320x400\n");	printf ("4: 360x480\n5: 640x480\n6: 800x600\n7: 1024x768\n");	printf ("\nWhich? ");	c = pl_getchar () - '1';	printf ("\n");    } while (c < 0 || c > 6);    printf("Want (W)rite-page flipping, normal (P)age flipping\n");    printf("using copyscreen, or (N)o page flipping (W/F/N)\n");    printf("(W is faster but may not work, N will always work\n");    printf("but sometimes looks tacky) ?\n");    c2 = pl_getchar();    printf ("\n");    gmode = mode[c];    winflipping = Winflipping[c];    if (!vga_hasmode (gmode)) {	fprintf (stderr, "Mode not available.\n");	exit (-1);    }    vga_setmode (gmode);    gl_setcontextvga (gmode);    ginfo = vga_getmodeinfo (gmode);    PL_screen_width = ginfo->width;    PL_screen_height = ginfo->height;    if (PL_init_plane (&plane)) {	fprintf (stderr, "Unable to intialise data structures.\n");    }    plane->posx = PL_screen_width / 2;	/*Where origin will be printed */    plane->posy = PL_screen_height / 2;    PL_init_palette ();/* to see what the palette looks like: *//* for(i=0;i<256;i++) gl_line(0,i,PL_screen_width,i,i);   getchar(); */    /* Allow write flipping 	on 320x200 even though ginfo doesn't report more 	than 64k of memory:*/    if ((PL_screen_width * PL_screen_height * 2 > ginfo->maxpixels		    && gmode != G320x200x256) || c2 != 'W')	winflipping = 0;    if (winflipping) {	printf("Using Write-page Flipping.\n");	Startpage[0] = 0;  /*define pages offsets into memory*/	Startpage[1] = Winflippages[c];	winflip ();    } else {	gl_getcontext (&physcr);	gl_setcontextvgavirtual (gmode);	gl_getcontext (&virscr);	if(c2 != 'N') {	    if(gl_enablepageflipping (&physcr))		printf("Using Page Flipping.\n"); 	}    }    gl_enableclipping ();    PL_animate (plane, PL_redraw, PL_handle_key);    PL_cleanup (plane);    vga_setmode (TEXT);    return 0;}

⌨️ 快捷键说明

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