dポイントプレゼントキャンペーン実施中!

テキストモードで24×80のがその画面を準備し、"スペース"と"*"で画面上に図形を描き、どんな図形かを調べるプログラム
http://www-itolab.ics.nitech.ac.jp/lecture/crepo …
に置いてある"rec_angle.c"をUNIXで動くようにしたいのですが、できません。エラーの内容から

A.1行目 #include "dos.h"
B.3行目 #define VRAM 0xa000
C.148行目から193行目 IBM-PC用のcheck_point(),gotoxy(),cls() 
D.195行目から225行目 PC98用のcheck_point(),gotoxy(),cls()

辺りが怪しいのです。実際にコンパイルするときはCとDのどちらかはコメントアウトしなければいけません。
上のURLではIBM用がコメント扱いになっています。(208行目の"/*"と219行目の"*/"は打ち間違いです。)



そして方針としては

(1)dos.h、int86、peekなどをUNIX上で使用できるような環境にする。
(2)IBM用の関数らを書き換える。
(3)PC98用の関数らを書き換える。

が考えられます。
自分としては(3)がいいと思っています。

203行目: dat=peek(VRAM,xy);
212行目: printf("\x1b{");
223、4行目: printf("\x1b{"); printf("2J");

だけをUNIXで使えるものに置き換えればいいようなので。(自信がないですが)
(1)、(2)については全くどうしていいか分かりません。



どのような方法でもいいのでUNIXで(それ難しい場合はせめてWINDOWSで)動くようにしたいのですが、どうかお助けください。どちらもGCCを使っています。

A 回答 (4件)

基本的には、機種依存の次の3つの関数を置き換えることで可能です。


・check_point(int a,int b)
 テキスト座標(a,b)の文字が'*'なら1を、そうでないなら0を返す
・gotoxy(int x,int y)
 テキスト座標(x,y)にカーソルを移動
・cls()
 テキストスクリーンをクリアする
(テキスト座標は(0,0)~ )

UNIXのVT100端末の場合は、こちらのエスケースシーケンスで
関数を作成すれば可能かもしれません。
http://homepage3.nifty.com/peterpan/etescseq-ese …

gotoxy(int x,int y)は、printf("\x1b[%d;%dH",y+1,x+1);
cls()は、printf("\x1b[2J");
あたりで実現可能かもしれませんが、check_point(int a,int b)は
難しいかもしれません。

Windows環境ならMS-DOSモードまたはDOS窓で、IBMPC版で動かしてみると
動くと思います(PC-98xxをお使いでなければ)
コンパイラはDOS用のフリーのLSI-C86でやってみてください。
http://homepage3.nifty.com/aokura/phoebe/phoebe. …
    • good
    • 0
この回答へのお礼

WINDOWS環境ではLSIコンパイラでIBMPC版を動かせました。ありがとうございます。とりあえず実行結果がわかり助かりました。
gotoxy(),clsのエスケープシーケンスに関する考察参考になりました。

お礼日時:2003/12/14 05:49

Unixの場合、画面消去や指定したカーソル位置への書き込みをエスケープシーケンスを使うのは邪道です。

termcap, terminfo, cursesと言ったライブラリ(画面情報データベースからエスケープシーケンスを取得して動く)が準備されているのでこれを使ってください。
    • good
    • 0
この回答へのお礼

少し調べてみたのですがお恥ずかしながらtermcap,terminfo, cursesなどの使い方がわかりませんでした。。。私が実践するには難しそうなので、名前だけとどめさせていただきます。ご回答くださりありがとうございました。

お礼日時:2003/12/15 10:03

#1です.



やはり,私のは外してましたか......

以下は,自己完結させるために,書きますが,たぶんご質問とは関係ないでしょう.
「ドット」と書きましたのは,たとえば,キャラクタの「%」というのを画面に出したいときに,
PC98はテキストエリアというキャラクタコードを格納しておくところがあって,その内容を
BIOSが画面にフォントを使って展開するわけです.
この部分を,昔のマシンはBIOSとしてROMに内蔵していたので,PC98は他国語環境では
使えなかったわけです.

