Sélectionner une révision Git
-
Etienne BRATEAU a rédigéEtienne BRATEAU a rédigé
pen.c 6,00 Kio
#include "pen.h"
#include <graphics/newci.h>
#include <graphics/newcrt.h>
#include "logdef.h"
#include "logglobals.h"
#include "keyboard.h"
#include "log.h"
#include "window.h"
short rabstate = 0; ///< Rabbit recognizer state
const rablisttype rablist = {
{ 0, 0, 1 },
{ 0, 4, 2 },
{ 0, 3, 3 },
{ 0, 2, 4 },
{ 0, 1, 5 },
{ 0, 0, 6 },
{ 1, 0, 7 },
{ 2, 0, 8 },
{ 3, 0, 9 },
{ 4, 0, 10 },
{ 4, 1, 11 },
{ 4, 2, -12 },
{ 3, 2, 13 },
{ 2, 2, 14 },
{ 1, 2, 15 },
{ 2, 2, -18 },
{ 0, 2, 17 },
{ 1, 2, 15 },
{ 3, 2, -20 },
{ 2, 3, -20 },
{ 3, 3, 21 },
{ 4, 3, -23 },
{ 3, 4, -23 },
{ 4, 4, 42 }
};
const rabmustype discomadness = {
{ 3, 46 },
{ 0, 8 },
{ 4, 10 },
{ 0, 15 },
{ 4, 12 },
{ 0, 2 },
{ 5, 35 },
{ 0, 6 },
{ 4, 35 },
{ 0, 6 },
{ 5, 8 },
{ 0, 17 },
{ 5, 12 },
{ 0, 2 },
{ 6, 35 },
{ 0, 6 },
{ 5, 35 },
{ 0, 6 },
{ 6, 8 },
{ 0, 17 },
{ 6, 12 },
{ 0, 2 },
{ 8, 35 },
{ 0, 6 },
{ 3, 35 },
{ 0, 6 },
{ 4, 8 },
{ 0, 16 },
{ 4, 12 },
{ 0, 3 },
{ 5, 50 },
{ 0, 0 }
};
/** @brief Find the position of the pen.
Also draws the cursor, runs logic probe and handles Rabbit mode.
Returns:
- D, D0 if the pen is/was down;
- N, N0 if the pen is/was near;
- DN, UP if the pen is pressed/released;
- NR if pen remains near;
- OFFSCREEN if pen is off the screen edge;
- PX, PY, PX0, PY0 = new/old position;
- FX, FY = position in grid coordinates;
- MENUBOX = menu box number (0-15);
*/
void pen()
{
#define ALERTNESS 2 /* Time to get bored (in cs) */
#define DOZETIME 5 /* Time to sleep after nodding off */
long x, y;
short i, rx, ry, cred;
/* static int pollkbd2(void); */
static int oldx, oldy;
static long awake;
long now;
char rval, gval, bval;
/* the following section improves idling behavior */
/* contributed by Nick Bailey (een6njb@sun.leeds.ac.uk) */
/* Keep on your toes if s/he's still twitching about! */
now = timers_sysclock();
if (gg.t.x!=oldx || gg.t.y!=oldy || pollkbd2() || gg.busyflag)
{
awake = now;
oldx = gg.t.x; oldy = gg.t.y;
}
/* Be friendly when not running something important */
if (now-awake > (unsigned long)ALERTNESS)
microsleep((unsigned long)10000*DOZETIME);
/* end of idling-improvement section */
TRY(try3);
gg.t0 = gg.t;
m_readpen(&gg.t);
show_events();
gg.stillnear = (gg.stillnear && gg.t.near_);
gg.incircuit = (gg.t.y < baseline && gg.showpage > 0);
RECOVER(try3);
if (P_escapecode == -20)
_Escape(P_escapecode);
nc_printf("Graphics tablet error\n");
m_init_pen(tabletaddr);
m_alpha_on();
ENDTRY(try3);
if (snapflag && gg.incircuit)
{
gg.t.x = (gg.t.x + gg.hscale + gg.xoff) / gg.scale * gg.scale - gg.xoff;
gg.t.y = (gg.t.y + gg.hscale + gg.yoff) / gg.scale * gg.scale - gg.yoff;
}
if (gg.t.x < 0)
gg.t.x = 0;
else if (gg.t.x > across)
gg.t.x = across;
if (gg.t.y < 0)
gg.t.y = 0;
else if (gg.t.y > down)
gg.t.y = down;
if (gg.t.near_ && !gg.t.depressed)
{
rx = gg.t.x * 5 / across;
ry = gg.t.y * 5 / down;
if (rx != rablist[rabstate].x || ry != rablist[rabstate].y)
{
i = abs(rablist[rabstate].next) - 1;
do
{
i++;
} while ((rablist[i].x != rx || rablist[i].y != ry) &&
rablist[i].next < 0);
if (rablist[i].x == rx && rablist[i].y == ry)
{
if (i == rablistsize)
{
remcursor();
rabbits = !rabbits;
if (rabbits && !gg.quiet)
{
i = 1;
x = timers_sysclock();
do
{
y = discomadness[i - 1].time;
do
{
} while (timers_sysclock() <= x + y);
/* nothing */
i++;
x = timers_sysclock();
} while (y != 0);
}
rabstate = 0;
} else
rabstate = i;
} else
rabstate = 0;
}
}
else
{
rabstate = 0;
}
if (gg.probemode)
{
short cursx = getcursorxposition();
short cursy = getcursoryposition();
if (cursx != gg.t.x || cursy != gg.t.y)
{
if (gg.probesimtype != NULL)
checkprobe((int)gg.t.x, (int)gg.t.y);
probeflag = false;
drawcursor((int)gg.t.x, (int)gg.t.y);
}
else
{
if (!cursorflag)
drawcursor((int)gg.t.x, (int)gg.t.y);
if (!probeflag)
{
testprobe((int)gg.t.x, (int)gg.t.y);
probeflag = true;
}
}
if (!gg.t.near_ && briefprobe)
{
remcursor();
gg.probemode = false;
}
}
else
{
briefprobe = false;
if (gg.probesimtype != NULL)
unprobe();
if (gg.t.near_)
drawcursor((int)gg.t.x, (int)gg.t.y);
else
remcursor();
}
cred = gg.color.conflict;
if (anyconflicts && (cred == log_cred || cred == log_cred8) &&
(rcolormap[cred] == 255 || gcolormap[cred] == 255 ||
bcolormap[cred] == 255))
{
x = timers_sysclock() * 6 % 137 + 119;
rval = (char)(x * rcolormap[cred] / 255);
gval = (char)(x * gcolormap[cred] / 255);
bval = (char)(x * bcolormap[cred] / 255);
m_vsetcolors((long)cred, 1L, (unsigned char *) &rval,
(unsigned char *) &gval, (unsigned char *) &bval);
}
if (gg.t.moving)
{
gg.fastspeed = gg.fastmin;
fastsavetime = timers_sysclock();
}
else if (gg.fastspeed < gg.fastmax &&
timers_sysclock() > fastsavetime + gg.fastrate)
{
gg.fastspeed++;
fastsavetime = timers_sysclock();
}
gg.gridx = (gg.t.x + gg.hscale + gg.xoff) / gg.scale;
gg.gridy = (gg.t.y + gg.hscale + gg.yoff) / gg.scale;
}
/// Return TRUE if pen was tapped. Return FALSE if pen was held and/or moved.
int justtap()
{
long t0;
short tx, ty;
t0 = timers_sysclock() + tapdelay;
tx = gg.t.x;
ty = gg.t.y;
do
{
pen();
} while (gg.t.depressed && labs(gg.t.x - tx) <= taptolerance &&
labs(gg.t.y - ty) <= taptolerance && timers_sysclock() <= t0);
return (!gg.t.depressed);
}
/// Return TRUE if cursor is inside a certain rectangular area (screen coordinates).
int inbox(short x, short y, short x1, short y1)
{
return (gg.t.x >= x && gg.t.y >= y && gg.t.x <= x + x1 && gg.t.y <= y + y1);
}