Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C: PCX-tiedoston lataus ja piirto

sqwiik [28.11.2003 18:13:21]

#

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);

KimmoKM [28.11.2003 22:09:52]

#

Hyvältä näyttää. En tosin kokeillut (yritin kylläkin, linuxissa).

juoppo [01.03.2005 18:40:21]

#

Valittaa että (kaikista muuttujista) Uncleared function. Pitäskö tuosta esitellä kaikki muuttujat. (Ohjelma = Dev-C++)

sqwiik [17.09.2006 23:56:32]

#

Tämä koodi ei valitettavasti toimi kuin DOS-pohjaisissa ohjelmissa, sillä se perustuu näyttömuistin tökkimiseen.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta