Browse Source

- When trying to delete a line number including 0x0d such as 13, the program took a broken bug
- Change processing system from Turbo C2.0 to Visual C ++ 1.51
- Significantly improved loading speed
- Only the .wb entrance menu is displayed
- Sample game STAR WITCH (star.wb, star.txt) attached

Version 0.04 - from wonbe004.lzh

Kawamata Akira 23 years ago
parent
commit
3bc39a53f1
10 changed files with 1192 additions and 187 deletions
  1. 21 10
      makefile
  2. 44 0
      star.txt
  3. 501 0
      star.wb
  4. 310 0
      vc15_rt.asm
  5. 33 23
      win32text.c
  6. 270 150
      wonbe.c
  7. 3 1
      wonbe.dsp
  8. BIN
      wonbe.exe
  9. BIN
      wonbe.fx
  10. 10 3
      wonbe.txt

+ 21 - 10
makefile

@@ -1,23 +1,34 @@
+INCLUDE=C:\vshare\ww\dev\WWitch\include
+LIB=..\COMMON
 
-# start up routine
-C0WW_JAPANESE2=..\common\c0wwjpn2.obj
+LIBS=libww.lib runtime.lib
 
-C0WW=$(C0WW_JAPANESE2)
+LINKER=..\..\vc15\bin\link
+CC=..\..\vc15\bin\cl
+ASM=..\..\vc15\bin\masm
 
-LIBWW=@..\common\libww.rsp
-
-CFLAGS=-DWW -ms -zPCGROUP -zSDGROUP -zGDGROUP
+CFLAGS=/ASw /O /Gs /DWW
+AFLAGS=-Mx -DDISPLAY_MODE_JAPANESE1
+LFLAGS=/NOD /NOI /MAP
 
 all:	wonbe.fx
 
 wonbe.fx:	wonbe.bin
 	mkfent wonbe.cf
 
-wonbe.bin:	wonbe.obj
-	tlink /m /c $(C0WW) wonbe, wonbe, wonbe, $(LIBWW)
-	exe2fbin wonbe.exe wonbe.bin
+wonbe.bin:	wonbe.obj vc15_rt.obj
+	$(LINKER) @<<
+$(LFLAGS) vc15_rt.obj wonbe.obj,wonbe.sss,wonbe.map,$(LIBS);
+<<
+	echo 0000 >0000.sss
+	exe2bin wonbe.sss wonbe.bin <0000.sss
+	echo remove temp file
+	del 0000.sss
+	del wonbe.sss
 
 wonbe.obj:	wonbe.c
-	tcc -c $(CFLAGS) $(DEFINES) -IC:\vshare\ww\dev\WWitch\include wonbe.c
+	$(CC) -c $(CFLAGS) wonbe.c
 
+vc15_rt.obj: vc15_rt.asm
+	$(ASM) $(AFLAGS) vc15_rt.asm;
 

File diff suppressed because it is too large
+ 44 - 0
star.txt


+ 501 - 0
star.wb

