I've been meaning to ask this for a while now.

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
jason867
Posts: 78
Joined: Sun Jul 24, 2005 1:58 am
Contact:

I've been meaning to ask this for a while now.

Post by jason867 »

Ok, I have my own set of simple graphics routines in C for the PSP. They work fine and everything, but there's one thing that completely baffles me. Everyone says that PIXEL_SIZE is always either 2 or 4, depending on the video mode being used. Well, I used 2 for PIXEL_SIZE because of the video mode I was using (5551 I believe). But someone pointed out something that I had not noticed about my program, it was drawing a lot of stuff offscreen. He recommended changing PIXEL_SIZE to 1. I did so, and it solved the problem. However, PIXEL_SIZE is supposed to be 2 for this video mode, so what's the deal? I've looked through my code and have found nothing (although I'm not good at catching bugs).

So anyways, here is my graphics.h file, everything is in it. Can anyone point out what is causing me to have to set PIXEL_SIZE to 1 instead of 2?

Any help would be apreciated.

Code: Select all

//////////////////////////////////////////////////////////////////////////////////////////
// Graphics.h Version 1.3
// By Jason J. Owens
// August 28, 2005 10:27 AM
//////////////////////////////////////////////////////////////////////////////////////////

#ifndef __GRAPHICS__
#define __GRAPHICS__

// Includes
#include <pspdisplay.h>
#include <pspge.h>
#include <png.h>
//////////////////////////////////////////////////////////////////////////////////////////

// Function Prototypes
void PlotPixel&#40;int x,int y,int r,int g,int b&#41;;
void InitializeGraphics&#40;int mode&#41;;
void PlotLine&#40;int x0,int y0,int x1,int y1,int r,int g,int b&#41;;
void PlotCircle&#40;int xcenter,int ycenter,int radius,int r,int g,int b&#41;;
void screenshot&#40;const char* filename&#41;;
//////////////////////////////////////////////////////////////////////////////////////////

// #defines
#define BUF_WIDTH &#40;512&#41;
#define SCR_WIDTH &#40;480&#41;
#define SCR_HEIGHT &#40;272&#41;
#define PIXEL_SIZE &#40;1&#41; /* change this if you change to another screenmode */
#define FRAME_SIZE &#40;BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE&#41;
//////////////////////////////////////////////////////////////////////////////////////////

// Global Variables
u16 *VRAM=&#40;void *&#41;&#40;0x44000000&#41;;
//////////////////////////////////////////////////////////////////////////////////////////

// Function Definitions
// Plots a pixel on the screen using x,y, and three 0-255 shade color attributes.
void PlotPixel&#40;int x,int y,int r,int g,int b&#41;
&#123;
    // Tests whether pixel is being drawn off-screen, and returns imediately if so.
    if&#40;x<0||x>479||y<0||y>271||r<0||r>255||g<0||g>255||b<0||b>255&#41;
    &#123;
      return;
    &#125;

    int color=&#40;&#40;b>>3&#41;<<10&#41; | &#40;&#40;g>>3&#41;<<5&#41; | &#40;r>>3&#41; | 0x8000; // Creates and stores color.
    u16 *address=VRAM+&#40;&#40;&#40;&#40;512&#41;*PIXEL_SIZE&#41;*y&#41;+x&#41;; // Caculates address of pixel.
    *address=color; // Writes color code into address of the pixel.
    
&#125;
//////////////////////////////////////////////////////////////////////////////////////////

