C++からCOMファイルが生成できない。
>msdos tcc -mt nimotsu.cpp Turbo C++ Version 1.01 Copyright (c) 1990 Borland International nimotsu.cpp: Turbo Link Version 3.01 Copyright (c) 1987, 1990 Borland International Warning: No stack Available memory 408752 >msdos exe2bin nimotsu.exe nimotsu.com File cannot be converted
Cがあるじゃないか!
>msdos tcc -mt nimotsu.c Turbo C++ Version 1.01 Copyright (c) 1990 Borland International nimotsu.c: Turbo Link Version 3.01 Copyright (c) 1987, 1990 Borland International Warning: No stack Available memory 492048 >msdos exe2bin nimotsu.exe nimotsu.com >msdos nimotsu.com ######## # .. p # # oo # # # ######## a:left s:right w:up z:down. command?
nimotsu.c
#include <stdio.h> #include <string.h> typedef int bool; typedef int Object; #define true 1 #define false 0 /* #壁 _空間 .ゴール oブロック p人 */ char gStageData[] = "\ ########\n\ # .. p #\n\ # oo #\n\ # #\n\ ########"; #define gStageWidth 8 #define gStageHeight 5 enum OBJ { OBJ_SPACE, OBJ_WALL, OBJ_GOAL, OBJ_BLOCK, OBJ_BLOCK_ON_GOAL, OBJ_MAN, OBJ_MAN_ON_GOAL, OBJ_UNKNOWN, }; /* 関数プロトタイプ */ void initialize( Object* state, int w, char* stageData ); void draw( Object* state, int w, int h ); void update( Object* state, char input, int w, int h ); bool checkClear( Object* state, int w, int h ); int main(){ char input[1]; /* 一次元配列である理由は本文参照 */ Object* state = (Object*)malloc(sizeof(int) * gStageWidth * gStageHeight); /* 状態配列確保 */ initialize( state, gStageWidth, gStageData ); /* ステージ初期化 */ /* メインループ */ while ( true ){ /* まず描画 */ draw( state, gStageWidth, gStageHeight ); /* クリアチェック */ if ( checkClear(state, gStageWidth, gStageHeight ) ){ break; /* クリアチェック */ } /* 入力取得 */ printf("a:left s:right w:up z:down. command?\n"); /* 操作説明 */ gets(input); /* 更新 */ update( state, input[0], gStageWidth, gStageHeight ); } /* 祝いのメッセージ */ printf("Congratulation's! you won.\n"); /* 後始末 */ free(state); state = 0; return 0; } /* ---------------------以下関数定義------------------------------------------ */ /* いつか使う日も来るだろうと高さも渡す仕様にしたが、現状使っていないので名前だけ(height)コメントアウトしてある。 */ void initialize( Object* state, int width, char* stageData ){ const char* d = stageData; /* 読み込みポインタ */ int x = 0; int y = 0; while ( *d != '\0' ){ /* NULL文字でない間 */ Object t; /* 特に意味はないが使う回数が多い変数に私は良くtを使う。temporaryの略。たぶんよくない習慣だが、無駄に長い名前にして読みにくいのも困り物だろう。 */ switch ( *d ){ case '#': t = OBJ_WALL; break; case ' ': t = OBJ_SPACE; break; case 'o': t = OBJ_BLOCK; break; case 'O': t = OBJ_BLOCK_ON_GOAL; break; case '.': t = OBJ_GOAL; break; case 'p': t = OBJ_MAN; break; case 'P': t = OBJ_MAN_ON_GOAL; break; case '\n': x = 0; ++y; t = OBJ_UNKNOWN; break; /* 改行処理 */ default: t = OBJ_UNKNOWN; break; } ++d; if ( t != OBJ_UNKNOWN ){ /* 知らない文字なら無視するのでこのif文がある */ state[ y*width + x ] = t; /* 書き込み */ ++x; } } } void draw(Object* state, int width, int height ){ int x, y; char font[] = {' ', '#', '.', 'o', 'O', 'p', 'P'}; /* Object列挙の順 */ for ( y = 0; y < height; ++y ){ for (x=0; x < width; ++x ){ Object o = state[ y*width + x ]; printf("%c",font[ o ]); } printf("\n"); } } /* 第一引数はほかの関数ではstateとしているが、あまりに頻繁に使うので 短いsで済ませている。w,hもそれぞれwidth,heightである。 */ void update( Object* s, char input, int w, int h ){ /* 移動差分に変換(dはdifferenceでもdeltaでもお好きな方の略だと思って欲しい) */ int dx = 0; int dy = 0; int i = -1; int x, y, tx, ty, p, tp, tx2, ty2, tp2; switch ( input ){ case 'a': dx = -1; break; case 's': dx = 1; break; case 'w': dy = -1; break; case 'z': dy = 1; break; } /* 人座標を検索 */ for ( i = 0; i < w * h; ++i ){ if ( s[ i ] == OBJ_MAN || s[ i ] == OBJ_MAN_ON_GOAL ){ break; } } x = i % w; /* xは幅で割ったあまり */ y = i / w; /* yは幅で割った商 */ /* 移動後座標(tに意味はない。ごめんなさい) */ tx = x + dx; ty = y + dy; /* 座標の最大最小チェック。外れていれば不許可 */ if ( tx < 0 || ty < 0 || tx >= w || ty >= h ){ return; } /* A.その方向が空白またはゴール。人が移動。 */ p = y*w + x; /* 人位置 */ tp = ty*w + tx; /* ターゲット位置(TargetPosition) */ if ( s[ tp ] == OBJ_SPACE || s[ tp ] == OBJ_GOAL ){ s[ tp ] = ( s[ tp ] == OBJ_GOAL ) ? OBJ_MAN_ON_GOAL : OBJ_MAN; /* ゴールならゴール上の人に */ s[ p ] = ( s[ p ] == OBJ_MAN_ON_GOAL ) ? OBJ_GOAL : OBJ_SPACE; /* もともとゴール上ならゴールに */ /* B.その方向が箱。その方向の次のマスが空白またはゴールであれば移動。 */ }else if ( s[ tp ] == OBJ_BLOCK || s[ tp ] == OBJ_BLOCK_ON_GOAL ){ /* 2マス先が範囲内かチェック */ tx2 = tx + dx; ty2 = ty + dy; if ( tx2 < 0 || ty2 < 0 || tx2 >= w || ty2 >= h ){ /* 押せない */ return; } tp2 = ( ty + dy )*w + ( tx + dx ); /* 2マス先 */ if ( s[ tp2 ] == OBJ_SPACE || s[ tp2 ] == OBJ_GOAL ){ /* 順次入れ替え */ s[ tp2 ] = ( s[ tp2 ] == OBJ_GOAL ) ? OBJ_BLOCK_ON_GOAL : OBJ_BLOCK; s[ tp ] = ( s[ tp ] == OBJ_BLOCK_ON_GOAL ) ? OBJ_MAN_ON_GOAL : OBJ_MAN; s[ p ] = ( s[ p ] == OBJ_MAN_ON_GOAL ) ? OBJ_GOAL : OBJ_SPACE; } } } /* ブロックのみがなければクリアしている。 */ bool checkClear(Object* s, int width, int height ){ int i; for (i = 0; i < width*height; ++i ){ if ( s[ i ] == OBJ_BLOCK ){ return false; } } return true; }