@@ -0,0 +1,501 @@
+cls:print"Loading STAR WITCH..."
+locate 10,10:print "○○○○";
+100 cls:gosub 17000 'オープニング
+1000 cls
+1010 print "┏━━━━━━━━━┳━━━━━━━┳━━━━━━━━┓";
+1020 print "┃ 12345678┃       ┃        ┃";
+1030 print "┃1        ┃ENERGY ┃   ジャンプ ┃";
+1040 print "┃2        ┃       ┃        ┃";
+1050 print "┃3        ┃MISSILE┃   バーニア ┃";
+1060 print "┃4        ┃       ┃        ┃";
+1070 print "┃5        ┃LEFT   ┃   ウェーブ ┃";
+1080 print "┃6        ┃       ┃        ┃";
+1090 print "┃7        ┃DAY    ┃   ミサイル ┃";
+1100 print "┃8        ┃       ┃        ┃";
+1110 print "┣━━━━━━━━━┻━━━━━━━┻━━━━━━━━┫";
+1120 print "┃                          ┃";
+1130 print "┃                          ┃";
+1140 print "┃                          ┃";
+1150 print "┃                          ┃";
+1160 print "┃                          ┃";
+1170 print "┗━━━━━━━━━━━━━━━━━━━━━━━━━━┛";
+1175 print "   STAR WITCH ~ゴブリン帝国の野望~";
+1180 rem    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
+1190 rem
+2000 rem 初期化
+2005 randomize tick
+2010 E=4000 'EはWITCH号のエネルギー
+2020 M=10   'MはWITCH号の所持ミサイル
+2030 L=10   'Lはクリアすべきエリアの残り数
+2040 D=1    'Dは現在の日数 (1アクション1日)
+2042 S=0    'WITCH号のX位置
+2044 T=0    'WITCH号のY位置
+2050 A=0    '@(A)~@A(A+8*8-1)までが現在エリアの内容
+2060        '0:なし -1:小惑星 -2:輸送船
+2061        '正数はゴブリン戦艦でエネルギー量
+2065 W=A+8*8 'ワークエリアに使って良い配列の先頭位置
+2070 B=0    'エリア作成時の輸送船の数
+2080 G=0    'エリア作成時のゴブリン戦艦の数
+2090 S=1+rnd(4)    'エリア作成時の小惑星の数
+2095 H=0    '通算の撃破ゴブリン戦艦数
+2100 P=11   'メッセージエリアのY位置 (良く参照されるので変数に置く)
+2200 rem エリア進入
+2210 gosub 10000
+3000 rem ターン開始
+3010 gosub 25000 'ステータス更新
+3020 gosub 12000 '補給チェックと実行
+3030 gosub 11000 '敵の攻撃
+3100 rem コマンド選択
+3105 gosub 20000:locate 2,P+2:print "艦長、ご指示を";
+3110 c=0
+3120 locate 20, 2+(c*2):print "→";
+3200 s=wait
+3205 locate 20, 2+(c*2):print " ";
+3210 if s and scan_a then goto 4000+(c*1000)
+3220 if s and scan_x1 then c=c-1:if c<0 then c=3
+3230 if s and scan_x3 then c=c+1:if c>3 then c=0
+3290 goto 3120
+4000 '*******ジャンプ*******
+4010 f=0
+4020 for y=0 to 7:for x=0 to 7
+4030 if @(A+x+y*8) > 0 then f=f+1
+4040 next:next
+4050 if f=0 then goto 4200
+4060 gosub 20000
+4070 locate 2,P+1:print "艦長!";
+4080 locate 2,P+3:print "ゴブリン戦艦がまだ";f;"隻もいます!"
+4090 d=wait
+4100 gosub 20000
+4110 goto 3100
+4200 ' 行き先候補
+4210 gosub 20000
+4215 locate 2,P:print "目的地を指示してください"
+4220 for i=0 to 2
+4230 @(W+i*3)=1+rnd(5) 'ゴブリン戦艦1~5隻
+4240 @(W+i*3+1)=0:if rnd(3)=0 then @(W+i*3+1)=1 '輸送船は1/3の確率
+4250 @(W+i*3+2)=1+rnd(4) '小惑星1~5個
+4260 locate 4,P+1+i
+4270 print "ゴブリン";@(W+i*3);
+4280 print " 輸送船";@(W+i*3+1);
+4290 print " 小惑星"@(W+i*3+2);
+4300 next
+4400 rem 候補を選ぶ
+4410 c=0
+4420 locate 2, P+1+c:print "→";
+4500 s=wait
+4505 locate 2, P+1+c:print " ";
+4510 if s and scan_a then goto 4600
+4520 if s and scan_x1 then c=c-1:if c<0 then c=2
+4530 if s and scan_x3 then c=c+1:if c>2 then c=0
+4590 goto 4420
+4600 ' 次のエリアに行く
+4610 B=@(W+c*3+1)
+4620 G=@(W+c*3)
+4630 S=@(W+c*3+2)
+4700 gosub 20000
+4710 locate 2,P+1:print "ハイパースペース・ドライブ";
+4720 locate 2,P+3:print "  スタンバイOK!"
+4730 d=wait
+4740 gosub 20000
+4750 locate 2,P+2:print "次のエリアにジャンプします";
+4760 d=wait
+4780 gosub 20000
+4785 for y=0 to 7:for x=0 to 7:locate 2+x,2+y:print "※";:next:next
+4790 waitvb 75
+4795 if E>10 then E=E-10:goto 4800
+4796 locate 2,P+1:print "艦長! エネルギーが足りません!";
+4797 locate 4,P+3:print "通常空間に復帰できません!!";
+4798 d=wait:goto 19000
+4800 locate 2,P+2:print "ジャンプ成功! レーダー動作します";
+4810 d=wait
+4820 gosub 20000
+4890 D=D+1:L=L-1:goto 2200
+locate 10,10:print "●○○○";
+5000 '******バーニア*******
+5010 gosub 20000
+5020 locate 2,P+1:print "エリア内移動・スタンバイ";
+5030 locate 2,P+3:print "コースは? (0-360)";
+5040 X=21:Y=P:gosub 21000
+5050 if Z<0 then goto 3100 'キャンセルされた
+5060 if Z<=360 then s=Z:goto 5100
+5070 gosub 20000
+5080 locate 2,P+1:print "艦長!";
+5090 locate 2,P+3:print "コースは0から360までです!";
+5095 d=wait:goto 5010
+5100 gosub 20000
+5110 locate 2,P+1:print "エリア内移動・スタンバイ";
+5120 locate 2,P+3:print "距離は? (1-12)";
+5130 X=21:Y=P:gosub 21000
+5140 if Z<0 then goto 5010 'キャンセルされた
+5145 if Z>E+1 then goto 5190
+5150 if Z>=1 and Z<=12 then l=Z:E=E-l:goto 5200
+5155 gosub 20000
+5160 locate 2,P+1:print "艦長!";
+5170 locate 2,P+3:print "距離は1から12までです!";
+5180 d=wait:goto 5100
+5190 gosub 20000
+5192 locate 2,P+1:print "艦長!";
+5194 locate 2,P+3:print "エネルギーが足りません!";
+5198 d=wait:goto 5100
+5200 '移動アニメーション
+5210 gosub 20000
+5215 'locate 2+S,2+T:print " ";
+5220 X=s:gosub 23000:a=Y
+5230 X=s:gosub 22000:b=-Y '反時計回りにしたいのでマイナス
+5235 c=S:d=T '最後に有効であった座標を持つ
+5240 i=1:j=0 'iは本当の移動距離。jは見かけ上の移動距離
+5250 x=S+a*i/100
+5260 y=T+b*i/100
+5261 'debug S,T,x,y,a,b,i,s
+5262 if x<0 or x>7 or y<0 or y>7 then goto 5400
+5264 if @(A+x+y*8)=0 then goto 5270
+5266 gosub 20000:locate 2,P+2:print "衝突回避! 緊急停止!";d=wait
+5268 goto 5400 'ループを強制終了させる
+5270 if c=x and d=y then goto 5300 '見かけ上の移動が起きていない
+5272 j=j+1
+5275 locate 2+x,2+y:print "W";
+5280 locate 2+c,2+d:print " ";:c=x:d=y
+6285 D=D+1:gosub 25000
+5290 waitvb 75
+5300 i=i+1:if j<l then goto 5250
+5400 S=c:T=d
+5410 locate 2+S,2+T:print "W";
+5500 goto 3000
+6000 '*****ウェーブ*****
+6010 gosub 20000
+6020 locate 2,P+1:print "ウェーブキヤノン・スタンバイ";
+6030 locate 2,P+3:print " エネルギー量は? (1-";E-1;")";
+6040 X=21:Y=P:gosub 21000
+6050 if Z<0 then goto 3100 'キャンセルされた
+6060 if Z>=1 and Z<=E-1 then s=Z:goto 6100
+6070 gosub 20000
+6080 locate 2,P+1:print "艦長!";
+6090 locate 2,P+3:print " エネルギー量は1から";E-1;"までです!";
+6095 d=wait:goto 6010
+6100 gosub 20000
+6110 ' 存在するオブジェクト数を数える
+6120 f=0
+6130 for y=0 to 7:for x=0 to 7
+6140 if @(A+x+y*8) <> 0 then f=f+1
+6150 next:next
+6160 e=s/f:if e<1 then e=1 'eは1標的あたりの攻撃量
+6170 gosub 20000
+6180 locate 2,P+2:print "ウェーブキヤノン・発射!";
+6190 d=wait
+6200 for y=0 to 7:for x=0 to 7
+6210 if @(A+x+y*8) <= 0 then goto 6400
+6220 gosub 20000
+6230 locate 2,P+1:print "(";x+1;",";y+1;")のゴブリン戦艦にダメージ";e;
+6240 @(A+x+y*8)=@(A+x+y*8)-e:if @(A+x+y*8)<=0 then @(A+x+y*8)=0:goto 6300
+6245 locate 4,P+3:print "(残りエネルギー";@(A+x+y*8);")";
+6250 d=wait
+6290 goto 6400
+6300 locate 4,P+3:print "ゴブリン戦艦、撃沈!";:H=H+1
+6350 X=x:Y=y:gosub 24000 '爆発
+6400 next:next
+6900 E=E-s:
+6910 if L=0 then gosub 26000:if Y=0 then goto 18000
+6920 D=D+1:goto 3000
+locate 10,10:print "●●○○";
+7000 '******ミサイル******
+7010 if M>0 then goto 7100
+7020 gosub 20000
+7030 locate 2,P+1:print "艦長!";
+7040 locate 2,P+3:print "ミサイルの残弾はゼロです!";
+7050 d=wait
+7090 goto 3100
+7100 gosub 20000
+7110 locate 2,P+1:print "ミサイル・スタンバイ";
+7120 locate 2,P+3:print "コースは? (0-360)";
+7130 X=21:Y=P:gosub 21000
+7140 if Z<0 then goto 3100 'キャンセルされた
+7150 if Z<=360 then s=Z:goto 7200
+7160 gosub 20000
+7170 locate 2,P+1:print "艦長!";
+7180 locate 2,P+3:print "コースは0から360までです!";
+7190 d=wait:goto 7100
+7200 '移動アニメーション
+7205 M=M-1:gosub 25000
+7210 gosub 20000
+7220 X=s:gosub 23000:a=Y
+7230 X=s:gosub 22000:b=-Y '反時計回りにしたいのでマイナス
+7235 i=1
+7240 c=S:d=T '最後に有効であった座標を持つ
+7250 x=S+a*i/100
+7260 y=T+b*i/100
+7270 'debug S,T,x,y,a,b,i,s
+7280 if x<0 or x>7 or y<0 or y>7 then goto 7500
+7290 if @(A+x+y*8)<>0 then goto 7600
+7320 if c=x and d=y then goto 7370 '見かけ上の移動が起きていない
+7340 locate 2+x,2+y:print "M";
+7350 waitvb 75
+7360 locate 2+x,2+y:print " ";:c=x:d=y
+7370 i=i+1:goto 7250
+7400 goto 3000
+7500 'はずれ!
+7510 gosub 20000
+7515 locate 2,P+1:print "艦長!";
+7520 locate 4,P+3:print "攻撃は失敗です!";
+7530 d=wait
+7590 D=D+1:goto 3000
+7600 'あたり!
+7610 gosub 20000
+7620 locate 2,P+1:print "艦長!";
+7630 locate 4,P+3
+7640 if @(A+x+y*8)=-1 then print "小惑星に命中しました!";
+7650 if @(A+x+y*8)=-2 then print "輸送船に命中しました!";
+7660 if @(A+x+y*8)>0 then print "ゴブリン戦艦に命中しました!";
+7670 X=x:Y=y:gosub 24000 '爆発
+7680 'd=wait
+7690 gosub 20000
+7700 locate 4,P+2
+7710 if @(A+x+y*8)=-1 then print "小惑星の消滅を確認!";
+7720 if @(A+x+y*8)=-2 then print "輸送船乗組員の救助のため10日必要です";:D=D+1
+7730 if @(A+x+y*8)>0 then print "ゴブリン戦艦を撃沈!";:H=H+1
+7740 @(A+x+y*8)=0 'そこにはもう何もない
+7750 d=wait
+7760 if L=0 then gosub 26000:if Y=0 then goto 18000
+7790 D=D+1:goto 3000
+
+10000 rem エリア作成
+10005 for y=0 to 7:for x=0 to 7:@(A+x+y*8)=0:next:next
+10010 if B=0 then goto 10100
+10020 for i=0 to B-1
+10030 x=rnd(8):y=rnd(8)
+10040 if @(A+x+y*8) <> 0 then goto 10030
+10050 @(A+x+y*8)=-2
+10060 next
+10100 if G=0 then goto 10200
+10105 for i=0 to G-1
+10110 x=rnd(8):y=rnd(8)
+10120 if @(A+x+y*8) <> 0 then goto 10110
+10130 @(A+x+y*8)=400+rnd(200) 'ゴブリン戦艦のエネルギー初期値
+10140 next
+10200 for i=0 to S-1
+10210 x=rnd(8):y=rnd(8)
+10220 if @(A+x+y*8) <> 0 then goto 10210
+10230 @(A+x+y*8)=-1
+10240 next
+10250 'WITCH号の位置を確定
+10260 S=rnd(7):T=rnd(7)
+10270 if @(A+S+T*8) <> 0 then goto 10260
+10300 gosub 10500
+10400 return
+10500 'レーダー作動
+10510 for y=0 to 7:for x=0 to 7
+10520 locate x+2,y+2
+10530 t=@(A+x+y*8)
+10540 if t=0 then print " ";
+10550 if t=-1 then print "*";
+10560 if t=-2 then print "T";
+10570 if t>0 then print "G";
+10580 next:next
+10590 locate S+2,T+2:print "W";
+10600 return
+
+11000 '*****敵の攻撃*****
+11010 for y=0 to 7:for x=0 to 7
+11020 if @(A+x+y*8) <= 2 then goto 11900
+11025 n=@(A+x+y*8)/4+rnd(@(A+x+y*8)/2):if n<1 then 11900
+11030 gosub 20000
+11040 locate 2,P+1:print "(";x+1;",";y+1;")のゴブリン戦艦よりの攻撃!";
+11050 d=wait
+11070 locate 4,P+3:print "WITCH号に";n;"のダメージ!";
+11075 @(A+x+y*8)=@(A+x+y*8)-n
+11080 E=E-n:if E<0 then E=0
+11090 gosub 25000
+11100 d=wait
+11110 if E>0 then goto 11900
+11120 gosub 20000
+11130 locate 2,P+1:print "艦長!";
+11130 locate 4,P+3:print "エネルギーがもうありません!";
+11140 gosub 20000
+11150 locate 2,P+1:print "防御バリア機能停止";
+11160 locate 4,P+3:print "WITCH号の船体が砕けます!";
+11170 X=S:Y=T:gosub 24000 '爆発
+11180 gosub 20000
+11190 goto 19000 'BAD ENDING
+11900 next:next
+11910 return
+
+locate 10,10:print "●●●○";
+
+12000 '補給チェックと実行
+12020 f=0
+12030 if S>0 then if @(A+(S-1)+T*8)=-2 then f=1
+12040 if S<7 then if @(A+(S+1)+T*8)=-2 then f=1
+12050 if T>0 then if @(A+S+(T-1)*8)=-2 then f=1
+12060 if T<7 then if @(A+S+(T+1)*8)=-2 then f=1
+12070 if f=0 then return
+12080 gosub 20000
+12090 locate 2,P+1:print "艦長!";
+12100 locate 4,P+3:print "輸送船から補給を受けます。";
+12110 d=wait
+12120 E=4000:M=10
+12130 gosub 25000 'ステータス更新
+12190 return
+
+17000 'OPENING
+17010 cls
+17020 for i=0 to 1
+17030 locate 2,2:print "緊急指令!"
+17040 waitvb 30
+17050 locate 2,2:print "     "
+17060 waitvb 30
+17070 next
+17100 locate 2,2:print "緊急指令!"
+17110 cls:print
+17120 waitvb 30:print "  かねてより":print
+17130 waitvb 30:print "  我が地球連邦政府に敵対していた":print
+17140 waitvb 30:print "  凶悪なゴブリン帝国が":print
+17150 waitvb 30:print "  多数の宇宙戦艦で侵攻してきた":print
+17155 print
+17160 waitvb 30:print "  連邦艦隊ナンバーワン艦長の君に命じる":print
+17170 waitvb 30:print "  最新鋭戦艦WITCH号を指揮し":print
+17180 waitvb 30:print "  侵入したゴブリン戦艦を撃破せよ"
+17190 d=wait
+
+17200 cls
+17210 for i=0 to 4
+17220 if i=4 then locate 2, 2:print"  ■■■ ■■■■■  ■    ■■■■"
+17230 if i=3 then locate 2, 3:print" ■      ■   ■ ■   ■   ■"
+17240 if i=2 then locate 2, 4:print"  ■■■   ■   ■■■   ■■■■"
+17250 if i=1 then locate 2, 5:print"     ■  ■  ■   ■  ■  ■"
+17260 if i=0 then locate 2, 6:print"  ■■■   ■ ■     ■ ■   ■"
+17270 if i=0 then locate 2, 9:print"■  ■  ■ ■ ■■■  ■■■   ■  ■"
+17280 if i=1 then locate 2,10:print"■ ■ ■ ■ ■  ■  ■   ■  ■  ■"
+17290 if i=2 then locate 2,11:print"■ ■ ■ ■ ■  ■  ■      ■■■■"
+17300 if i=3 then locate 2,12:print"■ ■ ■ ■ ■  ■  ■   ■  ■  ■"
+17310 if i=4 then locate 2,13:print" ■   ■  ■  ■   ■■■   ■  ■"
+17320 waitvb 30:next
+17330 locate 9,15:print "~ゴブリン帝国の野望~";
+17340 d=wait
+17400 cls
+17410 print " ***WITCH号の最新装備を紹介する***":print
+17420 waitvb 30:print " 量子レーダー:"
+17430 print "  W←WITCH号 *←小惑星"
+17440 print "  G←ゴブリン戦艦 T←輸送船":print
+17450 waitvb 30:print " 超空間ジャンプドライブ:"
+17460 print "  エリア内の敵を全滅させたら次のエリアに進める。":print
+17470 waitvb 30:print " バーニア:"
+17480 print "  エリア内を移動できる。":print
+17490 waitvb 30:print " ウェーブキヤノン:"
+17500 print "  エリア内のすべての敵を同時攻撃":print
+17510 waitvb 30:print " 反応弾頭ミサイル:"
+17520 print "  敵艦も小惑星も一撃で粉砕する"
+17590 d=wait
+17600 cls
+17610 locate 8,8:print "それでは健闘を祈る!"
+17690 d=wait
+17700 cls
+17710 locate 5,8:print "艦長! WITCH号、出港します!"
+17790 d=wait
+17900 return
+
+18000 'GOOD ENDING
+18010 cls:print
+18020 waitvb 75:print " 作戦開始後";D;"日":print
+18030 waitvb 75:print " ";H;"隻の戦艦を失った":print
+18032 waitvb 75:print " ゴブリン帝国は、全面降伏した":print
+18035 waitvb 75:print " 宇宙の平和は守られたのだ":print
+18040 waitvb 75:print " WITCH号ならびに艦長の活躍をたたえ":print
+18050 waitvb 75:print " 全人類から感謝の言葉をおくる":print
+18060 waitvb 75:locate 10,14:print "ありがとう!"
+18070 waitvb 75:locate 10,16:print "CONGRATURATIONS!";
+18080 d=wait
+18090 end
+
+locate 10,10:print "●●●●";
+
+19000 'BAD ENDING
+19010 cls:print
+19020 waitvb 75:print " 作戦開始後";D;"日":print
+19030 waitvb 75:print " WITCH号、宇宙の藻屑と消える":print
+19040 waitvb 75:print " この日、地球連邦政府は、ゴブリン帝国に降伏":print
+19050 waitvb 75:print " 地球人はゴブリン帝国の奴隷となった":print
+19060 waitvb 75:locate 17,16:print "GAME OVER!";
+19080 d=wait
+19090 end
+20000 ' clear message
+20010 for i=11 to 15:locate 1,i
+20020 print "                          ";
+20030 next
+20040 return
+21000 ' 数値入力
+21010 locate X,Y+0:print "┏━━━━┓";
+21020 locate X,Y+1:print "┃    ┃";
+21030 locate X,Y+2:print "┃0000┃";
+21040 locate X,Y+3:print "┃    ┃";
+21050 locate X,Y+4:print "┗━━━━┛";
+21100 for i=0 to 3:@(W+i)=0:next
+21110 v=3 '桁位置
+21200 locate X+v+1,Y+1:print "↑";
+21210 locate X+v+1,Y+3:print "↓";
+21220 for i=0 to 3:locate X+i+1,Y+2:print @(W+i);:next
+21300 s=wait
+21310 locate X+v+1,Y+1:print " ";
+21320 locate X+v+1,Y+3:print " ";
+21330 if s and scan_x3 then @(W+v)=@(W+v)-1:if @(W+v)<0 then @(W+v)=9
+21340 if s and scan_x1 then @(W+v)=@(W+v)+1:if @(W+v)>9 then @(W+v)=0
+21350 if s and scan_x2 then v=v+1:if v>3 then v=0
+21360 if s and scan_x4 then v=v-1:if v<0 then v=3
+21365 if s and scan_a then goto 21400
+21370 if s and scan_b then Z=-1:return
+21380 goto 21200
+21400 Z=@(W+0)*1000+@(W+1)*100+@(W+2)*10+@(W+3)
+21410 return
+
+22000 ' 疑似三角関数(Y=sin(X)) Y=-100...100 X=0-360
+22010 X=X/5
+22020 if X<=18 then gosub 22100:return
+22030 if X<=36 then X=36-X:gosub 22100:return
+22040 if X<=54 then X=X-36:gosub 22100:Y=-Y:return
+22050 if X<=72 then X=72-X:gosub 22100:Y=-Y:return
+22060 X=X-72:goto 22020
+22100 if X=0  then Y=0
+22110 if X=1  then Y=8
+22120 if X=2  then Y=17
+22130 if X=3  then Y=25
+22140 if X=4  then Y=34
+22150 if X=5  then Y=42
+22160 if X=6  then Y=49
+22170 if X=7  then Y=57
+22180 if X=8  then Y=64
+22190 if X=9  then Y=70
+22200 if X=10 then Y=76
+22210 if X=11 then Y=81
+22220 if X=12 then Y=86
+22230 if X=13 then Y=90
+22240 if X=14 then Y=93
+22250 if X=15 then Y=96
+22260 if X=16 then Y=98
+22270 if X=17 then Y=99
+22280 if X=18 then Y=99
+22290 return
+23000 ' 疑似三角関数(cos)
+23010 X=X+90:gosub 22000:return
+24000 ' 爆発アニメーション
+24005 locate 2+X,2+Y:print "・";:waitvb 30
+24010 locate 2+X,2+Y:print "●";:waitvb 30
+24020 locate 2+X,2+Y:print "※";:waitvb 30
+24030 locate 2+X,2+Y:print " ";
+24040 d=wait
+24090 return
+25000 '******ステータス表示更新*****
+25010 locate 11,3:print "       ";
+25020 locate 14,3:print E;
+25030 locate 11,5:print "       ";
+25040 locate 14,5:print M;
+25050 locate 11,7:print "       ";
+25060 locate 14,7:print L;
+25070 locate 11,9:print "       ";
+25080 locate 14,9:print D;
+25090 return
+26000 ' エリア内残り敵戦艦を数えてYに返す
+26010 Y=0
+26020 for y=0 to 7:for x=0 to 7
+26030 if @(A+x+y*8)>0 then Y=Y+1
+26040 next:next
+26090 return
+
+cls:print"Loading Completed"

