Mouse/key input loop for making Basic games

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
sn3j
Manic Miner
Posts: 500
Joined: Mon Oct 31, 2022 12:29 am
Location: Germany

Mouse/key input loop for making Basic games

Post by sn3j »

Recently I've started making a mouse aware Basic game in the sense of Millenium 2.2 and wanted to share the input loop here.
The 'engine' responds to a Kempston mouse and key presses like shown in the animated gif below.
Anyone interested in building a fast, responsive mouse driven gameplay in Basic may find this helpful.

I am developing under BasinC IDE but also tested with FUSE (enable Kempston mouse in Periphals - General).
ZX Spin does not work because the mouse movement isn't captured. Likewise ZEsarUX and InkSpector had issues.
It should work on a real Speccy but that's not tested.
Spoiler
Image
Listing with comments:

Code: Select all

   1 BORDER 7:
     PAPER 7:
     INK 0:
     GO TO 1000
  20 GO TO USR u:
     REM USR u mostly returns 255, see Mouse
  30 PRINT AT 0,16;"up   ";:
     GO TO 20
  40 PRINT AT 0,16;"down ";:
     GO TO 20
  50 PRINT AT 0,16;"left ";:
     GO TO 20
  60 PRINT AT 0,16;"right";:
     GO TO 20
  70 PRINT AT 0,16;"save ";:
     GO TO 20
  80 PRINT AT 0,16;"load ";:
     GO TO 20
 223 PRINT AT 0,0;"--";:
     GO TO 20
 251 PRINT AT 0,0;"??";:
     GO TO 20
 252 PRINT AT 0,0;"++";:
     LET b=3:
     GO TO 20
 253 PRINT AT 0,0;"+.";:
     LET b=1:
     GO TO 20
 254 PRINT AT 0,0;".+";:
     LET b=2:
     GO TO 20
 255 IF NOT b THEN GO TO PEEK (64856+ CODE INKEY$)
 260 PRINT AT 0,0;"..";:
     LET x=PEEK (u-10):
     LET y=PEEK (u-11):
     PRINT AT 0,6;"clk ";y;" ";x,:
     LET a=PEEK (u-12):
     IF a=1 THEN GO SUB 300+10*y
 270 LET b=0:
     GO TO 20
 310 PRINT AT 0,16;"Ores ";:
     GO TO 2000
 330 PRINT AT 0,16;"Ships";:
     RETURN
 430 LET a=USR u(3):
     GO SUB 2050+50*(x<16):
     LET a=USR u(2):
     RETURN
 510 PRINT AT 0,16;"h++  ";:
     RETURN
 520 PRINT AT 0,16;"d++  ";:
     LET p(3)=p(3)+4:
     RETURN
 899 STOP :
     REM ^^ keys & button input handling
 900 FOR i=a TO a+127:
     POKE i,20:
     NEXT i
 910 POKE a+ CODE "\#011",30:
     POKE a+ CODE "\#010",40:
     POKE a+ CODE "\#008",50:
     POKE a+ CODE "\#009",60:
     POKE a+ CODE "q",30:
     POKE a+ CODE "a",40:
     POKE a+ CODE "o",50:
     POKE a+ CODE "p",60:
     POKE a+ CODE "s",70:
     POKE a+ CODE "l",80:
     RETURN :
     REM ^^ set up keypress map
 950 FOR i=a TO a-1+b*8:
     READ a:
     POKE i,a:
     NEXT i:
     RETURN :
     REM ^^ poke UDGs
1000 RESTORE 9000:
     READ a:
     CLEAR a*256-1:
     BORDER 5:
     GO SUB 8000
1010 CLS :
     PRINT AT 0,0;"____\#008\#008\#008\#008";:
     PRINT "\..";:
     LET a=64856:
     IF PEEK a<>20 THEN GO SUB 900
1020 PRINT "\..";:
     LET a=USR "a":
     IF NOT PEEK a THEN RESTORE 9799:
     READ b:
     GO SUB 950
1030 PRINT "\..";:
     RESTORE 7500:
     READ b:
     DIM m$(b,12):
     DIM m(b):
     DIM r(b):
     DIM p(4):
     LET p(1)=24
1040 FOR i=1 TO b:
     READ m$(i),m(i),r(i):
     NEXT i:
     LET mb=8:
     LET mt=191-mb:
     LET ml=8:
     LET mr=255-ml:
     LET mx=INT ((ml+mr)*.5):
     LET my=INT ((mt+mb)*.5)
