home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Action Ware 10: Quake
/
ACWARE10.iso
/
acware10
/
editors
/
mdlv14
/
mdl.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-07
|
16KB
|
619 lines
//
// this file by brian martin 1996
// brian@phyast.pitt.edu
//
// this is part of the source for the MedDLe quake model viewer/editor
//
//
#include "mdl.h"
int mdl_keys(MDL_model *);
void load_model(char *, MDL_model *);
void vline (unsigned char *, int *, int *,MDL_model );
MDL_window win2d, win3d;
// use this stuff for command line options
#define NUM_CFG_OPTIONS 3
char *cfg_option[NUM_CFG_OPTIONS] = {"mode","driver","progspath"};
char driver[128], progspath[128];
unsigned char pal[256*3];
unsigned char cmap[256*32];
//GrContext *BitMapContext;
void OpenColorMap(char *,unsigned char *);
//----------------------------------------------------------------------
int main (int argc, char *argv[])
{
FILE *in, *out, *qpal;
unsigned char bmppal[256*3];
unsigned bmpw, bmph;
struct MDL_model model;
char *in_filename,*out_filename,*filename;
char str[256];
char ch;
short cur_key;
short draw_3d=1;
short draw_triangles=0;
short draw_vertices=0;
short import_bmpfile=0;
short export_bmpfile=0;
short show_info=0;
unsigned i,j,k,l;
unsigned p1,p2,p3,p4;
int video_mode=0;
int update=0;
int refresh=0;
int oldx,oldy,oldr,oldl,oldm;
int selected=0;
int ontopof=0;
int selectedx, selectedy, selectedindex;
int madechanges=0;
int loop;
int goto_3d=0;
int skin;
float zoom_factor=2;
// set default values
driver[0]=NULL;
progspath[0]=NULL;
clrscr();
printf("MedDLe by Brian Martin version %2.1f\n\n",VERSION);
// get config file settings
if((in=fopen("mdl.cfg","rt"))==NULL)
{
fprintf(stderr,"Can't open mdl.cfg, using defaults... \n");
fprintf(stderr,"Things probably won't work. Hit a key. \n");
getch();
}
else
{
fprintf(stderr,"Reading mdl.cfg ...\n");
ch=0;
do
{
fscanf(in,"%s", str);
if(feof(in)) break;
if(str[0]=='#') {while(fgetc(in)!=0x0A);}
else
{
k=0;
for(i=0; i<NUM_CFG_OPTIONS; i++)
{
j=0;
while(*(cfg_option[i]+j)!=NULL)
{
k=i+1;
if(str[j]!=*(cfg_option[i]+j)) {k=0;break;}
j++;
}
if(k!=0) break;
}
if(k==0) fprintf(stderr,"Don't understand option \"%s\" in config file. \n",str);
else
{
fscanf(in,"%s", str);
switch (k)
{
case 1: video_mode=atoi(str); fprintf(stderr," - setting video mode = %d\n",video_mode); break;
case 2: strcpy(driver,str); fprintf(stderr," - setting driver = %s\n",driver);break;
case 3: strcpy(progspath,str); fprintf(stderr," - setting progspath = %s\n",progspath);break;
}
}
}
}while(!feof(in));
fclose(in);
}
// get command line options
for (argv++, argc--; argc && **argv == '-'; argv++, argc--)
{
if ((*argv)[1] == 'e' && argc-- > 1)
{
out_filename = *++argv;
export_bmpfile=1;
skin = atoi( *(++argv));
}
else if ((*argv)[1] == 'i' && argc-- > 1)
{
in_filename = *++argv;
import_bmpfile=1;
skin = atoi( *(++argv));
}
else if ((*argv)[1] == 'm' && argc-- > 1)
video_mode= atoi( *(++argv));
else if ((*argv)[1] == '2')
draw_3d = 0;
else if ((*argv)[1] == 's')
show_info = 1;
else if ((*argv)[1] == 'h')
{
fprintf(stderr, "Usage: mdl [-h] [-2] [-s] [-e <file.bmp> #] [-i <file.bmp> #] [-m #] file.mdl \n");
fprintf(stderr, " -h -- help screen\n");
fprintf(stderr, " -2 -- start in 2d view\n");
// fprintf(stderr, " -s -- show header information\n");
fprintf(stderr, " -e -- extract BMP file, skin #\n");
fprintf(stderr, " -i -- insert BMP file, skin #\n");
fprintf(stderr, " -m -- video mode\n");
fprintf(stderr, " 0 = 320x200 (default)\n");
fprintf(stderr, " 1-4 hi res modes\n");
exit(1);
}
else
{
fprintf(stderr, "What is %s? mdl -h will help you", *argv);
exit(1);
}
}
if (argc > 0)
filename = *argv;
else
{
fprintf(stderr, "mdl -h will help you", *argv);
exit(1);
}
// read in quake colors
BG_OpenPalette("mdl.pal",pal);
//read color map
OpenColorMap("mdl.map",cmap);
// read in mdl file
// and set up data
load_model(filename, &model);
// export bitmap of skin
if(export_bmpfile==1)
{
if((skin<=model.num_skins)&&(skin>0))
{
out=fopen(out_filename,"wb");
BG_WriteBMP(out, pal, model.skin[skin-1].bitmap, model.skinw, model.skinh);
fclose(out);
}
// new skin (polygon pic)
if(skin<=0)
{
int x1,x2,x3;
unsigned p1,p2,p3,p4;
unsigned char *pic;
pic= new(unsigned char)[model.skinw*model.skinh];
for(j=0; j<model.skinh; j++)
{
for(i=0; i<model.skinw; i++)
{
pic[i+model.skinw*j]=0;
}
}
int v1[2], v2[2];
for(i=0;i<model.num_triangles;i++)
{
p1=model.triangle[i*4+1];
p2=model.triangle[i*4+2];
p3=model.triangle[i*4+3];
p4=model.triangle[i*4];
x1=x2=x3=0;
if((model.vertex[3*p1]==32)&&(p4==0)) x1=model.skinw/2;
if((model.vertex[3*p2]==32)&&(p4==0)) x2=model.skinw/2;
if((model.vertex[3*p3]==32)&&(p4==0)) x3=model.skinw/2;
v1[0]=model.vertex[p2*3+1]+x2;
v1[1]=model.vertex[p2*3+2];
v2[0]=model.vertex[p3*3+1]+x3;
v2[1]=model.vertex[p3*3+2];
vline(pic,v1,v2,model);
v1[0]=model.vertex[p3*3+1]+x3;
v1[1]=model.vertex[p3*3+2];
v2[0]=model.vertex[p1*3+1]+x1;
v2[1]=model.vertex[p1*3+2];
vline(pic,v1,v2,model );
v1[0]=model.vertex[p1*3+1]+x1;
v1[1]=model.vertex[p1*3+2];
v2[0]=model.vertex[p2*3+1]+x2;
v2[1]=model.vertex[p2*3+2];
vline(pic,v1,v2,model);
}
out=fopen(out_filename,"wb");
BG_WriteBMP(out, pal, pic, model.skinw, model.skinh);
fclose(out);
delete [] pic;
}
goto the_end;
}
// import skin bmp
if((skin>0)&&(import_bmpfile==1))
{
unsigned char *pic;
in=fopen(in_filename,"rb");
rewind(in);
fseek(in,18,SEEK_SET);
fread(&bmpw,4,1,in);
fread(&bmph,4,1,in);
fseek(in,28,SEEK_CUR);
for (i = 0; i < 256; i++)
{
fread(bmppal+i*3 + 2,1,1,in);
fread(bmppal+i*3 + 1,1,1,in);
fread(bmppal+i*3 + 0,1,1,in);
fseek(in,1,SEEK_CUR);
}
//read new pic
pic=new (unsigned char)[(bmpw*bmph)];
int ali;
unsigned char junk[4];
if(bmpw<4) ali=4-bmpw;
else ali=bmpw%4;
for(j=bmph;j>0;j--)
{
for(i=0;i<bmpw;i++)
{
fread(&pic[i+bmpw*(j-1)],1,1,in);
}
if(ali!=0) fread(&junk[0],ali,1,in);
}
fclose(in);
// now stick the info in the model...
// match colors up
printf("matching colors\n");
char close_color[256];
for(i=0; i<256; i++)
{
close_color[i]=i;
float error, error0=1.566e5;
float e1,e2,e3;
for(j=0; j<256; j++)
{
e1= (float)(pal[j*3]-bmppal[i*3]);
e2= (float)(pal[j*3+1]-bmppal[i*3+1]);
e3= (float)(pal[j*3+2]-bmppal[i*3+2]);
error=e1*e1+e2*e2+e3*e3;
if(error<=error0)
{
error0=error;
close_color[i]=j;
}
}
}
//if adding a skin (not replacing)
if(skin>model.num_skins)
{
model.num_skins++; skin=model.num_skins;
// make room for more skin!
struct MDL_model_skin *tempskin;
tempskin=new(MDL_model_skin)[model.num_skins-1];
memcpy (tempskin, model.skin,sizeof(MDL_model_skin)*(model.num_skins-1));
delete [] model.skin;
model.skin = new (MDL_model_skin)[model.num_skins];
memcpy (model.skin,tempskin,sizeof(MDL_model_skin)*(model.num_skins-1));
delete [] tempskin;
model.skin[skin-1].bitmap=new (unsigned char)[model.skinw*model.skinh];
}
// resize pic if needed and add to model
printf("resizing pic\n");
double scalew, scaleh;
scalew=(double)(bmpw)/(double)(model.skinw);
scaleh=(double)(bmph)/(double)(model.skinh);
for(j=0; j<model.skinh;j++)
{
for(i=0;i<model.skinw;i++)
{
unsigned pic_index;
double di, dj;
di=(double)i;
dj=(double)j;
pic_index=(unsigned)(scalew*di)+(unsigned)(scaleh*dj)*(bmpw);
model.skin[skin-1].bitmap[i+j*model.skinw]=close_color[pic[pic_index]];
}
}
delete [] pic;
}
// intiate graphics mode
BG_GraphicsMode(driver,video_mode);
// change the screen colors to the quake palette
BG_SetPalette(pal);
// initiate mouse
BG_InitMouse();
BG_MouseStatus();
oldx=BG_MouseX;
oldy=BG_MouseY;
// intiate math tables
BG_InitMath();
BG_ClearScreen(0);
// loop through the 3 modes (3d,2d,help)
while(1)
{
if(draw_3d==1)
{
if((i=mdl_3d(&model,&win3d))==0) break;
if(i==2) draw_3d=2;
else draw_3d=0;
}
if(draw_3d==2)
{
if((i=mdl_keys(&model))==0) break;
if(i==1) draw_3d=0;
else draw_3d=1;
}
else
{
if((i=mdl_2d(&model,&win2d))==0) break;
if(i==2) draw_3d=2;
else draw_3d=1;
}
}
// go back to text mode
GrSetModeRestore(0);
BG_TextMode();
the_end:
clrscr();
// delete [] mdl.bitmap;
delete[] model.vertex;
delete [] model.triangle;
// for(j=0; j<mdl.num_frames; j++)
// {
// if(mdl.frame[j].atype!=0) delete [] mdl.frame[j].n3;
// delete [] mdl.frame[j].v;
// }
// delete [] mdl.frame;
// delete_3d_data(&mdl);
fprintf(stderr,"\nMedDLe v%2.1f 1996\n by Brian Martin\n brian@phyast.pitt.edu\n irc: ZombyWoof\n",VERSION);
return(0);
}
// read in the color map needed for shading
void OpenColorMap(char *mapfile,unsigned char *cm)
{
FILE *in;
in=fopen(mapfile,"rb");
fread(cm,1,256*32,in);
fclose(in);
}
// help file
int mdl_keys(MDL_model *m)
{
int loop=1;
int draw_3d=2;
int cur_key;
static int page=0;
int MAXPAGE=5;
int update =1;
BG_ClearScreen(0);
while(loop)
{
if(kbhit())
{
if((cur_key=getch())==0x0) cur_key=getch();
// cur_key=getch();
switch(cur_key)
{
case 27: loop=0; draw_3d=2; break;
case '3': loop=0; draw_3d=1; break;
case '2': loop=0; draw_3d=0; break;
case ARROW_RIGHT: case ARROW_DOWN: if(page<MAXPAGE) page+=1;
else page=0;
break;
case ARROW_LEFT: case ARROW_UP: if(page>0) page-=1;
else page=MAXPAGE;
break;
}
update=1;
}
if(update==1)
{
BG_ClearScreen(0);
update=0;
if(page==0)
{
// page 0
BG_Text("..About MedDLe..",BG_ScreenWidth/2-60,2,250,0);
BG_Text("MedDLe was written by Brian Martin",5,30,253,0);
BG_Text(" (on quake/irc I am the ZombyWoof!)",5,45,253,0);
BG_Text("",5,60,253,0);
BG_Text("It is free-ware and the source is included.",5,75,253,0);
BG_Text("This is NOT an id software product! ",5,90,253,0);
BG_Text("Questions or whatever go to:",5,105,253,0);
BG_Text("brian@phayst.pitt.edu ",5,120,253,0);
BG_Text("http://www.phyast.pitt.edu/~brian",5,135,253,0);
BG_Text("",5,150,253,0);
BG_Text("I will program for food. (i.e. hire me)",5,155,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
else if(page==1)
{
// page 1
BG_Text("..MedDLe Useful Keys..",BG_ScreenWidth/2-70,2,250,0);
BG_Text("Key Action",5,15,250,0);
BG_Text("1 Brings up Help",5,30,253,0);
BG_Text("2 Brings up (2D) Skin Editor",5,45,253,0);
BG_Text("3 Brings up (3D) Frame Editor",5,60,253,0);
BG_Text("Esc Exits",5,75,253,0);
BG_Text("These keys always work. For specifics, read on.",5,90,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
else if(page==2)
{
// page 2
BG_Text("..MedDLe Useful Keys..",BG_ScreenWidth/2-70,2,250,0);
BG_Text("Keys for 2D Mode",5,15,250,0);
BG_Text("1,3,Esc Help, 3d mode, exit",5,30,253,0);
BG_Text("<,> move through skins",5,45,253,0);
BG_Text("t Show wireframe (triangles)",5,60,253,0);
BG_Text("v Show vertices",5,75,253,0);
BG_Text("s Saves changes",5,90,253,0);
BG_Text(";,' change pants",5,105,253,0);
BG_Text("[,] change shirt",5,120,253,0);
BG_Text("Mouse and arrow keys move cursor",5,135,253,0);
BG_Text("Mouse Left Button grabs vertex",5,150,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
else if(page==3)
{
// page 3
BG_Text("..MedDLe Useful Keys..",BG_ScreenWidth/2-70,2,250,0);
BG_Text("Keys for 3D Mode",5,15,250,0);
BG_Text("1,2,Esc Help,Skin Editor,Exit",5,30,253,0);
BG_Text("r Reset View",5,45,253,0);
BG_Text("s Save View to file 'pic#.bmp'",5,60,253,0);
BG_Text("TAB change render mode",5,75,253,0);
BG_Text(";,' change pants",5,90,253,0);
BG_Text("[,] change shirt",5,105,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
else if(page==4)
{
// page 4
BG_Text("..MedDLe Useful Keys..",BG_ScreenWidth/2-70,2,250,0);
BG_Text("..MORE Keys for 3D Mode",5,15,250,0);
BG_Text("h Show Frame Header Info",5,30,253,0);
BG_Text("c Cycle Through Frames",5,45,253,0);
BG_Text("b Change Background Color",5,60,253,0);
BG_Text("Up/Down Move View Up or Down",5,75,253,0);
BG_Text("Left/Right Cycle Frames Forward/Backward",5,90,253,0);
BG_Text("Move Mouse moves light source",5,105,253,0);
BG_Text("Move Mouse front/back + Right Button Zooms in/out",5,120,253,0);
BG_Text("Move Mouse + Left Button Rotates Object",5,135,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
else if(page==5)
{
// page 5
BG_Text("..MedDLe Other Info..",BG_ScreenWidth/2-70,2,250,0);
BG_Text("Import bitmap by command line:",5,30,253,0);
BG_Text("mdl -i player.bmp [# skin] player.mdl",5,45,253,0);
BG_Text(" if # is bigger than num skins, adds a skin",5,60,253,0);
BG_Text("Export bitmaps by command line:",5,60,253,0);
BG_Text("mdl -e player.bmp [# skin] player.mdl",5,75,253,0);
BG_Text(" if # is 0, creats a blank skin",5,90,253,0);
BG_Text("Use arrow keys (up/down) to see more.",5,170,250,0);
}
}
}
if(draw_3d==2) return 0;
else if(draw_3d==1) return 2;
else return 1;
}
void load_model(char *filename, MDL_model *model)
{
FILE *in;
char str[256];
strcpy(str,progspath);
strcat(str,filename);
if((in=fopen(str,"rb"))==NULL)
{
printf("can't open mdl file \"%s\" ...exiting\n",str);
exit(1);
}
read_mdl(in, model);
fclose(in);
strcpy(model->filename,filename);
// setup 3d stuff
printf("wait... setting up 3d data.\n");
setup_3d_data(model);
}
void vline(unsigned char *pic, int *v1, int *v2, MDL_model model)
{
int i;
register int inc_ah,inc_al;
int dx,dy,long_d,short_d;
int d,add_dh,add_dl;
int inc_xh,inc_yh,inc_xl,inc_yl;
dx=v2[0]-v1[0]; dy=v2[1]-v1[1];
if(dx<0){dx=-dx; inc_xh=-1; inc_xl=-1;}
else { inc_xh=1; inc_xl=1; }
if(dy<0){dy=-dy;inc_yh=-model.skinw;
inc_yl=-model.skinw;
}
else { inc_yh= model.skinw;
inc_yl= model.skinw;
}
if(dx>dy){long_d=dx;short_d=dy;inc_yl=0;}
else {long_d=dy;short_d=dx;inc_xl=0;}
inc_ah=inc_xh+inc_yh;
inc_al=inc_xl+inc_yl;
pic+=v1[1]*model.skinw+v1[0];
d=2*short_d-long_d;
add_dl=2*short_d;
add_dh=2*short_d-2*long_d;
for(i=0;i<=long_d;i++)
{
*pic=11;
if(d>=0){pic+=inc_ah; d+=add_dh;}
else {pic+=inc_al; d+=add_dl;}
}
}