diff --git a/Makefile b/Makefile index 3229b77e5e0e71b900d9fdbf895e5c2add43c489..4b26dafcd803c741ec448c466cf55177038aa346 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,8 @@ TOOLOBJ = $(SIMOBJ) \ $(TARGET_DIR)/tool.o $(TARGET_DIR)/utils.o \ $(TARGET_DIR)/pagewriter.o $(TARGET_DIR)/pagereader.o \ $(TARGET_DIR)/configreader.o $(TARGET_DIR)/attrs.o \ - $(TARGET_DIR)/keyboard.o $(TARGET_DIR)/box.o + $(TARGET_DIR)/keyboard.o $(TARGET_DIR)/box.o \ + $(TARGET_DIR)/pen.o $(TARGET_DIR)/ana/%.o: $(SRC_DIR)/ana/%.c diff --git a/include/graphics/newcrt.h b/include/graphics/newcrt.h index 8d3446d996de01b27af0a92bcf375191db419b51..44a98b817490df6947f4d3ff0c7dd21897668754 100644 --- a/include/graphics/newcrt.h +++ b/include/graphics/newcrt.h @@ -1,6 +1,8 @@ #ifndef NEWCRT_H #define NEWCRT_H #include <X11/Xlib.h> +#include <utils/p2c.h> +#include <stdio.h> /* Caged_date="r nc_revision='V1.01: $X';" */ #define nc_revision "V1.01: Dec 17, 1988 11:00 pm" diff --git a/include/log.h b/include/log.h index a146e7f10dd591d21ab1b385a6b6e5dbe16e1a0d..63cfc18b3ad55d14bf99a1af8ddb3beaa5175493 100644 --- a/include/log.h +++ b/include/log.h @@ -7,7 +7,7 @@ #include "wire.h" #include "node.h" -void pen(); +void show_events(); void report(int num, char *s); void log_setmode(const char *s); long getint(char *s, long def); @@ -52,5 +52,8 @@ void addboxat(short x1, short y1, short x2, short y2); void settofrom(log_grec **g, char *name); void solderat(short x, short y); void frysolder(short x, short y); +void unprobe(); +void checkprobe(short xx, short yy); +void testprobe(short xx, short yy); #endif diff --git a/include/pen.h b/include/pen.h new file mode 100644 index 0000000000000000000000000000000000000000..5b13e1a64711767991c3ec13b04841498f228f1a --- /dev/null +++ b/include/pen.h @@ -0,0 +1,8 @@ +#ifndef PEN_H +#define PEN_H + +void pen(); +int justtap(); +int inbox(short x, short y, short x1, short y1); + +#endif diff --git a/src/box.c b/src/box.c index d284553c06a25c80cbf14487f0aed80f9ffe4de7..8b74ccf06078a264e7324c88917983df985ab1a6 100644 --- a/src/box.c +++ b/src/box.c @@ -4,6 +4,7 @@ #include "log.h" #include "utils.h" #include "keyboard.h" +#include "pen.h" /// Link box to the current page. void linkbox(log_brec *b) diff --git a/src/gate.c b/src/gate.c index 553a6d5df9768abef18e6c0a964999647854a511..581bdba6b5675f5bb2a67e3cda39233c6bc462f7 100644 --- a/src/gate.c +++ b/src/gate.c @@ -15,6 +15,7 @@ #include "tool.h" #include "keyboard.h" #include "box.h" +#include "pen.h" /// Check if inside a gate's "yellow box." /** new version by Tim Edwards, Dec 1996 */ diff --git a/src/keyboard.c b/src/keyboard.c index 832e70b098fb0b6baa3aaf3eec1efaa42ebcd807..8261b4b11f155bf96f78c5b28e5a76b47355e9e8 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5,6 +5,7 @@ #include "logdef.h" #include "log.h" #include "screen.h" +#include "pen.h" /// Return TRUE if a key has been pressed (via keyboard or menu boxes). int pollkbd2() diff --git a/src/label.c b/src/label.c index 5e87c70c3fc6b47881440c3efe03c578acae07d9..8c7326a926788aa54362ef306e87cb3b9eb11f4c 100644 --- a/src/label.c +++ b/src/label.c @@ -13,6 +13,7 @@ #include "screen.h" #include "log.h" #include "keyboard.h" +#include "pen.h" /** diff --git a/src/log.c b/src/log.c index 462f75b6e0ab5d92d7cbc96df83960c8e4724a7d..c00505e5a841e84fb4812ce0a05482a542e51db4 100644 --- a/src/log.c +++ b/src/log.c @@ -75,6 +75,7 @@ #include "tool.h" #include "keyboard.h" #include "box.h" +#include "pen.h" #include "pagewriter.h" #include "pagereader.h" @@ -85,69 +86,6 @@ enum cursors; enum cursors cursortype; enum cursors oldcursortype; -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 } -}; - - log_action_t gg; ///< External global variables short cursx; ///< Current X position of cursor @@ -298,8 +236,6 @@ double status_oldtime; double status_oldtstep; long status_oldmem; -short rabstate; ///< Rabbit recognizer state - long helpptr; ///< Help descriptor int popup_grid; ///< Pop-up menus @@ -429,7 +365,7 @@ void log_setmode(const char *s) drawstr2(across + menux3, line2, modename); } -static void unprobe() +void unprobe() { gg.probenode = NULL; gg.probegate = NULL; @@ -460,7 +396,7 @@ static log_krec *peninkind(short xx, short yy) /** @brief Find which wire, pin, or gate the Probe is touching and set PROBENODE or PROBEGATE to its address. */ -static void testprobe(short xx, short yy) +void testprobe(short xx, short yy) { log_grec *g; log_krec *k; @@ -537,7 +473,7 @@ static void testprobe(short xx, short yy) } -static void checkprobe(short xx, short yy) +void checkprobe(short xx, short yy) { short x, y; @@ -722,7 +658,7 @@ void resetmessages() /** @brief Debug function to show current number of events received and current simulation time. */ -static void show_events() +void show_events() { /*zEMBED char buf[30]; @@ -742,215 +678,6 @@ static void show_events() */ } - -/** @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) - { - 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. -static 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). -static 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); -} - - #define spacing 10 void message(char *msg) @@ -12856,7 +12583,6 @@ static void initialize() gg.probekind = NULL; probeflag = false; briefprobe = false; - rabstate = 0; rabbits = false; rabflag = false; firsttraining = true; diff --git a/src/pen.c b/src/pen.c new file mode 100644 index 0000000000000000000000000000000000000000..234b27d8b58f9b095f64a0fd2af9a071baf44d30 --- /dev/null +++ b/src/pen.c @@ -0,0 +1,281 @@ +#include "pen.h" + +#include <graphics/newci.h> +#include <graphics/newcrt.h> +#include "logdef.h" +#include "logglobals.h" +#include "keyboard.h" +#include "log.h" +#include "screen.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) + { + 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); +} +