Väsäsin nopean grafiikankäsittelysysteemin Erkki Saaressa-peliini, ja ajttelin sitten vielä laittaa sen tänne. Se kun kerran toimii, optimoitu 320x200x256-moodille.
Pienenä haittana pcx-lataajassa on että se toimii moitteetta vain jos kuvan leveys on 4:n monikerta...
#include <stdlib.h> /* muistinvarausta varten */ #include <stdio.h> /* I/O-funktiot */ /* Jos borlandc, käytä seuraavaa: */ unsigned char far *ruutu=(char*far)0xa0000000; #define putpixel(x, y, c) ruutu[(y)*320+(x)]=c /* Jos djgpp, käytä seuraavaa */ #include <go32.h> #define putpixel(x, y, c) _farpokeb( _dos_ds, 0xA0000+(y)*320+(x), c) /* Itse rakenne */ typedef struct BITMAP{ unsigned char *bitmap; /* data */ int w, h; /* koko */ }BITMAP; /* Tähän liittyvät funktiot */ /* Lataa pcx-muotoisen kuvan Kiitos vilikille pcx-latausmetodista qbasicille, käänsin sen tässä c:lle. Virheen sattuessa lopettaa ohjelman juoksun. */ BITMAP load_pcx(char * filu){ int xsize, ysize, tavu1, tavu2, position=0, lisa, x; BITMAP kuva; FILE *handle=fopen(filu, "rb"); if(handle==NULL) { printf("Virhe PCX-tiedoston avauksessa: Tiedostoa %s ei löydy!\n", filu); exit(1); } fseek(handle, 8, SEEK_SET); xsize=fgetc(handle)+(fgetc(handle)<<8)+1; ysize=fgetc(handle)+(fgetc(handle)<<8)+1; switch(xsize % 4){ case 0: lisa = 0; break; case 1: lisa = 3; break; case 2: lisa = 2; break; case 3: lisa = 1; break; }; xsize+=lisa; kuva.bitmap = (char*)malloc(xsize*ysize); kuva.w = xsize; kuva.h = ysize; if(kuva.bitmap == NULL){cprintf("Error: ei muistia");exit(1);} fseek(handle, 128, SEEK_SET); while(position<xsize*ysize){ tavu1=fgetc(handle); if(tavu1>192) { tavu2=fgetc(handle); for(; tavu1>192; tavu1--) kuva.bitmap[position++]=tavu2; } else kuva.bitmap[position++]=tavu1; } fclose(handle); return kuva; } /* Lataa paletin pcx-tiedostosta */ void loadpal(char *filu) { FILE *handle=fopen(filu, "rb"); int c; if(handle==NULL) { printf("Virhe PCX-tiedoston palettia luettaessa:" " Tiedostoa ei löydy!\n"); exit(1); } fseek(handle,-768,SEEK_END); /* väritieto alkaa */ outportb(0x3C8, 0); for(c=0; c<256*3; c++) outportb(0x3C9, fgetc(handle)/4); fclose(handle); } /* vapauttaa muistin */ void free_bitmap(BITMAP *b){ free(b->bitmap); } /* Kaikkein kaunein... piirtofunktiot */ /* piirtää bittikartan kohtaan x,y */ void draw_bitmap(BITMAP b, int x, int y){ int x2, y2, c=0; for(y2=0;y2< b.h; y2++) for(x2=0;x2< b.w; x2++,c++) putpixel(x2+x, y2+y, b.bitmap[c]); } /* piirtää b:n käyttäen t:tä taustana. Kuvien täytyy olla samankokoisia! */ void double_draw_bitmap(BITMAP b, BITMAP t, int x, int y){ int x2, y2, c=0; for(y2=0;y2< b.h; y2++) for(x2=0;x2< b.w; x2++,c++) if(b.bitmap[c])putpixel(x2+x, y2+y, b.bitmap[c]); else putpixel(x2+x, y2+y, t.bitmap[c]); }
/* Näin sitä käytellään */ textmode(0x13); BITMAP kuva; BITMAP tausta; kuva = load_pcx("hahmo.pcx"); tausta = load_pcx("tausta.pcx"); draw_bitmap(kuva, 10, 10); /* piirtää kuvan ruudulle kohtaan(10,10) */ /* Piirtää kuvan taustakuvan kanssa, eli kaikki kuvan mustat pisteet korvataan taustakuvan pisteillä piirrettäessä. */ double_draw_bitmap(kuva, tausta, 20, 10); free_bitmap(&kuva); free_bitmap(&tausta);
Hyvältä näyttää. En tosin kokeillut (yritin kylläkin, linuxissa).
Valittaa että (kaikista muuttujista) Uncleared function. Pitäskö tuosta esitellä kaikki muuttujat. (Ohjelma = Dev-C++)
Tämä koodi ei valitettavasti toimi kuin DOS-pohjaisissa ohjelmissa, sillä se perustuu näyttömuistin tökkimiseen.
Aihe on jo aika vanha, joten et voi enää vastata siihen.