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.
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,
void DisegnaAssi(BYTE far*Sc,
void DisegnaParabola(BYTE far*Sc,
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:
break;
case _KAOREADY:
case _KAOPARAM:
a2=1;
a2=-1;
break;
case _KAORESET:
break;
case _KAORUN:
break;
}
}
void VuotaSchermo(BYTE far*Sc,
{
WORD size=x*y;
asm les di,Sc
asm mov cx,size
asm mov al,col
asm rep stosb
}
void DisegnaAssi(BYTE far*Sc,
{
int i;
BYTE far*s;
for(s=Sc+cy*x,i=0;i
for(s=Sc+cx+1,i=0;i
}
void DisegnaParabola(BYTE far*Sc,
{
int X,Y,oldY;
BYTE far*s;
for(oldY=-32767,s=Sc,X=-cx;
{
Y=-(a1*X*X/a2+b1*X/b2+cc);
if(isbetween(Y+cy,0,y-1))
oldY=-cy;
oldY=(y-cy)-1;
*(s+(oldY+cy)*x)=col;
else
*(s+(oldY+cy)*x)=col;
*(s+(oldY+cy)*x)=col;
}
}
———————————————————————-
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.
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.