home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
towns_os
/
kenban
/
kenban.c
next >
Wrap
Text File
|
1980-01-02
|
12KB
|
532 lines
/***************************************************************************
TMENU.IF2 登録用 .FMB/.PMB 試聴プログラム Ver 1.0
1990/12/01 HONESEN (自来也愛好会)
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <egb.h>
#include <mos.h>
#include <snd.h>
#define ON 1
#define OFF 0
#define FM 0
#define PCM 64
struct name {
short x, y;
short len;
char nam[9];
};
/**** BIOS ワークエリア ****/
char eWork[1536],
mWork[4096],
sWork[16384];
/**** 共通変数エリア、テーブル ****/
int ch; /* チャンネル番号 FM:0 / PCM:64 */
struct name tone[128],
fsw[] = {{0, 0, 4, "DOWN"},
{0, 0, 4, " UP "},
{0, 0, 4, "EXIT"}};
int xy[][4] = {{320, 8, 367, 31}, /* DOWN */
{375, 8, 422, 31}, /* UP */
{470, 8, 517, 31}, /* EXIT */
{ 0, 72, 639, 167}, /* TONE */
{ 48, 236, 635, 315}, /* KEYh */
{ 4, 380, 591, 459}}; /* KEYl */
int b_key[] = {12,25, 37,50, 75,88, 98,111, 121,134};
int p_key[] = {10,20,30,40,55,70,80,92,100,115,125,140};
int white[] = {0, 2, 4, 5, 7, 9, 11},
black[] = {1, 3, 6, 8, 10};
int base, offset, ch_flg, crnt_key, w_or_b;
int cpybuf[10000];
/*------------ bload : FM/PCM 音色ファイル読み込み関数 -----------------*/
bload(path) /* ret = 成功:0 / 失敗:1 */
char *path; /* ファイル名 */
{
char *p, dum[8];
int l;
if ((l=strlen(path)) > 4) {
p = path + l - 4;
if (!strcmp(p,".fmb") || !strcmp(p,".FMB")) {
if (!SND_fm_bank_load(path,dum)) {
ch = FM;
return(0);
}
}
else if (!strcmp(p,".pmb") || !strcmp(p,".PMB")) {
if (!SND_pcm_bank_load(path,dum)) {
ch = PCM;
return(0);
}
}
}
return(1);
}
/*----------- get_tname : 音色名を tone[] に読み込む関数---------*/
void get_tnam()
{
char buf[128], *p, *q;
int i;
for (i=0; i<(ch==FM? 128: 32); i++) {
SND_inst_read(ch, i, buf);
buf[8] = '\0';
tone[i].len = 0;
p = tone[i].nam; q = buf;
while ((*p++=*q++) >= ' ') tone[i].len++;
*(p-1) = '\0';
}
}
/*------------------- box : 矩形描画関数 ------------------------*/
void box(x1, y1, x2, y2, c)
int x1, y1, x2, y2; /* 対角線座標 */
int c;
{
short para[32];
MOS_disp(0);
EGB_color(eWork, 0, c); EGB_color(eWork, 2, c);
para[0] = x1; para[1] = y1;
para[2] = x2; para[3] = y2;
EGB_rectangle(eWork, (char*)para);
MOS_disp(1);
}
/*------------------- pset : 点描画関数 ------------------------*/
void pset(x, y, c)
int x, y; /* 座標 */
int c;
{
short para[32];
MOS_disp(0);
EGB_color(eWork, 0, c);
para[0] = 1;
para[1] = x; para[2] = y;
EGB_pset(eWork, (char*)para);
MOS_disp(1);
}
/*----------------- button : ボタンの縁取り関数 ----------------*/
void button(x1, y1, x2, y2, c1, c2)
int x1, y1, x2, y2, /* 対角線座標 */
c1, /* 左上の色 */
c2; /* 右下の色 */
{
short para[32];
MOS_disp(0);
EGB_color(eWork, 0, c1);
para[0] = 3;
para[1] = x1; para[2] = y2;
para[3] = x1; para[4] = y1;
para[5] = x2-1; para[6] = y1;
EGB_connect(eWork, (char*)para);
EGB_color(eWork, 0, c2);
para[0] = 7;
para[1] = x2; para[2] = y2;
para[3] = x2; para[4] = y1;
para[5] = x2-1; para[6] = y1+1;
para[7] = x2-1; para[8] = y2-1;
para[9] = x1+1; para[10] = y2-1;
para[11] = x1+1;para[12] = y2;
para[13] = x2; para[14] = y2;
EGB_connect(eWork, (char*)para);
MOS_disp(1);
}
/*-------------- sw_on_off : ボタンのオン・オフ関数 ------------------*/
void sw_on_off(x1, y1, x2, y2, s, f1, f2)
int x1, y1, x2, y2; /* 対角線座標 */
struct name *s; /* キートップ文字列 */
int f1, f2; /* ON / OFF */
{
int c1, c2, sc;
if (f1 == ON) {
c1 = 8; c2 = 15; sc = 12;
}
else {
c1 = 15; c2 = 8; sc = 0;
}
EGB_textZoom(eWork, 0, 8, 16);
EGB_fontStyle(eWork, 0);
if (f2) button(x1, y1, x2, y2, c1, c2);
s->x = x1 + 8; s->y = y2 - 3;
EGB_color(eWork, 0, sc);
MOS_disp(0);
EGB_sjisString(eWork, (char*)s);
MOS_disp(1);
}
/*------------- disp_one_sw : 音色スイッチ表示関数 -----------------*/
void disp_one_sw(f1, f2)
int f1, f2;
{
int x, y;
x = (offset/4)*80 + xy[3][0] + 1;
y = (offset%4)*24 + xy[3][1] + 1;
box(x, y, x+75, y+19, 7);
sw_on_off(x-1, y-1, x+77, y+21, &tone[base+offset], f1, f2);
}
/*------------- disp_all_sw : 全音色スイッチ表示関数 -----------------*/
void disp_all_sw(f2)
int f2;
{
int i;
struct name s;
for (offset=0; offset<32; offset++) {
disp_one_sw(OFF, f2);
}
offset = 0;
disp_one_sw(ON, 1);
box(0, 52, 639, 71, 5);
EGB_textZoom(eWork, 0, 8, 16);
EGB_fontStyle(eWork, 1);
EGB_color(eWork, 0, 3);
s.len = 3; s.y = 70;
for (i=0; i<32; i+=4) {
s.x = i * 20 + 32;
s.nam[0] = (base+i+1)/100 + '0';
s.nam[1] = (base+i+1)%100/10 + '0';
s.nam[2] = (base+i+1)%10 + '0';
MOS_disp(0);
EGB_sjisString(eWork, (char*)&s);
MOS_disp(1);
}
SND_inst_change(ch, base); SND_inst_change(ch+1, base);
SND_inst_change(ch+2, base); SND_inst_change(ch+3, base);
}
/*-------------------- disp_key : 鍵盤表示 ---------------------------*/
void disp_key()
{
short para[32], symbuf[4];
int i, x, y, o;
box(xy[4][0],xy[4][1]-20,xy[4][0]+146,xy[4][1]-1, 7);
button(xy[4][0],xy[4][1]-20,xy[4][0]+146,xy[4][1]-1, 15, 8);
/*白鍵*/
MOS_disp(0);
EGB_color(eWork, 0, 0); EGB_color(eWork, 2, 15);
para[0] = 6;
para[2] = 236; para[4] = 312; para[6] = 315;
para[8] = 315; para[10] = 312; para[12] = 236;
for (i=xy[4][0]; i<xy[4][0]+21*7; i+=21) {
para[1] = i; para[3] = i; para[5] = i+3;
para[7] = i+17; para[9] = i+20; para[11] = i+20;
EGB_polygon(eWork, (char*)para);
}
/*黒鍵*/
for (i=0; i<10; i+=2) {
x = xy[4][0] + b_key[i];
box(x,235,x+1,283, 7);
box(x+12,235,x+13,283, 8);
box(x+2,284,x+11,285, 8);
box(x+2,235,x+11,283, 0);
pset(x+1,284,8);
pset(x+12,284,0);
pset(x,235,8);
}
/*コピー*/
MOS_disp(0);
*(int**)para = cpybuf;
para[2] = 0x14;
para[3] = xy[4][0]; para[4] = xy[4][1]-20;
para[5] = xy[4][0]+146; para[6] = xy[4][3];
EGB_getBlock(eWork, (char*)para);
EGB_color(eWork, 0, 14); EGB_color(eWork, 1, 8);
EGB_fontStyle(eWork, 5);
EGB_textZoom(eWork, 0, 16, 16);
symbuf[2] = 1;
y = xy[4][1]-20; o = 4;
for (x=xy[4][0]; x<xy[4][0]+21*28; x+=21*7) {
para[3] = x; para[4] = y;
para[5] = x+146; para[6] = y+99;
EGB_putBlock(eWork, 0, (char*)para);
symbuf[0] = x+65; symbuf[1] = y+17;
*(char*)(symbuf+3) = o + '0';
EGB_sjisString(eWork, (char*)symbuf);
o++;
}
y = xy[5][1]-20; o = 0;
for (x=xy[5][0]; x<xy[5][0]+21*28; x+=21*7) {
para[3] = x; para[4] = y;
para[5] = x+146; para[6] = y+99;
EGB_putBlock(eWork, 0, (char*)para);
symbuf[0] = x+65; symbuf[1] = y+17;
*(char*)(symbuf+3) = o + '0';
EGB_sjisString(eWork, (char*)symbuf);
o++;
}
MOS_disp(1);
}
/*----------------- disp_tnam : 音色ファイル名の表示 -----------------*/
void disp_tnam(nam)
char *nam;
{
short para[64];
EGB_color(eWork, 0, 1);
EGB_fontStyle(eWork, 1);
EGB_textZoom(eWork, 0, 8, 16);
para[0] = 8; para[1] = 28;
strcpy((char*)para+6, nam);
para[2] = strlen(nam);
if (para[2] > 38) para[2] = 38;
EGB_sjisString(eWork, (char*)para);
}
/*--------------- paint_key : 鍵盤ペイント関数 ------------------------*/
void paint_key(n, c)
int n, c;
{
short para[32];
para[0] = ((n >= 60)? xy[4][0] + 21*7*((n-60)/12) + p_key[n%12]:
xy[5][0] + 21*7*((n-12)/12) + p_key[n%12]);
para[1] = ((n >= 60)? xy[4][1]+2: xy[5][1]+2);
MOS_disp(0);
EGB_color(eWork, 2, c);
EGB_closePaint(eWork, (char*)para);
MOS_disp(1);
}
/*------------------ key_off : キーオフ関数 ---------------------------*/
void key_off()
{
if (crnt_key != -1) {
paint_key(crnt_key, w_or_b);
SND_key_off(ch+ch_flg++);
ch_flg &= 3;
crnt_key = -1;
}
}
/*------------------ key_exit : "EXIT"キー関数 -----------------------*/
void key_exit()
{
int b, x, y;
key_off();
sw_on_off(xy[2][0],xy[2][1],xy[2][2],xy[2][3],&fsw[2],ON,1);
while (MOS_rdpos(&b,&x,&y),b);
sw_on_off(xy[2][0],xy[2][1],xy[2][2],xy[2][3],&fsw[2],OFF,1);
}
/*------------------ key_down : "DOWN"キー関数 -----------------------*/
void key_down()
{
int b, x, y;
key_off();
sw_on_off(xy[0][0],xy[0][1],xy[0][2],xy[0][3],&fsw[0],ON,1);
if (ch == FM) {
if (base > 31) {
disp_one_sw(OFF, 1);
base -= 32;
disp_all_sw(0);
}
}
while (MOS_rdpos(&b,&x,&y),b);
sw_on_off(xy[0][0],xy[0][1],xy[0][2],xy[0][3],&fsw[0],OFF,1);
SND_inst_change(ch, base); SND_inst_change(ch+1, base);
SND_inst_change(ch+2, base); SND_inst_change(ch+3, base);
}
/*-------------------- key_up : "UP"キー関数 -------------------------*/
void key_up()
{
int b, x, y;
key_off();
sw_on_off(xy[1][0],xy[1][1],xy[1][2],xy[1][3],&fsw[1],ON,1);
if (ch == FM) {
if (base < 96) {
disp_one_sw(OFF, 1);
base += 32;
disp_all_sw(0);
}
}
while (MOS_rdpos(&b,&x,&y),b);
sw_on_off(xy[1][0],xy[1][1],xy[1][2],xy[1][3],&fsw[1],OFF,1);
SND_inst_change(ch, base); SND_inst_change(ch+1, base);
SND_inst_change(ch+2, base); SND_inst_change(ch+3, base);
}
/*------------ key_tchg : 音色切り替えキー関数 -----------------------*/
void key_tchg(x, y)
int x, y;
{
int b, x1, y1;
key_off();
disp_one_sw(OFF, 1);
offset = (x/80)*4 + (y-xy[3][1])/24;
disp_one_sw(ON, 1);
while (MOS_rdpos(&b,&x1,&y1),b);
SND_inst_change(ch, base+offset); SND_inst_change(ch+1, base+offset);
SND_inst_change(ch+2, base+offset); SND_inst_change(ch+3, base+offset);
}
/*------------------ key_on : キーオン関数 ---------------------------*/
void key_on(x, y, o)
int x, y, o;
{
int i, j, k, w;
o += x / 147; x %= 147;
i = white[x/21];
w = 15;
if (y < 50) {
for (j=0; j<10&&(x<b_key[j]||b_key[j+1]<x); j+=2);
if (j < 10) {
i = black[j/2];
w = 0;
}
}
k = (o+1)*12 + i;
if (crnt_key == -1) {
SND_key_on(ch+ch_flg, k, 100);
paint_key(k, 10);
crnt_key = k;
w_or_b = w;
}
else if (crnt_key != k ) {
key_off();
SND_key_on(ch+ch_flg, k, 100);
paint_key(k, 10);
crnt_key = k;
w_or_b = w;
}
}
/*--------------------- main : メイン関数 ----------------------------*/
void main(argc, argv)
int argc;
char *argv[];
{
int i, mb, mx, my;
/**** サウンド初期設定 ****/
SND_init(sWork);
SND_elevol_init();
SND_elevol_mute(3);
/**** 音色ファイルの読み込み ****/
if (argc==0 || bload(argv[1])) goto end;
get_tnam();
/**** グラフィック初期設定 ****/
EGB_init(eWork, 1536);
EGB_displayPage(eWork, 0, 0);
EGB_paintMode(eWork, 0x0022);
/**** マウス初期設定 ****/
MOS_start(mWork, 4096);
MOS_horizon(0, 639);
MOS_vertical(0, 479);
MOS_setpos(320, 240);
MOS_disp(1);
/**** 画面初期設定 ****/
/* 背景 */
box(0, 0, 639, 479, 5);
/* DOWN UP EXIT */
for (i=0; i<3; i++) {
box(xy[i][0], xy[i][1], xy[i][2], xy[i][3], 7);
sw_on_off(xy[i][0], xy[i][1], xy[i][2], xy[i][3],
&fsw[i], OFF, 1);
}
/* 音色スイッチ表示 */
base = 0;
disp_all_sw(1);
/* 鍵盤表示 */
disp_key();
/* ファイル名表示 */
disp_tnam(argv[1]);
EGB_displayPage(eWork, 1, 3);
/**** マウス入力ループ ****/
crnt_key = -1; ch_flg = 0;
while (1) {
while (MOS_rdpos(&mb, &mx, &my), mb==0) key_off();
for (i=0; i<6&&(mx<xy[i][0]||xy[i][2]<mx
||my<xy[i][1]||xy[i][3]<my); i++);
switch (i) {
case 0 : key_down();
break;
case 1 : key_up();
break;
case 2 : key_exit();
goto end;
case 3 : key_tchg(mx, my);
break;
case 4 : key_on(mx-xy[4][0], my-xy[4][1], 4);
break;
case 5 : key_on(mx-xy[5][0], my-xy[5][1], 0);
break;
default: key_off();
break;
}
}
/**** 終了 ****/
end:
MOS_end();
SND_elevol_mute(0);
SND_end();
}