/* * 3do-view - 3D objects (3DO) viewer for MS-Dos/Win32/SVGAlib/X11 * * 3do-view.c - main application file * ____________________________________________________________ * * Developed by Ondrej Jombik * and Stefan Soun * Copyright (c) 1997-2000 Condy software inc. * Copyright (c) 2001-2004 Platon SDG, http://platon.sk/ * All rights reserved. * * See README file for more information about this software. * See COPYING file for license information. * * Download the latest version from * http://platon.sk/projects/games/ */ /* $Platon: games/3do-view/3do-view.c,v 1.10 2004/04/06 09:54:14 nepto Exp $ */ #include #include #include #include #include /* target operating system type */ #if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11 # include #endif #if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 # include # include #endif #if PLATON_SYSTEM_WIN32 # include # include # include #endif #if PLATON_SYSTEM_MSDOS # include #endif #if PLATON_SYSTEM_X11 # include #endif #include #include #include #include #include "dir.h" #define PI 3.1415926536 #define ALFA PI/6 #define BETA PI/6 #define OSX 1 #define OSY 2 #define OSZ 4 enum modes { MODE_MAIN_MENU, MODE_AUTOMATIC_TURNING, MODE_MANUAL_TURNING, MODE_FILE_SELECTION, MODE_INFORMATION, MODE_EXIT_DIALOG, MODE_QUIT }; enum file_selector_modes { MODE_SELECTED_NONE, MODE_SELECTED_DIRECTORY, MODE_SELECTED_FILE, MODE_SELECTED_DIRECTORY_MOVE, MODE_SELECTED_FILE_MOVE }; int q,k,l,pocbod,stop=0; BYTE p; double ALFAX,ALFAY,ALFAZ,POSUNX=0.04,POSUNY=0.075,POSUNZ=0.111,POSXOLD,POSYOLD,POSZOLD; int bodxbase[100],bodybase[100],bodzbase[100], bodx[100],body[100],bodz[100]; int pocspoj[100],spoj[100][20]; /* Function prototypes */ int open_3do_file(const char *filename); void vykresli(int color); void intro(void) /* {{{ */ { printf("\r\n3D OBJECTS (3DO) viewer\r\n"); printf("Copyright (c) 1998-2000 Condy software inc.\r\n"); printf("Copyright (c) 2001-2004 Platon Software Development Group\r\n"); } /* }}} */ /************************ ERROR1 (mouse error) ******************************/ void ERROR1(void) /* {{{ */ { intro(); textbackground(CYAN); textcolor(RED+BLINK); cprintf("\r\nFATAL ERROR"); textbackground(0); textcolor(15); cprintf("\r\nThis program requires mouse.\r\n"); exit(0); } /* }}} */ /************************ ERROR2 (file error) *******************************/ void ERROR2(void) /* {{{ */ { intro(); printf("\r\nCommand line: 3do-view \r\nname - 3D Object file (.3do)\r\n"); exit(0); } /* }}} */ /************************* INTERFACE ****************************************/ void intface(void) /* {{{ */ { hidemouse(); setfillstyle(1, 0); rectangle(479,0,639,479); bar(480,1,638,478); rectangle(486,27,633,80); rectangle(486,117,633,170); rectangle(486,207,633,260); rectangle(486,297,633,350); rectangle(486,387,633,440); setcolor(GREEN); outtextxy(559,70,"AUTOMAT. OTACANIE"); outtextxy(559,160,"MANUALNE OTACANIE"); setcolor(LIGHTBLUE); outtextxy(559,250,"OTVORENIE SUBORU"); outtextxy(559,340,"INFORMACIE"); setcolor(RED); outtextxy(559,430,"KONIEC"); setcolor(WHITE); delay(50); q = MODE_MAIN_MENU; showmouse(); } /* }}} */ /********************* AUTOMATICKE OTACANIE OBJEKTU *************************/ void run(void) /* {{{ */ { hidemouse(); setfillstyle(1, 0); bar(480,1,638,478); outtextxy(559,16,"AUTOMAT. OTACANIE"); rectangle(486,387,633,440); rectangle(486,297,633,350); rectangle(486,207,633,260); rectangle(486,40,526,70); rectangle(593,40,633,70); rectangle(486,90,526,120); rectangle(593,90,633,120); rectangle(486,140,526,170); rectangle(593,140,633,170); setcolor(GREEN); outtextxy(559,55,"X"); outtextxy(559,105,"Y"); outtextxy(559,155,"Z"); setcolor(RED); outtextxy(506,55,"+"); outtextxy(506,105,"+"); outtextxy(506,155,"+"); setcolor(LIGHTBLUE); outtextxy(612,55,"-"); outtextxy(612,105,"-"); outtextxy(612,155,"-"); setcolor(WHITE); outtextxy(559,250,"POKRACOVANIE"); outtextxy(559,340,"STOP"); outtextxy(559,430,"HLAVNE MENU"); showmouse(); delay(50); q = MODE_AUTOMATIC_TURNING; } /* }}} */ /********************** POKRACOVANIE OTACANIA *******************************/ void CONTINUE(void) /* {{{ */ { if (stop==1);{ POSUNX=POSXOLD; POSUNY=POSYOLD; POSUNZ=POSZOLD; stop=0; } } /* }}} */ /************************** ZASTAVENIE OTACANIA *****************************/ void STOP(void) /* {{{ */ { if (stop!=1) { POSXOLD=POSUNX; POSYOLD=POSUNY; POSZOLD=POSUNZ; POSUNX=0; POSUNY=0; POSUNZ=0; stop=1; } } /* }}} */ /************************* MANUALNE OTACANIE ********************************/ void manual(void) /* {{{ */ { hidemouse(); setfillstyle(1, 0); bar(480,1,638,478); STOP(); rectangle(486,40,526,70); rectangle(593,40,633,70); rectangle(486,90,526,120); rectangle(593,90,633,120); rectangle(486,140,526,170); rectangle(593,140,633,170); rectangle(486,387,633,440); outtextxy(559,16,"MANUALNE OTACANIE"); setcolor(GREEN); outtextxy(559,55,"X"); outtextxy(559,105,"Y"); outtextxy(559,155,"Z"); setcolor(RED); outtextxy(506,55,"+"); outtextxy(506,105,"+"); outtextxy(506,155,"+"); setcolor(LIGHTBLUE); outtextxy(612,55,"-"); outtextxy(612,105,"-"); outtextxy(612,155,"-"); setcolor(WHITE); outtextxy(559,430,"HLAVNE MENU"); showmouse(); q = MODE_MANUAL_TURNING; } /* }}} */ /*************************** FILE SELECTOR **********************************/ void file_selector(int mode, int item) /* {{{ */ { register int i; static int files_offset = 0, directories_offset = 0; static int files_size = 0, directories_size = 0; static char **directories = NULL; static char **files = NULL; char out_str[18]; if (mode == MODE_SELECTED_DIRECTORY) { item += directories_offset; if (item >= 0 && item < directories_size) chdir(directories[item]); if (directories != NULL) free_directories_or_files(directories); if (files != NULL) free_directories_or_files(files); directories = NULL; files = NULL; files_offset = 0; directories_offset = 0; } else if (mode == MODE_SELECTED_FILE) { item += files_offset; if (item >= 0 && item < files_size) { vykresli(BLACK); if (open_3do_file(files[item])) { settextjustify(LEFT_TEXT, TOP_TEXT); bar(1, 1, 470, 11); setcolor(WHITE); outtextxy(1, 1, files[item]); settextjustify(CENTER_TEXT, CENTER_TEXT); } vykresli(WHITE); } } else if (mode == MODE_SELECTED_DIRECTORY_MOVE) { directories_offset += item; directories_offset = min(directories_size - 14, directories_offset); directories_offset = max(0, directories_offset); } else if (mode == MODE_SELECTED_FILE_MOVE) { files_offset += item; files_offset = min(files_size - 14, files_offset); files_offset = max(0, files_offset); } if (directories == NULL && files == NULL) { get_directories_and_files(&directories, &files); for (i = 0; directories != NULL && directories[i] != NULL; i++); directories_size = i; for (i = 0; files != NULL && files[i] != NULL; i++); files_size = i; } if (q != MODE_FILE_SELECTION || mode == MODE_SELECTED_DIRECTORY || mode == MODE_SELECTED_DIRECTORY_MOVE || mode == MODE_SELECTED_FILE_MOVE) { hidemouse(); setfillstyle(1, 0); bar(480,1,638,478); outtextxy(559,16,"OTVORENIE SUBORU"); rectangle(486,387,633,440); outtextxy(559,430,"HLAVNE MENU"); /* directories box */ rectangle(486,37,633,185); rectangle(486,190,505,200); rectangle(509,190,524,200); rectangle(595,190,610,200); rectangle(614,190,633,200); setcolor(directories_offset == 0 ? LIGHTGRAY: WHITE); outtextxy(496, 196, "<<"); outtextxy(517, 196, "<"); setcolor(directories_offset == max(0, directories_size - 14) ? LIGHTGRAY : WHITE); outtextxy(603, 196, ">"); outtextxy(624, 196, ">>"); setcolor(WHITE); sprintf(out_str, "[%d]", directories_size); outtextxy(559, 196, out_str); /* files box */ rectangle(486,207,633,355); rectangle(486,360,505,370); rectangle(509,360,524,370); rectangle(595,360,610,370); rectangle(614,360,633,370); setcolor(files_offset == 0 ? LIGHTGRAY : WHITE); outtextxy(496, 366, "<<"); outtextxy(517, 366, "<"); setcolor(files_offset == max(0, files_size - 14) ? LIGHTGRAY : WHITE); outtextxy(603, 366, ">"); outtextxy(624, 366, ">>"); setcolor(WHITE); sprintf(out_str, "[%d]", files_size); outtextxy(559, 366, out_str); settextjustify(LEFT_TEXT, CENTER_TEXT); for (i = 0; directories != NULL && directories[i] != NULL && i < 14; i++) { strncpy(out_str, directories[i + directories_offset], 18); if (strlen(directories[i + directories_offset]) > 17) strcpy(out_str + 15, "..."); outtextxy(490, 47 + i * 10, out_str); } for (i = 0; files != NULL && files[i] != NULL && i < 14; i++) { strncpy(out_str, files[i + files_offset], 18); if (strlen(files[i + files_offset]) > 17) strcpy(out_str + 15, "..."); outtextxy(490, 217 + i * 10, out_str); } settextjustify(CENTER_TEXT, CENTER_TEXT); showmouse(); if ((mode != MODE_SELECTED_DIRECTORY_MOVE || abs(item) > 1) && (mode != MODE_SELECTED_FILE_MOVE || abs(item) > 1)) delay(160); } q = MODE_FILE_SELECTION; } /* }}} */ /**************************** INFORMACIE ************************************/ void info(void) /* {{{ */ { hidemouse(); setfillstyle(1, 0); bar(480,1,638,478); outtextxy(559,16,"INFORMACIE"); rectangle(486,387,633,440); outtextxy(559,430,"HLAVNE MENU"); showmouse(); delay(50); q = MODE_INFORMATION; } /* }}} */ /*************************** QUIT *******************************************/ void quit(void) /* {{{ */ { hidemouse(); setfillstyle(1, 0); bar(480,1,638,478); rectangle(486,387,633,440); rectangle(486,297,633,350); outtextxy(559,16,"KONIEC PROGRAMU?"); setcolor(RED); outtextxy(559,340,"ANO"); setcolor(LIGHTBLUE); outtextxy(559,430,"NIE"); setcolor(WHITE); showmouse(); delay(100); q = MODE_EXIT_DIALOG; } /* }}} */ /******************** VYKRESLENIE OBJEKTU Z 3D DO 2D ************************/ void vykresli(int color) /* {{{ */ { register int x1,x2,y1,y2; register double sin_ALFA, cos_ALFA, sin_BETA, cos_BETA; sin_ALFA = sin(ALFA); cos_ALFA = cos(ALFA); sin_BETA = sin(BETA); cos_BETA = cos(BETA); setcolor(color); hidemouse(); for (k=1;k<=pocbod;k++) { for (l=1;l<=pocspoj[k];l++) { x1=-bodx[k]*cos_ALFA+body[k]*cos_BETA; y1=bodx[k]*sin_ALFA+body[k]*sin_BETA-bodz[k]; x2=-bodx[spoj[k][l]]*cos_ALFA+body[spoj[k][l]]*cos_BETA; y2=bodx[spoj[k][l]]*sin_ALFA+body[spoj[k][l]]*sin_BETA-bodz[spoj[k][l]]; if (x1<-238)x1=-238; if (x1>238)x1=238; if (x2<-238)x2=-238; if (x2>238)x2=238; if (y1<-238)y1=-238; if (y1>238)y1=238; if (y2<-238)y2=-238; if (y2>238)y2=238; line(240+x1,240+y1,240+x2,240+y2); } } showmouse(); } /* }}} */ /******************** POSUNUTIE PODLA OSI X,Y,Z *****************************/ void posun(void) /* {{{ */ { int xbod,ybod,zbod; for (k=1;k<=pocbod;k++) { xbod=bodxbase[k]; ybod=bodybase[k]; zbod=bodzbase[k]; if (p&OSX) { int newpoint; newpoint=xbod*cos(ALFAZ)-ybod*sin(ALFAZ); ybod=xbod*sin(ALFAZ)+ybod*cos(ALFAZ); xbod=newpoint; } if (p&OSY) { int newpoint; newpoint=xbod*cos(ALFAY)+zbod*sin(ALFAY); zbod=-xbod*sin(ALFAY)+zbod*cos(ALFAY); xbod=newpoint; } if (p&OSZ) { int newpoint; newpoint=ybod*cos(ALFAX)-zbod*sin(ALFAX); zbod=ybod*sin(ALFAX)+zbod*cos(ALFAX); ybod=newpoint; } bodx[k]=xbod; body[k]=ybod; bodz[k]=zbod; } } /* }}} */ /**** ISINBAR (ZISTENIE POZICIE KURZORU VZHLADOM NA PLOCHU X1,Y1,X2,Y2) *****/ BYTE isinbar(int x1,int y1,int x2,int y2) /* {{{ */ { WORD xx,yy; if (getmousepos(&xx, &yy) != 1) return 0; if (x1 > x2 && y1 > y2) return xx < x1 && xx > x2 && yy < y1 && yy > y2; if (x1 > x2 && y1 < y2) return xx < x1 && xx > x2 && yy < y2 && yy > y1; if (x1 < x2 && y1 > y2) return xx < x2 && xx > x1 && yy < y1 && yy > y2; if (x1 < x2 && y1 < y2) return xx < x2 && xx > x1 && yy < y2 && yy > y1; return 0; } /* }}} */ /**************************** OPEN 3DO FILE *********************************/ int open_3do_file(const char *filename) /* {{{ */ { FILE *f; if ((f = fopen(filename, "rt")) == NULL) { #if 0 my_graph_close(); printf("File not found. [%s]\n",filename); exit(1); #endif return 0; } if (fscanf(f,"%d",&pocbod) != 1) { fclose(f); return 0; } for (k=1;k<=pocbod;k++) { fscanf(f,"%d",&bodxbase[k]); fscanf(f,"%d",&bodybase[k]); fscanf(f,"%d",&bodzbase[k]); } for (k=1;k<=pocbod;k++) { fscanf(f,"%d",&pocspoj[k]); for (l=1;l<=pocspoj[k];l++) { fscanf(f,"%d",&spoj[k][l]); } } fclose(f); return 1; } /* }}} */ /**************************** HLAVNY PROGRAM ********************************/ int main(int argc,char *argv[]) /* {{{ */ { char pomstr[100]; clrscr(); if ((initmouse()!=2)&&(initmouse()!=3))ERROR1(); if (argc > 1) { if (strcmp(argv[1], "-h") && strcmp(argv[1], "--help")) (void) open_3do_file(argv[1]); else ERROR2(); } if (my_graph_init(1) < 0) { return 1; } settextjustify(CENTER_TEXT, CENTER_TEXT); settextstyle(0,0,1); intface(); ALFAY=0; ALFAX=0; ALFAZ=0; p=OSX+OSY+OSZ; showmouse(); while (q != MODE_QUIT) { if (isinbar(486,387,633,440) == 1 && q == MODE_MAIN_MENU) quit(); if (isinbar(486,297,633,350) == 1 && q == MODE_MAIN_MENU) info(); if (isinbar(486,27,633,80) == 1 && q == MODE_MAIN_MENU) run(); if (isinbar(486,387,633,440) == 1 && q == MODE_MANUAL_TURNING) { intface(); CONTINUE(); } if (isinbar(486,387,633,440) == 1 && q != MODE_MAIN_MENU) intface(); if (isinbar(486,207,633,260) == 1 && q == MODE_MAIN_MENU) file_selector(MODE_SELECTED_NONE, 0); if (isinbar(486,117,633,170) == 1 && q == MODE_MAIN_MENU) manual(); if (q == MODE_FILE_SELECTION) { int mode = MODE_SELECTED_NONE; int item = 0; if (isinbar(486,37,633,185)) { mode = MODE_SELECTED_DIRECTORY; } else if (isinbar(486,207,633,355)) { mode = MODE_SELECTED_FILE; } else if (isinbar(486,190,505,200)) { mode = MODE_SELECTED_DIRECTORY_MOVE; item = -10; } else if (isinbar(509,190,524,200)) { mode = MODE_SELECTED_DIRECTORY_MOVE; item = -1; } else if (isinbar(595,190,610,200)) { mode = MODE_SELECTED_DIRECTORY_MOVE; item = 1; } else if (isinbar(614,190,633,200)) { mode = MODE_SELECTED_DIRECTORY_MOVE; item = 10; } else if (isinbar(486,360,505,370)) { mode = MODE_SELECTED_FILE_MOVE; item = -10; } else if (isinbar(509,360,524,370)) { mode = MODE_SELECTED_FILE_MOVE; item = -1; } else if (isinbar(595,360,610,370)) { mode = MODE_SELECTED_FILE_MOVE; item = 1; } else if (isinbar(614,360,633,370)) { mode = MODE_SELECTED_FILE_MOVE; item = 10; } if (mode != MODE_SELECTED_NONE) { if (item == 0) { WORD yy; getmousepos(NULL, &yy); item = yy; item -= mode == MODE_SELECTED_FILE ? 212 : 42; item /= 10; item = min(13, item); item = max(0, item); } file_selector(mode, item); } } if (q == MODE_AUTOMATIC_TURNING) { if (stop!=1) { if (isinbar(486,40,526,70)==1) { if (POSUNX==0)p=p+OSX; if (POSUNX!=-0.001)POSUNX+=0.001; else POSUNX=0; POSUNX+=0.001; if (POSUNX==0)p=p-OSX; } if (isinbar(593,40,633,70)==1) { if (POSUNX==0)p=p+OSX; if (POSUNX!=0.001)POSUNX-=0.001; else POSUNX=0; if (POSUNX==0)p=p-OSX; } if (isinbar(486,90,526,120)==1) { if (POSUNY==0)p=p+OSY; if (POSUNY!=-0.001)POSUNY+=0.001; else POSUNY=0; if (POSUNY==0)p=p-OSY; } if (isinbar(593,90,633,120)==1) { if (POSUNY==0)p=p+OSY; if (POSUNY!=0.001)POSUNY-=0.001; else POSUNY=0; if (POSUNY==0)p=p-OSY; } if (isinbar(486,140,526,170)==1) { if (POSUNZ==0)p=p+OSZ; if (POSUNZ!=-0.001)POSUNZ+=0.001; else POSUNZ=0; if (POSUNZ==0)p=p-OSZ; } if (isinbar(593,140,633,170)==1) { if (POSUNZ==0)p=p+OSZ; if (POSUNZ!=0.001)POSUNZ-=0.001; else POSUNZ=0; if (POSUNZ==0)p=p-OSZ; } } if (isinbar(486,207,633,260)==1)CONTINUE(); if ((isinbar(486,297,633,350)==1)&&(stop!=1))STOP(); setcolor(WHITE); sprintf(pomstr,"%+04.0f",POSUNX*1000); bar(530,60,590,70); outtextxy(555,65,pomstr); sprintf(pomstr,"%+04.0f",POSUNY*1000); bar(530,110,590,120); outtextxy(555,115,pomstr); sprintf(pomstr,"%+04.0f",POSUNZ*1000); bar(530,160,590,170); outtextxy(555,165,pomstr); } if (q == MODE_EXIT_DIALOG) if (isinbar(486,297,633,350) == 1) q = MODE_QUIT; if (q == MODE_MANUAL_TURNING) { if (isinbar(486,40,526,70) == 1) POSUNX += 0.01; if (isinbar(593,40,633,70) == 1) POSUNX -= 0.01; if (isinbar(486,90,526,120) == 1) POSUNY += 0.01; if (isinbar(593,90,633,120) == 1) POSUNY -= 0.01; if (isinbar(486,140,526,170) == 1) POSUNZ += 0.01; if (isinbar(593,140,633,170) == 1) POSUNZ -= 0.01; } my_graph_refresh(); delay(50); if ((POSUNX>0.0005)||(POSUNY>0.0005)||(POSUNZ>0.0005) ||(POSUNX<-0.0005)||(POSUNY<-0.0005)||(POSUNZ<-0.0005)) { vykresli(BLACK); if (POSUNX!=0) { if (ALFAX>=180)ALFAX=0; else ALFAX+=POSUNX; } if (POSUNY!=0) { if (ALFAY>=180)ALFAY=0; else ALFAY+=POSUNY; } if (POSUNZ!=0) { if (ALFAZ>=180)ALFAZ=0; else ALFAZ+=POSUNZ; } posun(); vykresli(WHITE); } if (q == MODE_MANUAL_TURNING) { POSUNX=0; POSUNY=0; POSUNZ=0; } } my_graph_close(); clrscr(); endstring("3do-view"); textcolor(0x07);cputs("\r\n\nEspecially thanX 2 "); textcolor(11);cputs("Stefan Soun "); textcolor(0x07);cputs("a.k.a. "); textcolor(128+0x0f);cputs("Pysta"); cputs("\r\n"); return 0; } /* }}} */ /* Modeline for ViM {{{ * vim: set ts=4: * vim600: fdm=marker fdl=0 fdc=0: * }}} */