tExas News vom 27. Dezember 1999
Uwe schickte mir folgende email:
Meine Frage an Markus van Griethuijsen (Programmier von AvigoConnect für Lotus) griethu@xs4all.nl war
I waited a long time for this programme. I’m happy that you had produced it and I will express you my praise. Its a very nice tool. Would you send me a Mail if it is possible to send documents from Notes to Avigo? Thank you very much.
Das ist seine Antwort:
I will not update the program anymore, the source is published on the web so I hope someone else will continue.Met vriendelijke groet / With kind regards, Markus van Griethuijsen griethu@xs4all.nl
Die Firma Microbasic Deutschland vertreibt leider nicht mehr die Intellisync – Vollversion. Nach einer Anfrage meinerseits versucht nun PMS-Systems (AvigoPool) http://www.pmssystem.de/avigo.htm die Vertriebsrechte zu erhalten.
René's Avigo Page
I gave up the development for the Avigo some time ago. So please do not expect too much here.
The purpose of this page is to provide support for programmers of the
TI Avigo organizer. I will provide sample source code to get you
started, help on the way, and complete projects.
Content
Installing and testing the SDK
The Numbers Game (Les Chiffres) (Ver 1.2)
German Hollidays (Feiertage) (Ver. 1.2)
Computing the Sunset (Ver. 1.1)
That’s all for now.
René's Avigo Page: Installing and testing the SDK
Installing and Running the SDK
Buying the SDK
The SDK is a commercial product by Advocet. Go to their Web-Page and get more information.
They shipped the SDK to me within seven days. The SDK includes
- a devoper IDE,
- a debugger and simulator for Avigo programs,
- documentation of the Avigo API and the tools.
Installing
I had no problems installing the SDK from the CD-ROM. However, neither the IDE,
nor the simulator runs on NT. The IDE claims about an incorrect DLL, and the simulator about lacking VESA support.
Advocet should be able to fix both. However, you can use the SDK on Windows NT quite comofortably as described
below.
I had a problem on another Windows 95b machine. The installation complained about
not being able to replace a MFC library and refuses to let me skip that replacement. So I had to close several
running programs (screen manager etc.) before I could go on. Installation on Windows can be a nightmare!
One more problem occured on another Windows 95 machine (with a ATI XPression graphics
card). The Simulator mouse destroys the screen picture there. This is probably due to false Vesa drivers.
Maybe it is a good idea to include the p100sdk\bin directory into the path. There
is a setenv batch file in p100sdk that sets some environment variables and extends the path (in a very amateurish
way). However, I did not need any of this.
Testing
The first thing to do is to start the IDE and open the help. You will see a tutorial
section. Follow the instructions. You need to open a new directory and copy the tutorial files, then set up your
project and test it. At one point you need to run a batch file in a DOS window, because a bitmap needs to be converted
into bin format. Just do it. I did set the environment with p100sdk\setenv.bat before, but that may not be necessary.
You may want to try a
simple program, which was the first one I wrote. Got it after a few hours
of reading around in the documentation and the tutorial example, and after a considerable bit of trial and error.
Too bad that the debug program shows no variable contents. I find most debuggers useless and help myself with variable
dumps.
Bugs and Problems
I met a few bugs.
The compiler is somewhat sloppy with checking of code correctness. It will accept
code, which cannot be accessed, or labels, which are never used. Thus forgetting the case keyword in a switch statement
will be accepted, but not work. Furthermore, there are things like
<font face="Arial, Helvetica">counter++:</font>
with a “:” instead of a “;”. This is accepted as a label.
So be careful. Of course, this is not really a bug.
Sometimes, code won’t recompile with strange error messages. Try rebooting the
system. Then try deleteing all object files and the *.lin files. If this does not help, try deleteing everything
but your sources and bitmap files, and set up a new project.
Imported files might not compile, if you have the wrong line separators. To get
that right, copy the files to the clipboard and import them into notepad. This editor seems to fix that problem.
I met it only once, when I copied and pasted the file directly from the browser to the IDE.
It is annoying that the code window goes to the beginning of the file at each
compiler run. You can use bookmarks to find back to specific points. During compilation the file window will be
distorted. Don’t worry. It seems that auto-indent is not functioning properly too. I found no way to help this.
Not Using the IDE
After all, it might be a good idea to use another editor (like my favourite UltraEdit)
and call the compiler from it. This is possible by writing a batch file with the following content
<font face="Arial, Helvetica">path=c:\p100sdk\bin<br />call make -f </font><i><font face="Arial, Helvetica">Project</font></i><font face="Arial, Helvetica">.mak</font>
where Project
is the name of your project. Then call that command from your editor, which should be able to catch the compiler
output. This assumes that the IDE has set up the flash files, the make files and several project settings. The
simulator can be started with
<font face="Arial, Helvetica">c:\p100sdk\bin\falcon</font>
in the directory of your project. Since this does not work on Windows NT, you
might want to use the great Freeware
Simulator. Thanks to Gerard Vermeugen for this masterpiece! You can use
his simulator for development in the following way. You first open the simulator by typing avsim and after setting
up the Avigo, go to the system setup page and switch off the display of the startup graphics. Then exit the simulator
and copy the RAM file
<font face="Arial, Helvetica">copy avsim.sav avsim.bak</font>
Create a batch file, which copies the RAM file back before it starts the simulator.
E.g.
<font face="Arial, Helvetica">copy avsim.bak avsim.sav<br />start avsim</font>
This will give you a fresh simulator. You may install an application with the
menu. The menu even contains a list of recenty installed applications. It’s a very good piece of software. I haven’t
yet found a bug.
René's Avigo Page: The Lotto Program

