![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-10-27 21:27 |
共 47,815 主题排行 / 349,929 发帖 / 今日 1 篇 / 48,290 会员排行 |
| DOS启动盘 & LOGO技术 (启动盘室) » [原创] |
| 可打印版本 768 / 2 |
| 第1楼 TurboY | 发表于 2005-01-26 00:00 |
| 中级用户 发帖 99 积分 322 来自 湖北 | |
|
[原创] 这是我以前写的一个小程序,用来制作Windows98/DOS7启动动画LOGO。去年把运行文件贴出后,有人提出要看源码,我自己觉得写得不好,就想改一下再传上来,但这事一放下就是几个月,自己都差点儿忘了。现在想还是先传上来再说,也不怕丢人了,总有人愿意看的。程序的编译环境是DJGPP2+ALLEGRO3.11,自己准备吧。
在这里阅读语法加亮的源码:http://yisir.51.net/arti0039.php 在这里下载(含源码):http://yisir.51.net/tools/logobar.zip 引子&原理: 现在,Windows95、Windows98、WindowsMe以其优秀的兼容性和易操作性仍占据了许多用户的计算机。当我们启动计算机时,都会看到一段带有滚动色条的LOGO-“蓝天白云”,这已经成为了Windows9x的标志。许多文章都透露,“蓝天白云”其实是位于C盘根目录下的一个文件LOGO.SYS,这其实是一个320X400X256色的BMP文件,用简单的“画图”就可以制作出来。但BMP是静态的,WindowsLOGO是如何将它动起来的呢?这涉及到调色板方面的知识。现在几乎所有的显卡都支持真彩色,但真彩色中的一个点需要至少24位的空间来存储,一个基本的640*480画面就需要640X480X3=921600字节,这对某些空间要求严格的程序来说太浪费了。因此几乎所有的显卡都支持调色板索引色方式,如VGA13H模式--此显示模式分辨率为320X200,可显示262144色(2^18),但因为使用了256项的调色板,所以同时只能显示262144色中的256色。虽牺牲了一部分色彩数,却使得每个点的占用空间缩小到了8位即一个字节,它记录着此色在调色板中的位置号,程序通过查表就可找到相应的RGB值并将之准确地显示出来。反过来说,我们甚至可以只修改调色板中记录的RGB值就可以使屏幕上部分点的色彩发生改变,而不用去重新绘点。微软的Windows9x系列在启动LOGO中就采用的方法与此类似:分辨率为320X400,同屏同时只显示256色,每个颜色对应调色板中的一种RGB色彩。当操作系统启动时,程序控制调色板最后的20项的颜色RGB分量按一定规则循环改变,屏幕上就使用了这20项色的点就出现了相应的动画效果--合理安排那些色点的位置就可以产生有趣的动画。现在有XrX Add Bar Utility,Animate Bar等工具可以在一个普通的BMP文件底部动画条效果,如果您更有创意的话,它们就不能胜任了--它们只能在图像的底部添加,源图像必须是320X400 256色的BMP文件--功能太少了。 这就是这个程序产生的原因。本程序可以做到更多您所想要的效果,不信您就试试看。不过,由于我写程序的机器太老(P75)只能运行DOS,此程序是用命令行参数来控制的。相信这不会难着你吧! 软件名: LOGOBAR 易老师的LOGO.SYS动画条制作工具 版权说明: 本程序是自由软件,还有待改进。您可以使用它,可以复制给朋友,如果您觉得它给了 您乐趣,希望Email给作者([email protected])分享。如果您有任何商用目的,也请先通 知作者。 作者: 431700 湖北省天门市实验初级中学 易华卫 Email: [email protected] 主页: http://yisir.9126.com 版本: V1.0 beta,2004年6月25日于湖北省天门市麻洋镇支教时编译。 用法: LOGOBAR 源图像 源图像 是一个您已经设计好的图像文件,格式可以是BMP,PCX,LBM,TGA,BTW, 最好是Windows标准的BMP格式,图像的尺寸可以是320X400,色彩数 为256。也可是其他值,程序可以自动转换成320X400X256。 选项: /TO=LOGO文件 将加了动画条的图像保存成LOGO文件,缺省值为LOGO.SYS。你可以使 用选项“/TO=C:\LOGO.SYS”来直接安装。 /PO=BOTTON|TOP|LEFT|RIGHT|MASKn 添加动画条的位置,缺省值为:BOTTON BOTTON 在图像下方添加动画条,类似Windows9x自带方式 TOP 在图像上方添加动画条 LEFT 在图像左侧添加动画条 RIGHT 在图像右侧添加动画条 MASKn 在图像中指定为蒙板区域按指定规则绘制动画条(见“高级选项”) /BC=n 动画条使用的色彩数,缺省值为20 /C1=色彩1 渐变色的起始色,以16进制表示RGB, 缺省值为 00FF00 (绿色) /C2=色彩2 渐变色的结束色,以16进制表示RGB, 缺省值为 000000 (黑色) /NP 不预览 /MT- 使用微软的另一种动画方式(不推荐) 高级选项: /PO=MASKn 在图像中指定为蒙板区域按指定规则绘制动画条,约定图像的左上角 (0,0)像素点的颜色为蒙板色,图中所有以该色填充的区域构成蒙板区 域,在蒙板区域中根据n值有7种方式来绘制色条动画。 n=1 从左向右画竖色条,动画效果为色条向右运动 n=2 从上向下画横色条,动画效果为色条向下运动 n=3 从左上向右下画//形色条,动画效果为色条向右下运动 n=4 从右上向左下画\\形色条,动画效果为色条向左下运动 n=5 从中心向四周画辐射色,动画效果如风车顺时针转动 n=6 从中心向四周画同心椭圆,动画效果为椭圆由小变大 n=7 从中心向四周画同心矩形,动画效果为矩形由小变大 如果你在n前使用了“-”,那动画的运动方向将和上面相反。 示例:<CR>代表回车 LOGOBAR mylogo.bmp<CR> 在mylogo.bmp的底部加上色条,预览,并保存为LOGO.SYS LOGOBAR mylogo.bmp /TO=C:\LOGO.SYS<CR>加色条后安装。 LOGOBAR cat.bmp /PO=MASK7<CR>, 在图cai.bmp中按蒙板区域做矩形渐大动画效果。 更多示例请运行DEMO.BAT。请注意DEMO.BMP和各参数与对应的效果。 下面是源代码: |
|
| 第2楼 TurboY | 发表于 2005-01-26 00:00 |
| 中级用户 发帖 99 积分 322 来自 湖北 | |
|
源代码 //源文件名: logobar.c
//作者: 易华卫 //编写日期: 2004年6月 //开发环境: DJGPP2+ALLEGRO3 //用途: 用一个图文件生成Windows9x启动动画LOGO文件 //命令行说明: // LOGOBAR 源图像 // 源图像 是一个您已经设计好的图像文件,格式可以是BMP,PCX,LBM,TGA,BTW, // 最好是Windows标准的BMP格式,图像的尺寸可以是320X400,色彩数 // 为256。也可是其他值,程序可以自动转换成320X400X256。 // 选项: // /TO=LOGO文件 将加了动画条的图像保存成LOGO文件,缺省值为LOGO.SYS。你可以使 // 用选项“/TO=C:\LOGO.SYS”来直接安装。 // /PO=BOTTON|TOP|LEFT|RIGHT|MASKn 添加动画条的位置,缺省值为:BOTTON // BOTTON 在图像下方添加动画条,类似Windows9x自带方式 // TOP 在图像上方添加动画条 // LEFT 在图像左侧添加动画条 // RIGHT 在图像右侧添加动画条 // MASKn 在图像中指定为蒙板区域按指定规则绘制动画条(见“高级选项”) // /BC=n 动画条使用的色彩数,缺省值为20 // /C1=色彩1 渐变色的起始色,以16进制表示RGB, 缺省值为 00FF00 (绿色) // /C2=色彩2 渐变色的结束色,以16进制表示RGB, 缺省值为 000000 (黑色) // /NP 不预览 /MT- 使用微软的另一种动画方式(不推荐) // 高级选项: // /PO=MASKn 在图像中指定为蒙板区域按指定规则绘制动画条,约定图像的左上角 // (0,0)像素点的颜色为蒙板色,图中所有以该色填充的区域构成蒙板区 // 域,在蒙板区域中根据n值有7种方式来绘制色条动画。 // n=1 从左向右画竖色条,动画效果为色条向右运动 // n=2 从上向下画横色条,动画效果为色条向下运动 // n=3 从左上向右下画//形色条,动画效果为色条向右下运动 // n=4 从右上向左下画\\形色条,动画效果为色条向左下运动 // n=5 从中心向四周画辐射色,动画效果如风车顺时针转动 // n=6 从中心向四周画同心椭圆,动画效果为椭圆由小变大 // n=7 从中心向四周画同心矩形,动画效果为矩形由小变大 // 如果你在n前使用了“-”,那动画的运动方向将和上面相反。 //详细说明见 logobar_cn.txt #include <stdio.h> #include <math.h> #include <stdlib.h> #include <ctype.h> #include "allegro.h" #define AT_BOTTON 0 #define AT_TOP 1 #define AT_LEFT 2 #define AT_RIGHT 3 #define AT_MASK 4 #define FILL_H 1 //Left - right #define FILL_V 2 //top - botton #define FILL_LTRB 3 //left_top - right_botton #define FILL_RTLB 4 //right_top - left_botton #define FILL_ROTATE 5 //rotate right/left #define FILL_CIRCLE 6 //Circle center to outer #define FILL_RECT 7 //Rectange #define FILL_END 7 //globe variable char srcfile="\0",tagfile="LOGO.SYS"; int barcolors=20; //motion logo used colors int motiontype=0; //MS's mode of pallete motion int position=AT_BOTTON; //Add bar here int fillmode=FILL_H; //Bar color filled mode int colordirect=0; //0=L-R/U-D/turn right, 1=R-L/D-U/turn left int maskcolor=0; RGB startcolor={0,255,0},endcolor={0,0,0}; int nopreview=0; char cmd_msg= "Yisir's WIN9x LOGO.SYS animate bar maker V1.0beta, 2004-6-25, Tianmen Hubei\n" "Usage: LOGOBAR srcfile \n" "\tsrcfile A image file(*.BMP,*.PCX,*.LBM,*.TGA)." "BTW, the Windows LOGO is 320*200 256 colors BMP file, but don't worry, " "I will convert it for you.\n" "Option:\n" "\t/TO=filename Save TO a bitmap file, default=LOGO.SYS.\n" "\t You can use /TO=C:\\LOGO.SYS to install it now.\n" "\t/PO=BOTTON|TOP|LEFT|RIGHT|MASKn position of colorbar, default:BOTTON\n" "\t/BC=n color number of bar\n" "\t/C1=color1 Gradient start color, default: 00FF00 (green)\n" "\t/C2=color2 Gradient end color, default: 000000 (black)\n" "\t/NP No preview /MT- use other Windows animate Type\n"; // "Press any key to see more options...\n"; char more_msg= "Advanced options:" "/PO=MASKn use the color of top-left point as mask, with 7 fill mode\n" "\tn=1 from left to right in mask area\n" "\tn=2 from top to botton in mask area\n" "\tn=3 from top-left to botton-right in mask area\n" "\tn=4 from top-right to botton-left in mask area\n" "\tn=5 windmill rotate in mask area\n" "\tn=6 circle from center to outer in mask area\n" "\tn=7 rectangle from center to outer in mask area\n" "\tIf you use \"-\" , it will be filled with the contrary direction.\n" "This is a freeware, welcome to visit my site http://yisir.9126.com to find more." "Thank you for testing it, and I wish you like it." ; char yisir_info= "made by Yisir's LOGOBAR, welcome to visit http://yisir.9126.com"; int htoi(char *hex); int adject_pallete(BITMAP *bmp, RGB *pal); int gen_barcolor(RGB *pal); int preview(BITMAP *bmp, RGB *bmppal); int makelogobar(void); int init_argv(int argc, char* argv); main(int argc, char* argv) { allegro_init(); install_keyboard(); if (!init_argv(argc,argv)) { printf("source file is %s, target file is: %s\n",srcfile,tagfile); makelogobar(); } allegro_exit(); return 0; } //convert hex string to integer int htoi(char *hex) { int v=0; char *p; for(p=hex;*p;p++) { if (*p>='0'&&*p<='9' ![]() { v*=16; v+=*p-'0'; } else if (*p>='A'&&*p<='F' ![]() { v*=16; v+=*p-'A'+10; } else break; } return v; } //将源图像中的实际用色移到调色板的前端 int adject_pallete(BITMAP *bmp, RGB *pal) { int i,colorcounter,ips,ipt,x,y; struct cpal_struct { int used; int newidx; } cpal; PALLETE tmp; //caculate color counter printf("Adject color pallete, please wait a while.\n" ;for (i=0;i<256;i++) { cpal.used=0; cpal.newidx=0; } for (i=0;i<bmp->h;i++) { int x; for (x=0;x<bmp->w;x++) { cpal].used++; } } for (i=0,colorcounter=0;i<256;i++) colorcounter+=(cpal.used?1:0); printf("Used color number: %d\nNow pallete is being sorted...",colorcounter); //Move maskcolor to the fisrt item in pallete if (position==AT_MASK) { maskcolor=bmp->line; bmp->line=bmp->line; cpal.newidx=0; cpal.used=0; maskcolor=0; } //the first color will be used to display background, so it is black. tmp.r=0; tmp.g=0; tmp.b=0; //adject, sort color, move used color to begin space. ips=0; ipt=1; while (ips<256) { if (cpal.used) { cpal.newidx=ipt; tmp=pal; ipt++; } ips++; } //write new color index in picture for (y=0;y<bmp->h;y++) { for (x=0;x<bmp->w;x++) { int t; t=bmp->line; bmp->line=cpal.newidx; } } //write picture pallete for (i=0;i<256;i++) pal=tmp; printf(" Finished.\n" ;return colorcounter; } //生成COLORBAR所用的渐变色 int gen_barcolor(RGB *pal) { //green int i; //single color has 6 bits. float dr,dg,db; dr=(0.0+endcolor.r-startcolor.r)/barcolors*2; dg=(0.0+endcolor.g-startcolor.g)/barcolors*2; db=(0.0+endcolor.b-startcolor.b)/barcolors*2; for (i=0;i<barcolors/2;i++) { pal.r=pal.r=(startcolor.r+dr*i)/4; pal.g=pal.g=(startcolor.g+dg*i)/4; pal.b=pal.b=(startcolor.b+db*i)/4; } return 0; } //preview logo animater int preview(BITMAP *bmp, RGB *bmppal) { PALLETE pal; int i; printf("\nPress any key to preview...\n" ;while (!keypressed()); readkey(); for (i=0;i<256;i++) pal=bmppal; set_color_depth(8); i=set_gfx_mode(GFX_MODEX,320,400,0,0); /* Checks if any error occured during screen mode initialization */ if ( i != 0 ) { printf("Error setting graphics mode\n%s\n\n", allegro_error); /* Shut down Allegro */ /*allegro_exit ();*/ return 1; } set_palette(pal); blit(bmp,screen,0,0,0,0,bmp->w,bmp->h); textout_centre(screen,font,"Press any key to end...",160,370,255-barcolors/2); while (!keypressed()) { RGB tmp; tmp=pal; for (i=256-barcolors;i<255;i++) pal=pal; pal=tmp; set_palette_range(pal,256-barcolors,255,1); delay(200); } set_gfx_mode(GFX_TEXT,640,480,0,0); return 0; } //主要程序 //在图像上加上色条并做成MS要求的格式 int makelogobar(void) { BITMAP *filebmp,*bmp; PALLETE pal; int i; FILE *fp; unsigned char *buf; //Load image from file. set_color_depth(8); set_color_conversion(COLORCONV_REDUCE_TO_256); filebmp=load_bitmap(srcfile,pal); if (!filebmp) { allegro_exit(); printf("Error loading %s!\n", srcfile); exit(1); } bmp=create_bitmap_ex(8,320,400); stretch_blit(filebmp, bmp, 0,0, filebmp->w,filebmp->h, 0,0, 320,400); destroy_bitmap(filebmp); //caculate color counter adject_pallete(bmp,pal); printf("StartColor:%02X%02X%02X, EndColor:%02X%02X%02X", startcolor.r,startcolor.g, startcolor.b, endcolor.r,endcolor.g,endcolor.b); printf("\nNow add color bar...\n" ;gen_barcolor(pal); switch(position) { BITMAP *mask_bmp; case AT_BOTTON: //Bar at bottom of screen for (i=0;i<barcolors;i++) { rectfill(bmp,bmp->w*i/barcolors,bmp->h-10, (i+1)*bmp->w/barcolors-1,bmp->h-1, colordirect?256-barcolors+i:255-i); } break; case AT_TOP: //Bar at top of screen for (i=0;i<barcolors;i++) { rectfill(bmp,i*bmp->w/barcolors,0, (i+1)*bmp->w/barcolors-1,9, colordirect?256-barcolors+i:255-i); } break; case AT_LEFT: //Bar at left of screen for (i=0;i<barcolors;i++) { rectfill(bmp, 0, i*bmp->h/barcolors,9, (i+1)*bmp->h/barcolors-1, colordirect?256-barcolors+i:255-i); } break; case AT_RIGHT: //Bar at left of screen for (i=0;i<barcolors;i++) { rectfill(bmp,bmp->w-10,i*bmp->h/barcolors, bmp->w-1,(i+1)*bmp->h/barcolors-1, colordirect?256-barcolors+i:255-i); } break; case AT_MASK: mask_bmp=create_bitmap_ex(8,320,400); //rectfill(mask_bmp,0,0,319,399,0); switch (fillmode) { int ix,iy; case FILL_H: for (i=0;i<barcolors;i++) { int c=colordirect?256-barcolors+i:255-i; rectfill(mask_bmp,mask_bmp->w*i/barcolors,0, (i+1)*mask_bmp->w/barcolors-1,mask_bmp-> h-1,c); } break; case FILL_V: for (i=0;i<barcolors;i++) { int c=colordirect?256-barcolors+i:255-i; rectfill(mask_bmp,0,mask_bmp->h*i/barcolors, mask_bmp->w-1,(i+1)*mask_bmp-> h/barcolors-1,c); } break; case FILL_LTRB: for (i=0;i<barcolors;i++) { int ii; int c=colordirect?256-barcolors+i:255-i; for (iy=i*(mask_bmp->h+mask_bmp->w)/barcolors;iy<(i+1)*(mask_bmp->h+mask_bmp-> w)/barcolors;iy++) { line(mask_bmp,0,iy,iy,0,c); } } break; case FILL_RTLB: for (i=0;i<barcolors;i++) { int c=colordirect?256-barcolors+i:255-i; int ii; for (iy=i*(mask_bmp->h+mask_bmp->w)/barcolors;iy<(i+1)*(mask_bmp->h+mask_bmp-> w)/barcolors;iy++) { line(mask_bmp,mask_bmp->w-iy,0,mask_bmp->w,iy,c); } } break; case FILL_ROTATE: { rectfill(mask_bmp,0,0,mask_bmp->w-1,mask_bmp->h-1,255); for (i=0;i<barcolors;i++) { int x1,y1,x2,y2; int c=colordirect?256-barcolors+i:255-i; x1=bmp->w/2+bmp->h/2*cos(i*2*PI/barcolors); y1=bmp->h/2+bmp->h*sin(i*2*PI/barcolors); x2=bmp->w/2+bmp->h/2*cos((i+1)*2*PI/barcolors); y2=bmp->h/2+bmp->h*sin((i+1)*2*PI/barcolors); triangle(mask_bmp,mask_bmp->w/2,mask_bmp->h/2,x1,y1,x2,y2,c); } } break; case FILL_CIRCLE: case FILL_RECT: { rectfill(mask_bmp,0,0,mask_bmp->w-1,mask_bmp->h-1,255); for (i=0;i<barcolors;i++) { int c=colordirect?255-i:256-barcolors+i; int r=sqrt(mask_bmp->w*mask_bmp->w+mask_bmp->h*mask_bmp-> h)/2*(barcolors-i)/barcolors; if (fillmode==FILL_CIRCLE) ellipsefill(mask_bmp,mask_bmp->w/2,mask_bmp->h/2,r,r,c); else if (fillmode==FILL_RECT) rectfill(mask_bmp,mask_bmp->w/2-r,mask_bmp->h/2-r,mask_bmp->w/2+r,mask_bmp->h/2+r, c); } } break; } //end switch(fillmode) draw_sprite(mask_bmp,bmp,0,0); destroy_bitmap(bmp); bmp=mask_bmp; break; } //preview if (!nopreview) preview(bmp,pal); //Save to new file: LOGO.SYS i=save_bmp(tagfile,bmp,pal); if (i) { destroy_bitmap(bmp); allegro_exit(); printf("Error write to %s\n",tagfile); exit(2); } //Modify used color index fp=fopen(tagfile,"rb" ;i=filelength(fileno(fp)); buf=(unsigned char*) malloc(i); fread(buf,1,i,fp); fclose(fp); buf=256-barcolors; buf=motiontype; fp=fopen(tagfile,"wb" ;fwrite(buf,1,i,fp); fwrite(yisir_info,1,strlen(yisir_info),fp); fclose(fp); free(buf); printf("Success write to %s\n",tagfile); destroy_bitmap(bmp); return 0; } //Read and do command options //处理命令行参数 int init_argv(int argc, char* argv) { if (argc==1) { printf("%s",cmd_msg); printf("%s",more_msg); return -1; } else { int i; for (i=1;i<argc;i++) { if (argv!='/' && argv!='-' ![]() { strcpy(srcfile,argv); }else { char para,*p; strcpy(para,argv); for (p=para;*p;p++) *p=toupper(*p); if (!strncmp(para+1,"TO=",3)) { strcpy(tagfile,argv+4); } else if (!strncmp(para+1,"PO=",3)) { if (!strcmp(para+4,"BOTTON" )position=AT_BOTTON; else if (!strcmp(para+4,"TOP" )position=AT_TOP; else if (!strcmp(para+4,"LEFT" )position=AT_LEFT; else if (!strcmp(para+4,"RIGHT" )position=AT_RIGHT; else if (!strncmp(para+4,"MASK",4)) { position=AT_MASK; colordirect=(para=='-'?1:0); fillmode=abs(atoi(para+8)); if (fillmode<=0 || fillmode>FILL_END) fillmode=FILL_H; } } else if (!strncmp(para+1,"BC=",3)) { barcolors=atoi(para+4); } else if (!strncmp(para+1,"MT-",3)) { motiontype=1; } else if (!strncmp(para+1,"C1=",3)) { int c=htoi(para+4); startcolor.r = c>>16 & 0xff; startcolor.g = c>>8 & 0xff; startcolor.b = c & 0xff; } else if (!strncmp(para+1,"C2=",3)) { int c=htoi(para+4); endcolor.r = c>>16 & 0xff; endcolor.g = c>>8 & 0xff; endcolor.b = c & 0xff; } else if (!strncmp(para+1,"NP",2)) { nopreview=1; } } } if (srcfile==0) { printf("Need srcfile! Run again without any option to display the usage.\n" ;return -1; } return 0; } //end if(argc==1) return 0; } |
|
| 第3楼 JonePeng | 发表于 2005-01-26 00:00 |
| 金牌会员 发帖 1,883 积分 4,562 来自 广东广州 | |
|
支持原创!我当年读高中的时候也研究过VGA13H以及256色的SVGA编程。
|
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |