Author Topic: How to display pixel in certain location  (Read 2712 times)

0 Members and 1 Guest are viewing this topic.

Offline Yeong

  • Not a bridge
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3739
  • Rating: +278/-12
  • Survivor of Apocalypse
    • View Profile
How to display pixel in certain location
« on: May 03, 2011, 07:32:47 pm »
Well, after reading Hot_Dog's ASM tutorial, I decided to make my own sprite routine, but I can't even display a single pixel into the screen...
How do I do that?
Sig wipe!

Offline Deep Toaster

  • So much to do, so much time, so little motivation
  • Administrator
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 8217
  • Rating: +758/-15
    • View Profile
    • ClrHome
Re: How to display pixel in certain location
« Reply #1 on: May 03, 2011, 07:47:24 pm »
Well, remember how the screen is stored. It's 768 bytes located at plotSScreen -- 12 bytes per row, 64 rows. Each byte represents eight pixels.

That means you have some math to do. Say you want to display something on the sixteenth row down and tenth row across. The row is easy to find: it's just 15*12+plotSScreen (15 being the number of rows before it).

The 10th column is in the second byte on that row, or byte 1 (counting from zero). So the byte in question is 15*12+1+plotSScreen.

Remember that in ASM, you can only store whole bytes at a time (not true, but it's easier that way). But you don't want to mess up what's already in the 9th, 11th, 12th, etc. pixels on that row. That's where bitmasking comes in: you take what's already there, change the desired pixel, and store it back.

Here's an example code to do it (untested but it should work):

Code: (TI-ASM) [Select]
    LD HL,15*12+1+plotSScreen    ; this is a constant value
    LD A,(HL)    ; get the pixels already there
    OR %01000000    ; flip only that particular bit (pixel)
    LD (HL),A    ; store it back
    BCALL(_GrfBufCpy)    ; display to screen

Why OR %01000000? Remember that you have 8 pixels in that byte you took, but you only want to flip bit 6 (second from the left). By masking it with an OR %01000000, you make sure that that bit becomes a 1 (pixel turned on). Then you store it back and call _GrfBufCpy to display the screen.




SirCmpwn

  • Guest
Re: How to display pixel in certain location
« Reply #2 on: May 03, 2011, 07:52:23 pm »
Also, I'd recommend trying to think up ways to make it work without doing one pixel at a time.  You can do up to 8 pixels at once, and it's a lot faster.  Use it to your advantage.

Offline Deep Toaster

  • So much to do, so much time, so little motivation
  • Administrator
  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 8217
  • Rating: +758/-15
    • View Profile
    • ClrHome
Re: How to display pixel in certain location
« Reply #3 on: May 03, 2011, 07:54:48 pm »
Also, I'd recommend trying to think up ways to make it work without doing one pixel at a time.  You can do up to 8 pixels at once, and it's a lot faster.  Use it to your advantage.

^ Great for lines and other graphics. Taking a byte and storing it back is a lot faster than doing it eight times :)

Only bad part is the amount of maths involved :D




Offline Xeda112358

  • they/them
  • Moderator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 4704
  • Rating: +719/-6
  • Calc-u-lator, do doo doo do do do.
    • View Profile
Re: How to display pixel in certain location
« Reply #4 on: May 03, 2011, 08:54:59 pm »
Here is some sample code for pixel routines... Sorry I didn't add many notes to this :/ I am talking on the phone, programming on my calc and typing this up all at the same time XD
Code: [Select]
;===============================
DrawPixel
;===============================
;Inputs:
;     A is the drawing method:
;        0=Pixel Off
;        1=Pixel On
;        All else=Pixel Invert
;     B is the X coordinate
;     C is the Y coordinate
;===============================
     push af           ;F5
     call GetPixelLoc  ;CD****
     pop bc            ;C1
     inc b             ;04
     djnz PixelOn      ;1004
;Pixel Off
       cpl             ;2F     Inverts A
       and (hl)        ;A6
       ld (hl),a       ;77
       ret             ;C9
     djnz PixelInvert  ;1003
PixelOn:
       or (hl)         ;B6
       ld (hl),a       ;77
       ret             ;C9
PixelInvert:
       xor (hl)        ;AE
       ld (hl),a       ;77
       ret             ;C9
;===============================
GetPixelLoc:
;===============================
;Inputs:
;     B is X coordinate
;     C is Y coordinate
;Outputs:
;     HL points to the byte in plotSScreen
;     A is the mask
;     B is 0
;     C is unchanged
;     DE is C*12 (also BC*12)
;===============================

     ld a,b            ;78
     ld b,0            ;0600
     ld h,b            ;60
     ld l,c            ;69
     add hl,hl         ;29
     add hl,bc         ;09
     add hl,hl         ;29
     add hl,hl         ;29
     ld b,a            ;47
     ld d,h            ;54
     ld e,l            ;5D
     rrca              ;0F
     rrca              ;0F
     rrca              ;0F
     and 1Fh           ;E61F
     add 40h           ;C640
     ld l,a            ;6F
     ld h,93h          ;2693
     add hl,de         ;19
     ld a,b            ;78
     and 7             ;E607
     ld b,a            ;47
     inc b             ;04
     ld a,1            ;3E01
Loop:
     rrca              ;0F
     djnz Loop         ;10FD
     ret               ;C9
EDIT: This can probably be optimised...
EDIT2: Also, I made it Call GetPixelLoc instead of making it inline because GetPixelLoc has other uses, too, for code.
EDIT3: So I figured if it was in your code, it might work better as a call, but if you aren't using it for anything else, place it inline to save 3 bytes.

Offline FloppusMaximus

  • LV5 Advanced (Next: 300)
  • *****
  • Posts: 290
  • Rating: +57/-5
    • View Profile
Re: How to display pixel in certain location
« Reply #5 on: May 03, 2011, 09:14:02 pm »
For GetPixelLoc, note that shells include the ionGetPixel routine, which does the same thing but uses slightly different inputs (A = column and E = row.)  There's also the system routine IOffset (known as FIND_PIXEL on the TI-82), which is similar (though slower, naturally) but doesn't add the address of plotSScreen to HL.