So here is my first application. I tried to keep it simple enough to be
understandable, but yet involved enough to show something. You may
download and try the complete source here. The included Bitmap is of
size 50×52, and I did it with Painbrush Pro. The size is the same as
the bitmap in the tutorial example. Above you can see a the logo
converted to GIF. It is probably best to keep the logo as simple as
possible. The complete application is here to try on your Avigo.
Lotto.app
16 kb
lotto.zip
2 kb
Now open a new project and add the C-file as source. Add the bitmap as
icon and convert it to dot format with the button on the icon page.
Then compile the source and start the simulator. Go to the applications
and start the Lotto program. You will see the following Avigo screen.

It simply displays 6 numbers randomly chosen out of 49. It has a menu
on its left top containing entries “New Numbers” and “Exit”, which is
dropped down at this moment, and it can be closed with the cross at the
top right. Nothing spectacular, and of little use. But it serves as a
demo for a simple Avigo program. By the way, you can do screen prints
with a menu item in the debugger.
While trying this in the simulator, I noticed that the menu selection
does not work properly with the mouse. You have to try a bit to get the
“New Numbers” entry to respond.
What follows is the source. I am going to explain most of it later.
/* you have to include all those header files
*/
#include “p100plib.h”
#include “ressdk.h”
#include “math.h”
#include “packet.h”
/* you have to decleare a static string for the window
title
*/
unsigned char test_title[] = “Test Title”;
/* you have to declere the event handlers BANKED and extern
*/
extern BANKED void test_draw (VOID_PTR view);
extern BANKED void test_handle_event (VOID_PTR view,
unsigned short *evType, unsigned char x, unsigned char y);
/* define the command constants (belongs to a header file)
*/
#define cmdNew 1000
/* define the main menu structure
*/
const MENUITEM MainMenu[] =
{ {“New Numbers”, cmdNew, 0},
{“Exit”, cmCancel, 0},
{”\0”, 0, 0}
};
/* those are the routines to generate Lotto numbers
*/
#define Ntotal 49
#define Nchosen 6
int Numbers[Ntotal];
void init_numbers ()
/* initialize the first 6 as chosen
*/
{ int i;
for (i=0; i<Ntotal; i++) Numbers[i]=0;
for (i=0; i<Nchosen; i++) Numbers[i]=1;
}
void mix_numbers ()
/* randomly mix them (thanks to the random() function)
*/
{ int i,j,h;
for (i=Ntotal-1; i>0; i—)
{ j=random(i+1);
if (j!=i)
{ h=Numbers[j]; Numbers[j]=Numbers[i]; Numbers[i]=h;
}
}
}
/* this is the definition of the drawing routine,
which is inserted for the main window with the
help of the BankedAssign() function.
*/
void test_draw (VOID_PTR view)
{ /* the pointer is really a point to a DESKBOX */
PDESKBOX *dsk;
dsk=(PDESKBOX *)view;
int i,y; /* C++ like (variables need not be at function start) */
PDESKBOX_draw(view); /* default, clears the view */
SetFontType (PRPFONT14B); /* biggest font available */
unsigned char s256; /* for forming the string */
y=dsk->top+40; /* the row of the first string */
for (i=0; i<Ntotal; i++) /* draw all chosen numbers */
if (Numbers[i])
{ /* convert to string and draw */
NumericToStr((double)(i+1),s,DTINTEGER);
WriteString(dsk->left+20,y,s,0);
y+=20; /* increment row */
}
}
/* the event handler for the menu commands and for
the main window
*/
void test_handle_event (VOID_PTR view,
unsigned short *evType, unsigned char x, unsigned char y)
{ /* convert view to deskbox */
PDESKBOX *dsk;
dsk=(PDESKBOX *)view;
/* call default handler (don’t know why) */
PDESKBOX_handleEvent(view,evType,x,y);
/* switch events */
if (*evType==evCommand)
{ switch (TOWORD)
{ case cmdNew : /* user wants other numbers */
ClearEvent(evType);
/* event taken */
mix_numbers(); /* shuffle */
dsk->draw(view);
/* redraw window */
break;
}
}
}
short main (void)
{
/* pointer to the main window (properly destroy it at end) */
PDESKBOX *dsk;
/* init our Lotto numbers */
init_numbers();
randomize();
mix_numbers();
/* create a window covering all of the screen
with a menu, a title and a close box */
dsk = (PDESKBOX *)CreateDeskBox(‘A’,0,0,159,239,
MK_FAR_PTR(test_title),MK_FAR_PTR(MainMenu),0,
bafClose|bafDotTitle);
dsk->options &= ~ofFindable; /* no find in this application */
/* assign the event handlers to this window */
BankedAssign(dsk->handleEvent,test_handle_event);
BankedAssign(dsk->draw,test_draw);
/* seems to generate the main event loop */
ExecView ((PGROUP *) dsk);
/* destroy the window */
Destroy ((VOID_PTR) dsk);
return 0;
}
after only a few hours. Furthermore, the programming style is a bit
different to my favourite Java style, though there are related things.
The compiler is ANSI-C with a few restrictions described in the on-line
help. It has no // comments, but allows variable declarations at every
place in a function. It has a few more keywords like the BANKED
modifier, which marks a function as being available from outside its
16k bank. As you will guess by this memory organization, pointers are
16 Bit wide. So you have to convert pointers to 32 Bit, if you pass
them to system calls. This is done by the MK_FAR_PTR macro.
The main function has no arguments and returns a short. This program
uses main to generate the numbers for the Lotto run, to initialize a DeskBox?
and start the event loop. I won’t comment much on the generation of the
random numbers. There is a random function, which is useful here. Maybe
randomize initializes the random number generator with the Avigo time.
init_numbers();A DeskBox is an analoge of a window. It may have a title, a menu and a close button, all determined by the CreateDeskBox function arguments. And it has a drawing area. The Avigo SDK calls a DeskBox an object. There is a hierarchie of objects. The grandfather is a PVIEW. This program only uses the DeskBox. I do not understand the rest of the objects at this time.
randomize();mix_numbers();
The second statement makes sure the find button is off while this application runs.dsk = (PDESKBOX *)CreateDeskBox(‘A’,0,0,159,239,
MK_FAR_PTR(test_title),MK_FAR_PTR(MainMenu),0,
bafClose|bafDotTitle);
dsk->options &= ~ofFindable; /* no find in this application */
The application then assigns pointers to event handlers for the DeskBox? with the BankedAssign?
function. These handlers must be BANKED functions, because they are
called from outside. The correct way to do this is to declare a
function prototype at the beginning or in a header file. The test_draw
function is the redraw routine for the DeskBox? and the test_handle_event function will handle all events, like pen clicks or menus.
extern BANKED void test_draw (VOID_PTR view);
extern BANKED void test_handle_event (VOID_PTR view,
unsigned short *evType, unsigned char x, unsigned char y);
After this preperation, we are ready for the event loop. The event loop is entered with
ExecView ((PGROUP *) dsk);
is triggered by the close button or by the “Exit” menu entry, because I
gave it that value. The menu is defined in an array of MENUITEM
structures. This array is passed as a far pointer to the CreateDeskBox function.
const MENUITEM MainMenu[] =
{ {“New Numbers”, cmdNew, 0},
{“Exit”, cmCancel, 0},
{”\0”, 0, 0}
};
We now discuss the test_draw function.
void test_draw (VOID_PTR view)
{ /* the pointer is really a point to a DESKBOX */
PDESKBOX *dsk;
dsk=(PDESKBOX )view;
int i,y; / C++ like (variables need not be at function start) /
PDESKBOX_draw(view); / default, clears the view /
SetFontType (PRPFONT14B); / biggest font available /
unsigned char s256; / for forming the string /
y=dsk->top+40; / the row of the first string /
for (i=0; i<Ntotal; i++) / draw all chosen numbers */
if (Numbers[i])
{ /* convert to string and draw /
NumericToStr((double)(i+1),s,DTINTEGER);
WriteString(dsk->left+20,y,s,0);
y+=20; / increment row */
}
}
The type name PDESKBOX is somewhat misleading, because it not a pointer
but a structure. We first call the default drawing routine, which will
clear the window. Then we set the font and paint our numbers into the
window. The window margins are with the window bounds and the title
line. There seems to be no way to determine the interior drawing area.
However, it might be save to use absolute constants here. To format a
number, we can use the NumericToStr function.
The test_handle_event routine is very similar.
void test_handle_event (VOID_PTR view,
unsigned short *evType, unsigned char x, unsigned char y)
{ /* convert view to deskbox */
PDESKBOX *dsk;
dsk=(PDESKBOX *)view;
/* call default handler (don’t know why) */
PDESKBOX_handleEvent(view,evType,x,y);
/* switch events */
if (*evType==evCommand)
{ switch (TOWORD)
{ case cmdNew : /* user wants other numbers */
ClearEvent(evType);
/* event taken */
mix_numbers(); /* shuffle */
dsk->draw(view);/* redraw window */
break;
}
}
}
It calls the default event handler by a reason beyond me. Then it
checks for the correct event type. Events are declared invalid by the
ClearEvent routine. This feature is the reason events are passed by a
pointer. The event number is hidden in the x and y parameters, which
might also serve to describe pen events. We simply mix our random
numbers and repaint the DeskBox with its drawing routine.
This is as much as I understood by now. Hope it helps you. More complex projects will follow.
René Grothmann
René's Avigo Page: The Numbers Game
This is my second try on the Avigo system. It is actually a port from a
Java applet and then again from very old C routines I once wrote. The
problem is based on a TV show in french channel one.

