KULT Underground

una della più "antiche" e-zine italiane – attiva dal 1994

KAO: l’arte di crescere (3)

6 min read

KAO: l’arte di crescere (3)

Dopo un mese di astinenza, eccoci di nuovo insieme a riprendere il nostro cammino alla scoperta dei KAO. Grazie all’interesse mostrato da alcuni nuovi collaboratori della rivista ho deciso di iniziare a sviluppare codice che consenta di testare e, perchè no, utilizzare i
KAO al di fuori di KULT, in modo da spronare maggiormente i lettori alla loro creazione.
Di seguito, in questo articolo presenterò quindi headers e codice in C che potrete tranquillamente “ritagliare” e utilizzare sia per vostro uso personale, sia, cosa che io mi auguro, per creare applicazioni che possano arricchire la rivista.
Tutto il codice presentato, salvo precise indicazioni contrarie, è da considerarsi Public Domain, di conseguenza spero che anche chi non vuole assolutamente impegolarsi in pindalici esercizi programmativi per KULT, possa trovarne giovamento ugualmente.
Per prima cosa ecco quindi una prima parte di codice che verrà utilizzato da header dai KAO, che vi consiglio di salvare in un file chiamato “EXTERN.H”
———————————————————————-

// KULT Add On – 5212 Entertaiment
// Header per file KAO pubblicato su
// KULT Underground n.9 – Luglio 1994
// by Marco Giorgini

// ***** COSTANTI ******
define BOOL unsigned char define TRUE 1 define FALSE 0
define DWORD unsigned long define WORD unsigned int define BYTE unsigned char
define _KAOINIT 0 define _KAORESET 1 define _KAOREADY 2 define _KAORUN 3 define _KAOSTOP 4 define _KAOPARAM 5
define _UNKNOWN 0 define _BACKGROUND 1 define _EXCLUSIVE 2 define _EVENTCALLED 4 define _MOUSEWANTED 8 define _KEYSWANTED 16 define _VIDEO 256 define _TXT 512 define _ERROR 65535

// ****** MACRO *******
define max(a,b) (((a)>(b)) ?(a):(b))
define _ID (area->ID) define _count (area->count) define _ASK (area->ASK) define _flag (area->flag) define _cmd (area->cmd) define _data (area->data)

// ****** STRUTTURE *******
typedef struct KULTAREA{
WORD ASK;
WORD ID;
long count;
char far*cmd;
long far*data;
};
typedef struct CELTYPE{
BOOL used;
BOOL undoc1;
WORD x;
WORD y;
WORD px;
WORD py;
WORD size;
BYTE trasparent;
BOOL OwnPalette;
BYTE far*Palette;
BYTE far*Image;
WORD undoc2;
WORD undoc3;
};

———————————————————————-

Poi, eccovi, nelle sue limitazioni, la prima versione del TEK, ovvero del programma che vi consentirà di provare i vostri KAO.
Cosa altro vi occorre dunque per cominciare?
Beh, un compilatore C per DOS, un linker (che di solito viene fornito insieme al compilatore) e una buona dose di volontà e di pazienza.
La volontà ovviamente vi servirà per rimanere attaccati al computer invece di dedicarvi ad attività più consuete, e la pazienza invece vi aiuterà a non insultarmi troppo quando/se comincerete ad avere problemi con il codice.
Ma vediamo ora, passo dopo passo, come procedere per usare il TEK.

1)    Prendete il vostro KAOXXX.C e dopo averlo compilato linkatelo, in modo da ottenere un .EXE dall’originale .OBJ
2)    Eseguite l’EXE2BIN per trasformare in .COM in vostro .EXE
3)    Rinominate il .COM in .KAO
4)    Lanciate il TEK con il vostro KAO come parametro.
che tradotto in file .BAT diventa (compilazione a parte):

TLINK %1
EXE2BIN %1.EXE %1.COM
REN %1.COM %1.KAO
TEK %1

Qualche cosiderazione sul prima e sul dopo. Prima, ovviamente, vuol dire la fase di compilazione del KAO, e il dopo, invece la sessione di esecuzione del TEK.
Come già ricordato la volta scorsa un KAO non ha un main, ma ha comunque necessità di avere una sezione principale che potete chiamare come vi pare (io la chiamo kaomain), ma che deve essere la prima cosa che verrà compilata, presente nel vostro codice.
Questo vuol dire che le funzioni che creerete dovranno apparire DOPO il kaomain, e che anche le variabili globali non potranno essere dichiarate prima di quella parte. Per evitare errori o warning in compilazione questo rende necessaria la dichiarazione dei prototipi delle funzioni che utilizzerete, e la dichiarazione in primis come extern delle vostre globali. Ovvero avrete:

