Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Листинг 17.6. Демонстрационная программа мозаичного смещающегося слоя (TILES.C)





#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <dos.h>

#include "paral.h"

#include "tiles.h"

char *MemBuf,

*BackGroundBmp,

*ForeGroundBnip,

*VideoRam;

PcxFile pcx;

int volatile KeyScan;

int frames=0,

PrevMode;

int background,

foreground, position;

char *tiles[NUM_TILES+l];

int tilemap[TILES_TOTAL];

void interrupt (*OldInt9)(void);

//

//

int ReadPcxFile(char *filename,PcxFile *pcx)

{

long i;

int mode=NORMAL,nbytes;

char abyte,*p;

FILE *f;

f=fopen(filename,"rb");

if(f==NULL)

return PCX_NOFILE;

fread(&pcx->hdr,sizeof(PcxHeader),l,f);

pcx->width=1+pcx->hdr.xmax-pcx->hdr.xmin;

pcx->height=1+pcx->hdr.ymax-pcx->hdr.ymin;

pcx->imagebytes= (unsigned int) (pcx->width*pcx->height);

if(pcx->imagebytes > PCX_MAX_SIZE)

return PCX_TOOBIG;

pcx->bitmap= (char*)malloc(pcx->imagebytes);

if(pcx->bitmap == NULL)

return PCX_NOMEM;

p=pcx->bitmap;

for(i=0;i<pcx->imagebytes;i++)

{

if(mode == NORMAL)

{

abyte=fgetc(f);

if((unsigned char)abyte > Oxbf)

{ nbytes=abyte & 0x3f;

abyte=fgetc(f);

if(-—nbytes > 0) mode=RLE;

}

}

else if(--nbytes ==0)

mode=NORMAL;

*p++=abyte;

}

fseek(f,-768L,SEEK_END);

fread(pcx->pal,768,1, f);

p=pcx->pal;

for(i=0;i<768;i++) *p++=*p>>2;

fclose(f);

return PCX_OK;

}

//

void _interrupt NewInt9(void) {

register char x;

KeyScan=inp(Ox60);

x=inp(0х61);

outp(0x61,(x|0x80));

outp(0x61,x);

outp(0х20,0х20);

if(KeyScan == RIGHT__ARROW__REL ||

KeyScan == LEFT__ARROW_REL)

KeyScan=0;

}

//

void RestoreKeyboard(void) {

_dos_setvect(KEYBOARD,OldInt9);

}

//

void InitKeyboard(void)

{

Oldlnt9=_dos_getvect(KEYBOARD);

_dos_setvect(KEYBOARD,Newlnt9);

}

//

void SetAllRgbPalettefchar *pal)

{

struct SREGS s;

union REGS r;

segread(&s);

s.es=FP_SEG((void far*)pal);

r.x.dx=FP_OFF((void far*)pal);

r.x.ax=0xl012;

r.x.bx=0;

r.x.cx=256;

int86x(0xl0,&r,&r,&s);

}

//

void InitVideo()

{

union REGS r;

r.h.ah=0x0f;

int86(0xl0,&r,&r); PrevMode=r.h.al;

r.x.ax=0xl3;

int86(0xl0,&r,&r);

VideoRam=MK_FP(0xa000,0);

}

//

void RestoreVideo()

{

union REGS r;

r.x.ax=PrevMode;

int86(0xl0,&r,&r);

}

//

int InitBitmaps()

{

int r;

background=foreground=l;

r=ReadPcxFile("backgrnd.pcx",&pcx);

if(r!= PCX_OK) return FALSE;

BackGroundBnip=pcx.bitmap;

SetAllRgbPalette(pcx.pal);,

r=ReadPcxFile("foregrnd.pcx",&pcx);

if(r!= PCX_OK) return FALSE;

ForeGroundBmp=pcx.bitmap;

MemBuf=malloc(MEMBLK);

if(MemBuf == NULL) return FALSE;

memset(MemBuf,0, MEMBLK);

return TRUE;

) //

void FreeMem()

{

free(MemBuf);

free(BackGroundBmp);

free(ForeGroundBmp);

FreeTiles(};

}

//

void DrawLayers()

{ OpaqueBlt(BackGroundBmp,0,100,background);

TransparentBIt(ForeGroundBmp,50,100,foreground);

DrawTiles(position,54);

}

//