+ 310 - 0
vc15_rt.asm

@@ -0,0 +1,310 @@
+;***
+;vc15_rt.asm: Wonder Witch Start-up code for Visual C++ 1.5x
+;
+
+SRAM_SEG		equ	1000h
+
+MAXPATHLEN		equ	64
+
+INT_EXIT		equ	10h
+INT_DISP		equ	12h
+INT_TEXT		equ	13h
+
+DISPLAY_CONTROL		equ	00h
+SPRITE_SET_RANGE	equ	0bh
+SCREEN_SET_SCROLL	equ	13h
+SCREEN2_SET_WINDOW	equ	15h
+SPRITE_SET_WINDOW	equ	17h
+SCREEN_SET_VRAM		equ	21h
+SPRITE_SET_VRAM		equ	22h
+
+TEXT_SCREEN_INIT	equ	00h
+TEXT_SET_MODE		equ	02h
+TEXT_SET_SCREEN		equ	0eh
+
+TEXT_MODE_ANK		equ	0
+TEXT_MODE_ANK_SJIS	equ	1
+TEXT_MODE_SJIS		equ	2
+
+SCREEN1			equ	0
+SCREEN2			equ	1
+
+DCM_SCR1		equ	1
+DCM_SCR2		equ	2
+
+V_SPRITE_START		equ	0
+V_SPRITE_COUNT		equ	0
+
+ifdef DISPLAY_MODE_JAPANESE1
+V_DISPLAY_CONTROL	equ	DCM_SCR2
+V_TEXT_SCREEN		equ	SCREEN2
+V_TEXT_MODE		equ	TEXT_MODE_ANK_SJIS
+V_SCREEN1_VRAM		equ	3		; duplicated with screen2
+V_SCREEN2_VRAM		equ	3
+V_SPRITE_VRAM		equ	11
+V_STACK_TOP		equ	01600h
+endif
+
+ifdef DISPLAY_MODE_JAPANESE2
+V_DISPLAY_CONTROL	equ	DCM_SCR1 + DCM_SCR2
+V_TEXT_SCREEN		equ	SCREEN2
+V_TEXT_MODE		equ	TEXT_MODE_ANK_SJIS
+V_SCREEN1_VRAM		equ	2
+V_SCREEN2_VRAM		equ	3
+V_SPRITE_VRAM		equ	7
+V_STACK_TOP		equ	00e00h
+endif
+
+ifdef DISPLAY_MODE_ASCII1
+V_DISPLAY_CONTROL	equ	DCM_SCR2
+V_TEXT_SCREEN		equ	SCREEN2
+V_TEXT_MODE		equ	TEXT_MODE_ANK
+V_SCREEN1_VRAM		equ	6		; duplicated with screen2
+V_SCREEN2_VRAM		equ	6
+V_SPRITE_VRAM		equ	23
+V_STACK_TOP		equ	02e00h
+endif
+
+ifdef DISPLAY_MODE_ASCII2
+V_DISPLAY_CONTROL	equ	DCM_SCR1 + DCM_SCR2
+V_TEXT_SCREEN		equ	SCREEN2
+V_TEXT_MODE		equ	TEXT_MODE_ANK
+V_SCREEN1_VRAM		equ	6
+V_SCREEN2_VRAM		equ	5
+V_SPRITE_VRAM		equ	19
+V_STACK_TOP		equ	02600h
+endif
+
+_TEXT		segment byte public 'CODE'
+_TEXT		ends
+
+TEXT		segment byte public 'CODE'
+TEXT		ends
+
+_DATA		segment para public 'DATA'
+dseg_start	proc	far
+dseg_start	endp
+_DATA		ends
+
+DATA		segment para public 'DATA'
+DATA		ends
+
+CONST		segment para public 'CONST'
+CONST		ends
+
+_BSS		segment word public 'BSS'
+bss_start	proc	far
+bss_start	endp
+_BSS		ends
+
+BSS		segment word public 'BSS'
+BSS		ends
+
+c_common		segment word public 'BSS'
+c_common		ends
+
+_HEAP		segment para public 'HEAP'
+heap_start	proc	far
+heap_start	endp
+_HEAP		ends
+
+CGROUP		group   _TEXT, TEXT
+DGROUP		group   _DATA, DATA, CONST, _BSS, BSS, c_common, _HEAP
+
+     		assume  cs:CGROUP, ds:DGROUP, es:DGROUP
+
+_TEXT		segment byte public 'CODE'
+		extrn	_main	:near
+		public	_load0
+		public	_run0
+		public	_exit0
+
+_load0		proc	far
+		push	ds
+
+		push	di
+		push	si
+		push	cx
+		push	bx
+
+; calcurate initialized data size
+		mov	cx, offset DGROUP:bss_start
+		shr	cx, 1		; word alignmented
+
+; copy initialized data into user ds
+		mov	ax, cs
+		sub	ax, CGROUP
+;		add	ax, seg dseg_start
+		add	ax, DGROUP
+		mov	ds, ax
+		mov	ax, SRAM_SEG
+		mov	es, ax
+		mov	si, offset DGROUP:dseg_start
+		mov	di, si
+	rep	movsw
+
+; clear bss
+		mov	cx, offset DGROUP:heap_start
+		push	cx
+		mov	di, offset DGROUP:bss_start
+		sub	cx, di
+		shr	cx, 1
+		xor	ax, ax
+	rep	stosw
+
+; calcurate heap start position
+; set argv starting position at heap start
+		pop	es:[__argv]
+
+		mov	dx, cs
+		mov	ax, offset _run0
+
+		pop	bx
+		pop	cx
+		pop	si
+		pop	di
+
+		pop	ds
+		ret
+_load0		endp
+
+_run0		proc	far ;C, argc :word, argv :near ptr
+		push	bp
+		mov	bp,sp
+		push	ds
+		mov	dx, SRAM_SEG
+		mov	es, dx
+		mov	ds, dx
+;		mov	ax, sp
+;		mov	word ptr ds:[__sp], ax
+;		mov	ax, ss
+;		mov	word ptr ds:[__sp + 2], ax
+
+;; setup SP according to the display modes
+
+;;	display_control(0);
+		mov	bx, 0
+		mov	ah, DISPLAY_CONTROL
+		int	INT_DISP
+
+;;	screen_set_scroll(SCREEN1, 0, 0);
+		mov	bx, 00000h
+		mov	al, SCREEN1
+		mov	ah, SCREEN_SET_SCROLL
+		int	INT_DISP
+
+;;	screen_set_scroll(SCREEN2, 0, 0);
+		mov	bx, 00000h
+		mov	al, SCREEN2
+		mov	ah, SCREEN_SET_SCROLL
+		int	INT_DISP
+
+;;	screen2_set_window(0, 0, 255, 255)
+		mov	cx, 0ffffh
+		mov	bx, 00000h
+		mov	ah, SCREEN2_SET_WINDOW
+		int	INT_DISP
+
+;;	sprite_set_window(0, 0, 255, 255)
+		mov	cx, 0ffffh
+		mov	bx, 00000h
+		mov	ah, SPRITE_SET_WINDOW
+		int	INT_DISP
+
+;;	text_set_screen(V_TEXT_SCREEN);
+		mov	al, V_TEXT_SCREEN
+		mov	ah, TEXT_SET_SCREEN
+		int	INT_TEXT
+
+;;	text_set_mode(V_TEXT_MODE);
+		mov	bx, V_TEXT_MODE
+		mov	ah, TEXT_SET_MODE
+		int	INT_TEXT
+
+;;	screen_set_vram(SCREEN1, V_SCREEN1_VRAM)
+		mov	bx, V_SCREEN1_VRAM
+		mov	al, SCREEN1
+		mov	ah, SCREEN_SET_VRAM
+		int	INT_DISP
+
+;;	screen_set_vram(SCREEN2, V_SCREEN2_VRAM)
+		mov	bx, V_SCREEN2_VRAM
+		mov	al, SCREEN2
+		mov	ah, SCREEN_SET_VRAM
+		int	INT_DISP
+
+;;	sprite_set_vram(SCREEN2, V_SCREEN2_VRAM)
+		mov	bx, V_SPRITE_VRAM
+		mov	ah, SPRITE_SET_VRAM
+		int	INT_DISP
+
+;;	sprite_set_range(V_SPRITE_START, V_SPRITE_COUNT)
+		mov	cx, V_SPRITE_COUNT
+		mov	bx, V_SPRITE_START
+		mov	ah, SPRITE_SET_RANGE
+		int	INT_DISP
+
+;;	display_control(V_DISPLAY_CONTROL);
+		mov	bx, V_DISPLAY_CONTROL
+		mov	ah, DISPLAY_CONTROL
+		int	INT_DISP
+
+		MOV	CX, [BP + 8]	; for argv	; mov	bx, argc
+		MOV	BX, [BP + 6]	; for argc	; mov	cx, argv
+
+		mov	ax, V_STACK_TOP
+		mov	sp, ax
+		push	cx	; argv
+		push	bx	; argc
+		call	_main
+_exit00:
+_exit0:
+		int	INT_EXIT
+		;mov	sp,bp
+		;pop	bp
+		;ret
+_run0		endp
+
+;_exit0:
+;		mov	ax, SRAM_SEG
+;		mov	es, ax
+;		les	ax, dword ptr es:[__sp]
+;		mov	sp, ax
+;		mov	ax, es
+;		mov	ss, ax
+;		jmp	_exit00
+_TEXT		ends
+
+_DATA		segment para public 'DATA'
+
+public	__acrtused		; trick to force in startup
+	__acrtused = 9876h	; funny value not easily matched in SYMDEB
+
+		public __id
+		public __pid
+		public __ppid
+		public __pcbid
+		public __ppcbid
+		public __ilib
+		public __proc
+		public __cwfs
+		public __currentdir
+		public __argv
+		public __heap
+;dseg_start:
+__id		db	'TCC', 0
+__pid		dw	?
+__ppid		dw	?
+__pcbid		dw	?
+__ppcbid	dw	?
+__ilib		dd	?
+__proc		dd	?
+__cwfs		dd	?
+__currentdir	db	MAXPATHLEN dup (?)
+__argv		dw	?
+__resource	dd	?
+__heap		dw	?
+_DATA		ends
+
+		end
+

