www.xbdev.net xbdev - software development
Friday December 14, 2018
home | about | contact | Donations

     
 

XBOX Programming

More than just a hobby...

 

Setting a Pixel on the screen.

 

Well one thing at a time... we have a working xbe... now if we could only put some pixels on the screen.... the power will be ours....mahahaha..

So with a bit of creativity, and of course a bit of assembly, we can do this magical trick.  We only need to find where in memory we need to write to, and the format...which is BGR....and not RGB as many people might think :)

 

So how would be go about doing it in standard C?... as when I show you the assembly in a sec...a lot of people are going to run away screaming!  But don't be affraid...its not that bad once you get past what it is and how it works .... so don't give up.

 

 

Code: code.cpp

#define SCREEN_WIDTH    640

#define SCREEN_HEIGHT   480

 

int framebuffer = 0xf0010000 + 640*320 + 80;

 

void DrawPixel(int x, int y, unsigned int dwPixelColourRGB) // AARRGGBB

{

    // Placed into memory in the order BLUE-GREEN-RED not RGB as you'd think :)

    ((unsigned char*)framebuffer)[(x + y*SCREEN_WIDTH)*4+0] = dwPixelColourRGB & 0x000000ff;

    ((unsigned char*)framebuffer)[(x + y*SCREEN_WIDTH)*4+1] = (dwPixelColourRGB & 0x0000ff00) >> 8;

    ((unsigned char*)framebuffer)[(x + y*SCREEN_WIDTH)*4+2] = (dwPixelColourRGB & 0x00ff0000) >> 16;

}

 

int main()

{

      while(true)

      {

            DrawPixel(SCREEN_WIDTH/2 ,SCREEN_HEIGHT/2, 0xff0000);

      }

  return 0;

}

 

Now if you compiled that code and ran it on the xbox with the openxdk or even the msxdk it should draw a single pixel in the middle of the screen :)... a RED pixel as well :)

 

But where not here to look at how to do it in C... we want the real juicy stuff....the assembly....oh yeah...

 

 

Assembly: code.asm

; code.asm

 

; C:>nasm code.asm -o code.xbe

 

; This includeds the header information for the xbe file.

%include "header.asm"

 

; CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE

; CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE ** CODE

 

; Lets jump to the entry point in our code e.g. like we do with main() in C...

jmp   start

 

 

framebuffer:

dd    0xf0010000 + 640*320 + 80;

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DrawPixel:

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; Setup Function

      push  ebp                           ; Setup our function

      mov   ebp, esp

 

      ; ecx = y;

      ; ebx = x

      ; ecx*=640

      ; ecx = x+y*640

      mov   ecx, DWORD [ebp+12]                 ; put y pos in ecx

      imul  ecx, 640   

      mov   ebx, DWORD [ebp+8]                  ; put x pos int edx

      add   ecx, ebx                      ; hence ecx = x+y*640

     

      mov   ebx, DWORD [framebuffer]            ; Get the location in memory

                                          ; where we will put this pixel

                                          ; e.g. framebuffer

 

; Put blue pixel into memory

      mov   eax, DWORD [ebp+16]                 ; put pixel colour in eax

      and   eax, 255

     

      mov   BYTE [ebx+ecx*4], al

 

; Put green pixel into memory

      mov   eax, DWORD [ebp+16]                 ; put pixel colour in edx

      and   eax, 65280

      shr   eax, 8

 

      mov   BYTE [ebx+ecx*4+1], al

 

; Put red pixel into memory

      mov   eax, DWORD [ebp+16]

      and   eax, 16711680

      shr   eax, 16

 

      mov   BYTE [ebx+ecx*4+2], al

 

; tidy up and return from function call

      pop   ebp

      ret   0

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; End of DrawPixel

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

 

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; Globals

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

xpos:

dd    310                     ; width/2 = 640/2 = 310

ypos:

dd    240                     ; height/2 = 480/2 = 240     

colour:

dd    0xff0000              ; Red colour pixel

 

xloop:                           ; We do a simple loop and draw a small line

dd    0x50

 

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

start:

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

     

a_loop:

 

      ; This is the same as DrawPixel(x, y, colour)

      push  DWORD [colour]

      push DWORD [ypos]

      push  DWORD [xpos]

      call  DrawPixel

      add   esp, 12

 

      ; Increment the ypos.

      mov   eax, [ypos]

      add   eax, 1

      mov   [ypos], eax

 

      ; Loop around 100 times back to loopx - as sometimes people say...I can't see

      ; the red pixel...so using this simple asm loop... we've managed to draw a

      ; simple line :)

      mov eax, [xloop]

      dec eax

      mov [xloop],eax

      jne a_loop

 

 

      ; Program has now finished, so we simply just stay here and loop :)

bbb: 

      jmp bbb;

 

 

 

 

; END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE

; END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE ** END OF CODE

 

 

TIMES 0x6000-($-$$) DB 0x90   ; this will make our section finish at 0x6000

                                ; from the start of the file.

 

TIMES 0x7000-($-$$) DB 0x0    ; And of course, this will make our file size

                                ; equal to 0x7000 a nice round number -

                                ; 0x7000 is 28672bytes... so if you assemble the file

                                ; you should find its that size exactly.

 

 

So what will you expect when you run this baby up.....turn your xbox on and send that xbe running?.... any ideas?  Well it will draw a sweet red line in the middle of the screen using our home made "DrawPixel(..)" function..

 

On the right, you can see a mini screenshot of what to expect - I know this is not the most amazing thing in the world... but its a fantastic way to improve your asm skills...and see how optimised you can make your code.

 

Beleive me also, now that you have your DrawPixel function out of the way, drawing a line won't be as hard :)

 

 

Which as will probably be the next tutorial - How to draw a line.... as once you can draw a line, you can draw cubes... triangles..... etc... use 3D data.... you could even draw images to the screen with your DrawPixel function :).... which sounds like a cool add on later on I think.

 

 

 

 

{Feedback is always welcome - webmaster@xbdev.net}

 

 

 

 
 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved.
Designated tutorial and software are the property of their respective owners.