void AnimLoop() {

while(KeyScan!= ESC_PRESSED)

{

switch(KeyScan)

{ case RIGHT_ARROW_PRESSED:

position+=4;

if(position > TOTAL_SCROLL) {

position=TOTAL_SCROLL;

break;

}

background-=1;

if(background < 1)

background+=VIEW_WIDTH;

foreground-=2; if(foreground < 1)

foreground+=VIEW_WIDTH;

break;

case LEFT_ARROW_PRESSED:

position-=4;

if(position < 0) {

position=0;

break;

}

background+=1;

if(background > VIEW_WIDTH-1) background-=VIEW_WIDTH;

foreground+=2;

if (foreground > VIEW_WIDTH-1) foreground-=VIEW_WIDTH;

break;

default:

break;

} DrawLayers();

memcpy(VideoRam,MemBuf,MEMBLK);

frames++;

} }

//

void Initialize()

{

position=0;

InitVideo(};

InitKeyboard();

if(!InitBitmaps())

{

Cleanup();

printf("\nError loading bitmaps\n");

exit(l);

} ReadTileMap("tilemap.dat");

ReadTiles();

}

// void Cleanup() {

RestoreVideo();

RestoreKeyboard();

FreeMem();

}

void ReadTiles(void)

{

PcxFile pcx;

char buf[80];

int i,result;

tiles[0]=NULL;

for(i=l;i<=NUM_TILES;i++)

{

sprintf(buf,"t%d.pcx",i);

result=ReadPcxFile(buf,&pcx);

if(result!= PCX_OK) (printf("\nerror reading file: %s\n",buf);

exit(1);

} tiles[i]=pcx.bitmap;

} }

void FreeTiles() { int i;

for(i=0;i<NUM_TILES;i++) free(tiles[i]);

}

void ReadTileMap(char *filename)

{

int i;

FILE *f;

f=fopen(filename,"rt");

for (i=0; i<TILES__TOTAL; i-H-) {

fscanf(f,"%d",&(tilemap[i]));

}

fclose(f);

}

//

void DrawTile(char *bmp,int x,int y,int offset, int width)

{

char *dest;

int i;

if(bmp == NULL) return;

dest=MemBuf+y*VIEW_WIDTH+x;

bmp+=offset;

for(i=0;i<TILE_HEIGHT;i++) {

memcpy(dest,bmp,width);

dest+=VIEW_WIDTH;

bmp+=TILE_WIDTH;

} }

//

void DrawTiles(int VirtualX,int Starty)

{

int i,x,index,offset,row,limit;

index=VirtualX>>SHIFT;

offset=VirtualX - (index<<SHIFT);

limit=TILES_PER_ROW;

if(offset==0)

limit--;

for(row=Starty;row<Starty+TILE_HEIGHT*TILE_ROWS;

row+=TILE_HEIGHT) {

x=TILE_WIDTH-of£set;

DrawTile(tiles[tilemap[index]],0,row,offset,

TILE_WIDTH-offset);

for(i=index+l;i<index+limit;i++)

{

DrawTile(tiles [tilemap [i]], x, row, 0, TILE_WIDTH);

x+=TILE_WIDTH;

} DrawTile(tiles [tilemap[i] ],x, row, 0,offset);

index+=TILE_COLS;

}

}

//

int main() { clock_t begin,fini;

Initialize();

begin=clock();

AnimLoop();

fini=clock();

Cleanup();

printf("Frames: %d\nfps: %f\n",frames,

(float)CLK_TCK*frames/(fini-begin));

return 0;

)

Устранение эффекта сдвига кадра

На медленных машинах или на машинах с медленными видеокартами можно заметить некий сдвиг изображения, как будто оно копируется на экран. Из-за эффекта сдвига изображение выглядит как бы разорванным. Этот интересный но нежелательный эффект появляется оттого, что адаптер сканирует видеобуфер и рисует изображение на дисплее примерно 60 раз в секунду. Этот процесс называется регенерацией экрана. Если программа в момент начала регенерации дисплея находится в процессе рисования кадра, вы заметите эффект сдвига изображения.

К счастью, существуют методы проверки статуса регенерации экрана. На VGA-карте есть регистр, сообщающий, регенерируется ли экран в настоящее время- Все, что требуется для устранения эффекта сдвига кадра, это подождать, пока регенерация экрана завершится. Затем можно начать рисовать изображение.

В Листинге 17.7 содержится фрагмент программы, ожидающей завершения цикла регенерации экрана. Это дает вам примерно 1/60 секунды, чтобы нарисовать следующий кадр. Данный фрагмент можно поместить непосредственно перед функцией, перемещающей кадр из системной памяти в видеобуфер. Выполняйте такую проверку каждый раз перед копированием буфера на экран. Только на очень быстрых машинах или при использовании небольшого окна вывода, одной шестидесятой секунды будет достаточно для изображения нескольких планов и их копирования на экран. Это главный недостаток режима 13h. Единственная альтернатива проверке на регенерацию экрана — это использование видеорежимов, поддерживающих несколько видеостраниц, и переключение между ними.

Date: 2015-09-18; view: 339; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.007 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию