From: "A.Appleyard" To: DJGPP AT DELORIE DOT COM Date: Mon, 18 Mar 1996 15:26:22 GMT Subject: Finding what graphic modes there are Message-ID: <617A6926E0@fs2.mt.umist.ac.uk> As a way got djgpp graphics to find what DOS or VESA screen mode corresponds with what djgpp screen mode without needing all those graphics drivers, I wrote the following. I haven't tested it yet, but it should serve as a start. #include #include #include #include #include /*-----*/ #define pk __attribute__((packed)) #define uns unsigned typedef uns char byte; #define Regs _go32_dpmi_registers Regs R; #define Int int86dpmi /*-----*//* Simulate a software interrupt from protected mode */ /* With thanks to Eli Zaretski for this function */ int int86dpmi(int intno) {REGS r,s; Regs S; S=R; S.x.ss=S.x.sp=0; /* DPMI server is to provide stack for interrupt call */ S.x.flags=0; /* he likeliest forgot to zero the flags */ r.h.bl=intno; r.h.bh=0; r.x.cx=0; r.x.di=(int)&S; if(intno==0x21 && S.x.ax==0x4b00) {r.x.ax=0xff0a; int86(0x21,&r,&s);} /* child*/ else {r.x.ax=0x0300; int86(0x31,&r,&s);} R=S; return R.d.eax;} /*-----*//* conventional memory */ class c_mem {public: _go32_dpmi_seginfo x; inline c_mem(int nbytes){x.size=nbytes; _go32_dpmi_allocate_dos_memory(&x);}; inline segof(uns short&s,uns short&o){s=x.rm_segment; o=x.rm_offset;}; inline ~c_mem(){_go32_dpmi_free_dos_memory(&x);};}; /*-----*//* format of info returned by `AX=0x4f01, int10' */ typedef struct modeinfo {short modeattr pk; byte waattr,wbattr pk; short wgran,wsize,waseg,wbseg pk; long farwposfn pk; short bytesperline,wide,high pk; byte cwide,chigh,nplanes,bitsperpixel,nbanks,memmod,banksize,npages,res1, redsize,redpos,greensize,greenpos,bluesize,bluepos,ressize,respos,dircolor pk;}; /*-----*/ typedef struct{short mode,w,h,graphic,interlaced;} mi; modeinfo M; /*-----*/ int minfo(int mode){int i; c_mem buf(256); byte*p=(byte*)(&M); R.x.ax=0x4f01; R.x.cx=mode; buf.segof(R.x.es,R.x.di); Int(0x10); if((R.x.ax&255)!=0x4f) return 0; /* if some old PC can't call it */ dosmemget(buf.x.rm_segment*16+buf.x.rm_offset,40,&m); return M.modeattr&1;} /* returns 1 if that PC has that mode, else 0 */ /*-----*/ int nmi=-1; mi MI[64]; /* for info re screen modes found */ /*-----*/ void findmodes(){int nmi,i,j,k,g; mi m; if(nmi>=0) return; /* no need to call it again in the same program run */ for(nmi=i=0;i<1024;i++) {if(!minfo(i)) continue; MI[nmi].mode=i; g=MI[nmi].graphic=(M.modeattr&16)>>4; MI[nmi].w=M.wide; MI[mni].h=M.high; /* those two fields seem to return pixels if graphic, chars if text */ MI[nmi].interlaced=0; /* SOMEONE TELL ME HOW TO FIND IF MODE i IS INTERLACED, PLEASE */ if(nmi++>63) break;} for(k=1,i=nmi;i>0;i--) while(k) if(k=j=0;jMI[j+1].w ?1: MI[j].wMI[j+1].h) { k=1; m=MI[j]; MI[j]=MI[j+1]; MI[j+1]=m;} /* bubble-sort the modes found into ascending width then ascending height */ } /*-----*/ int dos_mode_for_djgpp_mode(int mode,int wide,int high){int i,m,X,Y; mi*p; switch(mode){ case 0: case 1: return 3; /* text 80*25, text default */ case 3: wide=high=99999; /* biggest text */ case 2: p=0; /* text of desired size */ for(i=0;iw; Y=p->h; if(X>wide) if(Y>high) return p->mode; /* gone far enough */} return p?p->mode:3; /* he will have to accept the biggest there is */ case 4: return 13; /* graphic 320*200 */ case 7: case 8: wide=high=99999; goto Z; /* biggest graphic */ case 5: wide=640; high=480; /* graphic 640*480 */ case 6: Z: /* graphic of desired size, reject interlaced if 7 */ for(p=0,i=0;iw>wide) if(p->h>high) return p->mode; /* gone far enough */} return p?p->mode:3; /* he will have to accept the biggest there is */} default: return 3;}