// Plots a line according to the given values, startX, startY, endX, endY, and color&#58; R,G,B.
void PlotLine&#40;int x0,int y0,int x1,int y1,int r,int g,int b&#41;
&#123;
   int dy = y1 - y0;
   int dx = x1 - x0;
   float t = &#40;float&#41; 0.5;                      // offset for rounding

   PlotPixel&#40;x0,y0,r,g,b&#41;;
   
   // If endpoints are the same, then don't draw the line, just return.
   if&#40; dy == 0 && dx == 0 &#41; return;

   if &#40;abs&#40;dx&#41; > abs&#40;dy&#41;&#41; // slope < 1
   &#123;
      float m = &#40;float&#41; dy / &#40;float&#41; dx;      // compute slope
      t += y0;
      dx = &#40;dx < 0&#41; ? -1 &#58; 1;
      m *= dx;
      while &#40;x0 != x1&#41;
      &#123;
         x0 += dx;                           // step to next x value
         t += m;                             // add slope to y value
         PlotPixel&#40;x0,&#40;int&#41;t,r,g,b&#41;;
      &#125;
   &#125;
   else // slope >= 1
   &#123;
      float m = &#40;float&#41; dx / &#40;float&#41; dy;      // compute slope
      t += x0;
      dy = &#40;dy < 0&#41; ? -1 &#58; 1;
      m *= dy;
      while &#40;y0 != y1&#41;
      &#123;
         y0 += dy;                           // step to next y value
         t += m;                             // add slope to x value
         PlotPixel&#40;&#40;int&#41;t,y0,r,g,b&#41;;
      &#125;
   &#125;
&#125;
//////////////////////////////////////////////////////////////////////////////////////////

// Plots a circle according to the given values, centerX, centerY, radius, and color&#58; R,G,B.
void PlotCircle&#40;int xcenter,int ycenter,int radius,int r,int g,int b&#41;
&#123;
    int x=0;
    int y=radius;
    int p=3 - 2 * radius;

    while&#40;x <= y&#41;
    &#123;
        PlotPixel&#40;xcenter+x,ycenter+y,r,g,b&#41;;
        PlotPixel&#40;xcenter-x,ycenter+y,r,g,b&#41;;
        PlotPixel&#40;xcenter+x,ycenter-y,r,g,b&#41;;
        PlotPixel&#40;xcenter-x,ycenter-y,r,g,b&#41;;
        PlotPixel&#40;xcenter+y,ycenter+x,r,g,b&#41;;
        PlotPixel&#40;xcenter-y,ycenter+x,r,g,b&#41;;
        PlotPixel&#40;xcenter+y,ycenter-x,r,g,b&#41;;
        PlotPixel&#40;xcenter-y,ycenter-x,r,g,b&#41;;

        if&#40;p < 0&#41;
            p += 4 * x++ + 6;
        else
            p += 4 * &#40;x++ - y--&#41; + 10;
    &#125;
&#125;
///////////////////////////////////////////////////////////////////////////////////

// Initializes the PSP Display.
void InitializeGraphics&#40;int mode&#41;
&#123;
    sceDisplaySetMode&#40;mode,SCR_WIDTH,SCR_HEIGHT&#41;; // Sets the display mode.
    sceDisplaySetFrameBuf&#40;VRAM,BUF_WIDTH,1,1&#41;; // Sets the address of the frame buffer.
&#125;
//////////////////////////////////////////////////////////////////////////////////////////

