assembly - How to manipulate array in emu8086 -


i creating simple game program in emu8086. using arrow keys able print asterisk in every direction want. problem there requirement if printed 5 asterisk tail of asterisk should remove body of asterisk remain 5 every print.

from research, used array have no idea yet how manipulate in array, since don't know how track array's tail , position me able print space delete tail.

like:

1. * 2. * 3. * 4. * 5. * 

after clicking direction should like.. in case it's down direction.. how combination of other directions?

1.  2.* 3.* 4.* 5.* 6.* 

here's printing code

continue:  mov ah, 2   ;print asterisk mov dl, "*" int 21h   continue2: mov ch, 32  ;hide blinking cursor mov ah, 1 int 10h   mov ah, 00h ;input direction int 16h    cmp ah, je          cmp ah, left je  left cmp ah, down je  down  cmp ah, right je  right 

you can use called "ring buffer", if know maximum length of snake.

the "arrays" in assembly continuous area of memory, structure defined code.

let's have snake 5 asterisks long @ most, use buffer of 6 [x, y] positions define that, 5 positions asterisks head tail, 6th position previous tail position, i.e. space printed "erase" tail.

i re-arrange in code bit, having such buffer positions long power of 2 (next power of 2 after 6 8, if snake grow, fill screen, need 80*25=2000 positions @ most, , next power of 2 2048). , keep around index head element (then pick direction toward next body parts wish, put head last during init, buffer[0] contain "space" tail, buffer[1] last asterisk "tail", ... buffer[5] "head" asterisk, , keep around headindex=5 (or rather directly memory offset headoffset = 10, each element 2 bytes ([x,y]) , 5*2 = 10).

so have "ring buffer" body parts positions in data section:

buffer_size  equ  2*8  ; or 2*2048 growing snake     ; "2*", because each position 2 bytes big  snakelength:     dw      ? headoffset:     dw      ? positions:     db      buffer_size dup (?) 

and code, initialize snake length 5, first 6 pairs of bytes in positions snake starts (including "space" tail @ first position!), , head offset 10 (5th position byte-pair in buffer).

now print snake, load headoffset , snakelength, , "snakelength" many times:

  • fetch 2 bytes positions + offset, [x,y]
  • print asterisk there
  • decrement offset two
  • and <register offset>,(buffer_size-2), make point last element of memory in case offset 0 (that's reason, why power of two, allow me wrap around "ring buffer" single and instruction , bit masking operation).

and 1 more iteration, time printing space, not asterisk (for final element).

that's how draw snake defined in such array.

how "move" in direction, let's (-1, 0) (to left):

  • read headoffset value
  • read current position of head [positions + headoffset]
  • increment offset 2
  • and <register offset>,(buffer_size-2) makes point next element in buffer
  • add (-1, 0) current head position
  • store updated position [positions + offset]
  • store offset new headoffset (which make last tail asterisk position new "space" tail, , previous "space" tail out of reach same snakelength).

after draw new state of data, snake "move" left 1 step.

how grow snake: same move, update snakelength +1, last 2 elements of buffer still used previous asterisk+space tail, keeping tail @ same position, while head moved ahead. (you can grow snake +1 in each step method, don't add new body parts tail ... that's how old snake games work, when eat bigger food makes snake grow n parts, done on n next steps, not instantly).

so have array of 8 positions, 6 used. 6 used defined headoffset, goes around , wraps around (from offset 0 going "down" offset 14 (8*2-2), , offset 14 going means landing @ offset 0, "ring buffer" warping around, "ring", without beginning or end).


alternative have array of 6 positions, , when move snake, literally move data in array position i position i-1, , writing new head position last array element. simpler understand @ first try, "ring buffer" solution superior because don't have move block of memory every time snake moves, add new head , adjust offset/length data, instead of moving positions in memory, move offset access data. (with 1500 parts long snake means saving 3000 bytes memmove setting 1 new element , updating offset). price introduction of offset warping logic (to go offset 14 0 , 0 14) every time move 1 element next, done single and instruction, still faster copying memory of buffer.


emu8086 inferior, , lector should update tools , course (how nasm + dosbox + neat debugger, of universities have still turbo debugger student-licenses around 199x era).


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -