From: shaun@octel.com (Ralph Neutrino)
Newsgroups: comp.lang.c
Subject: Re: Curious bug...
Date: 28 Jul 92 04:34:05 GMT
Organization: Octel Communications Inc., Milpitas Ca.

In article <1992Jul22.050021.3974@uwm.edu> pegasus@csd4.csd.uwm.edu (David R Hucke) writes:
>Hello everybody!
>What happens is this:  When I run the program in the QC Environment it
>works fine.  The characters are correct, and the colors are not correct.
>
>When I run the program from DOS (outside of the QC Environment) the characters
>are correct but the colors are not correct.
>
>Can somebody tell me what is wrong here?

Not sure, but you might want to try opening the file
>   if(!(file = fopen("c:\\test.scn","r"))){

using binary mode ("rb") instead of text mode.

>    for(j=0;j<8;j++)
>	for(i=0;i<20;i++){
>   	    fscanf(file,"%c%c",&x,&y);    /* reading in attribute and
>					     character bytes */
>	    menu[j][i] = (short)((y<<8)+x);  /* putting together screen
>						character ---> attribute
>						and character.  Shifting
>						one of the bytes. */
>	}

This loop is really inefficient.  I've used the following definitions and
accompanying functions with good success in the past:

--- 8< snip >8 ---

/* code by @Man & Spike */
/* public domain 1989   */

struct cell                     /* single character cell on screen      */
{
     char character;
     char attribute;
};
 
typedef struct cell screen [25][80];    /* whole screen in one array    */
 
cputchxy(char q, int x, int y)
{
   screen far *scr = (screen far *)0xb8000000l;      /* CGA - EGA - VGA */
/* screen far *scr = (screen far *)0xb0000000l;         MDA - hercules  */
 
   (*scr)[y][x].character = q;                       /* write to screen */
}
 
print(char *str, int x, int y)
{
   screen far *scr = (screen far *)0xb8000000l;      /* CGA - EGA - VGA */
/* screen far *scr = (screen far *)0xb0000000l;         MDA - hercules  */
 
    while(*str)
        (*scr)[y][x++].character = *str++;            /* write to screen */
}
--- 8< snip >8 ---

Using the above definition for screen, I'm almost positive you could use
fread() to read the screen into a near duplicate of the screen array
(since fread() can't read into far pointers) and then use memcpy() to move
it to the video buffer quickly.  Be sure you're using the large model if you
use memcpy(); use movedata() in the small and medium models.  Be sure to
#include <mem.h>.  This should work and be faster than your old code, unless
TheDraw saves the characater and attribute in the wrong order.  If you're 
still curious about your old code, a wild guess is to try turning on word
alignment.  

You will have to change this for larger screen modes.  The following items
may help you:

unsigned char far *p_cols = (unsigned char far *)0x0000044A;
                          /* ptr to bios data area:columns */
 
unsigned char far *p_lines = (unsigned char far *)0x00000484;
                          /* ptr to bios data area:lines   */

These seem to work even for Big Monster Video Modes (BMVMs) like 132x60.
 
Best of luck!

>===
>pegasus@csd4.csd.uwm.edu
>
>-- 
>pegasus@csd4.csd.uwm.edu                David R. Hucke
>                                        UW-Milwaukee Film Major
>--

Ooh!  Henious duplicate signature!  Bummer.

@Man
-- 
shaun@octel.com  ||  G is for Jesus

"We will buy Iron Camels from GoMotion
   Unlimited in Santa Clara California."