/* 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 ks2@st-and.ac.uk

   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;
}
