/*
* 3do-view - 3D objects (3DO) viewer for MS-Dos/Win32/SVGAlib/X11
*
* 3do-view.c - main application file
* ____________________________________________________________
*
* Developed by Ondrej Jombik <nepto@platon.sk>
* and Stefan Soun <neexist@orangemail.sk>
* 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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <system.h> /* target operating system type */
#if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11
# include <dos2linux.h>
#endif
#if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32
# include <conio.h>
# include <dos.h>
#endif
#if PLATON_SYSTEM_WIN32
# include <dos2win32.h>
# include <winbgim.h>
# include <direct.h>
#endif
#if PLATON_SYSTEM_MSDOS
# include <dir.h>
#endif
#if PLATON_SYSTEM_X11
# include <x11-bgi.h>
#endif
#include <typedef.h>
#include <standart.h>
#include <my-graph.h>
#include <mouse.h>
#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 <name>\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:
* }}} */
Platon Group <platon@platon.sk> http://platon.sk/
|