1050 GO SUB 7400:
     PRINT "\..";:
     POKE u-1,-1:
     POKE u-2,mx:
     POKE u-3,my:
     POKE u-4,ml:
     POKE u-5,mr:
     POKE u-6,mb:
     POKE u-7,mt
1060 GO SUB 1100:
     LET b=USR U(2):
     LET b=0:
     PRINT AT 0,0;"..";:
     GO TO 20:
     REM ^^ init game & enter main loop
1100 BORDER 7:
     PAPER 7:
     INK 0:
     CLS :
     OUT 254,5:
     PRINT #1; INK 1;AT 1,0;"\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''\''";
1110 PRINT PAPER 5; INK 1;AT 1,0;"Ore Refinery";AT 3,0;"Landing Bays";:
     PRINT PAPER 3; INK 1;AT 21,20;"Advance hour";#1; PAPER 4; INK 1;AT 0,20;"Advance day ";:
     RETURN :
     REM ^^ draw game screen
2000 PRINT BRIGHT 1;AT 8,6;"Materials in stock:
     ";
2010 FOR i=1 TO 4:
     PRINT BRIGHT 1; INK 0;AT 8+i,6;" ";m$(i);" ";m(i);TAB 26;:
     NEXT i:
     PRINT BRIGHT 1; INK 1;AT 13,6;"[more]"; INK 0;"        "; INK 1;"[done]";
2020 RETURN
2050 PRINT AT 8,6;TAB 26;AT 9,6;TAB 26;AT 10,6;TAB 26;AT 11,6;TAB 26;AT 12,6;TAB 26;AT 13,6;TAB 26;:
     RETURN
2100 IF  SCREEN$ (13,7)<>"m" THEN GO TO 2150
2110 PRINT BRIGHT 1;AT 8,6;"Refinery ore yield:
     ";
2120 FOR i=1 TO 4:
     PRINT BRIGHT 1; INK 0;AT 8+i,6;" ";m$(i);" ";r(i);TAB 26;:
     NEXT i:
     PRINT BRIGHT 1; INK 1;AT 13,6;"[stats]"; INK 0;"       "; INK 1;"[done]";
2130 RETURN
2150 IF  SCREEN$ (13,7)<>"s" THEN GO TO 2200
2160 PRINT BRIGHT 1;AT 8,6;"Refinery settings:
      ";AT 9,6;" Staff required  80 ";AT 10,6;" Staff available ";p(3);TAB 26;AT 11,6;" Power consumpt  45";
2170 PRINT BRIGHT 1;AT 12,6;" Operations:
     ";y$(1+p(4));" "; INK 1;AT 13,6;"[";"dis" AND p(4);"engage]"; INK 0;TAB 20; INK 1;"[done]";
2180 RETURN
2200 IF  SCREEN$ (13,7)<>"e" THEN GO TO 2250
2210 IF p(3)<80 THEN LET s$=" not enough staff ":
     GO TO 2950
2220 IF p(2)<45 THEN LET s$="insufficient power":
     GO TO 2950
2250 LET p(4)=1-p(4):
     GO TO 2160
2950 PRINT AT 15,6; FLASH 1; INK 2;" ";s$;" ";:
     PAUSE 1:
     PAUSE 150:
     PRINT AT 15,6;TAB 26;:
     RETURN
7400 DIM y$(4,3):
     RESTORE 7400:
     READ y$(1),y$(2),y$(3),y$(4):
     RETURN :
     DATA "off","on","no","yes"
7500 DATA 4,"Cloppium",18,1.2,"Ferrium",0,4.4,"Oozenium",7,2.8,"Zapponium",0,0.6:
     REM ^^ game data
8000 RESTORE 9000:
     READ a,u:
     LET i=256*u+2:
     IF PEEK (i+3)<>u THEN GO SUB 8200:
     GO TO 1000:
     REM ^^ load/poke usrs
8010 LET b=PEEK i:
     DIM U(b):
     FOR j=1 TO b:
     LET i=i+6:
     LET U(j)=256*PEEK i+PEEK (i-1):
     NEXT j
8020 LET u=U(1):
     RETURN :
     REM ^^ init usrs
8200 RESTORE 9000:
     READ a,u,j,n,k:
     DIM P(n,3):
     DIM S(n,9):
     DIM U(k):
     POKE 256*u+2,k:
     LET j=256*u+6+6*k:
     LET m=1:
     LET k=0
