/* Hi guys, here is a bit of code for bitmap scaling. I'm sure that
  it's all been seen before but it may help someone. I know that the
  scale loop can be optimised by introducing more variables, but if
  anyone spots any other optimisations, please point them out.

  Compile with bcc, Coments/Suggestions to [email protected]

  Keith                                                                */


//RAW format is first 2 words x,y dimensions,rest data
//ie full screen is 64004 bytes

//Use a full screen bm.

//#include <defines.h>
//#include <mode13h.h>
#include <conio.h>
#include <dos.h>
//#include <raw.h>
#include <stdlib.h>
//#include <loadpal.h>
#include <string.h>

char far* vga=(char far*)MK_FP(0xA000,0);

char far* LoadRAW(char* fname,int& x,int& y);

void SetMode13h();
void SetModeText();
void FillVGA(char c);

//width,height,new width, new height, x,y of top left on screen

void ScaleBM(char far* bm,int w,int h,int nw,int nh,int xpos,int ypos)
{
char far* loc=vga+xpos+320*ypos;

char far* bmc=bm;

static long fpxinc,fpxcur,fpyinc,fpycur;

fpxinc=(long)((long)w*65535L)/(long)nw;

fpyinc=(long)((long)h*65535L)/(long)nh;

register int i,j;

fpycur=0;

for(j=0;j<nh;j++) {

       fpxcur=0;

       for(i=0;i<nw;i++) {
               loc[i]=bmc[fpxcur>>16];
               fpxcur+=fpxinc; }
       loc+=320;
       bmc=&bm[(fpycur>>16) * w];
       fpycur+=fpyinc; }
}

extern void SetMode13h();
extern void SetModeText();

main(int argc,char** argv)
{
char far* bm;
long x,y,z;

int w,h;

if(argc!=2) exit(1);

bm=LoadRAW(argv[1],w,h);

if(bm==NULL) exit(1);

// pal* p;

argv[1][strlen(argv[1])-3]='p';
argv[1][strlen(argv[1])-2]='a';
argv[1][strlen(argv[1])-1]='l';

// p=LoadPal(argv[1]);

SetMode13h();

// SetPal(p);

x=w/2;
y=h/2;

char q=0;

while(q!=27) {

   int xscr,yscr;

   for(z=400;z>16;z--) {

       xscr=(x<<4)/z;    //d=2^4=16 => screen fill at z=16 with fullscr bm
       yscr=(y<<4)/z;

       ScaleBM(bm,w,h,xscr*2,yscr*2,-xscr+160,-yscr+100);
       }

   q=getch();
   FillVGA(0); }

SetModeText();

return(0);
}

void SetMode13h()
{
_AH=0;         //BIOS service 00h
_AL=0x13;      //mode 13h
asm int 0x10
}

void SetModeText()
{
_AH=0;
_AL=0x03;
asm int 0x10
}

void FillVGA(char c)
{
_fmemset(vga,c,64000L);
}

#include <stdio.h>
#include <sys\stat.h>
#include <alloc.h>
#include "raw.h"

char far* LoadRAW(char* fname,int& x,int& y)
{
FILE* file=fopen(fname,"rb");

if(file==NULL) {
       printf("Cannot open %s\n",fname);
       return NULL; }

fread(&x,2,1,file);
fread(&y,2,1,file);

struct stat statbuf;

fstat(fileno(file),&statbuf);

// if((long)x*(long)y != (long)statbuf.st_size-4) {
//        printf("Invalid file %s\n",fname);
//        return NULL; }

char far* rawbuf=(char far*)farmalloc((long)statbuf.st_size-4);

if(rawbuf==NULL) {
       printf("Alloc failed\n");
       return NULL; }

for(long i=0;i<statbuf.st_size-4;i++) fread(&rawbuf[i],1,1,file);

fclose(file);

return rawbuf;
}