标题:1024*768*256色 TC3.0 显示PCX图片
只看楼主
pfqwsqqq
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2011-9-11
结帖率:100%
已结贴  问题点数:20 回复次数:2 
1024*768*256色 TC3.0 显示PCX图片
各位过路的好心大神们,在下在做课设。遇到了这么一个难题。在页面中,我每插入一张图片,就修改一次调色板寄存器的值。插入一张PCX图片没有问题,但是多张图片就会让前面的图片变花。如果只改一次图片的调色板,那么后面的就花。。。这个怎么解决
#include<io.h>
#include<stdio.h>
#include<dos.h>
#include<string.h>
#include<math.h>
#include<stdio.h>
#include<bios.h>
#include<mem.h>
#include<fcntl.h>
#include<stdlib.h>
#include<conio.h>


#define    VGA256 0x105
#define TEXT_MODE 0x03
#define    PALETTE_MASK    0x3c6
#define    PALETTE_REGISTER_RD    0x3c7
#define    PALETTE_REGISTER_WR    0x3c8
#define    PALETTE_DATA    0x3c9

unsigned char far *video_buffer=(char far *)0xA0000000L; //将指针变量 video_buffer指向显存起始地址
float sin_look[361];
float cos_look[361];
unsigned char far *rom_char_set=(char far *)0xF000FA6EL;

typedef struct pcx_header_typ
{
    char manufacturer;
    char version;
    char encoding;
    char bits_per_pixel;
    int x,y;
    int width,height;
    int horz_res;
    int vert_res;
    char ega_palette[48];
    char reserved;
    char num_color_planes;
    int bytes_per_line;
    int palette_type;
    char padding[58];
} pcx_header, *pcx_header_ptr;

typedef    struct    RGB_color_typ
{
    unsigned    char    red;
    unsigned    char    green;
    unsigned    char    blue;
}RGB_color,*RGB_color_ptr;

typedef struct pcx_picture_typ
{
    pcx_header header;
    RGB_color palette[256];
    char far *buffer;
} pcx_picture, *pcx_picture_ptr;

void selectpage(int y)
{   
    asm{
        mov    AX, 4F05h
        mov    BX, 0
        mov    DX, y    //进行BIOS视频显示方式功能调用
        int    10h
    }
}

/* 设置显示模式函数 */
void Set_Video_Mode(int mode)   
{
    union REGS regs;            //定义输出和返回寄存器
    regs.x.ax=0x4f02;            //ax存放功能号  0h表示进入视频模式设定
    regs.x.bx=mode;                //bx存放要设定的视频模式
    int86(0x10,&regs,&regs);    //通过10h 中断设定显示模式
}

/* 直接画点函数 */
void Plot_Pixel_Fast(int x,int y,char color)   
{
    selectpage(y>>6);
    video_buffer[((y)<<10)+x]=color;    //(y*1024+x)向偏移的指针变量地址写入字节数据color
}

/* 获取点颜色 函数 */
int GetPixel(int x,int y)
{
    int color;
    selectpage(y>>6);
    color=video_buffer[(y<<10)+x];    //点的颜色等于屏幕点对应显存位置的数据
    return (color);
}

void Get_Palette_Register(int index,RGB_color_ptr color)
{
    outp(PALETTE_MASK,0xff);
    outp(PALETTE_REGISTER_RD,index);
    color->red=inp(PALETTE_DATA);
    color->green=inp(PALETTE_DATA);
    color->blue=inp(PALETTE_DATA);
}

void Set_Palette_Register(int index,RGB_color_ptr color)
{
    outp(PALETTE_MASK,0xff);
    outp(PALETTE_REGISTER_WR,index);
    outp(PALETTE_DATA,color->red);
    outp(PALETTE_DATA,color->green);
    outp(PALETTE_DATA,color->blue);
}