8210 READ a:
     LET b=j+a:
     REM exchnd par area offset
8220 READ a:
     IF a<>256 THEN POKE j,a:
     LET j=j+1:
     GO TO 8220:
     REM init exc data area
8230 LET j=b:
     LET a=INT (j/256):
     POKE 256*u+3,195:
     POKE 256*u+4,j-256*a:
     POKE 256*u+5,a:
     REM poke exc jump
8240 READ a:
     IF a<>256 THEN POKE j,a:
     LET j=j+1:
     GO TO 8240:
     REM poke exc handler
8250 READ s$,c,a:
     PRINT "M";m;" ";s$,"#sr:";c;" #db:";a:
     POKE j,a:
     LET b=j+1:
     LET j=b+2*a:
     REM module #sr #db
8260 FOR i=1 TO a:
     READ a:
     LET P(m,i)=j:
     POKE b+1,INT (j/256):
     POKE b,j-256*PEEK (b+1):
     LET b=b+2:
     LET j=j+a:
     NEXT i:
     REM allocate data blocks
8270 FOR i=1 TO c:
     READ s$,a,b:
     PRINT " ";s$,j:
     LET b=j+b:
     LET S(m,i)=b
8280 IF a THEN LET k=k+1:
     LET U(k)=b:
     LET a=INT (b/256):
     LET b=256*u+6*k:
     PRINT "export M";m;"#";i,"\@";U(k):
     POKE b,1:
     POKE b+1,U(k)-256*a:
     POKE b+2,a:
     POKE b+3,96:
     POKE b+4,105:
     POKE b+5,233:
     REM module function spec/export
8290 READ a:
     IF a<>256 THEN POKE j,a:
     LET j=j+1:
     GO TO 8290:
     REM init par area
8300 LET j=S(m,i):
     REM skip to &sr and poke to table
8310 READ a:
     IF a<256 THEN POKE j,a:
     LET j=j+1:
     GO TO 8310:
     REM poke sr bytes
8320 IF a>256 THEN POKE j+1,INT (a/256):
     POKE j,a-256*PEEK (j+1):
     LET j=j+2:
     GO TO 8310:
     REM poke 16bit values
8330 NEXT i:
     RESTORE 9000:
     READ a,a,a:
     IF j>a THEN PRINT "asm overflow":
     BORDER 2:
     STOP
8340 LET m=m+1:
     IF m<=n THEN GO TO 8250:
     REM next module
8350 LET a=INT (j/256):
     LET b=j-256*a:
     LET i=256*u:
     POKE i,b:
     POKE i+1,a-u:
     PRINT "ok ";j-i;" bytes":
     RETURN :
     REM ^^ poke code block
8400 RESTORE 9000:
     READ a,a:
     FOR i=a*256 TO 65535:
     PRINT i,PEEK i:
     NEXT i:
     STOP :
     REM ^^ list code block
9000 DATA 250,250,64856,1,3:
     REM ^^ ramt,asmorg,asmt,#modules,#usrs
9010 DATA 4,0,0,0,0,256:
     REM -- ExcHandler -4..-3:xdta -2..-1:&badsr
9011 DATA 193,42,4,u,43,112,43,113:
     REM popbc,ldhl(ORG+4),ld(--hl)b,ld(--hl)c
9012 DATA 3,10,43,119,11,10,43,119:
     REM lda(++bc),ld(--hl)a,lda(--bc),ld(--hl)a
9013 DATA 33,71,92,52,207,25:
     REM ldhl SUBPPC,inc(hl),rsterr#26
9014 DATA 256:
     REM ^^ ExcHandler
9050 DATA "Svcs",8,0:
     REM == Svcs module #sr,#db
9080 DATA "ScnAdr",0,0:
     DATA 256
9081 DATA 122,230,248,31,254,96,212,3,u:
     DATA 31,31,111,170,230,248,170,103
9082 DATA 123,173,230,248,173,15,15,15,111:
     DATA 201,256
9085 DATA "Plot",0,8,128,64,32,16,8,4,2,1:
     DATA 256:
     REM --   bit masks
9086 DATA 123,230,7,33,S(m,i)-8,133,111:
     DATA 48,1,36,70,205,S(m,i-1),126
9087 DATA 168,119,201:
     DATA 256
9090 DATA "MCurs",0,0:
     DATA 256