+ 33 - 23
win32text.c

@@ -9,7 +9,8 @@
 #define SCREEN_SIZE_Y (144/8)
 static WORD screen[SCREEN_SIZE_X][SCREEN_SIZE_Y];
 
-static WORD lastChar;
+//static WORD lastChar;
+static UINT lastVKey;
 
 static HWND hwnd;
 
@@ -22,6 +23,7 @@ static void wmPaint( HWND hWnd, HDC hdc )
 
 	GetClientRect( hWnd, &rect );
 
+	SelectObject( hdc, GetStockObject( SYSTEM_FIXED_FONT ) );
 	GetTextMetrics( hdc, &tm );
 
 	xArea = SCREEN_SIZE_X * tm.tmMaxCharWidth;
@@ -48,11 +50,19 @@ static void wmPaint( HWND hWnd, HDC hdc )
 					rectDraw.top+y*tm.tmHeight,
 					str, 2 );
 			} else {
-				str[0] = (BYTE)val;
-				TextOut( hdc,
-					rectDraw.left+x*tm.tmMaxCharWidth,
-					rectDraw.top+y*tm.tmHeight,
-					str, 1 );
+				static char table[] = " !”#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|} ̄";
+				if( val >= 0x20 && val <= 0x7e ) {
+					TextOut( hdc,
+						rectDraw.left+x*tm.tmMaxCharWidth,
+						rectDraw.top+y*tm.tmHeight,
+						&table[(val-0x20)*2], 2 );
+				} else {
+					str[0] = (BYTE)val;
+					TextOut( hdc,
+						rectDraw.left+x*tm.tmMaxCharWidth,
+						rectDraw.top+y*tm.tmHeight,
+						str, 1 );
+				}
 			}
 		}
 	}
