From: "Alex Barsamian" Newsgroups: comp.os.msdos.djgpp Subject: Yet another graphics problem... Date: Sun, 5 Oct 1997 01:28:48 -0600 Organization: Biohazard Software Lines: 342 Message-ID: <617g3k$ipr@bgtnsc03.worldnet.att.net> NNTP-Posting-Host: 12.65.147.223 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk I started out tonite porting my crusty mode 13h real mode graphics code out to djgpp. I can init the graphics mode okay, even write to the screen without too much trouble. Now for some reason when I began to implement the double buffer routines into the new source file, I compile without any trouble, but about 1/4 of the time, when I should be seeing a PCX image, I see a blank screen (in graphics mode), and the rest of the time I get a lovely page fault. The source code from tonite's work follows. It's just a series of simple, non-portable (yet!) functions to muck around in graphics, yet I am confounded as to why it is not working as it should. Any suggestions? (besides getting Allegro, which I do have, and think is wonderful, but I just want to write this code by myself for the most part, for the experience benefit :-) I think we can all understand that, huh?) Thanks in advance. Please email as well as post, I may not be able to read the newsgroups for a bit and I'd hate to muck thru bluesnews to find the responses :-) ) regards, alex djvbepcx.c follows (the source is also attached in case the horribleness that is IE4 screws up the formatting): #include #include #include #include int c, width, height, bytes_per_line, i; char ch; unsigned char *videoptr = (unsigned char *)0xA0000; unsigned char pallete[768]; unsigned char *buffer; // switch vesa banks using int10 void VBE_SwitchBank(short bank) { __asm__ __volatile__(" movw $0x4F05, %%ax; xorw %%bx, %%bx; int $0x10" : : "d" (bank) : "ax", "bx", "dx" ); } // set a vbe mode void VBE_SetMode(unsigned short mode) { __dpmi_regs regs; regs.x.ax = 0x4F02; regs.x.bx = mode; __dpmi_int(0x10, ®s); } // goto textmode void VBE_Shutdown() { VBE_SetMode(0x0003); // set to text mode } // Blit a buffer (unsigned char *) onscreen, switching // banks no more than absolutely neccesary. // this assumes the vbe 1.2 are present and functioning correctly, that is // to say, all banks look like they are 64k whether they physically are or // not void copy_buffer() char *source; char *dest; source=buffer; dest = videoptr + __djgpp_conventional_base; __djgpp_nearptr_enable(); /* 640*480*8bpp = 307200 bytes = 4*64K + 45056 bytes */ VBE_SwitchBank(0); // start at bank 0 memcpy(dest, source, 65536L); // copy 64k VBE_SwitchBank(1); // switch to bank 1 source += 65536L; // copy 64k memcpy(dest, source, 65536L); // rinse, lather, repeat . . . . VBE_SwitchBank(2); source += 65536L; memcpy(dest, source, 65536L); VBE_SwitchBank(3); source += 65536L; memcpy(dest, source, 65536L); VBE_SwitchBank(4); source += 65536L; memcpy(dest, source, 45056L); // only 45056 because 640*480!=65536*5 __djgpp_nearptr_disable(); } // get a pcx, skipping most unnecessary stuff that can be assumed // e.g., size (for now 640x480 pcx's are all i'll use, 8 bpp, etc. // I know this is far from portable but this is just to get this thing // rolling unsigned char *load_pcx(char *filename) { FILE *f; // file handle int count, c; // loop vars unsigned char data; // current data int num_bytes; // number of bytes in RLE run unsigned char *b; // buffer f = fopen(filename, "r"); if (!f) { printf("file not found\n"); return NULL; } getc(f); /* skip manufacturer ID */ getc(f); /* skip version flag */ getc(f); /* skip encoding flag */ getc(f); width = -(getw(f)); /* xmin */ height = -(getw(f)); /* ymin */ width += getw(f) + 1; /* xmax */ height += getw(f) + 1; /* ymax */ b = malloc(width*height); // malloc an appropriate buffer getc(f); /* skip DPI values */ for (c=0; c<16; c++) { /* skip the 16 color pallete */ getc(f); /* originally intended on using it */ getc(f); /* (for some reason . . . ) */ getc(f); /* which is why it looks like this */ } getc(f); // skip junk getc(f); bytes_per_line = getw(f); // just in case i start to use double- // scripted buffers for (c=0; c<60; c++) /* skip some more junk */ getc(f); count=0; while(count<=(width*height)) { // grab first piece of RLE data data=getc(f); // is it RLE? if((data>=192) && (data<=255)) { // if it is, how long is the run? num_bytes=data-192; // now that we know how long it is, grab the data // for the actual run. data=getc(f); // plug (data) into the buffer (num_bytes) times while(num_bytes-->0) b[count++]=data; } // end if RLE // not RLE? else // plug it in to the buffer b[count++]=data; } while (!feof(f)) { /* look for a 256 color pallete */ if (getc(f)==12) { for (c=0; c<256; c++) { pallete[c] = getc(f) / 4; // load it in pallete[c*2] = getc(f) / 4; pallete[c*3] = getc(f) / 4; } break; } } fclose(f); return b; } void VBE_Pal(unsigned char ColorNo, unsigned char R, unsigned char G, unsigned char B) { outp (0x03C8,ColorNo); // here is the pallette color I want to set outp (0x03C9,R); // set r, outp (0x03C9,G); // g, outp (0x03C9,B); // and b compo appropriately } void main() VBE_SetMode(0x101); // fire up graphics to 0x101 buffer=load_pcx("picture.pcx"); if(*buffer==NULL) { // do we have our picture? VBE_Shutdown(); printf("error loading pcx"); exit(0); } for(i=0; i<256; ++i) // set the pallete appropriately VBE_Pal(i, pallete[i], pallete[i*2], pallete[i*3]); copy_buffer(); // put the buffer onscreen getch(); VBE_Shutdown(); } begin 666 djvesa.c M(VEN8VQU9&4@/'-T9&EO+F@^#0HC:6YC;'5D92 \71E#L-"@D)>&]R=R E)6)X+" E)6)X.PT*"0EI;G0@)#!X,3 B#0H)"3H@ M.B B9"(@*&)A;FLI(#H@(F%X(BP@(F)X(BP@(F1X(@T*"2D[#0I]#0H-"B\O M('-E="!A('9B92!M;V1E#0H-"G9O:60 AT 5D)%7U-E=$UO9&4H=6YS:6=N960@ MPT*"5]?9'!M:5]R96=S(')E9W,[#0H)"YB>" ](&UO9&4[#0H)7U]D<&UI7VEN="@P M>#$P+" F2P AT 86QL(&)A;FMS(&QO;VL@ M;&EK92!T:&5Y(&%R92 V-&L@=VAE=&AE7-I8V%L;'D AT 87)E M(&]R#0HO+R!N;W0-"@T*=F]I9"!C;W!Y7V)U9F9E2AD97-T+"!S;W5R8V4L(#8U-3,V3"D[(" @+R\@8V]P M>2 V-&L@(" @(" @(" @(" @(" @(" @(" @#0H@(" @(" @(%9"15]3=VET M8VA"86YK*#$I.R @(" @(" @(" @(" @+R\@2AD97-T+"!S;W5R8V4L(#8U-3,V3"D[(" @(" -"@E60D5?4W=I=&-H M0F%N:R AT T*3L-"B @(" @(" @F4@*&9O#0X,"!P8W AT G"AC:&%R("IF:6QE;F%M92D-"GL-"B @(" @ M(" @1DE,12 J9CL@(" @(" @(" @(" @(" @(" @(" @(" O+R!F:6QE(&AA M;F1L90T*(" @(" @("!I;G0 AT 8V]U;G0L(&,[(" @(" @(" @(" @(" @(" @ M("\O(&QO;W @=F%R71EPT*(" @(" @(" @(" @(" @ M('!R:6YT9B AT B9FEL92!N;W0 AT 9F]U;F1<;B(I.PT*"0ER971U&UI;B J+PT*(" @(" @("!H96EG:'0@ M/2 M*&=E='6UA>" J+PT*#0H@(" @(" @ M(&(@/2!M86QL;V,H=VED=&@J:&5I9VAT*3L@("\O(&UA;&QO8R!A;B!A<'!R M;W!R:6%T92!B=69F97(-"@T*(" @(" @("!G971C*&8I.R @(" @(" @(" @ M(" @(" @(" O*B!S:VEP($1022!V86QU97,@*B\-"@T*(" @(" @("!F;W(@ M*&,],#L AT 8SPQ-CL@8RLK*2![(" @(" @(" @(" O*B!S:VEP('1H92 Q-B!C M;VQO71EPT*"0D) M+R\@:68@:70@:7,L(&AO=R!L;VYG(&ES('1H92!R=6X_#0H)"0EN=6U?8GET M97,]9&%T82TQ.3([#0H)"0DO+R!N;W<@=&AA="!W92!K;F]W(&AO=R!L;VYG M(&ET(&ES+"!GR @(" @(" @(" O*B!L;V]K M(&9OPT*"0EF;W(@*&,],#L AT 8SPR-38[(&,K*RD@>PT*(" @(" @(" @(" @ M(" @(" @(" @(" @<&%L;&5T95MC72 @(#T AT 9V5T8RAF*2 O(#0[("\O(&QO M860@:70@:6X-"@D)"7!A;&QE=&5;8RHR72 ](&=E=&,H9BD@+R T.PT*"0D) M<&%L;&5T95MC*C-=(#T AT 9V5T8RAF*2 O(#0[#0H)"2!]#0H)8G)E86L[#0H) M?0T*?0T*#0H)9F-L;W-E*&8I.PT*(" @(" @("!R971UPT*#0H);W5T<" H,'@P,T,X+$-O;&]R3F\I.R O+R!H M97)E(&ES('1H92!P86QL971T92!C;VQO"@B<&EC='5R92YP8W AT B*3L-"B @(" @(" @:68H*F)U9F9ER @(" @(" @(" @(" O+R!D;R!W92!H879E(&]U&ET*# I.PT*(" @(" @(" @(" @(" @('T-"@T*(" @(" @("!F;W(H M:3TP.R!I/#(U-CL@*RMI*2 @(" @(" @(" @("\O('-E="!T:&4@<&%L;&5T M92!A<'!R;W!R:6%T96QY#0H@(" @(" @(" @(" @(%9"15]086PH:2P@<&%L M;&5T95MI72P@<&%L;&5T95MI*C)=+"!P86QL971E6VDJ,UTI.PT*#0H@(" @ M(" @(&-O<'E?8G5F9F5R*"D[(" @(" @(" @(" @(" @(" @+R\@<'5T('1H M92!B=69F97(@;VYS8W)E96X-"B @(" @(" @9V5T8V AT H*3L@(" @(" @(" @ L(" @(" @(" @(" @(" -"B @(" @(" @5D)%7U-H=71D;W=N*"D[#0I]#0H` ` end