———————————————————————-

// include include xxxxxx
// prototipi funzioni xxxx();
// “prototipi” variabili extern xxxxx;
// MAIN void kaomain(xxx)
{
}
// variabili xxxxx
// funzioni xxxx()
{
}

———————————————————————-

Altra cosa di cui tener conto è che, quando proverete a compilare il vostro KAO.C, non essendoci il main, vi verrà segnalato un errore di linking. Questo è normale, ed è poi anche il motivo per cui eseguirete a mano la prima della sequenza di istruzioni sopra descritte. Cosa invece non “normale”, o comunque non accettabile è l’apparire di problemi quando questa istruzione (TLINK) viene eseguita. Se vi dovesse capitare una cosa del genere il motivo è semplice: avete usato qualche funzione di libreria, o, incauti, avete provato a usare dei long o float, che richiedono codice sempre di libreria per essere gestiti.
Cosa fare in questo caso?
Semplice. Le funzioni di libreria le potete/dovete riscrivere, e al posto di long e float dovete usare degli int. Si, mi rendo conto che è dura, ma vi garantisco che tutto è possibile (pensate che anche
SPEAKEN è un KAO).
Passando poi al “dopo”, ovvero al TEK, vi devo segnalare in cosa consiste il suo essere limitato: niente gestione del mouse, niente FONT, nè BIN, nè altre risorse di
KULT.
E’ stato creato esclusivamente per testare KAO che disegnino sul Cel numero 0, che il TEK considera lo schermo stesso. E’ possibile però allocare memoria e leggere la palette, nel caso vi dovesse servire.
La pressione di Hot Spot per il passaggio dei parametri è poi simulabile attraverso i tasti da ‘0’ a ‘9’, e per uscire basta premere il tasto ESC.
Un po’ pochino? Si, lo ammetto, ma il tempo è tiranno, e per cominciare comunque non mi sembra male.
Un’ultima nota prima di passare al KAO di esempio di questo mese: il TEK sfrutta il KAO “video.drv” per l’accesso alla memoria video, e quindi questo file deve essere presente nella stessa directory dell’eseguibile.

KAOMATH

Il programma di prova di questo mese si chiama KaoMath, ed è stato realizzato in ausilio di articoli di matematica dentro KULT
Underground. La parte più significativa dell’intero codice direi che consiste nel fatto che mostra come “simulare” un float usando coppie di int, e che funziona indipendentemente dalla dimensione del Cel su cui viene applicato, cosa visibile se lo lancerete tramite il TEK.
Ma cosa fa questo KAO?
Semplicemente disegna una parabola il cui parametro a può essere fatto variare dall’utente tramite un evento. Da qui a fare variare anche b e c direi che il passo è veramente corto, e lascio la risoluzione come esercizio per i lettori più intraprendenti.
Passando poi ad una breve descrizione del codice, noterete subito che, oltre al kaomain altre tre sono le funzioni presenti:
VuotaSchermo, che riempie del colore 0 il CEL;
DisegnaAssi, che disegna due linee perpendicolari in modo da simulare gli assi di un piano cartesiano;
DisegnaParabola, che si occupa di creare il grafico di una parabola.
Questa funzione mostra il primo problema implementativo di cui vi accennavo sopra.
Una parabola, infatti, dal punto di vista algebrico ha la seguente funzione:

y=a*x*x+b*x+c
dove a b e c dovrebbero essere valori reali. Considerare i coefficienti solamente interi infatti limita molto le possibilità di disegno. Che fare, allora? La mia idea, sicuramente non l’unica, nè per forza la migliore, è stata quella di usare due numeri int per i primi due coefficienti da usare come frazione, trasformando così la parabola in

y=a1*x*x/a2+b1*x/b2+c

Superfluo notare come sia indispensabile dividere il secondo coefficiente alla fine e non all’inizio (a1*x*x/a2 e non a1/a2*x*x), in quanto lavorando con interi la prima parte della moltiplicazione sarebbe 0 per ogni frazione minore di 1, e altrettanto superfluo usare una frazione anche per c, tutt’ora che si lavora su un sistema discreto.
Avete capito qualcosa?
Chissà. Beh, intanto provate a guardare il listato, e, quando vi sentirete pronti provate a compilarlo e a testarlo con il TEK.