@@ -70,10 +80,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 		EndPaint(hWnd, &ps);
 		break;
 
-	case WM_CHAR:
-		lastChar = (WORD)wParam;
+	case WM_KEYDOWN:
+		lastVKey = (WORD)wParam;
 		break;
 
+	//case WM_CHAR:
+	//	lastChar = (WORD)wParam;
+	//	break;
+
 	case WM_CLOSE:
 		return 0;	// 閉じちゃ駄目
 
@@ -166,7 +180,8 @@ int createText()
     DWORD dwThreadId, dwThrdParam = 1; 
     HANDLE hThread; 
 
-	lastChar = 0;
+	//lastChar = 0;
+	lastVKey = 0;
     hThread = CreateThread( 
         NULL,                        // no security attributes 
         0,                           // use default stack size  
@@ -179,42 +194,37 @@ int createText()
 
 unsigned short win32_wait()
 {
-	WORD t;
+	UINT t;
 	while( TRUE ) {
 		// 以下の2行は本当はマルチスレッド的にNGなんだけど
 		// テスト用環境だから大目に見る
-		t = lastChar;
-		lastChar = 0;
+		t = lastVKey;
+		lastVKey = 0;
 		switch( t ) {
-		case 'p':
 		case 'P':
 			return 0x02;	// START BUTTON
-		case ' ':
+		case VK_SPACE:
 			return 0x04;	//KEYWORD_SCAN_A;
-		case 0x1b:
+		case VK_ESCAPE:
 			return 0x08;	//KEYWORD_SCAN_B;
-		case 'e':
+		case VK_UP:
 		case 'E':
 			return 0x10;	//KEYWORD_SCAN_X1;
-		case 'd':
+		case VK_RIGHT:
 		case 'D':
 			return 0x20;	//KEYWORD_SCAN_X2;
-		case 'x':
+		case VK_DOWN:
 		case 'X':
 			return 0x40;	//KEYWORD_SCAN_X3;
-		case 's':
+		case VK_LEFT:
 		case 'S':
 			return 0x80;	//KEYWORD_SCAN_X4;
-		case 't':
 		case 'T':
 			return 0x100;	//KEYWORD_SCAN_Y1;
-		case 'g':
 		case 'G':
 			return 0x200;	//KEYWORD_SCAN_Y2;
-		case 'v':
 		case 'V':
 			return 0x400;	//KEYWORD_SCAN_Y3;
-		case 'f':
 		case 'F':
 			return 0x800;	//KEYWORD_SCAN_Y4;
 		}

+ 270 - 150
wonbe.c

@@ -7,18 +7,22 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#ifdef WIN32
+#include <assert.h>
+#endif
 #ifdef WW
 #include <sys/comm.h>
 #include <sys/process.h>
 #include <sys/fcntl.h>
 #include <sys/bios.h>
+#define assert(x)
 #endif
 #include "keywords.h"
 #ifdef WIN32
 #include "win32text.h"
 #endif
 
-char myVersion[] = "0.03";
+char myVersion[] = "0.04";
 
 #ifdef WW
 #define MEMMOVE mymemmove
@@ -106,7 +110,7 @@ void consoleInput( BYTE * buf, WORD len )
 			if( ch == 0x08 ) {	/* BS */
 				if( cursor > 0 ) {
 					cursor--;
-					comm_send_char( ch );
+					comm_send_char( (unsigned char)ch );
 					continue;
 				}
 			}
@@ -119,7 +123,7 @@ inputAsChar:
 				if( cursor < len-1 ) {
 					buf[cursor] = ch;
 					cursor++;
-					comm_send_char( ch );
+					comm_send_char( (unsigned char)ch );
 				}
 			}
 		}
@@ -134,39 +138,91 @@ typedef struct {
 	const BYTE * name;
 } KEYWORDITEM;
 
-KEYWORDITEM keywords[] = {
-	{ KEYWORD_IF,"if" },
-	{ KEYWORD_PRINT,"print" },
-	{ KEYWORD_LOCATE,"locate" },
+KEYWORDITEM keywordsA[] = {
+	{ KEYWORD_AND,"and" },
+	{ KEYWORD_ABS,"abs" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsB[] = {
+	{ KEYWORD_BREAK,"break" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsC[] = {
+	{ KEYWORD_CHR,"chr" },
 	{ KEYWORD_CLS,"cls" },
+	{ KEYWORD_CONT,"cont" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsD[] = {
+	{ KEYWORD_DEBUG,"debug" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsE[] = {
+	{ KEYWORD_END,"end" },
+	{ KEYWORD_EXIT,"exit" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsF[] = {
+	{ KEYWORD_FOR,"for" },
+	{ KEYWORD_FILES,"files" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsG[] = {
 	{ KEYWORD_GOTO,"goto" },
 	{ KEYWORD_GOSUB,"gosub" },
-	{ KEYWORD_RETURN,"return" },
-	{ KEYWORD_FOR,"for" },
-	{ KEYWORD_NEXT,"next" },
-	{ KEYWORD_END,"end" },
-	{ KEYWORD_BREAK,"break" },
-	{ KEYWORD_REM,"rem" },
-	{ KEYWORD_NEW,"new" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsI[] = {
+	{ KEYWORD_IF,"if" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsL[] = {
+	{ KEYWORD_LOCATE,"locate" },
 	{ KEYWORD_LIST,"list" },
-	{ KEYWORD_RUN,"run" },
-	{ KEYWORD_CONT,"cont" },
-	{ KEYWORD_SAVE,"save" },
 	{ KEYWORD_LOAD,"load" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsM[] = {
 	{ KEYWORD_MERGE,"merge" },
-	{ KEYWORD_RANDOMIZE,"randomize" },
-	{ KEYWORD_EXIT,"exit" },
-	{ KEYWORD_DEBUG,"debug" },
-	{ KEYWORD_WAITVB,"waitvb" },
-	{ KEYWORD_FILES,"files" },
-	{ KEYWORD_AND,"and" },
-	{ KEYWORD_OR,"or" },
-	{ KEYWORD_XOR,"xor" },
+	{ 0,NULL }
+};
+KEYWORDITEM keywordsN[] = {
+	{ KEYWORD_NEXT,"next" },
 	{ KEYWORD_NOT,"not" },
-	{ KEYWORD_WAIT,"wait" },
+	{ KEYWORD_NEW,"new" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsO[] = {
+	{ KEYWORD_OR,"or" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsP[] = {
+	{ KEYWORD_PRINT,"print" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsR[] = {
+	{ KEYWORD_REM,"rem" },
+	{ KEYWORD_RETURN,"return" },
 	{ KEYWORD_RND,"rnd" },
-	{ KEYWORD_ABS,"abs" },
-	{ KEYWORD_TICK,"tick" },
+	{ KEYWORD_RUN,"run" },
+	{ KEYWORD_RANDOMIZE,"randomize" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsS[] = {
+	{ KEYWORD_STEP,"step" },
 	{ KEYWORD_SCAN_A,"scan_a" },
 	{ KEYWORD_SCAN_B,"scan_b" },
 	{ KEYWORD_SCAN_X1,"scan_x1" },
@@ -178,13 +234,37 @@ KEYWORDITEM keywords[] = {
 	{ KEYWORD_SCAN_Y3,"scan_y3" },
 	{ KEYWORD_SCAN_Y4,"scan_y4" },
 	{ KEYWORD_SCAN,"scan" },	/* scanはscna_Xより後になければならない */
+	{ KEYWORD_SAVE,"save" },
+	{ 0,NULL }
+};
+KEYWORDITEM keywordsT[] = {
 	{ KEYWORD_THEN,"then" },
-	{ KEYWORD_CHR,"chr" },
 	{ KEYWORD_TO,"to" },
-	{ KEYWORD_STEP,"step" },
+	{ KEYWORD_TICK,"tick" },
 	{ 0,NULL }
 };
 
+KEYWORDITEM keywordsW[] = {
+	{ KEYWORD_WAITVB,"waitvb" },
+	{ KEYWORD_WAIT,"wait" },	// waitはwaitvbより後になければならない
+	{ 0,NULL }
+};
+
+KEYWORDITEM keywordsX[] = {
+	{ KEYWORD_XOR,"xor" },
+	{ 0,NULL }
+};
+
+KEYWORDITEM * keywordsIndex[26] = {
+	keywordsA, keywordsB, keywordsC, keywordsD, 
+	keywordsE, keywordsF, keywordsG, NULL, 
+	keywordsI, NULL,      NULL,      keywordsL, 
+	keywordsM, keywordsN, keywordsO, keywordsP, 
+	NULL,      keywordsR, keywordsS, keywordsT, 
+	NULL,      NULL,      keywordsW, keywordsX, 
+	NULL,      NULL
+};
+
 /* インタラクティブモード時の1行バッファ */
 BYTE waRawLine[LINE_SIZE];
 BYTE waCoockedLine[LINE_SIZE];
@@ -254,6 +334,9 @@ int requestNextAction;	/* 
 #define REQUEST_MERGE_FILE 7
 /* REQUEST_RUN_LINENUMBERで実行開始をリクエストする行番号 */
 WORD runLineNumber;
+// 編集機能が追加専用モードであることを示す
+// REQUEST_RUN_FILE or REQUEST_LOAD_FILE経由で処理するときだけTRUEとなる
+BOOL appendMode = FALSE;
 
 /* エラー発生 */
 void syntaxError()
@@ -377,6 +460,14 @@ BYTE * skipToEOL( BYTE * p )
 	}
 }
 
+BYTE * skipToNextLine( BYTE * p )
+{
+	return skipToEOL( p+4 );	// +4は行番号2バイト行長さ2バイト
+}
+
+#if 1
+#define mytolower(ch) ((ch >= 'A' && ch <= 'Z')? ch - 'A' + 'a' : ch)
+#else
 BYTE mytolower( BYTE ch )
 {
 	if( ch >= 'A' && ch <= 'Z' ) {
@@ -384,6 +475,7 @@ BYTE mytolower( BYTE ch )
 	}
 	return ch;
 }
+#endif
 
 /* シフトJISの1バイト目かどうか判断。マクロなので副作用に注意 */
 #define IsDBCSLeadByte(ch) ((ch >= 0x81 && ch <= 0x9f) || (ch >= 0xe0 && ch <= 0xfc))
@@ -407,7 +499,7 @@ void processLineHeader()
 {
 	if( !bInteractive ) {
 		currentLineNumber = *((WORD *)executionPointer);
-		executionPointer += 2;
+		executionPointer += 4;	// +4は行番号2バイト行長さ2バイト
 	} else {
 		currentLineNumber = 0;
 	}
@@ -427,9 +519,7 @@ BYTE * getLineReferenceFromLineNumber( WORD lineNumber )
 		if( lineNumber == t ) {
 			return p;
 		}
-		p += 2;
-		p = skipToEOL( p );
-		p++;
+		p += *((WORD *)(p+2));
 	}
 }
 
@@ -446,9 +536,7 @@ BYTE * getInsertionPointFromLineNumber( WORD lineNumber )
 		if( lineNumber <= t ) {
 			return p;
 		}
-		p += 2;
-		p = skipToEOL( p );
-		p++;
+		p += *((WORD *)(p+2));
 	}
 }
 
@@ -519,7 +607,7 @@ void ptextTab()
 	xCursor = (xCursor+TABSTOP) / TABSTOP * TABSTOP;
 }
 
-void ptextString( const BYTE * msg )
+void ptextString( const BYTE FAR * msg )
 {
 	while( TRUE ) {
 		WORD ch;
@@ -591,7 +679,7 @@ BOOL sourceDump( FILE FAR * fp, WORD from, WORD to )
 		lineNumber = *((WORD*)p);
 		if( lineNumber == 0 ) break;
 		if( lineNumber > to ) break;
-		p += 2;
+		p += 4;
 		b = commonPrint(fp,"%d",lineNumber);
 		if( b == FALSE ) return FALSE;
 		while( TRUE ) {
@@ -626,29 +714,38 @@ BOOL sourceDump( FILE FAR * fp, WORD from, WORD to )
 					p++;
 				}
 			} else if( *p >= 0x80 ) {
-				KEYWORDITEM * k = keywords;
-				while( TRUE ) {
-					if( k->id == 0 ) {
-						b = commonPrint(fp,"[?%x?]", *p );
-						if( b == FALSE ) return FALSE;
-						p++;
-						break;
-					}
-					if( k->id == *p ) {
-						b = commonPrint(fp, k->name );
-						if( b == FALSE ) return FALSE;
-						p++;
-						if( k->id == KEYWORD_REM ) {	/* コメントのあとはそのまま行末まで転送 */
-							while( TRUE ) {
-								if( *p == EOL ) break;
-								b = commonPrint(fp,"%c",*p);
-								if( b == FALSE ) return FALSE;
-								p++;
+				int i;
+				BOOL found;
+				found = FALSE;
+				for( i=0; i<26; i++ ) {
+					KEYWORDITEM * k;
+					if( found ) break;
+					k = keywordsIndex[i];
+					if( k == NULL ) continue;
+					while( TRUE ) {
+						if( k->id == 0 ) break;
+						if( k->id == *p ) {
+							b = commonPrint(fp, k->name );
+							if( b == FALSE ) return FALSE;
+							p++;
+							if( k->id == KEYWORD_REM ) {	/* コメントのあとはそのまま行末まで転送 */
+								while( TRUE ) {
+									if( *p == EOL ) break;
+									b = commonPrint(fp,"%c",*p);
+									if( b == FALSE ) return FALSE;
+									p++;
+								}
 							}
+							found = TRUE;
+							break;
 						}
-						break;
+						k++;
 					}
-					k++;
+				}
+				if( !found ) {
+					b = commonPrint(fp,"[?%x?]", *p );
+					if( b == FALSE ) return FALSE;
+					p++;
 				}
 			} else {
 				b = commonPrint(fp,"%c",*p);
@@ -1516,13 +1613,21 @@ void editLine()
 {
 	WORD wishLineNumber;
 	BYTE ch, * p, * target;
-	/* トリックに注意! */
-	/* 行頭の整数を、行番号に変換するには結果的に先頭の0x01を取り去るだけで良い */
-	MEMMOVE( waCoockedLine, waCoockedLine+1, LINE_SIZE-1 );
-	/* トリック終わり。この時点でwsCoockedLineは、プログラム内部表現の形式に一致している */
-	wishLineNumber = *((WORD*)waCoockedLine);
-	p = waCoockedLine+2;
-	target = getLineReferenceFromLineNumber( wishLineNumber );
+	WORD lineNumber;
+
+	// プログラム領域に行を格納する場合は
+	// 先頭に2バイトの行番号と2バイトの行長さの情報が格納される
+	// 一方、中間言語翻訳の結果は先頭に0x01で始まる10進整数が行番号として入っている
+	// このギャップを転送時に解消しなければならない
+
+	// ここに来ているということは、waCoockedLine[0]が0x01つまり10進整数である //
+	assert( waCoockedLine[0] == 0x01 );
+	wishLineNumber = *((WORD*)&waCoockedLine[1]);
+	p = waCoockedLine+3;
+	//target = getLineReferenceFromLineNumber( wishLineNumber );
+	target = getInsertionPointFromLineNumber( wishLineNumber );
+	lineNumber = *((WORD*)target);
+
 	while( TRUE ) {
 		ch = *p++;
 		if( ch != ' ' && ch != '\t' ) break;
@@ -1531,37 +1636,31 @@ void editLine()
 		WORD delta;
 		BYTE * from;
 		/* removing the line */
-		if( target == NULL ) {
+		if( lineNumber == 0 || lineNumber != wishLineNumber ) {
 			lineNumberNotFound( wishLineNumber );
 			return;
 		}
-		from = skipToEOL(target)+1;
+		from = skipToNextLine(target);
 		delta = from-target;
 		MEMMOVE( target, from, (WORD)(dataTop-(from-wa)) );
 		dataTop -= delta;
-		/*clearRuntimeInfo();*/
 	} else {
-		WORD len;
-		len = skipToEOL(waCoockedLine+2)-waCoockedLine+1;
-		if( target == NULL ) {
+		WORD len;	// プログラム領域上に収めるときのサイズ
+		len = skipToEOL(p)-waCoockedLine-1+2+1; //-1は0x01の分。+2は長さ情報。+1はEOL
+		if( lineNumber == 0 || lineNumber != wishLineNumber ) {
 			/* insert new line */
-			/*const BYTE * to;*/
 			if( dataTop + len >= WORKAREA_SIZE ) {
 				outOfMemory();
 				return;
 			}
-			target = getInsertionPointFromLineNumber( wishLineNumber );
-			/* to = skipToEOL(target)+1; */
 			MEMMOVE( target+len, target, (WORD)(dataTop-(target-wa)) );
-			MEMMOVE( target, waCoockedLine, len );
 			dataTop += len;
-			/*clearRuntimeInfo();*/
 		} else {
 			/* replace line */
 			WORD lost;
 			BYTE * nextline;
 			int delta;
-			nextline = skipToEOL(target)+1;
+			nextline = skipToNextLine(target)+1;
 			lost = nextline-target;
 			delta = len-lost;
 			if( dataTop + delta >= WORKAREA_SIZE ) {
@@ -1569,13 +1668,42 @@ void editLine()
 				return;
 			}
 			MEMMOVE( nextline+delta, nextline, (WORD)(dataTop-(nextline-wa)) );
-			MEMMOVE( target, waCoockedLine, len );
 			dataTop += delta;
-			/*clearRuntimeInfo();*/
 		}
+		// まず行番号をコピーする
+		*((WORD*)target) = *((WORD*)&waCoockedLine[1]);
+		// 行の長さを収める
+		*((WORD*)(target+2)) = len;
+		// 残りをコピーする
+		MEMMOVE( target+4, waCoockedLine+3, (WORD)(len-4) );
 	}
 }
 
+/* 追加専門の行エディタ */
+void appendLine()
+{
+	BYTE * target;
+	WORD len;	// プログラム領域上に収めるときのサイズ
+	len = skipToEOL(waCoockedLine+3)-waCoockedLine-1+2+1; //-1は0x01の分。+2は長さ情報。+1はEOL
+	if( dataTop + len >= WORKAREA_SIZE ) {
+		outOfMemory();
+		return;
+	}
+	target = &wa[dataTop-5];	// -5 is len of last-line-marker
+	// まず行番号をコピーする
+	*((WORD*)target) = *((WORD*)&waCoockedLine[1]);
+	// 行の長さを収める
+	*((WORD*)(target+2)) = len;
+	// 残りをコピーする
+	MEMMOVE( target+4, waCoockedLine+3, (WORD)(len-4) );
+	dataTop += len;
+	wa[dataTop-5] = 0;
+	wa[dataTop-4] = 0;
+	wa[dataTop-3] = 0;
+	wa[dataTop-2] = 0;
+	wa[dataTop-1] = EOL;
+}
+
 /* 中間言語に翻訳する */
 BOOL convertInternalCode( BYTE * waCoockedLine, const BYTE * waRawLine )
 {
@@ -1583,6 +1711,8 @@ BOOL convertInternalCode( BYTE * waCoockedLine, const BYTE * waRawLine )
 	BYTE * dst = waCoockedLine;
 	while( TRUE ) {
 		if( *src == '\0' ) break;
+		if( *src == '\n' ) break;
+		if( *src == '\r' ) break;
 		if( *src == ' ' || *src == '\t' ) {
 			*dst++ = *src++;
 		} else if( *src < 0x20 ) {
@@ -1657,7 +1787,11 @@ BOOL convertInternalCode( BYTE * waCoockedLine, const BYTE * waRawLine )
 			BYTE next = *(src+1);
 			if( (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z') ) {
 				WORD id;
-				KEYWORDITEM * p = keywords;
+				KEYWORDITEM * p = keywordsIndex[mytolower(*src)-'a'];
+				if( p == NULL ) {
+					syntaxError();
+					return FALSE;
+				}
 				id = 0;
 				while( TRUE ) {
 					const BYTE * ps, * pd;
@@ -1814,18 +1948,8 @@ void interactiveMain( FILE FAR * fp )
 			consoleInput( waRawLine, LINE_SIZE );
 		} else {
 			char FAR * r;
-			char * p;
 			r = fgets( waRawLine, LINE_SIZE, fp );
 			if( r == NULL ) break;
-			p = waRawLine;
-			while( TRUE ) {
-				if( *p == '\0' ) break;
-				if( *p == '\n' || *p == '\r') {
-					*p = '\0';
-					break;
-				}
-				p++;
-			}
 		}
 #ifdef WW
 		if( fp == NULL ) {
@@ -1841,7 +1965,11 @@ void interactiveMain( FILE FAR * fp )
 		/* 数値で開始されているか? */
 		if( waCoockedLine[0] == 0x01 ) {
 			/* 行エディタを呼び出す */
-			editLine();
+			if( appendMode ) {
+				appendLine();
+			} else {
+				editLine();
+			}
 			if( fp == NULL ) {
 				clearRuntimeInfo();
 			}
@@ -1879,8 +2007,10 @@ void do_new()
 	codeTop = 0;
 	wa[0] = 0;
 	wa[1] = 0;
-	wa[2] = EOL;
-	dataTop = 3;
+	wa[2] = 0;
+	wa[3] = 0;
+	wa[4] = EOL;
+	dataTop = 5;
 }
 
 BOOL do_merge( const BYTE * filename )
@@ -1912,14 +2042,18 @@ void superMain()
 			break;
 		case REQUEST_RUN_FILE:
 			do_new();
+			appendMode=TRUE;
 			b = do_merge( waRawLine );
+			appendMode=FALSE;
 			if( b ) {
 				do_run( 0 );
 			}
 			break;
 		case REQUEST_LOAD_FILE:
 			do_new();
+			appendMode=TRUE;
 			do_merge( waRawLine );
+			appendMode=FALSE;
 			break;
 		case REQUEST_MERGE_FILE:
 			do_merge( waRawLine );
@@ -1945,12 +2079,10 @@ void superMain()
 BOOL entranceUI()
 {
 #define MAX_ENT 15
-	/* この関数内のstaticはTurbo-C 2.0のSS!=DS問題を回避するために必要なもの */
-	static int i;
-	struct stat statbuf;
-	static char names[MAX_ENT][MAXFNAME];
-	static int nent;
-	static int c, select;
+	int i;
+	struct stat statbuf[MAX_ENT];
+	int nent;
+	int c, select;
 
 	ptextCLS();
 	ptextString( "ワンべぇ V" );
@@ -1964,37 +2096,20 @@ BOOL entranceUI()
 	for (i = 0; i < nent; i++) {
 		int result;
 		if( c >= MAX_ENT ) break;
-		result = getent(NULL, i, &statbuf);
+		result = getent(NULL, i, &statbuf[c]);
 		if (result == E_FS_SUCCESS) {
-			if (statbuf.count != -1) {
-				/* Freya OSのバグ? 回避コード */
-				{
-					static int p;
-					int q;
-					p = 0;
-					q = 0;
-					waRawLine[p++] = statbuf.info[q++];
-					waRawLine[p++] = statbuf.info[q++];
-					while( TRUE ) {
-						if( statbuf.info[q] == '\0' ) break;
-						waRawLine[p++] = statbuf.info[q++];
+			if (statbuf[c].count != -1) {
+				char FAR * p;
+				int l;
+				p = statbuf[c].name;
+				l = strlen(p);
+				if( l >= 3 ) {
+					if( p[l-3] == '.' && p[l-2] == 'w' && p[l-1] == 'b' ) {
+						ptextLocate(1,c+2);
+						ptextString( statbuf[c].info );
+						c++;
 					}
-					waRawLine[p++] = '\0';
-					ptextLocate(1,c+2);
-					ptextString( waRawLine );
 				}
-				{
-					static int r;
-					int q;
-					q = 0;
-					r = 0;
-					while( TRUE ) {
-						if( statbuf.name[q] == '\0' ) break;
-						names[c][r++] = statbuf.name[q++];
-					}
-					names[c][r] = '\0';
-				}
-				c++;
 			}
 		}
 	}
@@ -2006,34 +2121,39 @@ BOOL entranceUI()
 			ptextLocate(0,i+2);
 			ptextString( " " );
 		}
-		ptextLocate(0,select+2);
-		ptextString( "→" );
+		if( c > 0 ) {
+			ptextLocate(0,select+2);
+			ptextString( "→" );
+		}
 		key = key_wait();
-		/* START */
+		/* START button */
 		if( key & 0x02 ) return FALSE;	/* 中止 */
-		/* A */
-		if( key & 0x04 ) {
-			strcpy( waRawLine, names[select] );
-			requestNextAction = REQUEST_RUN_FILE;
-			runtimeOnly = TRUE;
-			return TRUE;
-		}
-		/* B */
+		/* B button */
 		if( key & 0x08 ) return FALSE;	/* 中止 */
-		/* X1 or Y1 */
-		if( (key & 0x10) != 0 || (key & 0x100) != 0 ) {
-			select = select-1;
-			if( select < 0 ) {
-				select = c-1;
+		if( c > 0 ) {
+			/* A button */
+			if( key & 0x04 ) {
+				strcpy( waRawLine, statbuf[select].name );
+				requestNextAction = REQUEST_RUN_FILE;
+				runtimeOnly = TRUE;
+				return TRUE;
 			}
-		}
-		/* X3 or Y3 */
-		if( (key & 0x40) != 0 || (key & 0x400) != 0 ) {
-			select = select+1;
-			if( select >= c ) {
-				select = 0;
+			/* X1 or Y1 */
+			if( (key & 0x10) != 0 || (key & 0x100) != 0 ) {
+				select = select-1;
+				if( select < 0 ) {
+					select = c-1;
+				}
+			}
+			/* X3 or Y3 */
+			if( (key & 0x40) != 0 || (key & 0x400) != 0 ) {
+				select = select+1;
+				if( select >= c ) {
+					select = 0;
+				}
 			}
 		}
+		/* Y2 button */
 		if( (key & 0x200) != 0 ) {
 			return TRUE;
 		}

+ 3 - 1
wonbe.dsp

@@ -39,6 +39,7 @@ RSC=rc.exe
 # PROP Use_Debug_Libraries 0
 # PROP Output_Dir "Release"
 # PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
 # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
@@ -62,6 +63,7 @@ LINK32=link.exe
 # PROP Use_Debug_Libraries 1
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
 # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
@@ -72,7 +74,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
 
 !ENDIF 
 

BIN
wonbe.exe


BIN
wonbe.fx


+ 10 - 3
wonbe.txt

@@ -1,6 +1,6 @@
 ワンべぇ: WONBE, WonderWitch BASIC Environment
-                                               暫定マニュアル Ver 0.03
-                                                         2000年11月7
+                                               暫定マニュアル Ver 0.04
+                                                        2000年11月12
                                                       株式会社ピーデー
                                                               川俣 晶
                                  Copyright 2000 (c) by Pie Dey Co.Ltd.
@@ -203,7 +203,7 @@ tick
  システムタイマーのtickを返します。ただし、本来のtick値は符号無し32bit整数であり、ここで得られるのは16bit符号あり整数であることに注意が必要です。はみ出たbitは捨てられます。
 
 ● ファイル保存時の拡張子
- 一応、ワンべぇのソースフィルは、".wb"で終わるファイル名にしておいて下さい。現在エントランスメニューには全ファイルが見えていますが、".wb"で終わるファイル名だけに限定しようかと考えています。
+ ワンべぇのソースフィルは、".wb"で終わるファイル名にしておいて下さい。loadなどのコマンドでは拡張子に関係なく読み込めますが、エントランスメニューに表示されるのは".wb"で終わるファイル名だけです。
 
 ● 配布規則
  現バージョンは品質が不明のテスト版です。
@@ -221,6 +221,13 @@ tick
 
 ● 変更履歴
 
+2000年11月12日 Ver 0.04
+・13など0x0dを含む行番号を削除しようとするとプログラムが壊れたバグを取った
+・処理系をTurbo C2.0からVisual C++ 1.51に変更
+・ロード速度を大幅に改善
+・エントランスメニューは.wbのみ表示
+・サンプルゲームSTAR WITCH(star.wb, star.txt)を添付
+
 2000年11月7日 Ver 0.03
 ・演算子の優先順位 単項演算子 > */ > +- > 比較演算子 > and,or,xor
 ・比較演算子成立時の値を1から-1に変更

Some files were not shown because too many files changed in this diff