9091 DATA 213,28,205,S(m,i-1),28,205,S(m,i-1):
     DATA 29,20,205,S(m,i-1),29,205,S(m,i-1)
9092 DATA 20,205,S(m,i-1),28,28,205,S(m,i-1):
     DATA 28,20,205,S(m,i-1),209,195,S(m,i-1):
     DATA 256
9100 DATA "Mouse",1,13,0,0,0,0,0,0,174,1:
     DATA 254,1,87,127,1,256:
     REM --  -1:vis 2/3:mxy 4/7:lrbt 8/9:xy 10/11:atxy
9101 DATA 197,221,225,11,10,1,223,0,167,248:
     DATA 5,256
9102 DATA "Mouse2",0,0:
     DATA 256
9103 DATA 8,237,88,221,102,-3,221,126,-9:
     DATA 221,115,-9,147,242,j+14,221,94,-6
9104 DATA 132,48,3,187,48,13,123,24,10:
     DATA 221,94,-7,132,56,3,187,56,1,123
9105 DATA 221,119,-3,87,6,251,237,120:
     DATA 221,110,-2,221,94,-8,221,119,-8
9106 DATA 147,242,j+14,221,94,-4,133:
     DATA 48,3,187,48,13,123,24,10
9107 DATA 221,94,-5,133,56,3,187,56,1,123:
     DATA 221,119,-2,95,8,56,14,237,82
9108 DATA 40,51,25,167,32,47,213,235:
     DATA 205,S(m,i-2),209:
     DATA 256
9110 DATA "MDraw",0,0:
     DATA 256
9111 DATA 205,S(m,i-3),122,15,15,15,230,31:
     DATA 221,119,-11,15,15,15,230,3,246,88
9112 DATA 103,125,230,31,221,119,-10,126:
     DATA 15,15,15,230,7,221,119,-13,126
9113 DATA 230,7,221,119,-12:
     DATA 6,250,237,120,246,224,79,6,0,201:
     DATA 256
9120 DATA "MShow",1,0:
     DATA 256
9121 DATA 221,33,S(m,i-3),221,126,-1,135:
     DATA 200,221,54,-1,0,1,223,255,63
9122 DATA 218,S(m,i-2),237,120,221,119,-9:
     DATA 6,251,237,120,221,119,-8,24,-21:
     DATA 256
9130 DATA "MHide",1,0:
     DATA 256
9131 DATA 33,S(m,i-4)-1,126,167,192,52:
     DATA 43,94,43,86,195,S(m,i-5):
     DATA 256
9799 DATA 2:
     REM UDGs
9800 DATA 24,60,126,24,24,126,60,24
9801 DATA 0,36,102,255,255,102,36,0
9802 DATA 0,60,66,64,64,66,60,0
9803 DATA 0,120,68,66,66,68,120,0
9804 DATA 0,126,64,124,64,64,126,0
9805 DATA 0,126,64,124,64,64,64,0
9806 DATA 0,60,66,64,78,66,60,0
9807 DATA 0,66,66,126,66,66,66,0
9808 DATA 0,62,8,8,8,8,62,0
9809 DATA 0,2,2,2,66,66,60,0
9810 DATA 0,68,72,112,72,68,66,0
9811 DATA 0,64,64,64,64,64,126,0
9812 DATA 0,66,102,90,66,66,66,0
9813 DATA 0,66,98,82,74,70,66,0
9814 DATA 0,60,66,66,66,66,60,0
9815 DATA 0,124,66,66,124,64,64,0
9816 DATA 0,60,66,66,82,74,60,0
9817 DATA 0,124,66,66,124,68,66,0
9818 DATA 0,60,64,60,2,66,60,0
9819 DATA 0,254,16,16,16,16,16,0
9820 DATA 0,66,66,66,66,66,60,0
Variables used:

Code: Select all

Var a:          // any
Var u:          // fast const for U(1)
Var b:          // mouse button pressed 1=left 2=right 3=both
Var mb/mt/ml/mr/my/mx:             // mouse area and position
Var u:          // USRs: (1) Mouse (2) MShow (3) MHide
     NumArray(3) = 64154, 64318, 64352
Var m:          // ore in stock
     NumArray(4) = 18, 0, 7, 0
Var r:          // ore yield
     NumArray(4) = 1.2, 4.4, 2.8, 0.6
Var p:          // (1) people (2) power (3) staff (4) refinery off/on
     NumArray(4) = 24, 0, 0, 0