// Saves a screenshot of the screen to filename.
void screenshot&#40;const char* filename&#41;
&#123; 
   png_structp png_ptr;
   png_infop info_ptr; 
   FILE* fp; 
   int i, x, y;
   u16* data = VRAM;
   int width=SCR_WIDTH;
   int height=SCR_HEIGHT;
   int linesize=BUF_WIDTH;
   int saveAlpha=0;
   u8* line;

   if &#40;&#40;fp = fopen&#40;filename, "wb"&#41;&#41; == NULL&#41; return;
   png_ptr = png_create_write_struct&#40;PNG_LIBPNG_VER_STRING, NULL, NULL, NULL&#41;; 
   if &#40;!png_ptr&#41; return;
   info_ptr = png_create_info_struct&#40;png_ptr&#41;; 
   if &#40;!info_ptr&#41; &#123; 
      png_destroy_write_struct&#40;&png_ptr, &#40;png_infopp&#41;NULL&#41;;
      return;
   &#125; 
   png_init_io&#40;png_ptr, fp&#41;;
   png_set_IHDR&#40;png_ptr, info_ptr, width, height, 8,
      saveAlpha ? PNG_COLOR_TYPE_RGBA &#58; PNG_COLOR_TYPE_RGB, 
      PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT&#41;; 
   png_write_info&#40;png_ptr, info_ptr&#41;; 
   line = &#40;u8*&#41; malloc&#40;width * &#40;saveAlpha ? 4 &#58; 3&#41;&#41;; 
   for &#40;y = 0; y < height; y++&#41; &#123; 
      for &#40;i = 0, x = 0; x < width; x++&#41; &#123; 
         u16 color = data&#91;x + y * linesize&#93;;
         int r = &#40;color & 0x1f&#41; << 3; 
         int g = &#40;&#40;color >> 5&#41; & 0x1f&#41; << 3 ; 
         int b = &#40;&#40;color >> 10&#41; & 0x1f&#41; << 3 ; 
         line&#91;i++&#93; = r; 
         line&#91;i++&#93; = g; 
         line&#91;i++&#93; = b; 
         if &#40;saveAlpha&#41; &#123; 
            int a = color & 0x8000 ? 0xff &#58; 0; 
            line&#91;i++&#93; = a; 
         &#125; 
      &#125; 
      png_write_row&#40;png_ptr, line&#41;; 
   &#125; 
   free&#40;line&#41;; 
   png_write_end&#40;png_ptr, info_ptr&#41;; 
   png_destroy_write_struct&#40;&png_ptr, &#40;png_infopp&#41;NULL&#41;; 
   fclose&#40;fp&#41;; 
&#125;
///////////////////////////////////////////////////////////////////////////////////////
#endif

//////////////////////////////////////////////////////////////////////////////////////////
Ask not for whom the bell tolls, it tolls for thee, besides, I'm playing my PSP, tee hee!
------------------------------------------------------
Visit my website for my PSP Homebrew!
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Re: I've been meaning to ask this for a while now.

Post by Shine »

You are using sceDisplaySetFrameBuf(VRAM,BUF_WIDTH,1,1), which I would write like sceDisplaySetFrameBuf(VRAM,BUF_WIDTH,PSP_DISPLAY_PIXEL_FORMAT_5551, PSP_DISPLAY_SETBUF_NEXTFRAME) and one pixel is 2 bytes long, but you are using u16 pointers, so your pixel size is 1 u16 entry in your array.
jason867
Posts: 78
Joined: Sun Jul 24, 2005 1:58 am
Contact:

Post by jason867 »

So do you mean that I should change the way I use sceDisplaySetFramBuf() to your way, and then instead of this;

Code: Select all

u16 *address=VRAM+&#40;&#40;&#40;&#40;512&#41;*PIXEL_SIZE&#41;*y&#41;+x&#41;;
I should have this;

Code: Select all

u8 *address=VRAM+&#40;&#40;&#40;&#40;512&#41;*PIXEL_SIZE&#41;*y&#41;+x&#41;;
and then it would work right with PIXEL_SIZE being 2 instead of 1?

Sorry, I'm a bit thickheaded.
Ask not for whom the bell tolls, it tolls for thee, besides, I'm playing my PSP, tee hee!
------------------------------------------------------
Visit my website for my PSP Homebrew!
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

jason867 wrote:So do you mean that I should change the way I use sceDisplaySetFramBuf() to your way, and then instead of this;

Code: Select all

u16 *address=VRAM+&#40;&#40;&#40;&#40;512&#41;*PIXEL_SIZE&#41;*y&#41;+x&#41;;
I should have this;

Code: Select all

u8 *address=VRAM+&#40;&#40;&#40;&#40;512&#41;*PIXEL_SIZE&#41;*y&#41;+x&#41;;
and then it would work right with PIXEL_SIZE being 2 instead of 1?
No. I'm sure you know that adding a scalar to a pointer adds the size of the type to which the pointer points, multiplied by the scalar in bytes, to the address (if not, please read a good C learning book), so if you change VRAM to u8*, you could use PIXEL_SIZE=2, but it doesn't make sense, because it is easier to access the memory as u16*.
Post Reply