dnjiro’s 9VAe blog

誰でもアニメが作れる無料ソフト9VAeきゅうべえ開発者のブログ

MicroPythonから X-BASIC / XC への変換、X68K関数対応表:ひとコマ解説

 

MicroPythonプログラムをX-BASICにすれば、Cに変換コンパイルし、高速に実行できます。X68000 Z 実機で、MicroPython と X-BASICのコード変換、X68K関数の記述方法についてまとめました。



MicroPython開発ディスクの作り方Cコンパイラ開発ディスクの作り方

X68000 Z 資料

参考にした記事はこちらです。

X68000 Z ツール入手先

 

X-BASICの起動

X68000Z システムディスク(ビジュアルシェル)から

  1. BASICをダブルクリック > BASICフォルダが開きます
  2. BASIC.Xをダブルクリック

コマンドプロンプトから

  • basic

 

X-BASIC サンプルプログラム(マウス左ボタンで線をひく)

10 int x,y,xx,yy,dx,dy,right,left
20 screen 1,3,1,1 30 x=0 : y=0
40 print("Draw line with Mouse. Exit=Move to bottom") 50 while y<500 60 mspos(xx,yy) 70 msstat(dx,dy,left,right) 80 if left<>0 then { 90 line(x,y,xx,yy,xx)
100 } 110 x = xx : y = yy
120 endwhile

上のプログラムを入力し、

  • run

するとマウスを動かして画面に線をひくことができます。エラーが出た場合

  • list

でプログラムを表示し、カーソルを移動させて修正できます。

上のプログラムの説明

