News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Create a pointer to a table

Started by popcalent, June 04, 2021, 12:18:52 PM

Previous topic - Next topic

popcalent

Hello all!

I'm working on a code that prints sprites. The sprites are stored as tables in this way:

SPRITE_1 DB '00111100#'
         DB '01000010#'
         DB '01000010#'
         DB '00111100#','$'


This would print a "circle" (I simplified a lot to keep the post simple). 1 means put a pixel, 0 means skip, # means end of line.

I have this subroutine that prints the sprite:

PRINT_SPRITE PROC NEAR
                ;CX=POSITION_X, BX=POSITION_Y
                PUSH EVERYTHING
                MOV  DI, 0
                MOV DX, CX
PRINT_SPRITE_:
                MOV AL, SPRITE_1[DI]
                CMP SPRITE_1[DI],'0'
                JE   SKIP_PIXEL
                PUTPIXEL CX, BX, COLOR
SKIP_PIXEL:
                INC DI
                INC DX         
                CMP SPRITE_1[DI], '#'      ; END OF LINE?
                JNE  NONEWLINE
                MOV DX, CX                 ; RESET POSITION X
                INC BX                     ; INC POSITION Y
                INC DI
NONEWLINE:
                CMP SPRITE_1[DI],'$'       ; END OF SPRITE?
                JNE PRINT_SPRITE_
                POP EVERYTHING
                RET


And this is how I call the subroutine:

MOV CX, POSITION_X
MOV BX, POSITION_Y
CALL PRINT_SPRITE

However, the subroutine only prints SPRITE_1 (duh!). I want a variable to have the address of any sprite table. This is what I tried:

1) I created a variable that will store the address of any table
SPRITE_PTR DB ?

2) I moved the address of a sprite to the variable
MOV AX, BYTE PTR SPRITE_1
MOV SPRITE_PTR, AX
MOV CX, POSITION_X
MOV BX, POSITION_Y
CALL PRINT_SPRITE


3) I used the variable inside the subroutine like this:
...
CMP SPRITE_PTR[DI], '0'
...


This didn't work. Alternatively, I did this (which also didn't work):
2B)
LEA AX, SPRITE_1
MOV SPRITE_PTR, AX

3B)
...
CMP [SPRITE_PTR], '0'
...

So, what is it? What am I doing wrong? Thanks!


mineiro

hello sir popcalent;

;inside data segment
sprite1 db "one#$"
sprite1_sz equ sprite1-$    ;this is one way to get data size, maybe can be usefull, not used in example
sprite2 db "two#$"
sprite2_sz equ sprite2-$

;addresses are 16 bits (define word (dw) instead of define byte (db))
sprite_table dw sprite1,sprite2,0

;inside code segment
;supposing that data or extra segments are ok
mov cx,X
mov bx,Y
lea di,sprite1      ;mov di,offset sprite1
call print_sprite
mov cx,X
mov bx,Y
lea di,sprite2      ;mov di,offset sprite2
call print_sprite

;change 2 things in your PRINT_SPRITE procedure:
1:remove/comment "MOV  DI, 0", that's reseting everytime di register to start offset
2:change all ocurrences of "SPRITE_1[DI]" to "byte ptr [di]"
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

popcalent

Mineiro,  that's exactly what I needed! Thanks a lot, you rock!

daydreamer

If you have 16x16 pixel sprites=256 bytes/sprite
using lea bx,sprite0
Add bh,spritenumber ;0,1,2,3,4 becomes +0,256,512,768,1024

my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

popcalent

Quote from: daydreamer on June 05, 2021, 08:53:37 PM
If you have 16x16 pixel sprites=256 bytes/sprite
using lea bx,sprite0
Add bh,spritenumber ;0,1,2,3,4 becomes +0,256,512,768,1024

Thanks, daydreamer! I have 32x32 pixel sprites, so I can easily break them into 4x16x16 sprites each.  :thumbsup: