www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/03/18/12:09:18

From: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
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 <std.h>
#include <pc.h>
#include <dos.h>
#include <dpmi.h>
#include <go32.h>
/*-----*/
#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;j<i-1;j++)
  if(MI[j].w>MI[j+1].w ?1: MI[j].w<MI[j+1].w ?0: MI[j].h>MI[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;i<nmi;i++) if(!MI.graphic) {p=MI+i; X=p->w; 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;i<nmi;i++) if(MI.graphic) if(mode==7?!MI[i].interlaced:1) {
        p=MI+i;
        if(p->w>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;}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019