English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. Blitz Basic

 
 
Thread Tools
Old 03 August 2013, 11:30   #1
htdreams
Registered User
htdreams's Avatar
 
Join Date: Dec 2012
Location: Ferrol / A Coruna / Spain
Posts: 14
Blitz2 keyboard issues

Hi!

I put aside my project with tile maps and 8way scrolling to make a little game for a retro party event wich is scheduled for 23 August.

This little game features 4 players, 2 of them using joysticks and the other 2 the keyboard, and it's made in Blitz2 for running in Amiga 500.

I've switched form 32colors mode to 16colors for speed issues, i'm currently using only Blitz2 graphics methods (bblit).

But the main issue i'm facing, and the one for i'm seeking for advice, is regarding rawstatus blitz2 function, as i have key locks for using more than one key from some rows:

If i use cursor keys, i can push up&left or another combination, and it works

If i use wasd keys, if i push w & a (or d) both works, but if i push a&s or s&d i don't get any response as if the keys aren't pressed

And trying other keys make cursor keys not working, so this will ruin my idea of multiplayer gaming with keyboard.

I'm programming this in a real A1200, and did test it in A600 winuae emulated (not problems with keyboard, all keys works nice) and real A500 (where i can use wasd but if both players use cursors & wasd i get key locks also)

Is there any other way to read keyboard input and not having this issue?

I'm searching through the blitz mailing list archives, and read something about keyboard interrupts (i didn't investigate it yet)

Here is my full code for the moment (i plan on comment on all i can and make it public so anyone could get into blitz2 game programming, at least as far as i can get :-) )

Code:
; Retroferrol 2013
; Game by HtDreams (prog) & Jojo73 (gfx)
; htdreams: adepedro *at* proyecto-iris.com
; Proyecto-iris

; --------------
.INITIALIZATION
; --------------

WBStartup

.CONSTANTS

.TYPES
NEWTYPE.character
  x.w
  y.w
  start_shape.b    ; start shape for all animations for this character
  dir.b            ; direction 1 right, 2 left
  anm.b            ; current action animation
  frame.b          ; animation frame counter
  framedelay.b     ; delay used to slow animation
  state.w          ; what is doing this character
  destx.w          ; dest coordinates
  desty.w
  speed.b          ; number of pixels character moves in each step
  player.b         ; character controlled by player if > 0
  hasbox.b         ; flag to tell if the player carries a box-0/1
                   ; and if the box is opened-2/3 or launched-4
  boxactionwait.b  ; counter to make the player wait a bit before dropping a box
  boxx.w           ; box carried by the player, x and y pos when the player
  boxy.w           ; launch it
  boxdir.b         ; when the player launch the box will tell direction
End NEWTYPE

.DECLARATIONS

Dim playercontrols(2,7) ; controls configuration
playercontrols(1,1) = $4c ; cursor keys
playercontrols(1,2) = $4d
playercontrols(1,3) = $4f
playercontrols(1,4) = $4e
playercontrols(1,5) = $61 ; right shift key (button 1)
playercontrols(1,6) = $65 ; right alt key (button 2)
playercontrols(1,7) = -1   ; use keyboard

playercontrols(2,1) = $3e;$11 ; wasd
playercontrols(2,2) = $2d;$21
playercontrols(2,3) = $2e;$20
playercontrols(2,4) = $2f;$22
playercontrols(2,5) = $0f;$60 ; left shift key (button 1)
playercontrols(2,6) = $3c;$64 ; left alt key (button 2)
playercontrols(2,7) = -1   ; use joystick 2 (ignore keycodes in 1-5 values)


Dim ybuffer(4) ; for calculating drawing order, we have just 4 objects for now
ybuffer(1) = 1
ybuffer(2) = 2
ybuffer(3) = 3
ybuffer(4) = 4