X-BASIC
意味
int x,y 変数の定義(文字列は str、自然数は float)
screen 1,3,1,1 768 x 512 x 16色(31kHz) mode
x=0 : y=0 :で区切ると複数行を1行で書ける(マルチステートメント
while y<500
endwhile

y が500より小さい間、繰り返す

mspos(xx,yy) マウス座標取得
msstat(dx,dy,left,right)  マウスボタン、マウス移動値取得
line(x,y,xx,yy,c) 色cで線をひく
  • save "xxx.bas"

でプログラムを保存できます(xxxは好きな名前)

  • load "xxx.bas"

でプログラムを読み出せます。BASICの終了は

  • system

です。

もっと複雑なサンプルプログラムはこちらを御覧ください。

 

MicroPython

  • X-BASICよりも複雑なプログラムが簡単につくれます。
  • ファイル処理、256バイトより長い文字列処理ができます。
  • ただ実行速度はX-BASICより遅いです。
  • MicroPythonの使い方はこちらをご覧ください

MicroPython から X-BASIC への変換

MicroPythonのプログラムをX-BASICに変換し、Cコンパイルすれば、高速に実行できます。試作プログラムは MicroPythonで開発し、速度が遅ければ、X-BASICに変換するのがよいでしょう。コード変換は次のように行うとよいです。

  1. MicroPythonプログラムの行頭に行番号を追加する。修正は ED エディタ
  2. Basicを起動し、load "ファイル"で読み込むとエラーが出て読み込みが止まる。
  3. list でエラー行の手前まで表示されるので、system で終了し、ED エディタでエラー行を修正。
  4. 下の MicroPython と X-BASIC の対応表を参考に修正していく

行番号を追加するPythonプログラム

MicroPython のプログラムを読み込んで、行番号を追加し、単純な変換まで行うPythonプログラムです。src= に変換元のPythonファイル名、dst=に変換後のBASICファイル名を書いて実行(micropyt addlno.py)すれば、Pythonの各行に、行番号を追加します。

簡単なキーワードの変換も行います。単純な変換なので間違えることもあります。

この処理を行ったあと、手作業で変換すると楽です。

 

 

import os
src = 'xxxx.py'  #変換元のPythonファイル名に変更してください
dst = 'xxxx.bas' #変換後のBasicファイル名に変更してください
no = 10
fr=open(src,'r')
fw=open(dst,'w')
for ln in fr:
  if len(ln)<=1:
    ln = '/*\n'
  x = ln.find('#')
  if x>=0:
    ln =ln[0:x]+'/*'+ln[x+1:-1]+'\n'
  while ln.find('if')>=0:
    x = ln.find('==')
    if x>=0:
      ln =ln[0:x]+'='+ln[x+2:]
      continue
    x = ln.find('!=')
    if x>=0:
      ln =ln[0:x]+'<>'+ln[x+2:]
      continue
    break
  while ln.find('<<')>=0:
    x = ln.find('|')
    if x>=0:
      ln =ln[0:x]+' or '+ln[x+1:-1]+'\n'
      continue
    x = ln.find('&')
    if x>=0:
      ln =ln[0:x]+' and '+ln[x+1:-1]+'\n'
      continue
    x = ln.find('<<')
    if x>=0:
      ln =ln[0:x]+' shl '+ln[x+2:-1]+'\n'    

  while ln.find('>>')>=0:
    x = ln.find('|')
    if x>=0:
      ln =ln[0:x]+' or '+ln[x+1:-1]+'\n'
      continue
    x = ln.find('&')
    if x>=0:
      ln =ln[0:x]+' and '+ln[x+1:-1]+'\n'
      continue
    x = ln.find('>>')
    if x>=0:
      ln =ln[0:x]+' shr '+ln[x+2:-1]+'\n'

  while ln.find('0x')>=0:
    x = ln.find('0x')
    if x>=0:
      ln =ln[0:x]+'&h'+ln[x+2:-1]+'\n'

  while ln.find('%')>=0:
    x = ln.find('%')
    if x>=0:
      ln =ln[0:x]+' mod '+ln[x+1:-1]+'\n'

  x = ln.find('return')
  if x>=0:
    ln =ln[0:x+6]+'('+ln[x+6:-1]+')\n'
  x = ln.find('def')
  if x>=0:
    ln =ln[0:x]+'func'+ln[x+3:-2]+'\n'

  ss=str(no)+' '+ln
  print(ss)
  fw.write(ss)
  no+=10
fr.close()
fw.close()
    

X-BASIC 起動・終了

basic  /*BASIC起動*/
list /*プログラム表示、修正*/ run /*実行*/ save "ファイル名.bas" /*保存*/ load "ファイル名.bas" /*読み出し*/ exit() /*BASIC終了*/

 

X-BASIC と MicroPython の比較

参考にした資料

起動、終了

X-BASIC
MicroPython
メモ
basic micropyt 起動
system (F10キー) Ctrl+D 終了

対応表

X-BASIC
MicroPython
/* コメント # コメント
return(1) return 1
print a,b,c  print(a,b,c)
if a=1 and b<>0 then{ }else{ } if a==1 and b!=0: else:
for i=0 to 9 next for i in range(10):
10 mod 8 10 % 8

(x shl 4) or ( (y and &hf0) shr 4)

(x << 4) | ( (y & 0xf0) >> 4)
s = chr$(34)+"abc"+chr$(34) s = '"'+'abc"'

func str xxx(x;int) endfunc

型宣言が必要。省略はint

def xxx(x):

型宣言がない。代入によって型が変化する

 str 文字は 256 バイトが最大  文字数は無制限
 フォルダのファイルを取得できない

import os

os.listdir('フォルダ名') #フォルダのファイル取得

error off error on で囲まないと fopen でエラー終了 open

変数、配列

 int a = 1 /*型必要、定数のみ書ける*/

float b: b = 1/2. /*:はマルチ*/

str c:c = “ABC”+chr$(34) /*Max256文字*/

print a,b,c /*()かっこ不要*/

a = 1 #型宣言不要

b = 1/2

c = 'ABC”'

print(a,b,c)  #( )が必要

 

a=1:b=2 /*:マルチステートメント*/

a,b = 1,2 #複数代入可  

int a(3)={5,1,3,4) /*宣言より要素が1多い 最初はa(0)=5,a(3)=4*/

print a(0) 

a=[5,1,3,4]

print(a[0])

 
int a(3)={1,1,1,1) a = [1]*4   
素数を変更できない a = list() #空  
int a(4)={0,1,2,3,4) a = list(range(5))   
str a(3)={"a","textbook","of","x-basic"} a = "a textbook of Python".split()  
 できない a[-1] #配列の一番最後、負は後ろから数える  
できない  a[0:2] #最初から2つ  
できない  a[1:3] #2番目から2つ。Pythonは開始:終了で指定  
 要素数を変更できない a.append(2) #aの最後に2を追加  

型変換

X-BASIC
Python
 

float x:x=val(a)

int x:x=atoi(a)

x = float(a) 

x = int(a)

 

str s:s = str$(1/3.)

str s:s = hex$(a)

right$("000"+hex$(a),4)

 

s = str(1/3) #数値を文字列にする 

s = hex(a) #16進数

s ='{:04x}'.format(a) #16進数4桁

s ='{:02x}{:02x}'.format(a,a) #16進数2桁を2つ並べる

 

for ループ

X-BASIC
Python
 

for i=0 to 9

next

for i in range(10):  

dim int a(3)={5,1,3,4}

for i=0 to 3

d=a(i)

next

a = [5, 1, 3, 4]

for d in a:

 

 
     

if else

X-BASIC
Python
 

if (a = 1) and (b <> 0) then {

  print "a1 bx"

}else if a=1 then {
  print "a1b0"
}else{

  print "NO"

}

if (a == 1) and (b != 0):

  print("a1 bx")

elif a==1:
  print("a1b0")
else:

  print("NO")

 

 

数値計算

X-BASIC
Python
 

 

float a:a=pi(1.) /*円周率x1*/

float a:a=sqr(2.)

import math

a = math.pi #円周率

a = math.sqrt(2)  #ルート

 
(rr shl 8) or (gg shr 2)  (rr << 8) | (gg>>2)  
&hFFFF 0xFFFF #16進数  
a = 10 mod 8 /*余り*/ a = 10 % 8  

文字の結合、検索

X-BASIC
Python
 

str s:s="abc"+"def"

str s:s="abc"+str$(1.2)

 

int a:a=strlen(s)

s = "abc" + "def"
s = "abc"+str(1.2)    #数値は文字にしてから結合
a = len(a)            #文字の長さ、半角も全角も1文字
 
str s="abcabc" s = "abc"*2   

str a="abcdef"

instr(1,a,"cd") /*結果は3 最初の数字は検索開始(最初は1)*/

instr(1,a,"x")/*結果は0*/

a = "abcdef"

a.find("cd") #結果は 2

a.find("x") #結果は-1

 

 

関数

X-BASIC
Python
 

float a

while 1

  input "> ",a

  print a, myabs(a)

endwhile

func float /*func は後ろにおく*/ myabs(x;float):

  if x<0 then return(-x)

  return(x) /*値を返さなくても()が必要*/

endfunc

def myabs(x):

  if x<0: return -x 

  return x #( )は不要

while True:

  a = float(input("> "))

  print(a, myabs(a))

 

不要。関数外の変数も読み書きできる

関数の引数に256文字の文字をいれると落ちることがある。

サイズが大きい変数は関数外定義がよい

a=1

def f():

  global a #関数外の変数

  print a

 

関数のデフォルト引数はない

 

def f(a,b=2,c=3):#デフォルト引数

  return a + b + c

f(1,1,1) #答えは3

f(1) #答えは6

f(1,c=2) #答えは5

 

関数を変数にいれることはできない

def f1():

  print("f1")

def f2():

  print("f2")

def F(y): #関数を変数にいれられる

  y()

F(f2)

F(f1)

 

ファイル, OS処理

X-BASIC
Python
 

int fp

str s[256]

fp=fopen("test.txt","c") /*cは新規作成する*/

fwrites("111\n 222\n 333\n",fp) /*¥nは改行にならない*/

fclose(fp)

fp=fopen("test.txt","r")

freads(s,fp)

fclose(fp)

print s

 

import os

print(os.getcwd())

f= open('test.txt','w')

f.write('111\n 222\n 333\n')

f.close()

f = open('test.txt','r')

s = f.read()

f.close()

print(s)

 

 

int fp

str s[256]/*256文字以内しか使えない*/

error off /*ファイルがなくても中断しない

fp=fopen("test.txt","r")

while freads(s,fp)>0

  print s

endwhile

fclose(fp)

error on

 

import os

f = open('autoexec.bat','r')

for line in f:

  printf(line)

f.close()

 

error off /*ファイルなくても中断しない

frename("変更前ファイル名","変更後ファイル名")

fdelete("ファイル名")

error on

import os

os.rename('変更前ファイル名','変更後ファイル名')

os.remove('ファイル名')

os.listdir('フォルダ名')

 
exit(0)

import sys

sys.exit() #プログラムの終了

 

 X68K関数(X-BASIC / MicroPython / XC)対応表

X-BASIC
MicroPython
XC
意味
不要 from x68k import * # #include <basic0.h> 先頭にいれれば、x68k. を省略できる。
cls x68k.iocs(x68k.i.B_CLR_ST, 2) cls() テキスト画面消去
wipe()   basicと同じ グラフィック画面消去
window(x1,y1,x2,y2)   basicと同じ クリッピング
  x68k.crtmod(16, 1)   768 x 512 x 16色(31kHz)
  x68k.crtmod(14, 1)   255 x 255 x 65536色
screen 1,2,1,1   screen(1,2,1,1) 512 x 512 x 256色 x 2面
screen 1,3,1,1 x68k.crtmod(12, 1) screen(1,3,1,1) 512 x 512 x 65536色 x 1面
ky$=inkey$ key= x68k.iocs(x68k.i.B_KEYINP)

unsigned char ky[258];

b_inkeyS(ky);

キーを入力待ちして取得
ky$=inkey$(0) key= x68k.iocs(x68k.i.B_KEYSNS)

unsigned char ky[258];

b_inkey0(ky);

キー取得(入力待ちしない)
  key= x68k.iocs(x68k.i.B_SFTSNS)   シフトキー取得(入力待ちしない)
  key= x68k.iocs(x68k.i.B_BITSNS, group)   キー取得(入力待ちしない)
  x68k.dos(x68k.d.KFLUSH, b'¥x00¥x06¥x00¥xfe')   キーバッファクリア
beep
x68k.dos(x68k.d.INPOUT, b'\x00\x07')
beep(); ビープ音を鳴らす
vpage(1) x68k.iocs(x68k.i.G_CLR_ON) basicと同じ グラフィック表示する(3:2面重ねる)
apage(a)   basicと同じ 描画先(a=0,1..)
locate x,y x68k.iocs(x68k.i.B_LOCATE, x, y) locate(x,y) カーソルを(x,y)に移動
  xxyy = x68k.iocs(x68k.i.B_LOCATE, -1)   カーソル位置を取得
  x68k.iocs(x68k.i.B_COLOR, d1=pal)   文字の色 pal: 0=black, 1=cyan, 2=yellow, 3=white  
locate 0,0,1 x68k.iocs(x68k.i.OS_CURON) b_csw(1); カーソル表示
locate 0,0,0 x68k.iocs(x68k.i.OS_CUROF) b_csw(0); カーソルを消す
mouse(0) x68k.iocs(x68k.i.MS_INIT) basicと同じ マウス初期化
mouse(1) x68k.iocs(x68k.i.MS_CURON) basicと同じ マウスカーソルON
mouse(2) x68k.iocs(x68k.i.MS_CUROF) basicと同じ マウスカーソルOFF
mcr=mouse(3) mcr=x68k.iocs(x68k.i.MS_STAT) basicと同じ マウスカーソルの状態
msarea(x1,y1,x2,y2) x68k.iocs(x68k.i.MS_LIMIT,
(x1 << 16) | y1, (x2 << 16) | y2)
basicと同じ マウスの範囲設定
setmspos(x,y) x68k.iocs(x68k.i.MS_CURST,
(x << 16) | y)
basicと同じ
マウス位置指定
mspos(x,y) pos = x68k.iocs(x68k.i.MS_CURGT) mspos(&x,&y); マウス位置取得
(x=(pos >> 16) & 0xffff, y=pos & 0xffff)
msstat(dx, dy, lbtn, rbtn) stat = x68k.iocs(x68k.i.MS_GETDT) msstat(&dx, &dy, &lbtn, &rbtn); マウス移動、ボタン取得 (dx, dy, lbtn, rbtn)
  x68k.iocs(x68k.i.SKEY_MOD,-1)   ソフトキーボード ON
  x68k.iocs(x68k.i.SKEY_MOD,0)   ソフトキーボード OFF
  x68k.iocs(x68k.i.TPALET,pal,-2)   テキストパレット初期化
  x68k.iocs(x68k.i.TPALET,pal,color)   テキストパレット設定(colorは16bit:g5r5b5+0,  pal=0-3, 7,8(マウスポインタ))
  x68k.iocs(x68k.i.TPALET,pal,-1)   テキストパレット取得
  x68k.iocs(x68k.i.GPALET,pal,-2)   グラフィックパレット初期化
  x68k.iocs(x68k.i.GPALET,pal,color)   グラフィックパレット設定(colorは16bit:g5r5b5+0, pal=0-15)
  x68k.iocs(x68k.i.GPALET,pal,-1)   グラフィックパレット取得
hsv(h,s,v) x68k.iocs(x68k.i.HSVTORGB, (h<<16)|(s<<8)|v) basicと同じ HSVからRGB変換(h:0-191 0=R 64=G 128=B 32=Y 96=C 160=M  s,v:0-31)
なし   FILEBUF inf;
FILES(&inf,"*.*",atr);
atr=0x10(フォルダ)、0x20(ファイル)をカレントから1つ取得
なし   FILEBUF inf;
NFILES(&inf);
続きのファイルを取得、取得できたらreturn 0

描画関数

X-BASIC
MicroPython
XC
意味
不要 g=GVRam(0)   グラフィック画面
不要 tx=TVRam(0)   テキスト画面
line(x1,y1,x2,y2,pal)
line(x1,y1,x2,y2,pal,dot)
g.line(x1,y1,x2,y2,pal)
g.line(x1,y1,x2,y2,pal,dot)
line(x1,y1,x2,y2, pal,'NASI')
line(x1,y1,x2,y2, pal,dot)
x1,y1-x2,y2に線をひく。palは色
点線(dot=-1は実線,0は透明)
box(x1,y1,x2,y2,pal)
box(x1,y1,x2,y2,pal,dot)
g.box(x1,y1,x2,y2,pal)
g.box(x1,y1,x2,y2,pal,dot)
box(x1,y1,x2,y2, pal,'NASI')
box(x1,y1,x2,y2, pal,dot)
x1,y1-x2,y2の四角形を描く。palは色
点線の四角(dot=-1は実線,0は透明)
fill(x1,y1,x2,y2,pal) g.fill(x1,y1,x2,y2,pal) basicと同じ x1,y1-x2,y2の四角形を塗りつぶす。palは色
circle(x,y,r,pal)
circle(x,y,r,from,to)
g.circle(x,y,r,pal)
g.circle(x,y,r,from,to)
circle(x,y,r,pal, 'NASI', 'NASI', 'NASI') 中心x,y,半径rの円を描く。palは色
円弧(from,toは角度0-360)
get(x1,y1,x2,y2,mm)   get(x1,y1,x2,y2, mm, sizeof(mm)) 四角領域の画像を配列に記憶
put(x1,y1,x2,y2,mm)   put(x1,y1,x2,y2, mm, sizeof(mm)) 配列に記憶した画像を描画
symbol(x,y,str, h,v,f,col,a)   basicと同じ 文字描画  (hv:水平垂直倍率 f:フォント a:角度)

FM音源

  • OPMDRV3.X が必要です。比較的新しいゲームの sysフォルダにはいっています。
X-BASIC
MicroPython
意味
m_init()    
m_alloc(t,sz) x68k.iocs(x68k.i.OPMDRV,0x01,(t<<16)|sz) tトラック用に sz バイト確保
m_asign(ch,t) x68k.iocs(x68k.i.OPMDRV,0x02,(t<<16)|ch) tトラックをch チャンネル
m_free(t) x68k.iocs(x68k.i.OPMDRV,0x07,t) tトラックの残りバイト数
m_trk(t,mml)

mml+=mml+"¥x00"

x68k.iocs(x68k.i.OPMDRV,0x06,t,a1=mml)

トラックに音を設定
m_tempo(te) x68k.iocs(x68k.i.OPMDRV,0x05,te) テンポ te=32-200 

m_play()/*全再生*/

m_play(c1,c2..c8)

x68k.iocs(x68k.i.OPMDRV,0x08,pack('L',c),0,0) cチャンネル再生1-25

 Python特有の処理

以下のMicroPythonの処理は、X-BASICに変更するのが難しいので、使わないようにするのがよいです。

リストの代入と複製

a = [ 1, 2, 3]
b = a    #bはaと同じ
a[1]=0   #a を修正
b        #b も修正されてる
b = a.copy()   #浅いコピー(完全なコピーではない)
a[1]=10   #a を修正
b        #b は aをコピーしたときの値
id(a)
id(b)    #id(a) と id(b)が同じとき、中味は同じ

辞書

  • リストの中身を文字列で指定する仕組み
age = {"yamada":18, "tanaka":19}
age
age["yamada"]
age["sato"]=20      #"sato"が追加される
age
"okada" in age      #"okada"がはいっているか?
 

try  except (エラー処理)

  • 数字以外が入力されたときにエラー終了しないようにする
while True: 
    x = input("*** ")
    try:
        x = float(x)
    except:
        print("Not number")
        continue
    print(x)
    break
  • while True は無限ループです。Tは大文字
  • エラーが発生すると、except から実行されます。except: は必ず必要で、何もしないときは pass と書きます
  • continue は、while ループの先頭にもどります
  • break で、whileループを抜けます

 

内容:


解説動画の作り方

この記事のひとコマ解説GIFは、フリーソフト9VAeきゅうべえの「ひとコマ機能」で作成しています。

9VAeきゅうべえのダウンロード


 

 

  • 9VAeきゅうべえで、キャプチャー画面に、矢印や説明を加え、ページに「ひとコマ」設定するだけで作れます。
  • FFmpeg を使って Youtube 動画にすることもできます。

 

画面キャプチャ方法

OS
画面キャプチャ方法
保存先
 Windows
クリップボード
 Mac
  • Shift + Command + 4 (ShiftキーはZの左、スペースでウィンドウ指定)
デスクトップ
 Android
  •  電源 + 音量Down
 adbコマンド (開発者向け)
  •  adb shell screencap -p /sdcard/screen.png
     adb pull /sdcard/screen.png
フォトアプリ>
ライブラリ>
Screenshots
 
iPhone / iPad
  •  ホームボタン + 電源ボタン
  • サイドボタン + 音量UP
写真>
アルバム>
スクリーンショット
 Linux Mint
  • Print Screen キー
クリップボード
ファイル
 Amazon Fire
  • 電源 + 音量Down 1秒長押し
  • USBケーブルでPCと接続し、
    設定>接続デバイス>USB>ファイル転送
ピクチャ >
スクリーンショット
 Chromebook
  • Shift + Ctrl + ウィンドウ一覧キー(上の中央のキー)
マイファイル >
ダウンロード
 X68000 Z
 

アニメGIF、動画出力

  • ファイルメニュー>アニメGIF出力」または「動画出力」で、好きなサイズのアニメGIF または MP4動画 が作成できます。
    Win / RaspberryPi / Linux版 でMP4動画を作るには FFmpeg が必要Youtube解説
  • スマホの場合、端末内の「9VAe」フォルダの中に出力されます。フォトアプリで、「端末内の写真>9VAe」で見ることができます。
  • アニメGIFは、背景を透明にできます。音がいれられません。
  • MP4動画には音が入れられます。Youtubeに投稿できます。Youtubeに投稿する場合、1秒30コマ、高さ720 または 1080 で出力するとよいでしょう。

 

 

9VAeをつかえば素材動画が作れる 

      • 9VAeきゅうべえを使えば、オリジナルの素材動画が簡単に作れます。
      • Openclipart や  FreeSVG などフリーのSVGイラストをつかって動くキャラクタが作れます。
      • 動画編集ソフトで動画に合成できます。

OS

フリーソフト

9VAeで作成する素材動画

Windows

AviUtl

連番PNG または MP4

Mac/iPhone/iPad

iMovie

MP4 または QuickTime(古いMac)

Android

PowerDirector

GIF または MP4

作り方

 

      • もっと長いアニメを作ることもできます。以下をご覧ください。

9VAeきゅうべえ:長いアニメを作る方法 - Qiita

 

 

9VAeきゅうべえに関する質問