これに対して,AT互換機など最近主流のパソコンやWindowsはテキストエリアというコードを保持しておくところが
なくて,いきなりビットマップにフォント展開してしまいます.展開する部分もOSの機能として
持っています.
だから,「画面にキャラクタを書いて」,「そのキャラクタコードを読む」
というときに,「画面にキャラクタを書いて」はできますが,コードが無くなっているので,
「そのキャラクタコードを読む」というのができるのかな?
という気がします.

ハードの構成が違うので,それを吸収するしくみが必要と言うことです.

この点で,下記のような回答になってしまいました.
もしも,テキストコードを画面に保持しているところがあれば,そのアドレスを
読むことは可能(容易)です.

ご質問は,どうもこのテキストエリアの話のようですね.
誤解してました.すみません.

「エクステンダ」というのは,アドレスを拡張するためのしかけのはいったプログラム
です.WindowsのGCCはDOSベースのソフトです.最近のはエクステンダが要りませんが,
見えないところで動いていまして,アドレスの変換をやってます.

ご質問とはずれますが,
----------------------------------
24x80の配列を容易しておいて,(普通の配列)
その配列に対して読み書きをおこないつつ,
必要なら配列の内容を画面に表示させる
書き込みは
 A[x][,y]=1
読み込みは
 a = A[x][y]
----------------------------------
というのなら,すぐにでも作れます.

プログラムの確認が主目的なんですよね?
だったら,あまりインチキしてはいけませんね.
    • good
    • 0
この回答へのお礼

再度ご説明いただきありがとうございます。
教えていただいた配列を使う方法を、PC98版のエスケープシーケンスの書き換えと一緒に明日試してみたいと思います。


2次元配列を準備する。
"make_triangle()"、"make_square()"では、"gotoxy(x,y)"の"x"、"y"に対応した個所の配列の要素に"*"を入れる。
"check_point()"でその有無を検査する。

という具合で。


それにしても、Cをやっているとハードに関する知識が結構要求されるんですね。

お礼日時:2003/12/14 21:40

私も,昔,GCCで画面にプロットするルーチンを作ったことがあります.


どのようなご質問か,正確には分からないのですが,画面にドットを打ったり,
そのドットが点灯しているかどうかを検出したいのでしょうか.

基本的には,PC98と(いまでは一般的なPCの)DOSVなどの環境の違いは,
ビットマップ描画でして,画面=アドレス
と言うことです.
つまり,特定のアドレスに値をかきこむと,そのドットが点灯するのです.
また,そのアドレスがいくつであるか読み出すと,ドットが点灯しているかどうかが
分かります.いたって単純です.

問題は,「特定のアドレス」です.
画面がどのアドレスに割り当てられているのかは,システムに依存しています.
私の使っていたDJGCCの場合は,確か「0xd0000000」だったかと思います.

仮想記憶という考え方があって,物理アドレスはどんなアドレスにでも
マッピングできます.だから,システム(エクステンダ)がどんなマッピングをしているのか
わかりませんか?

アドレスさえわかれば,peek関数は簡単です.

peek(adress) は *(adress)

メモリ処理は,BASICよりもCの方が得意です.

特定のドットを点灯させるルーチンが作れれば,その他の関数は,
それを用いて作れます.(円や,四角形,塗りつぶしなど)
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございます。ドットというよりは"*"と" "(スペース)で作るアスキーアートのようなものです。
でもこの場合

3行目:   #define VRAM 0xa000
202行目: xy=(80*b+a)*2;
203行目: dat=peek(VRAM,xy);

などをみていると、"ドット"ならぬ"半角文字"を点単位とした24×80のスクリーンの各点が、特定のアドレスに割り当て割れているんでしょうかね。
浅学なもので"エクステンダ"なるものがどんなマッピングをしているのかは分かりません。。。

お礼日時:2003/12/14 05:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!