Dim frames_anm.b(2,2,4) ; direction, action, frame
; stopped, facing right
frames_anm(1,1,1) = 0
frames_anm(1,1,2) = 1
frames_anm(1,1,3) = 2
frames_anm(1,1,4) = 1
; runing, facing right
frames_anm(1,2,1) = 6
frames_anm(1,2,2) = 7
frames_anm(1,2,3) = 8
frames_anm(1,2,4) = 7
; stopped, facing left
frames_anm(2,1,1) = 3
frames_anm(2,1,2) = 4
frames_anm(2,1,3) = 5
frames_anm(2,1,4) = 4
; runing, facing left
frames_anm(2,2,1) = 9
frames_anm(2,2,2) = 10
frames_anm(2,2,3) = 11
frames_anm(2,2,4) = 10

Dim frames_rate.b(2) ; value used to update frames with a delay
frames_rate(1) = 3 ; idle animation
frames_rate(2) = 0 ; walking animation

BitMap 0,384,360,4 ; main game window
BitMap 1,384,360,4 ; double buffer with 0
BitMap 2,320,256,4 ; bitmap for loading graphics
BitMap 3,320,256,4 ; game background

progressbarValue = 0
totalsprites.w = 0
db.b = 0 ; flag for doublebuffer screen select
inputdelay.w = 0
waittime.w = 10
titleshapenumber = 8
titleshapecounter = 0
menuselect = 0
menuarrowframe = 0

LoadBitMap 0,"16cintro.iff",0
LoadBitMap 2,"16cmenu.iff",1
LoadBitMap 3,"16cfondo.iff",2

BLITZ
BlitzKeys On

.STATEMENTS
; update current slice with a line in the bottom
Statement progressbar{value}
  Use BitMap 0
  Boxf 0,240,(value*320)/100,242,15
  Show 0
End Statement


Slice 0,44,320,256,$fff8,4,8,16,384,384

; show intro image
Use Palette 0
Use BitMap 0
Show 0

; get menu and title shapes
Use BitMap 2
GetaShape 0,0,0,280,49     ; title retroferrol
GetaShape 1,0,49,21,20     ; title 2
GetaShape 2,23,49,22,20    ; title 0
GetaShape 3,46,49,14,20    ; title 1
GetaShape 4,62,49,21,26    ; title 3
GetaShape 5,86,49,106,18   ; menu game start
GetaShape 6,194,49,75,19   ; menu options
GetaShape 7,86,68,91,18    ; menu hi-score
GetaShape 21,178,68,73,11  ; menu exit
GetaShape 8,304,0,16,16    ; menu arrow 0
GetaShape 9,304,16,16,16   ; menu arrow 1
GetaShape 10,304,32,16,16  ; menu arrow 2
GetaShape 11,304,48,16,16  ; menu arrow 3
GetaShape 12,304,64,16,16  ; menu arrow 4
GetaShape 13,304,80,16,16  ; menu arrow 5
GetaShape 14,304,96,16,16  ; menu arrow 6
GetaShape 15,304,112,16,16 ; menu arrow 7

GetaShape 16,0,76,16,37    ; band box left
GetaShape 17,16,76,16,37   ; band box right
GetaShape 18,0,113,33,26   ; crate box
GetaShape 19,76,86,28,8    ; shadow
GetaShape 20,76,95,87,12   ; table

progressbarValue = 20
progressbar{progressbarValue}

Dim ch.character(4)
charnum = 1
USEPATH ch(charnum)
For charnum = 1 To 4
  \x = 60
  \y = 140
  \state = 0
  \start_shape = 22 + ((charnum-1) * 12)
  \speed = 1
  \anm = 1
  \dir = 1
  \frame = 1

  Use BitMap 2
  QAMIGA
  Select charnum
    Case 1
      LoadBitMap 2,"16cron.iff"
    Case 2
      LoadBitMap 2,"16cferix.iff"
    Case 3
      LoadBitMap 2,"16cjojo73.iff"
    Case 4
      LoadBitMap 2,"16chtdreams.iff"
  End Select
  VWait 50 ; wait until disk operations are over
  BLITZ

  ; get right/left still animation
  GetaShape \start_shape  ,0,0,40,55
  GetaShape \start_shape+1,40,0,40,55
  GetaShape \start_shape+2,80,0,40,55
  GetaShape \start_shape+3,0,56,40,55
  GetaShape \start_shape+4,40,56,40,55
  GetaShape \start_shape+5,80,56,40,55
  ; get right/left walk animation
  GetaShape \start_shape+6 ,120,0,40,55
  GetaShape \start_shape+7,160,0,40,55
  GetaShape \start_shape+8,200,0,40,55
  GetaShape \start_shape+9,120,56,40,55
  GetaShape \start_shape+10,160,56,40,55
  GetaShape \start_shape+11,200,56,40,55

  progressbarValue = progressbarValue + 20
  progressbar{progressbarValue}
Next

ch(1)\player = 1 ; force character 1 to be controlled by player 1
ch(1)\speed = 2

ch(2)\player = 2 ; force character 2 to be controlled by player 2
ch(2)\speed = 2

Use BitMap 0

gamestate = 0
While gamestate <> 4
  Select gamestate
    Case 0
      Gosub showmenu
    Case 1
      Gosub gamestart
    Case 2
      Gosub options
    Case 3
      Gosub hiscores
  End Select
Wend

End


.showmenu
 BLITZ
  Use Palette 2
  Use BitMap db
  Boxf 0,0,384,360,13
  Use BitMap 1-db
  Boxf 0,0,384,360,13
  menushowstate = 0
  counter = 0
  While menushowstate <> 10
    VWait
    Show db,0,50
    db = 1 - db
    Use BitMap db
    Select menushowstate
      Case 0
        ; show title
        Boxf 0,0,320,90,13 ; clean bg
        If counter < 50
          Blit 0,15,51 + counter - 50
          counter = counter + 1
        Else
         Blit 0,15,50 ; paint title to ensure both screens have it
         menushowstate = 1
         counter = 0
        End If
      Case 1
        ; show year characters
        counter = counter + 1
        Select counter
          Case 30
            Blit 1,210,90 ; show 2
          Case 31
            Blit 1,210,90 ; double buffer
          Case 60
            Blit 2,231,90 ; show 0
          Case 61
            Blit 2,231,90 ; double buffer
          Case 90
            Blit 3,253,90 ; show 1
          Case 91
            Blit 3,253,90 ; double buffer
          Case 120
            Blit 4,267,90 ; show 3
          Case 121
            Blit 4,267,90 ; double buffer
          Case 150
            menushowstate = 2
            counter = 0
            menu1y = 320
            menu2y = 320
            menu3y = 320
            menu4y = 320
        End Select
      Case 2
        Boxf 80,200,300,320,13
        ; show menu options
        counter = counter + 5
        If menu1y > 200
          menu1y = 320 - counter
        End If
        Blit 5, 100, menu1y
        If counter > 30
          If menu2y > 220
            menu2y = 320 + 29 - counter
          End If
          Blit 6,100,menu2y
        End If
        If counter > 60
          If menu3y > 240
            menu3y = 320 + 60 - counter
          End If
          Blit 7,100,menu3y
        End If
        If counter > 90
          If menu4y > 260
            menu4y = 320 + 90 - counter
          End If
          Blit 21,100,menu4y
        End If
        If counter = 160
          menushowstate = 3
        End If
      Case 3
        Boxf 80,200,96,320,13
        Select menuselect
          Case 0
            Blit 8+menuarrowframe,80,200
          Case 1
            Blit 8+menuarrowframe,80,220
          Case 2
            Blit 8+menuarrowframe,80,240
          Case 3
            Blit 8+menuarrowframe,80,260
        End Select

        If menuarrowfps = 0
          menuarrowframe = (menuarrowframe + 1) AND 7
          menuarrowfps = 2
        Else
          menuarrowfps = menuarrowfps - 1
        End If

        If inputdelay > 0
          inputdelay = inputdelay - 1
        Else
          If RawStatus($4c)
            ; key up
            menuselect = (menuselect - 1) AND 3
            inputdelay = waittime
          End If
          If RawStatus($4d)
            ; key down
            menuselect = (menuselect + 1) AND 3
            inputdelay = waittime
          End If
        End If
        If RawStatus($40) OR RawStatus($44)
          ; space bar or enter key
          Select menuselect
            Case 0 ; start game
              gamestate = 1
            Case 1 ; options
              gamestate = 2
            Case 2 ; hiscores
              gamestate = 3
            Case 3 ; exit
              gamestate = 4
          End Select
          menushowstate = 10
        End If
        If RawStatus($45)
          menushowstate = 10
          gamestate = 0
        End If
    End Select
  Wend