/*插入图片功能*/
void PCX_Load_Screen(unsigned    long    x0_pcx,unsigned    long    y0_pcx,
                     unsigned    long    x1_pcx,unsigned    long    y1_pcx,
                     int x_scn,int y_scn,
                     pcx_picture_ptr image,
                     char *filename,int *enable_palette)
{
    static    k=1;
    FILE *fp;
    int num_bytes,index;
    long count;
    int x=0;
    unsigned char data;
    char far *temp_buffer;
   
    // open the file   
    if((fp = fopen(filename,"rb"))==NULL)
    {
        fprintf(stderr,"Cannot open input file.\n");
        getch();
        exit(1);
    }
   
   
    // move to end of file then back up 768 bytes i.e. to begining of palette
    fseek(fp,-768L,SEEK_END);

    // load the pallete into the palette
    for (index=0; index<256; index++)
    {
        // get the red component
        image->palette[index].red   = (fgetc(fp) >> 2);

        // get the green component
        image->palette[index].green= (fgetc(fp) >> 2);

        // get the blue component
        image->palette[index].blue  = (fgetc(fp) >> 2);

    }    // end for index


    // change the palette to newly loaded palette if commanded to do so
    if (*enable_palette)
    {
        for (index=0; index<256; index++)
        {
            Set_Palette_Register(index,(RGB_color_ptr)&image->palette[index]);
        } // end for index
        *enable_palette=0;
    } // end if change palette
   
    fseek(fp,128L,SEEK_SET);
    count=0;
    selectpage(y_scn>>6);
    // load the data and decompress into buffer
    while(count<=(x1_pcx-x0_pcx) * (y1_pcx-y0_pcx))
    {
         // get the first piece of data
         data = fgetc(fp);
         
         // is this a rle?
         if (((int)data>=192) &&((int)data<=255))
        {
            num_bytes = data-192;    //读取重复次数
            data  = fgetc(fp);        //读出下一个字节,即颜色
            while(num_bytes-->0)
            {
                if(x>((x1_pcx-x0_pcx)-1))
                {
                    x-=x1_pcx-x0_pcx;
                    x_scn-=x1_pcx-x0_pcx;
                    y_scn+=1;
                    selectpage(y_scn>>6);
                }
               
                video_buffer[(y_scn<<10)+x_scn]=data;
               
                x_scn++;
                x++;
                count++;
               
            }   // end while

        }    // end if rle
        else
        {            
            if(x>((x1_pcx-x0_pcx)-1))
            {
                x-=x1_pcx-x0_pcx;
                x_scn-=x1_pcx-x0_pcx;
                y_scn+=1;
                selectpage(y_scn>>6);
            }
               
            video_buffer[(y_scn<<10)+x_scn]=data;
               
            x_scn++;
            x++;
            count++;
            
        }    // end else not rle

        
    }    // end while   
    fclose(fp);
}

void main(void)
{
    char    i;
    int    enable_palette=1;
    char *pcx="C://TC30//BIN//graphic//jietu0.pcx";
    pcx_picture    objects_pcx;
    Set_Video_Mode(VGA256);

    PCX_Load_Screen(0,0,300,350,0,0,(pcx_picture_ptr)&objects_pcx,pcx,&enable_palette);
    pcx="C://TC30//BIN//graphic//jietu1.pcx";
    PCX_Load_Screen(0,0,300,350,400,250,(pcx_picture_ptr)&objects_pcx,pcx,&enable_palette);
   

    getch();
//    Set_Video_Mode(TEXT_MODE);

}
10万火急,拜托各位了   
搜索更多相关主题的帖子: 调色板 include 图片 寄存器 
2011-10-09 18:09
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
得分:20 
如果你的显卡支持1024*768*16PP高彩色,或是800*600*16位高彩色,可以使用此模式显示不同的位图,不过你的直接写屏和色彩点函数代码都要改变,否则只有通过色彩表近似算法,使用一张公用的色彩表,将图片中实际颜色数与公用色彩表进行对应变换,可以得到一个和原图近似的图片效果。

我们都在路上。。。。。
2011-10-10 12:43
pfqwsqqq
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2011-9-11
得分:0 
但是课设就快到时间了,对了,共用色彩表怎么做?我能不能通过PS将图片的调色板全部统一?请尽快回复,谢谢了
2011-10-10 16:00



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-351906-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.248338 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved