REM >YogiLib REM REM Problems with display coordinate conversion: REM System does not take account of device aspect ratio. REM Problem is intractable if devices have different aspect ratios. REM Coordinates suggest aspect ratios vary from 0.74 to 0.8 REM So x/y problem almost goes away if internal coordinate system REM ranges from 0-1000 (x) and 0-800 (y). That's what I've done. DEF PROCyogi_touchscreen_boxes nboxes% = 1 nlines% = 9 houselight_line% = 0 floor_panel_line% = 1 central_mag_nosepoke_line% = 2: REM autoshaping magazine sensor right_sensor_nosepoke_line% = 3 middle_sensor_nosepoke_line% = 4 left_sensor_nosepoke_line% = 5 wall_mag_nosepoke_line% = 6: REM rear wall magazine sensor central_pellet_dispenser_line% = 7 wall_pellet_dispenser_line% = 8 DIM houselight%(nboxes%) DIM floor_panel%(nboxes%) DIM central_mag_nosepoke%(nboxes%) DIM wall_mag_nosepoke%(nboxes%) DIM right_sensor_nosepoke%(nboxes%) DIM middle_sensor_nosepoke%(nboxes%) DIM left_sensor_nosepoke%(nboxes%) DIM central_pellet_dispenser%(nboxes%) DIM wall_pellet_dispenser%(nboxes%) FOR box% = 1 TO nboxes% houselight%(box%) = FNswitch_number_2(box%, houselight_line%,nlines%) floor_panel%(box%) = FNswitch_number_2(box%, floor_panel_line%, nlines%) central_mag_nosepoke%(box%) = FNswitch_number_2(box%, central_mag_nosepoke_line%, nlines%) wall_mag_nosepoke%(box%) = FNswitch_number_2(box%, wall_mag_nosepoke_line%, nlines%) right_sensor_nosepoke%(box%) = FNswitch_number_2(box%, right_sensor_nosepoke_line%, nlines%) middle_sensor_nosepoke%(box%) = FNswitch_number_2(box%, middle_sensor_nosepoke_line%, nlines%) left_sensor_nosepoke%(box%) = FNswitch_number_2(box%, left_sensor_nosepoke_line%, nlines%) central_pellet_dispenser%(box%) = FNswitch_number_2(box%, central_pellet_dispenser_line%,nlines%) wall_pellet_dispenser%(box%) = FNswitch_number_2(box%, wall_pellet_dispenser_line%,nlines%) REM -------Take control of output/input lines------- PROCgovn_switch(houselight%(box%),E%) PROCfree_switch(floor_panel%(box%),E%) PROCfree_switch(central_mag_nosepoke%(box%),E%) PROCfree_switch(wall_mag_nosepoke%(box%),E%) PROCfree_switch(right_sensor_nosepoke%(box%),E%) PROCfree_switch(middle_sensor_nosepoke%(box%),E%) PROCfree_switch(left_sensor_nosepoke%(box%),E%) PROCgovn_switch(central_pellet_dispenser%(box%),E%) PROCgovn_switch(wall_pellet_dispenser%(box%),E%) NEXT REM Touchscreen input stuff, using library "JP" touchscreen_channel% = 0 max_touchscreens% = 0 :REM Arrays are indexed by channel number, so this must equal the greatest *channel number* used REM -- Yogi's touchscreens manage to generate serial overrun errors from time to time. REM This appears to be a serial hardware fault (it implies the incoming hardware buffer REM overflowed, so the handshaking wasn't rapid enough. Possibly an increase in the speed REM of the incoming serial processing code would help - I'll have a look at my touchscreen REM interpreter, but the Arachnid serial handler is beyond my control. Ultimately it just REM means that the serial hardware buffer is too small. It might be that it's the extra REM serial ports on the "Cobweb" card that are poorly designed; we haven't tried the REM touchscreen on the Archimedes' main serial port. REM REM Anyway, in lieu of a proper solution (and in the absence of constructive help from Cenes), REM I've reduced the data transmission rate of the touchscreen from 9600 to 1200 bps, using REM its DIP switches. REM REM Since we're now using a non-default setting, we need to tell the serial hardware. REM Parameters to PROCsconf(), described on p46 of Arachnid manual, are: REM channel REM data bits, typically 8 REM parity bits, typically 0 REM stop bits, typically 1 REM receive speed in bps REM transmit speed in bps REM lines REM -- bit mask of the handshaking lines to be used; bits 1,4,6,7,8 correspond to REM DCD, DTR, DSR, RTS, CTS respectively. Default is 384 (128+256, i.e. REM RTS and CTS). (16 Feb 2000 - er, hello, are we counting bits from 0 then?) REM -- I need to check the Arc serial port pinouts. 9-pin D. REM -- Touchscreen manual isn't clear but seems OK. RJ11 pinouts REM are 1 (DTR), 2 (TX), 3 (GND), 4 (GND), 5 (RX), 6 (CTS). REM It wires these to pins 1, 2, 5, nothing, 3, 4 respectively on the Arc. REM I presume the Arc pinouts are REM 1 (DCD), 2 (RX), 3 (TX), 4 (DTR???), 5 (GND), 6 (DSR), 7 (RTS), 8 (CTS). REM The touchscreen cable shorts Arc pins 7 and 8 together. REM *** WELL, THAT'S THE PROBLEM. IDIOTS. REM -- Arc internal serial port overrides this (always RTS+CTS, never DTR) so REM only DCD/DSR settings matter. "Cobweb" serial ports presumably take more notice REM of this setting. REM -- Arachnid manual recommends RTS+CTS handshaking and shorting together REM DCD-DTR-DSR on the computer's serial port for "typical" devices. REM -- Default for Arachnid and the touchscreen is RTS/CTS handshaking. REM -- SO IF RTS IS NOBBLED, LET'S TRY ADDING DTR SUPPORT, so lines% becomes REM 8. REM extent REM -- "when the number of free slots in the channel's rbuf falls below this REM level, the handshake lines will be set to busy... default is 10" REM Well, 10 is a perfectly reasonable value, and suggests that it is truly REM the hardware buffer that is at fault if we're getting overrun errors. REM PROCsconf(0, 8, 0, 1, 9600, 9600, 384, 10, E%): *AE REM 16 Feb 2000 - REM rewired the cable coming out of the touchscreen: REM REM Arc touch REM +- 1 DCD < REM | 2 RX < TX (red) REM | 3 TX > RX (white) REM +- 4 DTR > REM | 5 GND - GND (blue) REM +- 6 DSR < REM 7 RTS > CTS (black) REM 8 CTS < DTR (orange) REM 9 RI < REM REM Also switched all DIP switches on touchscreen OFF, REM to give hardware handshaking at 9600 bps (and other sensible defaults, REM which incidentally match the manufacturer's default and the Archimedes defaults, REM so we don't need to use PROCsconf() either.) PROCgeneric_touchscreen_init(max_touchscreens%) _tch_screentype%(touchscreen_channel%) = yogi_type% touch_min_x% = 1 touch_max_x% = 75 touch_min_y% = 1 touch_max_y% = 59 lcd_min_x% = 10 lcd_max_x% = 740 lcd_min_y% = 25 lcd_max_y% = 565 REM LCD x-size in my units: 666 = 15.5 cm REM LCD y-size in my units: 500 = 14.0 cm screen_min_y% = 0 screen_max_y% = 1023 screen_min_x% = 0 screen_max_x% = 1279 REM Internal coordinates, which get converted to others my_min_x% = 0 my_max_x% = 1000 my_min_y% = 0 my_max_y% = 800 screen_system% = 1 lcd_system% = 2 touch_system% = 3 my_system% = 4 ENDPROC DEF FNx_coord(in%, desired_system%) CASE desired_system% OF WHEN screen_system%: = ((in%-my_min_x%)/(my_max_x%-my_min_x%))*(screen_max_x%-screen_min_x%) + screen_min_x% WHEN lcd_system%: = ((in%-my_min_x%)/(my_max_x%-my_min_x%))*(lcd_max_x%-lcd_min_x%) + lcd_min_x% WHEN touch_system%: = ((in%-my_min_x%)/(my_max_x%-my_min_x%))*(touch_max_x%-touch_min_x%) + touch_min_x% WHEN my_system% REM This is fairly dappy, as it should do nothing. = ((in%-my_min_x%)/(my_max_x%-my_min_x%))*(my_max_x%-my_min_x%) + my_min_x% OTHERWISE: VDU7:PRINT"Bloody stupid call to FNx_coord()." ENDCASE =0 DEF FNy_coord(in%, desired_system%) CASE desired_system% OF WHEN screen_system%: = ((in%-my_min_y%)/(my_max_y%-my_min_y%))*(screen_max_y%-screen_min_y%) + screen_min_y% WHEN lcd_system%: = ((in%-my_min_y%)/(my_max_y%-my_min_y%))*(lcd_max_y%-lcd_min_y%) + lcd_min_y% WHEN touch_system%: = ((in%-my_min_y%)/(my_max_y%-my_min_y%))*(touch_max_y%-touch_min_y%) + touch_min_y% WHEN my_system% REM This is fairly dappy, as it should do nothing. = ((in%-my_min_y%)/(my_max_y%-my_min_y%))*(my_max_y%-my_min_y%) + my_min_y% OTHERWISE: VDU7:PRINT"Bloody stupid call to FNy_coord()." ENDCASE =0 DEF PROCyogi_multiscreen_init nscreens% = 1 DIM vdu_bank%(nscreens%-1) LOCAL bank% PROCscreen_init FOR bank%=0 TO nscreens%-1 PROCclaim_vdu_bank(vdu_bank%(bank%)) REM *** A bit bizarre; vdu_bank%() uninitialized. NEXT ENDPROC REM --------- REM Shortcut functions when you only have one screen! DEF PROClcd(lcd%) PROCswitch_vdu(vdu_bank%(lcd%)) ENDPROC DEF PROCupdate_lcd(lcd%) PROCcopy_vdu_bank_to_screen(vdu_bank%(lcd%), lcd%) ENDPROC DEF PROCscreen PROCswitch_vdu_to_screen ENDPROC REM ======================================================================== DEF PROCtwo_rectangle_mask(channel%) REM ======================================================================== PROCdefine_origin_bottom_left(channel%) PROCpoint_mode(channel%) PROCenable_superlabels(channel%) PROCdisable_coords_in_superlabels(channel%) PROCdisable_stylus_status(channel%) :REM *** Experiment with turning this on REM Now two regions, "L" and "R" REM parameters are channel, left, right, bottom, top, name PROCdefine_superlabel(channel%, 10, 35, 26, 52, "LLLLLLLLL") PROCdefine_superlabel(channel%, 40, 70, 26, 52, "RRRRRRRRR") ENDPROC DEF PROCfive_hole_boxes nboxes% = 6 nlines% = 16 nholes% = 5 first_aperturelight_line% = 0 : REM second-fifth are consecutive panelpush_line% = 5 traylight_line% = 6 tone_line% = 7 first_nosepoke_line% = 8 : REM second-fifth are consecutive houselight_line% = 13 pellet_line% = 14 DIM houselight%(nboxes%) DIM traylight%(nboxes%) DIM aperturelight%(nboxes%,nholes%) DIM pellet_dispenser%(nboxes%) DIM tone%(nboxes%) DIM nosepoke%(nboxes%,nholes%) DIM panelpush%(nboxes%) FOR box% = 1 TO nboxes% houselight%(box%) = FNswitch_number_2(box%, houselight_line%,nlines%) traylight%(box%) = FNswitch_number_2(box%, traylight_line%, nlines%) FOR hole% = 1 TO nholes% aperturelight%(box%, hole%) = FNswitch_number_2(box%, first_aperturelight_line% + hole% - 1, nlines%) nosepoke%(box%, hole%) = FNswitch_number_2(box%, first_nosepoke_line% + hole% - 1, nlines%) NEXT pellet_dispenser%(box%) = FNswitch_number_2(box%, pellet_line%,nlines%) tone%(box%) = FNswitch_number_2(box%, tone_line%,nlines%) panelpush%(box%) = FNswitch_number_2(box%, panelpush_line%,nlines%) REM -------Take control of output/input lines------- PROCgovn_switch(houselight%(box%),E%) PROCgovn_switch(traylight%(box%),E%) FOR hole% = 1 TO nholes% PROCgovn_switch(aperturelight%(box%, hole%),E%) PROCfree_switch(nosepoke%(box%, hole%),E%) NEXT PROCgovn_switch(pellet_dispenser%(box%),E%) PROCgovn_switch(tone%(box%),E%) PROCfree_switch(panelpush%(box%),E%) NEXT ENDPROC DEF PROCfive_hole_boxes_liar nboxes% = 6 nlines% = 15 nholes% = 5 first_aperturelight_line% = 0 : REM second-fifth are consecutive panelpush_line% = 5 traylight_line% = 6 tone_line% = 7 first_nosepoke_line% = 8 : REM second-fifth are consecutive houselight_line% = 13 pellet_line% = 14 DIM houselight%(nboxes%) DIM traylight%(nboxes%) DIM aperturelight%(nboxes%,nholes%) DIM pellet_dispenser%(nboxes%) DIM tone%(nboxes%) DIM nosepoke%(nboxes%,nholes%) DIM panelpush%(nboxes%) FOR box% = 1 TO nboxes% houselight%(box%) = FNswitch_number_2(box%, houselight_line%,nboxes%) traylight%(box%) = FNswitch_number_2(box%, traylight_line%, nboxes%) FOR hole% = 1 TO nholes% aperturelight%(box%, hole%) = FNswitch_number_2(box%, first_aperturelight_line% + hole% - 1, nboxes%) nosepoke%(box%, hole%) = FNswitch_number_2(box%, first_nosepoke_line% + hole% - 1, nboxes%) NEXT pellet_dispenser%(box%) = FNswitch_number_2(box%, pellet_line%,nboxes%) tone%(box%) = FNswitch_number_2(box%, tone_line%,nboxes%) panelpush%(box%) = FNswitch_number_2(box%, panelpush_line%,nboxes%) REM -------Take control of output/input lines------- PROCgovn_switch(houselight%(box%),E%) PROCgovn_switch(traylight%(box%),E%) FOR hole% = 1 TO nholes% PROCgovn_switch(aperturelight%(box%, hole%),E%) PROCfree_switch(nosepoke%(box%, hole%),E%) NEXT PROCgovn_switch(pellet_dispenser%(box%),E%) PROCgovn_switch(tone%(box%),E%) PROCfree_switch(panelpush%(box%),E%) NEXT ENDPROC REM ======================================================================== DEF PROCignore_serial_error_wait REM ======================================================================== REPEAT E%=0 PROCwait(E%) VDU 7 PRINT FNreport(E%);:PRINT;" (within Arachnid; don't know line number!)" REM That describes the error IF E%<&802D00 AND E%>&802DFF THEN END REM Not in Arachnid error number range, so die with an error report CASE (E% AND 255) OF WHEN 63: REM serial parity WHEN 64: REM serial framing WHEN 65: REM serial overrun OTHERWISE: END ENDCASE UNTIL FALSE ENDPROC