Var i:          // loop var
     NumFOR = 5, 4, 1, 1040, 2
Var j:          // loop var
     NumFOR = 4, 3, 1, 8010, 4
Var m$:         // ores used
     StrArray(4, 12) = "Cloppium    Ferrium     Oozenium    Zapponium   "
Var y$:         // maps 0 or 1 to a descriptive string
     StrArray(4, 3) = "offon no yes"
Var x/y:        // last click pos
Assembler:

Code: Select all

ScnAdr:                ; build screen& for de=(y,x) in hl
    ld a d             ; (0,0) means topleft screen corner
    and $f8
    rra
    cp 96
    call nc Ex         ; y >= 192, error
    rra
    rra
    ld l a
    xor d
    and $f8
    xor d
    ld h a             ; h = 0,1,0,d7,d6,d2,d1,d0
    ld a e
    xor l
    and $f8
    xor l
    rrca x3
    ld l a             ; l = d5,d4,d3,e7,e6,e5,e4,e3
    ret

Bitmasks:
.db 128,64,32,16,8,4,2,1

Plot:                  ; plot over 1 at de=(y,x)
                       ; changes b,hl
    ld a e
    and 7
    ld hl BitMasks
    add l
    ld l a
    jr nc 1
     inc h
    ld b (hl)          ; get bit mask according to x pos
    call ScnAdr
    ld a (hl)
    xor b              ; xor bit into the byte at (y,x)
    ld (hl) a
    ret

MCurs:                 ; draw mouse cursor at de=(y,x)
    push de            ; leaves de unchanged
    inc e
    call Plot
    inc e
    call Plot
    dec e
    inc d
    call Plot
    dec e
    call Plot
    inc d
    call Plot
    inc e
    inc e
    call Plot
    inc e
    inc d
    call Plot
    pop de
    jp Plot            ; hotspot goes last (hl is used by caller)

MousePars:
.db pap,ink            ;  paper,ink at mouse pos
.db aty,atx            ;  my,mx as ATTR coords
.db y,x                ;  raw Kempston mouse pos
.db mt,mb,mr,ml        ;  mouse cursor bounds
.db my,mx              ;  mouse pos in pixels
.db vis                ;  0=visible 1=hidden 255=disabled
                       ;
Mouse:                 ; Maintains mouse pos and gets button state.
                       ; Returns:
                       ;  255 - no button is pressed
                       ;  254 - right mouse button pressed
                       ;  253 - left mouse button pressed
                       ;  252 - mouse button 1+2 pressed
                       ;  223 - mouse is disabled
                       ;  224..251 unknown/floating button state
    push bc
    pop ix             ; get ptr to mouse params in ix
    dec bc
    ld a (bc)
    ld bc 223
    and a              ; visibility?
    ret m              ; mouse is disabled
    dec b              ; bc = 65503
Mouse2:
    exaf               ; save visibility flags in af'
    in e (c)           ; Kempston y
    ld h (ix-3)        ; h = my_last
    ld a (ix-9)        ; y_last
    ld (ix-9) e
    sub e              ; get the Kempston y delta (dy)
    jp p L1
    ld e (ix-6)        ; mb
    add h              ; my = dy + my_last
    jr nc 3
     cp e
     jr nc L2
    ld a e             ; restrict my to mb
    jr L2
L1:
    ld e (ix-7)        ; mt
    add h              ; my = dy + my_last
    jr c 3
     cp e
     jr c L2
    ld a e             ; restrict my to mt
L2:
    ld (ix-3) a        ; save my
    ld d a
    ld b 251           ; bc = 64479
    in a (c)           ; Kempston x
    ld l (ix-2)        ; l = mx_last
    ld e (ix-8)        ; x_last
    ld (ix-8) a
    sub e              ; get the Kempston x delta (dx)
    jp p L3
    ld e (ix-4)        ; ml
    add l              ; mx = dx + mx_last
    jr nc 3
     cp e
     jr nc L4
    ld a e             ; restrict mx to ml
    jr L4
L3:
    ld e (ix-5)        ; mr
    add l              ; mx = dx + mx_last
    jr c 3
     cp e
     jr c L4
    ld a e             ; restrict mx to mr
