home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
REND
/
REND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-29
|
36KB
|
1,439 lines
/*
* Rendering Program Ver 2
*
* 1989.12.17
* CopyRight T.Kobayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#if !defined(DJ) && !defined(UNIX)
#include <conio.h>
#endif
#if defined(MSC)
#include <sys/types.h>
#endif
#if defined(DJ) || defined(__BORLANDC__) || defined(MSC) || defined(UNIX)
#include <sys/stat.h>
#include <time.h>
#else
#include <stat.h>
#include <time.h>
#endif
#ifdef UNIX
#define tolower(c) (('A' <= (c) && (c) <= 'Z') ? ((c) - 'A' + 'a') : (c))
#endif
#define REND
#define ESC '\x1B'
#include "reader.h"
#include "glib.h"
#include "rend.h"
#ifndef NO_PICLIB
#include "piclib.h"
#endif
#ifdef BG
#include "bg.h"
#endif
/* 大域変数 */
int antiareas = 1 ; /* アンチエリアシング */
int nflag = FALSE ; /* 画像ファイル出力オプション */
int uflag = FALSE ; /* 画面出力オプション */
int picerrorflag = FALSE ; /* 画像ファイル出力エラー */
#ifdef EDGEANTI
int EdgeAntiFlag = TRUE;
#endif
#ifdef MAPANTI
int MapAntiFlag = FALSE;
#endif
#ifdef MOB
int TimeAnti = 1;
#endif
#ifdef WIREVIEW
int wiresize = 0;
#endif
int fullcoloroutflag = FALSE;
int fullcolorditherflag = FALSE;
#ifdef HIVISION
int XPosition = 0, YPosition = 0;
PixelType PixelMode = P256x256;
#endif
#ifdef BACKFACE
int backface = FALSE;
#endif
#ifdef XC
int WindowMode = FALSE ; /* ウインドウモード */
#endif
static Pointer(Atr*) atr = NULL ; /* アトリビュートリスト */
static Pointer(Object*) obj = NULL ; /* オブジェクトリスト */
static int startframe = 1 ; /* スタートフレーム */
static int endframe = 999 ; /* エンドフレーム */
#ifdef NO_PICLIB
static char picfile[F_NAME_LEN]="" ; /* 画像ファイル */
static int picnum=0 ; /* 画像ファイルの番号 */
#else
static PicSequence outseq; /* 画像ファイル名 */
#endif
#ifdef NO_PICLIB
static char backfile[F_NAME_LEN]="" ; /* 背景ファイル */
static int backnum = 0 ; /* 背景ファイルの番号 */
#else
static PicSequence backseq; /* 画像ファイル名 */
#endif
#ifdef STAR
static int stars = 0; /* 背景の星の数 */
static int stardir = 0; /* 背景の星の方向(上=0, 時計回り) */
static int starstep = 0; /* 背景の星の速さ */
#endif
static int tflag = FALSE ; /* テンポラリファイル使用フラグ */
static char tempfile[F_NAME_LEN] ; /* テンポラリファイル */
static char virfile[F_NAME_LEN] ; /* 仮想記憶ファイル */
static char *ext[4] =
{ ".ATR", ".SUF", ".FRM", ".FSC" }; /* 拡張子 */
#ifdef BG
static int bgmode = 4 ; /* バックグラウンドのモード */
static struct COMBUF combuf ; /* 通信バッファ */
#endif
#if defined(X68000)
static long dsize = 0L ; /* データ領域のサイズ */
static char **WindowArgv ; /* 引数ファイル名 */
static int WindowArgc ; /* 引数の数 */
#elif defined(DJ) || defined(UNIX) || defined(__WIN32__)
static long dsize = 16L*1024L*1024L ;/* データ領域のサイズ */
#elif defined(MSC) || defined(__BORLANDC__)
static long dsize = 200L*1024L ;/* データ領域のサイズ */
#else
static long dsize = 0L ;/* データ領域のサイズ */
#endif
#ifndef WINDOWS
static char precommandline[256] = "";
static char postcommandline[256] = "";
#endif
static char logfile[F_NAME_LEN]="REND.LOG";
static char logcommandline[1024]="";
static int logflag=FALSE;
FILE *logfp = NULL;
static long peakusedarea=0, peakfreearea = 256L * 1024L * 1024L;
static time_t starttime, laptime1, laptime2;
#ifdef RENDXVI
int _SSP;
#endif
/*
proto -s rend.c > temp
*/
#ifdef WINDOWS
extern void check_winmessage( void );
#else
static void check_esc( void );
#endif
#ifdef BG
static void check_kill( void );
#endif
static void mainloop( void );
static void analizeargs( int, char*[] );
static void analizeoption( char* );
static int piccheck( char* );
static void usage( void );
static void error( int, char* );
static int isext( char* );
#ifndef WINDOWS
void commandexec(char *, int, char *, int, char *, int);
#endif
#ifdef WINDOWS
int Main(int argc, char *argv[] )
#else
int main(int argc, char *argv[] )
#endif
{
#ifdef RENDXVI
_SSP = SUPER( 0 );
#endif
fprintf(stderr, "%s%s%s", program, version, copyright);
virtualmode = FALSE ;
#ifdef WINDOWS
interrupt = check_winmessage ;
#else
interrupt = check_esc ;
#endif
(*interrupt)();
errorexec = (void (*)(int))error ;
analizeargs( argc, argv );
#ifdef BG
if ( BackGroundJob )
{
int ret ;
static char sspbuf[1000] ;
extern char *_SEND ;
combuf.bufsize = 0 ;
combuf.address = NULL ;
combuf.flag = 0xFFFF ;
interrupt = check_kill ;
ret = bg_set( "REND", bgmode, _SEND, sspbuf+1000,
mainloop, &combuf, 2000 );
if ( ret < 0 )
{
fprintf( stderr,
"バックグラウンドプロセスを登録できませんでした。\n" );
exit( 1 );
}
freopen( "nul", "w", stdout );
freopen( "nul", "w", stderr );
keepexit( 1, 0 );
}
#endif
mainloop();
#ifdef RENDXVI
STACK_ADJUST:
SUPER( _SSP );
#endif
return( 0 );
}
#ifndef WINDOWS
static void check_esc()
{
#if (defined(VGA) || !defined(DJ)) && !defined(UNIX)
while( kbhit() != 0 )
{
if ( getch() == ESC )
{
fprintf( stderr, "\nESC キーが押されました。\n" );
fprintf( stderr, "処理を中断します。\n\n" );
fcloseall();
#ifdef VIRTUAL
if ( virtualmode )
unlink( virfile );
#endif
exit( 1 );
}
}
#endif
}
#endif
#ifdef BG
static void check_kill()
{
bg_check_kill( &combuf, "REND を終了します。" );
}
#endif
static void mainloop()
{
long n;
int fr ; /* フレーム数 */
char name[F_NAME_LEN] ;
long size ;
Frame *frame ;
Pointer(void*) mark;
Pointer(void*) errormark ;
FILE *fp ;
size = datasize();
mark = datamark();
for( fr = 1 ; fr < startframe ; ++fr )
{
#ifdef STAR
if (stars > 0) {
StarStep();
}
#endif
if ( frameskip() == 0 )
error( 1, NULL );
}
PictureOutput = picout ;
if ( ! uflag )
{
LineOutput = piclineout ;
#ifdef HIVISION
{
switch (PixelMode) {
case P256x256: crtinit( 256 ); break;
case P512x512: crtinit( 512 ); break;
case P640x400: crtinit( 512 ); break;
case P640x480: crtinit( 512 ); break;
case P1024x1024: crtinit( 1024 ); break;
case P1920x1125: crtinit( 2048 ); break;
case P2048x2048: crtinit( 2048 ); break;
case P4096x4096: crtinit( 4096 ); break;
default:
;
}
}
#else
crtinit( YPixel / antiareas );
#endif
}
if (logflag) {
laptime1 = time(NULL);
}
#ifdef NO_PICLIB
if ( picnum == 0 )
picnum = fr ;
#else
if (outseq.number == 0) {
outseq.number = fr;
}
PicSequence_forceAnim(&outseq);
#endif
while( ! end_of_file && fr <= endframe )
{
#ifndef WINDOWS
if (precommandline[0] != '\0') {
#ifdef NO_PICLIB
commandexec(precommandline, fr, picfile, picnum, backfile, backnum);
#else
commandexec(precommandline, fr, outseq.body, outseq.number, backseq.body, backseq.number);
#endif
}
#endif
frame = frameread( obj );
if ( frame == NULL )
error( 1, NULL );
errormark = datamark();
do
{
if ( ! uflag )
crtclr();
fprintf( stderr, "Frame %d\n", fr );
#ifndef VGA
fprintf( stderr, " 使用データ領域 : %ld Byte\n", size );
#else
fprintf( stderr, " Data : %ld Byte\n", size );
#endif
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "Frame %d\n", fr );
fprintf( logfp, " 使用データ領域 : %ld Byte\n", size );
}
#endif
n = ViewConv( frame );
picerrorflag = FALSE ;
if (logflag) {
laptime2 = time(NULL);
}
#ifndef VGA
fprintf( stderr, " 使用ワーク領域 : %ld Byte\n", datasize() - size );
fprintf( stderr, " ポリゴン数 : %ld\n", n );
#else
fprintf( stderr, " Work : %ld Byte\n", datasize() - size );
fprintf( stderr, " Polys : %ld\n", n );
#endif
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, " 使用ワーク領域 : %ld Byte\n",
datasize() - size );
fprintf( logfp, " ポリゴン数 : %ld\n", n );
}
#endif
#ifdef NO_PICLIB
sprintf( name, "%s%03d.PIC", picfile, picnum );
#else
PicSequence_get(&outseq, name);
#endif
if ( BackLoad )
{
#ifdef NO_PICLIB
if ( backnum == 0 )
{
sprintf( BackFile, "%s.PIC", backfile );
}
else
{
sprintf( BackFile, "%s%03d.PIC", backfile, backnum );
}
#else
PicSequence_get(&backseq, BackFile);
#endif
}
fp = picinit( name );
#ifdef WIREVIEW
if (nflag || fp != NULL) {
if (wiresize == 0) {
Display( frame, n );
} else {
wiresave();
}
}
#else
if (nflag || fp != NULL )
{
Display( frame, n );
}
#endif
if ( picerrorflag )
{
datarelease( errormark );
if ( ! uflag )
crtclr();
#ifdef WINDOWS
error(0, "ファイル出力に失敗しました" );
#endif
fprintf( stderr, "画像ファイル出力でエラーが発生しました。\n" );
fprintf( stderr, "ディスクがいっぱいだと思われます。\n" );
#ifndef WINDOWS
fprintf( stderr, "ディスクを入れ替えてください。\n" );
fprintf( stderr, "準備ができたらどれかキーを押してください。\n" );
#endif
#ifdef DJ
fgetc(stdin);
#else
#ifdef UNIX
fgetc(stdin);
#else
getch() ;
#endif
#endif
}
}
while( picerrorflag );
if (logflag) {
long freearea, usedarea;
time_t nowtime;
nowtime = time(NULL);
if (logfp != NULL) {
fprintf(logfp, "%24s %6dkB %6dkB %6dkB %8d %5d秒 %5d秒\n",
name, size/1024, ((usedarea=datasize())-size-1)/1024+1, (freearea=memgetsize())/1024,
n, laptime2 - laptime1, nowtime - laptime2);
if (usedarea > peakusedarea) {
peakusedarea = usedarea;
}
if (freearea < peakfreearea) {
peakfreearea = freearea;
}
laptime1 = nowtime;
}
}
datarelease( mark );
#ifndef WINDOWS
if (postcommandline[0] != '\0') {
#ifdef NO_PICLIB
commandexec(postcommandline, fr, picfile, picnum, backfile, backnum);
#else
commandexec(postcommandline, fr, outseq.body, outseq.number, backseq.body, backseq.number);
#endif
}
#endif
fr ++ ;
#ifdef NO_PICLIB
picnum ++ ;
if ( BackLoad && backnum != 0) {
backnum ++ ;
}
#else
PicSequence_next(&outseq);
if (BackLoad) {
PicSequence_next(&backseq);
}
#endif
}
if (logflag) {
time_t nowtime, lap;
nowtime = time(NULL);
lap = nowtime - starttime;
if (logfp != NULL) {
fprintf(logfp, "総所要時間=%d:%02d:%02d 最大使用メモリ領域=%8dkB 最小空きメモリ領域=%8dkB\n",
lap / 3600, (lap / 60) % 60, lap % 60,
(peakusedarea-1)/1024+1, peakfreearea/1024);
}
}
#ifndef DJ
#ifndef UNIX
fcloseall();
#endif
#endif
#ifdef VIRTUAL
if ( virtualmode )
unlink( virfile );
#endif
#ifdef BG
if ( BackGroundJob )
bg_kill();
#endif
}
/* コマンドラインの評価 */
static void analizeargs( argc, argv )
int argc ;
char *argv[] ;
{
int i, j;
int files[4] ;
char framefile[F_NAME_LEN], framesource[F_NAME_LEN], *p ;
char buf[256] ;
char *option ;
long fsctime ;
struct stat statbuf, *sbuf = &statbuf ;
option = getenv( "RENDLOG" );
if ( option == NULL )
option = getenv( "rendlog" );
if ( option != NULL ) {
logflag = TRUE;
if ( option[0] == '\0' )
strcpy( logfile, "REND.LOG" );
else
strcpy( logfile, option );
i = strlen( logfile );
if ( logfile[i-1] == '\\' || logfile[i-1] == ':' )
strcat( logfile, "REND.LOG" );
}
for (i = 1; i < argc; ++i) {
#ifdef NOSLASHOPT
if ((argv[i][0] == '-') && (argv[i][1] == 'l' || argv[i][1] == 'L')) {
#else
if ((argv[i][0] == '-' || argv[i][0] == '/') && (argv[i][1] == 'l' || argv[i][1] == 'L')) {
#endif
logflag = TRUE;
break;
}
}
if (logflag) {
for (i = 0; i < argc; ++i) {
strcat(logcommandline, " ");
strcat(logcommandline, argv[i]);
}
}
extendargs( &argc, &argv, 4, ext );
if ( argc == 1 )
usage() ;
#ifdef NO_PICLIB
strcpy( picfile, "" );
picnum = 0 ;
#else
outseq.body[0] = '\0';
outseq.number = 0;
backseq.body[0] = '\0';
#endif
for( i = 0 ; i < 4 ; ++i )
files[i] = 0 ;
#ifdef WINDOWS
XPixel = 320;
YPixel = 240;
PixelRatio = 1.0;
PixelMode = P512x512;
#endif
for( i = 1 ; i < argc ; ++i )
{
#ifdef NOSLASHOPT
if ( argv[i][0] == '-' )
#else
if ( argv[i][0] == '-' || argv[i][0] == '/' )
#endif
{
analizeoption( argv[i] );
argv[i] = "" ;
}
}
#ifdef XC
if ( WindowMode )
{
argv = WindowArgv - 1 ;
argc = WindowArgc + 1 ;
}
#endif
for( i = 1 ; i < argc ; ++i )
{
if ( argv[i][0] != '\0' )
{
j = isext( argv[i] ) ;
switch( j )
{
case -1 :
usage();
break ;
case 2 :
if ( files[3] == 0 )
{
strcpy( framefile, argv[i] );
files[2] = 1 ;
}
break ;
case 3 :
#ifndef WINDOWS
files[2] = 0 ;
files[3] = 1 ;
strcpy( framefile, argv[i] );
#endif
break ;
default :
files[j] ++ ;
break ;
}
}
}
#ifndef MESSAGE
fprintf( stderr, "\n" );
#endif
#ifdef BG
if ( BackGroundJob && dsize == 0 )
error( 0, "データ領域の大きさを指定されていません。" );
#endif
#ifdef WIREVIEW
if (wiresize > 0) {
ShadingModel = FLAT_SHADE;
}
#endif
XPixel *= antiareas ;
YPixel *= antiareas ;
if ( YPixel > MAXLINE )
error( 0, "解像度が高すぎます。" );
if (logflag) {
if (logfp != NULL) {
fputs("コマンドライン =", logfp);
fputs(logcommandline, logfp);
fputs("\n 画像ファイル名 データ ワーク 残メモリ ポリゴン数 透視変換 作画\n", logfp);
} else {
logflag = FALSE;
}
starttime = time(NULL);
}
/* エラーチェック */
if ( files[0] == 0 )
error( 0, "アトリビュートファイルがありません。" );
if ( files[1] == 0 )
error( 0, "形状ファイルがありません。" );
if ( files[2] == 0 && files[3] == 0 )
error( 0, "フレームファイルがありません。" );
#ifdef NO_PICLIB
if ( strcmp( picfile, "" ) == 0 )
strcpy( picfile, framefile );
picnum = piccheck( picfile );
#else
if (outseq.body[0] == '\0') {
PicSequence_set(&outseq, framefile);
strcpy(outseq.ext, "PIC");
}
#endif
/* フレームソースのときの処理 */
if ( files[3] > 0 )
{
strcpy( framesource, framefile );
p = strrchr( framefile, '.' );
strcpy( p, ".FRM" );
if ( stat( framesource, sbuf ) == -1 )
#ifdef JAP
error( 0, "フレームソ\ースファイルがありません。" );
#else
error( 0, "フレームソースファイルがありません。" );
#endif
fsctime = sbuf->st_atime ;
if ( stat( framefile, sbuf ) == -1 || fsctime > sbuf->st_atime )
{
option = getenv( "FFOPTION" );
if ( option == NULL )
option = getenv( "ffoption" );
if ( option == NULL )
option = "" ;
#ifdef DJ
sprintf( buf, "ff386 %s %s", option, framesource );
#else
sprintf( buf, "ff %s %s", option, framesource );
#endif
system( buf );
fprintf( stderr, "\n" );
}
}
/* データバッファの初期化 */
meminit( dsize );
#ifdef VIRTUAL
if ( virtualmode )
virinit( virfile );
#endif
#ifdef STAR
if (stars > 0) {
StarInit(stars, stardir, starstep);
}
#endif
/* アトリビュートファイルのリード */
fprintf( stderr, "Reading Attribute File\n" );
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "Reading Attribute File\n" );
}
#endif
for( i = 1 ; i < argc ; ++i )
{
if ( isext( argv[i] ) == 0 )
{
fprintf( stderr, "%s\n", argv[i] );
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "%s\n", argv[i] );
}
#endif
atr = atrread( argv[i], atr ) ;
if ( atr == NULL )
error( 1, NULL );
argv[i] = "" ;
}
}
if ( ShadingModel == GOURAUD_SHADE )
MapInit( atr );
/* 形状ファイルのリード */
fprintf( stderr, "Reading Object File\n" );
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "Reading Object File\n" );
}
#endif
if ( tflag )
tempopen( tempfile );
for( i = 1 ; i < argc ; ++i )
{
if ( isext( argv[i] ) == 1 )
{
fprintf( stderr, "%s\n", argv[i] );
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "%s\n", argv[i] );
}
#endif
if ( tflag )
obj = tempread( argv[i], obj );
else
obj = objread( argv[i], obj );
if ( obj == NULL )
error( 1, NULL );
argv[i] = "" ;
}
}
if ( tflag )
tempclose( tempfile );
if ( objatr( obj, atr ) == FALSE )
exit( 1 );
/* フレームファイルのオープン */
fprintf( stderr, "Reading Frame File\n" );
fprintf( stderr, "%s\n", framefile );
#ifdef WINDOWS
if (logflag && logfp != NULL) {
fprintf( logfp, "Reading Frame File\n" );
fprintf( logfp, "%s\n", framefile );
}
#endif
if ( frameopen( framefile ) == 0 )
error( 1, NULL );
}
/* オプションの評価、ファイル名のチェック */
static void analizeoption( str )
char *str ;
{
int i, n ;
char *p ;
#ifdef BG
struct PROCESS processbuf ;
#endif
switch( tolower( str[1] ) )
{
case 'a' :
#ifdef MAPANTI
if (tolower(str[2]) == 'm') {
MapAntiFlag = TRUE;
fprintf(stderr, "マッピングにアンチエイリアシングをかけます。\n");
break;
}
#endif
#ifdef MOB
if (tolower(str[2]) == 't') {
n = atoi(str+3);
if (n != 2 && n != 4) {
error( 0, "オプション'AT'の指定の誤り" );
}
fprintf( stderr,
"時間方向に %d 倍解像度でアンチエリアシングをかけます。\n", n );
TimeAnti = n;
break;
}
#endif
n = atoi( str+2 );
if ( n <= 1 || 9 <= n )
error( 0, "オプション'A'が 2 ~ 9 に収まってません" );
fprintf( stderr,
" %d 倍解像度でアンチエリアシングをかけます。\n", n );
antiareas = n ;
break ;
case 'b' :
#ifdef BGMAKE
if (str[2] == '\0') {
#endif
fprintf( stderr, "バックを透明にします。\n" );
TraBack = 1 ;
#ifdef BGMAKE
} else {
BgMake = 0;
p = str+2;
i = 0;
for (;*p;p++) {
if (*p == ',' || (i > 2 && *p == ':')) {
BgMakeFile[BgMake][i] = '\0';
i = 0;
BgMake++;
if (BgMake == 12) {
error( 0, "オプション'B'画像数が多すぎる" );
}
} else {
BgMakeFile[BgMake][i++] = *p;
}
}
BgMakeFile[BgMake][i] = '\0';
BgMake++;
if (BgMake == 1) {
fprintf( stderr, "背景球を、極座標系: %s で行います。\n",BgMakeFile[0]);
} else if (BgMake == 2) {
fprintf( stderr, "背景球を、前後: %s、左右: %s で行います。\n",
BgMakeFile[0], BgMakeFile[1]);
} else if (BgMake == 4) {
fprintf( stderr, "背景球を、前: %s、右: %s 後: %s 左: %s で行います。\n",
BgMakeFile[0], BgMakeFile[1],
BgMakeFile[2], BgMakeFile[3]);
} else if (BgMake == 6) {
fprintf( stderr, "背景球を、上前後: %s、上左右: %s 中前後: %s 中左右: %s 下前後: %s 下左右: %s で行います。\n",
BgMakeFile[0], BgMakeFile[1],
BgMakeFile[2], BgMakeFile[3],
BgMakeFile[4], BgMakeFile[5]);
} else if (BgMake == 12) {
fprintf( stderr,
"背景球を、\n"
"\t上: %s, %s, %s, %s\n"
"\t中: %s, %s, %s, %s\n"
"\t下: %s, %s, %s, %s\n"
"\t\tで行います。\n",
BgMakeFile[0], BgMakeFile[1],BgMakeFile[2],BgMakeFile[3],
BgMakeFile[4], BgMakeFile[5],BgMakeFile[6],BgMakeFile[7],
BgMakeFile[8], BgMakeFile[9],BgMakeFile[10],BgMakeFile[11]);
} else {
error( 0, "オプション'B' 画像の枚数がおかしい" );
}
}
#endif
break ;
case 'c' :
#ifdef HIVISION
{
int nx = 0, ny = 0;
int rx = 0, ry = 0;
int cc;
nx = atoi( str+2 ) ;
for (cc = 2; str[cc]; ++cc) {
if (str[cc] == 'X' || str[cc] == 'x' || str[cc] == '*'
|| str[cc] == ',' || str[cc] == ':') {
ny = atoi(str+cc+1);
break;
}
}
if (ny != 0) {
for (cc++; str[cc]; ++cc) {
if (str[cc] == ',' || str[cc] == ':') {
rx = atoi(str+cc+1);
break;
}
}
}
if (rx != 0) {
for (cc++; str[cc]; ++cc) {
if (str[cc] == ',' || str[cc] == ':') {
ry = atoi(str+cc+1);
break;
}
}
}
if (ny == 0) {
ny = nx;
}
XPixel = nx;
YPixel = ny;
if (nx == 320 && ny == 200) {
PixelMode = P320x200;
PixelRatio = 1.00;
} else if (nx == 320 && ny == 240) {
PixelMode = P512x512;
PixelRatio = 1.00;
} else if (nx == 640 && ny == 400) {
PixelMode = P640x400;
PixelRatio = 1.00;
} else if (nx == 640 && ny == 480) {
PixelMode = P640x480;
PixelRatio = 1.00;
} else if (nx == 1920 && ny == 1125) {
PixelMode = P1920x1125;
PixelRatio = 1.00;
} else if (2 <= nx && nx <= 512 && 2 <= ny && ny <= 512) {
if (XPixel > 256 || YPixel > 256) {
PixelMode = P512x512;
} else {
PixelMode = P256x256;
}
/* PixelRatio = 0.75;*/
PixelRatio = (Float)XPixel / (Float)YPixel * 0.75;
} else if (nx <= 1024 && ny <= 1024) {
PixelMode = P1024x1024;
PixelRatio = 0.75;
} else if (nx <= 2048 && ny <= 2048) {
PixelMode = P2048x2048;
PixelRatio = (Float)XPixel / (Float)YPixel * 0.75;
} else if (nx <= 4096 && ny <= 4096) {
PixelMode = P4096x4096;
PixelRatio = (Float)XPixel / (Float)YPixel * 0.75;
} else {
error( 0, "オプション'C' 解像度が高すぎる" );
}
if (rx != 0 && ry != 0) {
PixelRatio = (Float)XPixel / (Float)YPixel * (Float)ry / (Float)rx;
}
}
#else
n = atoi( str+2 ) ;
if ( n == 256 || n == 512 )
XPixel = YPixel = n ;
else
error( 0, "オプション'C'の指定の誤り" );
#endif
fprintf( stderr, "画面サイズは %d * %d です。\n", XPixel, YPixel );
break ;
case 'd' :
n = atoi(str+2);
if (tolower(str[2]) == 'r') {
fprintf( stderr, "ランダムディザをかけて作画します。\n");
fullcoloroutflag = FALSE;
fullcolorditherflag = RANDOMDITHER;
} else if (tolower(str[2]) == 'e' && str[3] == '2') {
fprintf( stderr, "誤差拡散で256色で作画します。\n");
fullcoloroutflag = FALSE;
fullcolorditherflag = ERRORDIFUSION2;
} else if (tolower(str[2]) == 'e') {
fprintf( stderr, "誤差拡散で作画します。\n");
fullcoloroutflag = FALSE;
fullcolorditherflag = ERRORDIFUSION;
} else if (n==0 || n == 200 || n == 400 || tolower(str[2]) == 'd'|| n == 2) {
fprintf( stderr, "ディザをかけて疑似200万色で作画します。\n");
fullcoloroutflag = FALSE;
fullcolorditherflag = ORDEREDDITHER4;
} else if (tolower(str[2]) == 'o' || n == 4) {
fprintf( stderr, "ディザをかけて疑似1400万色で作画します。\n");
fullcoloroutflag = FALSE;
fullcolorditherflag = ORDEREDDITHER8;
} else if (tolower(str[2]) == 'f'
|| tolower(str[2]) == 't' || n == 1600) {
fprintf( stderr, "16,777,216色フルカラーで作画します。\n");
fullcoloroutflag = TRUE;
fullcolorditherflag = ORDEREDDITHER4;
} else {
error( 0, "オプション'D'は r, e, o, tのどれか" );
}
break;
#ifndef WINDOWS
case 'e' :
if (str[2] == '0' || tolower(str[2]) == 's' || tolower(str[2]) == 'b') {
strcpy(precommandline, str+3);
fprintf( stderr, "各フレーム作画直前にコマンド'%s'を実行します。\n", str+3);
if (tolower(precommandline[0]) == 'd' &&
tolower(precommandline[1]) == 'e' &&
tolower(precommandline[2]) == 'l' &&
isspace(precommandline[3])) {
} else {
dsize = (long)-512*1024;
}
} else if (str[2] == '1' || tolower(str[2]) == 'e') {
strcpy(postcommandline, str+3);
fprintf( stderr, "各フレーム作画直後にコマンド'%s'を実行します。\n", str+3);
if (tolower(precommandline[0]) == 'd' &&
tolower(precommandline[1]) == 'e' &&
tolower(precommandline[2]) == 'l' &&
isspace(precommandline[3])) {
} else {
dsize = (long)-512*1024;
}
}
break;
#endif
case 'f' :
FrontClip = atof( str+2 );
if ( FrontClip <= 0.0 )
error( 0, "前面クリッピング距離がおかしい。" );
fprintf( stderr,
"前面クリッピング距離を %g にします。\n", FrontClip );
break ;
case 'g' :
ShadingModel = GOURAUD_SHADE ;
fprintf( stderr, "スムーズシェーディングをかけます。\n" );
break ;
case 'h' :
BackLoad = TRUE ;
#ifdef NO_PICLIB
strcpy( backfile, str+2 );
fprintf( stderr, "背景をファイル %s から読み込みます。\n", backfile );
backnum = piccheck( backfile );
#else
PicSequence_set(&backseq, str+2);
fprintf( stderr, "背景をファイル %s から読み込みます。\n", str+2 );
#endif
break ;
#ifdef STAR
case 'i' :
{
int cc, dir = 0, step = 0;
n = atoi(str+2);
for (cc = 2; str[cc]; ++cc) {
if (str[cc] == 'X' || str[cc] == 'x' || str[cc] == '*'
|| str[cc] == ',' || str[cc] == ':') {
dir = atoi(str+cc+1);
break;
}
}
if (isdigit(str[cc+1]) || str[cc+1] == '-') {
for (cc++; str[cc]; ++cc) {
if (str[cc] == ',' || str[cc] == ':') {
step = atoi(str+cc+1);
break;
}
}
}
if (n == 0) {
n = 1000;
}
if (-180 <= dir && dir <= 360 && 0 < step && step <= 360) {
fprintf( stderr, "背景に %d 度方向に速さ %d 度で進む %d 個の星を描きます。\n", dir, step, n );
stardir = dir;
starstep = step;
} else {
fprintf( stderr, "背景に %d 個の星を描きます。\n", n );
}
stars = n;
}
break;
#endif
#ifdef BG
case 'j' :
BackGroundJob = TRUE ;
n = atoi( str+2 );
if ( 0 < n && n < 256 )
bgmode = n ;
fprintf( stderr, "バックグラウンドジョブで実行します。\n" );
break ;
#endif
#ifdef EDGEANTI
case 'k' :
EdgeAntiFlag = FALSE;
fprintf( stderr, "エッジにアンチエイリアシングをかけません。\n" );
break;
#endif
case 'l' :
logflag = TRUE;
if ( str[2] == '\0' )
strcpy( logfile, "REND.LOG" );
else
strcpy( logfile, str+2 );
i = strlen( logfile );
if ( logfile[i-1] == '\\' || logfile[i-1] == ':' )
strcat( logfile, "REND.LOG" );
fprintf( stderr, "作画ログを %s に書き込みます。\n", logfile );
logfp = fopen(logfile, "a");
#ifdef WINDOWS
errfp = logfp;
#endif
break ;
case 'm' :
n = atoi( str+2 );
if ( n < -1000 || 16000 < n )
error( 0, "オプション'M' 指定の誤り" );
fprintf( stderr, "データ領域を %d Kbyte 確保します。\n", n );
dsize = (long)n * 1024L ;
break ;
case 'n' :
fprintf( stderr, "画像ファイルを出力しません。\n" );
nflag = 1 ;
break ;
case 'o' :
#ifdef NO_PICLIB
strcpy( picfile, str+2 );
#else
PicSequence_set(&outseq, str+2);
#endif
fprintf( stderr, "画像ファイル名を %s にします。\n", str+2 );
break ;
#ifdef HIVISION
case 'p' :
{
int nx, ny = 0;
int cc;
nx = atoi( str+2 ) ;
for (cc = 2; str[cc]; ++cc) {
if (str[cc] == 'X' || str[cc] == 'x' || str[cc] == '*'
|| str[cc] == ',' || str[cc] == ':') {
ny = atoi(str+cc+1);
break;
}
}
XPosition = nx;
YPosition = ny;
if (nx < 0 || nx >= 512 || ny < 0 || ny >= 512) {
error( 0, "オプション'P' の指定の誤り" );
}
}
break;
#endif
#ifdef BACKFACE
case 'q':
backface = TRUE;
fprintf(stderr, "裏面は作画しません。\n");
break;
#endif
#ifdef BG
case 'r':
strcpy( processbuf.name, "REND" );
n = bg_get( -1, &processbuf );
if ( n > 0 )
{
if ( bg_send( 0, n, 0xFFF9, NULL, 0 ) < 0 )
fprintf( stderr, " エラーが発生しました。\n" );
}
else
fprintf( stderr, " REND が存在しません。\n" );
exit( 0 );
#endif
#ifdef REFMAP
case 'r' :
RefMap = 1;
strcpy(RefMapFile[0], str+2);
while ((p = strchr(RefMapFile[RefMap-1], ',')) != NULL
|| (p = strchr(RefMapFile[RefMap-1]+2, ':')) != NULL) {
*p = '\0';
if (RefMap == 6) {
error( 0, "オプション'R' 画像の枚数が多すぎる" );
}
strcpy(RefMapFile[RefMap++], p+1);
}
if (RefMap == 1) {
fprintf( stderr, "環境マッピングを、極座標系: %s で行います。\n",RefMapFile[0]);
} else if (RefMap == 2) {
fprintf( stderr, "環境マッピングを、上半球: %s、下半球: %s で行います。\n",
RefMapFile[0], RefMapFile[1]);
} else if (RefMap == 6) {
fprintf( stderr,
"環境マッピングを、前: %s、右: %s 後: %s 左: %s 上: %s 下: %s で行います。\n",
RefMapFile[0], RefMapFile[1],RefMapFile[2],
RefMapFile[3], RefMapFile[4],RefMapFile[5]);
} else {
error( 0, "オプション'R' 画像の枚数がおかしい" );
}
break;
#endif
case 's' :
p = strchr( str+2, ':' );
if ( p != NULL )
*p = '\0' ;
/* スタートフレームのチェック */
startframe = atoi( str+2 );
if ( startframe <= 0 )
startframe = 1 ;
else
{
fprintf( stderr, " %d フレームから描き始めます。\n",
startframe );
}
/* エンドフレームのチェック */
if ( p != NULL )
{
/* エンドフレームがある */
endframe = atoi( p+1 );
if ( startframe > endframe )
error( 0, "オプション'S' 開始フレームよりも終了フレームの方が小さい" );
fprintf( stderr, " %d フレームで終わります。\n", endframe );
}
break ;
case 't' :
tflag = TRUE ;
if ( str[2] == '\0' )
strcpy( tempfile, "REND.TMP" );
else
strcpy( tempfile, str+2 );
i = strlen( tempfile );
if ( tempfile[i-1] == '\\' || tempfile[i-1] == ':' )
strcat( tempfile, "REND.TMP" );
fprintf( stderr, "テンポラリファイル %s を使用します。\n",
tempfile );
break ;
case 'u' :
uflag = TRUE ;
fprintf( stderr, "画面出力しません。\n" );
break ;
case 'v' :
virtualmode = TRUE ;
if ( str[2] == '\0' )
strcpy( virfile, "REND.SWP" );
else
strcpy( virfile, str+2 );
i = strlen( virfile );
if ( virfile[i-1] == '\\' || virfile[i-1] == ':' )
strcat( virfile, "REND.SWP" );
fprintf( stderr,
"仮想記憶ファイル %s を使用します。\n", virfile );
break ;
#ifdef WIREVIEW
case 'w' :
n = atoi( str+2 );
if ( n <= 1 || 5 <= n ) {
n = 1;
}
fprintf( stderr,"出力画像をワイヤーフレームにします。\n", n );
wiresize = n ;
break ;
#endif
#ifdef XC
case 'w' :
WindowMode = TRUE ;
WindowArgv = atoi( str+2 );
for( WindowArgc = 0 ; WindowArgv[WindowArgc] != NULL ; ++ WindowArgc );
fprintf( stderr, "ウインドウモードで実行します。\n" );
break ;
#endif
case '?' :
usage() ;
break ;
default :
error( 0, "不明のオプションを指定" );
}
}
#ifdef NO_PICLIB
/* 画像ファイル名のチェック */
static int piccheck( name )
char *name ;
{
char *p, *p2 ;
int i, n, ret ;
#if 0
if ( *name == '.' )
p = name + 2 ; /* 親ディレクトリを示す */
else
p = name ;
#else
if (p2 = strrchr(name, ':'), p2++ == NULL) {
p2 = name;
}
if (p = strrchr(p2, '\\'), p++ == NULL) {
p = p2;
}
#endif
p = strchr( p, '.' ) ;
if ( p != NULL ) /* 拡張子を削除する */
*p = '\0' ;
ret = 0 ;
n = strlen( name );
if ( isdigit( name[n-3] ) && isdigit( name[n-2] ) && isdigit( name[n-1] ) )
{
ret = atoi( name + n - 3 );
name[n-3] = '\0' ;
}
p = name + strlen( name ) - 1 ;
for( i = 0 ; *p != '\\' && *p != ':' && p >= name ; ++i )
--p ;
if ( ret != 0 && i > 5 )
error( 0, "画像ファイル名が長すぎます。" );
return( ret );
}
#endif
/* usage の表示 */
static void usage()
{
int i ;
static char *msg[] = {
"使用法:rend [ -Options ] [#<IndirectFile>] < File... ( .atr .suf .frm ) >",
"Option -a<num> : <num>倍解像度でアンチエリアシング",
#ifdef MAPANTI
" -am : マッピングにアンチエリアシングをかける",
#endif
#ifdef MOB
" -at<num> : 時間方向にアンチエイリアシング(<num>=2,3,4)",
#endif
" -b : 背景を透明にする",
#ifdef BGMAKE
" -b<file1>,<file2>,...",
" : 背景球を描く",
#endif
#ifdef HIVISION
" -c<numx>[:<numy>] : 画面サイズを<numx>×<numy>にする",
#else
" -c<num> : 画面サイズ",
#endif
/* " -d<num> : <num>万色で作画する(<num>=6,400,1600)",*/
" -d[<mode>] : ディザリングをかける(<mode>=2,4,r,e)",
#ifndef WINDOWS
" -e0<command> : コマンド実行(作画前)",
" -e1<command> : コマンド実行(作画後)",
#endif
" -f<num> : 前面クリッピング距離",
" -g : スムースシェーディングモード",
" -h<filename> : 背景をファイルから読み込む",
#ifdef STAR
/* " -i<num> : 背景<num>個の星を描く",*/
" -i<num>[:<d>:<s>] : 背景<num>個の星を<d>度の方向で速さ<s>度で描く",
#endif
#ifdef BG
" -j[mode] : バックグラウンドジョブで実行する",
" : ( Human68k ver 2.00 以上 )",
#endif
#ifdef EDGEANTI
" -k : エッジにアンチエイリアシングをかけない",
#endif
#if 0
" -l<filename> : ログを記録する",
#endif
" -m<num> : データ領域のサイズを指定する(Kbyte)",
" -n : 画像ファイルを出力しない",
" -o<name> : 画像ファイル名",
#ifdef HIVISION
" -p<numx>:<numy> : 画像左上の座標を(<numx>,<numy>)にする",
#endif
#ifdef BACKFACE
" -q : 裏面を描きません",
#endif
#ifdef BG
" -r : バックグラウンドジョブを中断させる。",
#endif
#ifdef REFMAP
" -r<file1>,... : 環境マッピングを行う。",
" ファイル数1: 極座標系",
" ファイル数2: 上半球、下半球",
" ファイル数6: 前、右、後、左、上、下",
#endif
" -s<num1>[:<num2>] : num1 スタートフレーム",
#ifdef JAP
" num2 エンドフレーム(省略可能\)",
#else
" num2 エンドフレーム(省略可能)",
#endif
#ifndef DJ
" -t[filename] : テンポラリファイル使用",
#endif
" -u : 画面出力しない",
#ifdef VIRTUAL
" -v[filename] : 仮想記憶モード",
#ifdef EMS
" -vEMS : EMSによる仮想記憶モード",
#endif
#endif
#ifdef WIREVIEW
" -w : ワイヤーフレーム出力",
#endif
#ifdef JAP
" -? : 使用法表\示",
#else
" -? : 使用法表示",
#endif
"#<インダイレクトファイル> は、そのファイルの中身を(改行は空白として)そこに書くのと同等です。",
"ESC キーで中止",
""
} ;
for( i = 0 ; strcmp( msg[i], "" ) != 0 ; ++i )
fprintf( stdout, "%s\n", msg[i] );
/* putc( '\n', stderr );*/
exit( 1 );
}
/* エラー */
static void error( n, msg )
int n ;
char *msg ;
{
#ifdef MESSAGE
extern int printwarning(const char *format, ...);
#endif
if ( n == 0 ) {
fprintf( stderr, "コマンドラインエラー:%s\n", msg );
#ifdef MESSAGE
printwarning("コマンドラインエラー:%s", msg);
#endif
}
#ifdef MESSAGE
else printwarning("エラーが発生しました。");
#endif
fprintf( stderr, "エラーが発生しました。\n\n" );
#ifndef DJ
#ifndef UNIX
fcloseall();
#endif
#endif
exit( 1 );
}
/*
拡張子の種類を返す。
戻り値 -1 : エラー
0 : .atr
1 : .suf
2 : .frm
3 : .fsc
*/
static int isext( file )
char *file ;
{
int i ;
char *p ;
p = strrchr( file, '.' );
if ( p == NULL )
return( -1 );
for( i = 0 ; i < 4 ; ++i )
{
if ( strcmpi( p, ext[i] ) == 0 )
return( i );
}
return( -1 );
}