Return

.gamestart
  bandpos = 32
  boxpos1 = 0
  randomnum1 = 0
  boxpos2 = 0
  randomnum2 = 100

  Buffer 0,16384
  Buffer 1,16384

  BLITZ
  Use Palette 2
  ; prepare backgrounds
  Use BitMap 0
  Scroll 0,0,320,256,32,50,3
  Use BitMap 1
  Scroll 0,0,320,256,32,50,3
  While gamestate <> 100
    VWait
    Show db,32,50
    db = 1 - db
    Use BitMap db
    UnBuffer db

    ; band animation
    Scroll 0,60,300,13,bandpos,110,3

    bandpos = bandpos + 1
    If bandpos = 42
      bandpos = 32
    End If

    ; box1 in band
    If (boxpos1 > 0) AND (boxpos1 < 340)
      BBlit db,18,boxpos1,94
    End If
    boxpos1 = boxpos1 + 1
    If boxpos1 > (340 + randomnum1)
      randomnum1 = Rnd(200)
      boxpos1 = 0 - randomnum1
    End If

    ; box2 in band
    If (boxpos2 > 0) AND (boxpos2 < 340)
      BBlit db,18,boxpos2,94
    End If
    boxpos2 = boxpos2 + 1
    If boxpos2 > (340 + randomnum2)
      randomnum2 = Rnd(200)
      boxpos2 = 0 - randomnum2
    End If

    ; band machine foreground panels
    Blit 16,32,92
    Blit 17,336,92

    charnum = 1
    Gosub characterstate
    charnum = 2
    Gosub characterstate
    charnum = 3
    Gosub characterstate
    charnum = 4
    Gosub characterstate

    ; arrange y-buffer
    For i=2 To 4
      indexvalue = ybuffer(i)
      yvalue = ch(ybuffer(i))\y
      j = i - 1
      While ((j > 0) AND (ch(ybuffer(j))\y > yvalue))
        ybuffer(j+1) = ybuffer(j)
        j = j - 1
      Wend
      ybuffer(j+1) = indexvalue
    Next

    ; first we paint shadows, as we dont mind shadows overlaping
    ; but we dont want shadows to paint over characters
    For i = 1 To 4
      charnum = ybuffer(i)
      Gosub charactershadowpaint
    Next

    For i = 1 To 4
      charnum = ybuffer(i)
      Gosub characterpaint
    Next

    ; blit the two bottom tables, so they will be over characters
    ; as this tables wont move we can simply blit them
    Blit 20,32,253
    Blit 20,264,253

    ; if a player puts a box on a table, we must paint the box above the table
    For i = 1 To 4
      charnum = i
      Gosub boxontablepaint
    Next

    If RawStatus($45)
      gamestate = 100
    End If
  Wend
  gamestate = 4; end game or 0 ; menu start
Return

.options
  gamestate = 1 ; for now we dont have this option available
Return

.hiscores
  gamestate = 1 ; for now we dont have this option available
Return

.characterstate
    Select \state
      Case 0
        ; waiting orders
        Select \player
          Case 0 ; character controlled by computer
            ; crappy ia to move around...
            If Rnd(100) > 99
              ; character will choose another position
              \state = 1
            End If
          Case 1 ; character controlled by player 1
            Gosub proccessplayercontrol
          Case 2 ; character controlled by player 2
            Gosub proccessplayercontrol
        End Select
      Case 1
        ; decide new dest
        \destx = Rnd(340)
        \desty = 87 + Rnd(120)
        \state = 2
      Case 2
        ; move to dest
        If (\x = \destx) AND (\y = \desty)
          \state = 0
          \anm = 1
        Else
          \anm = 2
          If \x < \destx
            \x = \x + \speed
            \dir = 1
          Else
            If \x > \destx
              \x = \x - \speed
              \dir = 2
            End If
          End If
          If \y < \desty
            \y = \y + \speed
          Else
            If \y > \desty
              \y = \y - \speed
            End If
          End If
        End If
    End Select
Return

.charactershadowpaint
  BBlit db,19,\x+7,\y+50
  If \hasbox = 4
    ; must paint the shadow from the box launched
    BBlit db,19,\boxx+7,\boxy+50
  End If
Return

.boxontablepaint
  Select \hasbox
    Case 2
      BBlit db,18,66,240
      If \boxactionwait = 0
        ; here we will put the opening box sequence table 1
        \hasbox = 0
      End If
    Case 3
      BBlit db,18,288,240
      If \boxactionwait = 0
        ; here we will put the opening box sequence table 2
        \hasbox = 0
      End If
  End Select
Return

.characterpaint
  Select \hasbox
    Case 1
      BBlit db,18,\x,\y
    Case 4
      BBlit db,18,\boxx,\boxy
      If \boxdir = 1
        If \boxx < 310
          \boxx = \boxx + 8
        Else
          \hasbox = 0
        End If
      Else
        If \boxx > 14
          \boxx = \boxx - 8
        Else
          \hasbox = 0
        End If
      End If
  End Select

  BBlit db,\start_shape + frames_anm(\dir, \anm, \frame),\x,\y
  ; select next frame, using the animation delay
  If \framedelay >= frames_rate(\anm)
    \framedelay = 0
    \frame = \frame + 1
    If \frame = 5 Then \frame = 1
  Else
    \framedelay = \framedelay + 1
  End If
Return

.proccessplayercontrol
  \anm = 1
  Let playerup = 0
  Let playerdown = 0
  Let playerleft = 0
  Let playerright = 0
  Let playeraction1 = 0
  Let playeraction2 = 0

  If playercontrols(\player,7) < 0
    If RawStatus(playercontrols(\player,1)) ; up control
      playerup = 1
    End If
    If RawStatus(playercontrols(\player,2)) ; down control
      playerdown = 1
    End If
    If RawStatus(playercontrols(\player,3)) ; left control
      playerleft = 1
    End If
    If RawStatus(playercontrols(\player,4)) ; right control
      playerright = 1
    End If
    If RawStatus(playercontrols(\player,5)) ; button 1
      playeraction1 = 1
    End If
    If RawStatus(playercontrols(\player,6)) ; button 2
      playeraction2 = 1
    End If
  Else
    If Joyy(playercontrols(\player,7)) = -1 ; up control
      playerup = 1
    Else
      If Joyy(playercontrols(\player,7)) = 1 ; down control
        playerdown = 1
      End If
    End If
    If Joyx(playercontrols(\player,7)) = 1 ; right control
      playerright = 1
    Else
      If Joyx(playercontrols(\player,7)) = -1 ; left control
        playerleft = 1
      End If
    End If
    Select Joyb(playercontrols(\player,7))
      Case 1
        playeraction1 = 1
      Case 2
        playeraction2 = 1
      Case 3
        playeraction1 = 1
        playeraction2 = 1
    End Select
  End If

  If playerup = 1
    If \y > 87 Then \y = \y - \speed
    \anm = 2
  End If
  If playerdown = 1
    If \y < 205 Then \y = \y + \speed
    \anm = 2
  End If
  If playerleft = 1
    If \x > 0 Then \x = \x - \speed
    \anm = 2
    \dir = 2
  End If
  If playerright = 1
    If \x < 340 Then \x = \x + \speed
    \anm = 2
    \dir = 1
  End If

  If \boxactionwait <> 0
    \boxactionwait = \boxactionwait - 1
  Else
    If playeraction1 = 1
      If \hasbox = 0
        ; pick up a box if character is near one on the band
        ; we measure from the middle of the box
        ; but as the box and the characters are 44 and 40, we
        ; can use just the x position
        ; of course the character needs to be at the band y position
        If (\y < 90)
          If (Abs(\x-(boxpos1)) < 10)
            ; player picks the box and reset boxpos1
            boxpos1 = 540 ; next frame will decide where to put box1 in band
            \hasbox = 1
          Else
            If Abs(\x-(boxpos2)) < 10
              boxpos2 = 540 ; next frame will decide where to put box2 in band
              \hasbox = 1
            End If
          End If
          If \hasbox = 1
            ; have the player wait some frames until droping the box
            \boxactionwait = 5
          End If
        End If
      Else
        If \hasbox = 1
          If \y > 200
            If \x < 115
              ; the player is at table 1
              \hasbox = 2
              \boxactionwait = 40
            Else
              If \x > 264
                ; the player is at table 2
                \hasbox = 3
                \boxactionwait = 40
              End If
            End If
          Else
            ; the player is not at the tables
            ; the player launchs the box in the direction he is facing
            \hasbox = 4
            \boxx = \x
            \boxy = \y
            \boxdir = \dir
          End If
        End If
      End If
    End If
  End If
Return
[ Show youtube player ]
htdreams is offline  
Old 16 August 2013, 16:46   #2
htdreams
Registered User
htdreams's Avatar
 
Join Date: Dec 2012
Location: Ferrol / A Coruna / Spain
Posts: 14
Ok, i've found a solution, not the one i would love to use, but at least now i can make games for 5 players on same computer :-)

The solution i've found is to abandon the idea of multiple users using keyboard, so one player will use keyboard, and the others 4 will use joysticks 1 & 2 (read using joyy/joyx/joyb) and joysticks 3 & 4 connected to the parallel port using this very simple schematics:

http://www.r3uk.com/index.php/home/3...ystick-adaptor

I managed to build it up myself, and i'm not into hardware :-)

The best part is the simplicity, as to read joysticks 3 & 4 there is only needed to do simple logical compares with readings from AMIGA CIA, at address $BFE101 for movement and $BFD000 for buttons (1 button each joystick)

This is the process in blitz:

Code:
dim joy3(5) ; up - down - left - right - action1 
dim joy4(5) ; up - down - left - right - action1 
multitapmovement.b = 0
multitapaction.b = 0

while gameloop
  multitapmovement = peek.b($bfe101)
  multitapaction = peek.b($bfd000)
  joy3(1) = (multitapmovement AND $01) = 0 ; up
  joy3(2) = (multitapmovement AND $02) = 0 ; down
  joy3(3) = (multitapmovement AND $04) = 0 ; left 
  joy3(4) = (multitapmovement AND $08) = 0 ; right
  joy3(5) = (multitapaction AND $01) = 0 ; action1

  joy4(1) = (multitapmovement AND $10) = 0 ; up
  joy4(2) = (multitapmovement AND $20) = 0 ; down
  joy4(3) = (multitapmovement AND $40) = 0 ; left 
  joy4(4) = (multitapmovement AND $80) = 0 ; right
  joy4(5) = (multitapaction AND $04) = 0 ; action1

  ; now it's just a matter of reading joy3 and joy4 arrays and it's done :-)

  vwait
wend
Hope this info is usefull for others :-)
htdreams is offline  
Old 16 August 2013, 16:58   #3
Franchute13
Registered User
Franchute13's Avatar
 
Join Date: Feb 2013
Location: Argentina
Posts: 251
thanks for sharing your code!
regards
Franchute13 is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Blitz2 Newcommandset BippyM Coders. Language 0 22 July 2012 00:59
A1200 Keyboard issues. Anakirob support.Hardware 5 13 January 2011 20:13
Amiga 500 with Supradrive Keyboard Issues Sargie support.Hardware 3 15 October 2010 04:31
WINUAE keyboard layout issues idog New to Emulation or Amiga scene 9 02 August 2010 13:16
Blitz2 Manual AlfaRomeo Amiga scene 18 01 May 2009 11:53

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 11:14.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.
Page generated in 0.06091 seconds with 13 queries