In the above picture, the problem is to form the 179 with 3, 5, 6, 6,
7, and 100 not using any number twice. The allowed operations are +, -,
- and /. You can either let the computer solve the problem, and the
solution in the captured image has been found by the computer. Or you
can try to solve yourself, using the right part of the panel. This is
done by selecting two numbers on the list of available numbers and
pressing an arithmetic button. Other screen elements are four buttons
and one label “New”.
The code consists of two header files and two C files. You can download the application with source in zipped form from here: numbers.zip
Screen Layout
The screen layout consists of several elements. Here is a list from the code
PNUMBERFIELD * INumbers6;
PNUMBERFIELD * ITarget;
PBUTTON * NewProblem;
PBUTTON * NewTarget;
PBUTTON * Solve;
PBUTTON * Retry;
PBUTTON * Plus;
PBUTTON * Minus;
PBUTTON * Div;
PBUTTON * Mult;
PLISTER * List;
PLABEL * Output5;
PLABEL * New;
displays a number picker, which is a small calculator. The screen is
repainted afterwards. It might be possible to save the image below the
picker, but I did not find the code for this. I did not want to invest
too much time for this application. The code to get and display a
number field is this:
/* Generate six number labels at the top */
for (i=0; i<6; i++)
{INumbers[i]=(PNUMBERFIELD *)CreateNumberField(
id++,
5+25*i, row,
(unsigned
char *)(Numbers+i),
DTINTEGER,
MK_FAR_PTR(“Input Number”));
INumbers[i]->right=25+25*i;
LoadBank(&(dsk->insert));
dsk->insertVOID_PTR)dsk,INumbers[i]);
}
/* Generate a target label centered below */
row+=20;
ITarget=(PNUMBERFIELD *)CreateNumberField(
id++, 65, row,
(unsigned char *)(&Target),
DTINTEGER, MK_FAR_PTR(“Input Target”;
ITarget->right=95;
LoadBank(&(dsk->insert));
dsk->insertVOID_PTR)dsk,ITarget);
operations are needed every time. However, they seem not to harm. By
the way, the objects are inserted into a DESKBOX object dsk, which is
the same as in the Lotto example.
Then we have six labels at the left. These are generated with the
CreateLabel function, just as the Number Fields. I won’t explain the
buttons either, because they are straightforward. The only change is a
command number, which the CreateButton function takes. This number will
be used in the event handler.
A more complicate topic is the list of available numbers at the right
panel. The Avigo SDk does not support a comfortable list element. It
only provides a LISTER object, which reacts on mouse buttons and calls
a redraw routine for each item. You have to override both event
handlers and take the proper action. My solution is this:
/* event handlers /
extern BANKED void list_writeItem (VOID_PTR view,
unsigned char x, unsigned char y, unsigned short item);
extern BANKED void list_pen (VOID_PTR view,
unsigned char x, unsigned char y);
int Available6,Marked6;
int NAvailable;
void setAvailable ()
/ copy numbers from the Numbers field */
{ int i;
for (i=0; i<6; i++)
{ Available[i]=Numbers[i];
Marked[i]=0;
}
NAvailable=6;
}
int nmarked ()
/* get number of marked objects */
{ int i,n=0;
for (i=0; i<NAvailable; i++)
if (Marked[i]) n++;
return n;
}
void list_writeItem (VOID_PTR view,
unsigned char x, unsigned char y, unsigned short item)
/* event handler for writing */
{ char s16;
PLISTER *p; p=(PLISTER *)view;
if (item>=NAvailable) return;
NumericToStr((double)Available[item],s,DTINTEGER);
SetFontType(PRPFONT11N);
WriteString(x,y,s,Marked[item]);
}
void unmarkall ()
/* unmark all numbers */
{ int i;
for (i=0; i<NAvailable; i++) Marked[i]=0;
}
void list_pen (VOID_PTR view, unsigned char x, unsigned char y)
/* event handler for pen touches */
{ PLISTER *p; p=(PLISTER *)view;
int i;
x=0;
i=(y-p->top)/((p->bottom-p->top)/6);
if (i>=0 && i<NAvailable)
{ if (nmarked()>=2)
{ if
(!Marked[i]) unmarkall();
}
Marked[i]=!Marked[i];
}
PLISTER_draw(view);
}
void availableremove (int j)
/* remove number at j from available numbers */
{ int i;
if (j>=NAvailable) return;
for (i=j; i<NAvailable-1; i++)
{ Available[i]=Available[i+1];
Marked[i]=Marked[i+1];
}
NAvailable—;
}
void availableappend (int h)
/* append number h to available nubmers */
{ if (NAvailable>=6) return;
Available[NAvailable]=h;
Marked[NAvailable]=0;
NAvailable++;
}
void available (int command)
/* called from the main event handler (buttons ,-,*,/) */
{ if (nmarked()!=2) return;
int h1,h2,i1,i2,f,i,h;
long L;
f=0;
for (i=0; i<NAvailable; i+)
{ if (Marked[i])
{ if
(f) i2=i;
else
i1=i;
f++;
}
}
h1=Available[i1]; h2=Available[i2];
if (NAvailable==6) clear();
switch (command)
{ case cmdPlus :
h=h1+h2;
writesolution(6-NAvailable,h1,h2,’+’,h);
break;
case cmdMinus :
if
(h1<h2)
{ h=h2-h1;
writesolution(6-NAvailable,h2,h1,’-’,h);
}
else
if (h1>h2)
{ h=h1-h2;
writesolution(6-NAvailable,h1,h2,’-’,h);
}
break;
case cmdMult :
L=h1*h2;
if
(L>30000l) return;
h=h1*h2;
writesolution(6-NAvailable,h1,h2,’*’,h);
break;
case cmdDiv :
if
(h1>h2)
{ if
(h1%h2!=0) return;
h=h1/h2;
writesolution(6-NAvailable,h1,h2,’/’,h);
}
else
if (h1<h2)
{ if
(h2%h1!=0) return;
h=h2/h1;
writesolution(6-NAvailable,h2,h1,’/’,h);
}
else
if (h1==h2)
{ h=1;
writesolution(6-NAvailable,h2,h1,’/’,h);
}
else
return;
}
availableremove(i2);
availableremove(i1);
availableappend(h);
}
which connects the +, -, * and / buttons to the available numbers list.
So it does not count. You have to assign the handler functions.
List=(PLISTER *)CreateLister?(
id++,95,row,120,row+5*15,6);
LoadBank(&(dsk->insert;
dsk->insertVOID_PTR)dsk,List);
BankedAssign(List->writeItem,list_writeItem);
BankedAssign(List->penDownAct,list_pen);
The last problem is to draw the lines, which seperate the panels. this is done in the panel redraw function.
void test_draw (VOID_PTR view)
{ /* the pointer is really a point to a DESKBOX */
PDESKBOX *dsk;
dsk=(PDESKBOX )view;
PDESKBOX_draw(view); / default, clears the view */
DrawLine(0,line1,160,line1,DRAW_BLACK);
DrawLine(0,line2,160,line2,DRAW_BLACK);
DrawLine(80,line1,80,line2,DRAW_BLACK);
}
The line1 and line2 variables are set by the generation routine, which inserts the screen elements from top to bottom.
After a first test, it was clear that a complete redraw of the screen
is to slow. So separate redraw functions had to be written for the
numbers, the target, the solution and the available number list.
void solution_draw ()
/* redraw the solution strings */
{ int i;
for (i=0; i<5; i++)
{ PVIEW *p;
p=(PVIEW *)Output[i];
FillRect(p->left,p->top,
p->right,p->bottom,
DRAW_WHITE);
PLABEL_draw((VOID_PTR)Output[i]);
}
}
void clearSolution ()
/* clear the solution area and redraw it */
{ clear();
solution_draw();
}
void available_draw ()
/* redraw the available nubmers */
{ PLISTER_draw((VOID_PTR)List);
}
void numbers_draw ()
/* redraw the numbers */
{ int i;
for (i=0; i<6; i++)
PNUMBERFIELD_draw((VOID_PTR)INumbers[i]);
}
void target_draw ()
/* redraw the target number */
{ PNUMBERFIELD_draw((VOID_PTR)ITarget);
}
The Solution strings are contained in the other source file, by the way.
Solving the problem
This routine is ported from the Java version. However, Java on a
Pentium 166 detects if any solution within seconds. I did not even
bother for multithreading. On the Avigo, detecting that there is no
solution takes minutes.
So I tried to make this interruptable by the user. I did it by calling GetEvent?
at regular intervals (every 1000 trials). However, this only makes the
application slower, since I am catching Timer interrupts only. In the
simulator however it works OK. So right now, you can only interrupt the
trial by pressing the TODO key. This does not work immediately, but
after a while. Switching off and on does not work. The Avigo just
resumes the computation. I will try to find a solution for this.
The main problem is the lack of a TestEvent function, which tests for events without waiting for them. There is a TestPutEvent
function but it only tests for events that you have put on the event
queue. It seems there is a special buffer for one such user put event.
I do switch off the auto power off during computation, and on again
after it is finished. So when the user interrupts the computation, its
auto power off setting may be switched off. I had not time to
investigate this.
Problems I met
I had two bugs, which were very hard to find. One was a missing case statement.
switch (TOWORD(x,y
{ cmdNewProblem :
ClearEvent(evType);
mix(); makeTarget();
PDESKBOX_draw(view);
break;
cmdNewTarget :
ClearEvent(evType);
makeTarget();
PDESKBOX_draw(view);
break;
}
A clever C compiler might issue a warning about two unused labels. But
this is one of the reasons, why Java abandoned simple form of goto and
label usage. Such errors tend to be very tough to detect.
The second bug was an index out of range. The simulated Avigo fell into
the setup routine (tab the screen here and so on), when the function in
question was called. This is not exactly a clear error message. Again,
such errors are much easier to find in Java.
René Grothmann
Seite 1 von 3, insgesamt 11 Einträge nächste Seite »












Social Media