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 + -
显示快捷键?