———————————————————————-

include

define NUMCMD 1
void VuotaSchermo(BYTE far*Sc,

WORD x,

WORD y,

BYTE col);

void DisegnaAssi(BYTE far*Sc,

WORD x,

WORD y,

WORD cx,

WORD cy,

BYTE col);

void DisegnaParabola(BYTE far*Sc,

WORD x,

WORD y,

int cx,

int cy,

int a1,

int a2,

int b1,

int b2,

int cc,

BYTE col);

void kaomain(struct KULTAREA far * area)
{
static char cmd[2*NUMCMD+1];
static long dataNUMCMD];
static BYTE far*Video;
static WORD sx,sy;
static WORD cx,cy;
static int a1,a2,b1,b2,cc;
switch(_ASK&255)
{
case _KAOINIT:

_count=0;

_ID=_VIDEO=NUMCMD;

cmd[1]=’C’; // dati

cmd[2]=0;

_cmd=cmd;

_data=data;

break;
case _KAOREADY:

{

Video=((struct CELTYPE far*)data[0])->Image;

sx=((struct CELTYPE far*)data[0])->x;

sy=((struct CELTYPE far*)data[0])->y;

cx=sx/2;

cy=sy-10;

a1=1;a2=32;

b1=0;b2=1;

cc=0;

}

case _KAOPARAM:

switch(_ASK/256)

{

case 1:

a2++;

if(a2==0)

a2=1;

break;

case 2:

a2–;

if(a2==0)

a2=-1;

}

VuotaSchermo(Video,

sx,sy,

0);

DisegnaAssi(Video,

sx,sy,

cx,cy,

255);

DisegnaParabola(Video,

sx,sy,

cx,cy,

a1,a2,

b1,b2,

cc,

251);

break;
case _KAORESET:
break;
case _KAORUN:
break;
}
}
void VuotaSchermo(BYTE far*Sc,

WORD x,

WORD y,

BYTE col)

{
WORD size=x*y;
asm les di,Sc
asm mov cx,size
asm mov al,col
asm rep stosb
}
void DisegnaAssi(BYTE far*Sc,

WORD x,

WORD y,

WORD cx,

WORD cy,

BYTE col)

{
int i;
BYTE far*s;
for(s=Sc+cy*x,i=0;i*s=col;
for(s=Sc+cx+1,i=0;i*s=col;
}
void DisegnaParabola(BYTE far*Sc,

WORD x,

WORD y,

int cx,

int cy,

int a1,

int a2,

int b1,

int b2,

int cc,

BYTE col)

{
int X,Y,oldY;
BYTE far*s;
for(oldY=-32767,s=Sc,X=-cx;

X<(int)(x-cx);

X++,s++)

{
Y=-(a1*X*X/a2+b1*X/b2+cc);
if(isbetween(Y+cy,0,y-1))

{

if(oldY==-32767)

if(X==-cx)

oldY=Y;

else

if(Y<0)

oldY=-cy;

else

oldY=(y-cy)-1;

if(oldY

for(;oldY

*(s+(oldY+cy)*x)=col;

else

for(;oldY>Y;oldY–)

*(s+(oldY+cy)*x)=col;

*(s+(Y+cy)*x)=col;

}

else

if(oldY!=-32767)

{

if(oldY

for(;oldY<(y-cy);oldY++)

*(s+(oldY+cy)*x)=col;

else

for(;oldY>=-cy;oldY–)

*(s+(oldY+cy)*x)=col;

oldY=-32767;

}

}
}

———————————————————————-

Per vedere cosa queste linee di codice riescono a fare cliccate qui.
Come già sottolineato anche nell’ultima “puntata”, sono a disposizione di chiunque sia interessato a conoscere meglio strutture o sistemi per sviluppare KAO, perciò se avete qualche idea interessante non esitate a farvi avanti.
Per il momento è tutto. Buon lavoro, e buone vacanze.

Marco Giorgini

Note tecniche: KAOMATH.C è stato compilato con il Borland C++ 3.1, modello HUGE (è importante!), e linkato con il TLINK sempre del
Borland C++ 3.1.

Commenta