L4:
    ld (ix-2) a        ; save mx
    ld e a             ; de=(my,mx) hl=(my_last,mx_last)
    exaf               ; get visibility flags
    jr c MDraw         ; C=first draw (from show mouse)
    sbc hl de          ; compare old/new mouse pos
    jr z L5            ; same pos, just check buttons
    add hl de
    and a              ; check visibility
    jr nz L5           ; hidden, just check buttons
    push de
    ex de hl
    call MCurL         ; draw cursor at de=(my_last,mx_last)
    pop de             ; de=(my,mx)
MDraw:
    call MCurL         ; draw cursor at de=(my/mx)
    ld a d
    rrca x3
    and 31
    ld (ix-11) a       ; save aty
    rrca x3
    and 3
    or 88
    ld h a             ; h = 0,1,0,1,1,0,d7,d6
    ld a l             ; l = d5,d4,d3,e7,e6,e5,e4,e3
    and 31
    ld (ix-10) a       ; save atx
    ld a (hl)
    rrca x3
    and 7
    ld (ix-13) a       ; save paper
    ld a (hl)
    and 7
    ld (ix-12) a       ; save ink
L5:
    ld b 250           ; bc = 64223
    in a (c)           ; get mouse button state
    or 224             ; assure >=224
    ld c a
    ld b 0
    ret                ; return 224..255

MShow:                 ; Show mouse cursor at current position
                       ; Returns: undefined
    ld ix Mouse
    ld a (ix-1)
    add a
    ret z              ; already visible
    ld (ix-1) 0
L1:
    ld bc 65503
    ccf
    jp c Mouse2        ; was hidden, redo my/mx and draw cursor
    in a (c)           ; Kempston y
    ld (ix-9) a
    ld b 251           ; bc = 64479
    in a (c)           ; Kempston x
    ld (ix-8) a
    jr L1              ; draw cursor

MHide:                 ; Hide cursor
                       ; Returns: undefined
    ld hl Mouse-1
    ld a (hl)          ; get visibility flag
    and a
    ret nz             ; already hidden or disabled
    inc (hl)           ; set visibility to 'hidden'
    dec hl
    ld e (hl)
    dec hl
    ld d (hl)
    jp MCurL           ; remove cursor at de=(my,mx)
This TAP contains the whole program. The machine code is weld into DATA statements, but could also be splitted off into a separate Basic program that just produces a code file to be read in by the main part. If anyone's interested I'll post such a version.
kmouse.tap
POKE 23614,10: STOP      1..0 hold, SS/m/n colors, b/spc toggle
Wall_Axe
Manic Miner
Posts: 500
Joined: Mon Nov 13, 2017 11:13 pm

Re: Mouse/key input loop for making Basic games

Post by Wall_Axe »

Looks like a cool game. How much ram does it take up?
I tried making something in Sinclair basic but couldn't deal with variables that were single letters only.

I tried six languages altogether and switched to machine code only in the end. As all the languages had fatal flaws.
sn3j
Manic Miner
Posts: 500
Joined: Mon Oct 31, 2022 12:29 am
Location: Germany

Re: Mouse/key input loop for making Basic games

Post by sn3j »

Wall_Axe wrote: Thu Nov 30, 2023 3:27 pm Looks like a cool game. How much ram does it take up?
I tried making something in Sinclair basic but couldn't deal with variables that were single letters only.

I tried six languages altogether and switched to machine code only in the end. As all the languages had fatal flaws.
The version above is just one dialog for demonstration, still plenty of space to add things.

Single letter variables are required to look them up as quickly as possible. If the program is interpreted (instead of compiled) you don't have much choice. You can occasionally use a multi-letter variable of course. Just make sure the variable lookup won't slow down execution too much. That is, the most used variables need to be created first.

I like Basic because it is easier to dabble with. When things work out I normally add small assembler routines to improve some performance.
POKE 23614,10: STOP      1..0 hold, SS/m/n colors, b/spc toggle
sn3j
Manic Miner
Posts: 500
Joined: Mon Oct 31, 2022 12:29 am
Location: Germany

Re: Mouse/key input loop for making Basic games

Post by sn3j »

Here's an update of the event handler.
I've added mouse region detection and some demo backgound to the program.

The commented listing with associated TAP files is available here:
https://colab.research.google.com/drive ... sp=sharing

It's shared on Google Colaboratory, you don't need a login to open it.
Feel free to leave a comment here or on the Colab notebook.

Image

The demo is directed towards Basic programmers who want to develop games with mouse support.
POKE 23614,10: STOP      1..0 hold, SS/m/n colors, b/spc toggle
Post Reply