GP32 Plotting A Circle


Tealion

Still Fresh
Joined
Mar 15, 2004
Messages
33
Age
37
Location
Exeter Devon UK
Website
Visit site
Here is some simple code to plot a simple circle if anybody wants to know, using Mr.Mirkos SDK

Code:
#include "gp32.h"
#include <math.h>

#define SCREENHEIGHT 320
#define SCREENWIDTH 240

#define BLACK 0x0000
#define WHITE 0xFFFF

/*Globals*/
unsigned short *framebuffer;

/*Prototypes*/
void DrawCircle(int shift_x, int shift_y, int vectorlength);

/*===================================================*/
int main() 
{
	int x, int vectlength = 50;

	framebuffer = (u16*) FRAMEBUFFER;
	gp_SetScreen(framebuffer,16);
	gp_ButtonInit();
	gp_SetCpuSpeed(66);
    
	/*clear screen*/
	for (x=0;x<320*240;x++)
  framebuffer[x]=WHITE; 
 
	/*scrres 320x240 half for centering*/
	DrawCircle(SCREENHEIGHT/2,SCREENWIDTH/2,vectlength);

	/*infinate loop until A button pressed*/
	while (1) 
  if ( gp_ButtonResult()&BA) gp_Reset(); 
  
	return 0;
}
/*===================================================*/

void DrawCircle(int shift_x, int shift_y, int vectorlength)
{
	int x,y;
	float angle = 0.0;
	float angle_stepsize = 0.1;

	while( angle < 2*PI)
  {
  x = vectorlength * cos(angle);
  y = vectorlength * sin(angle);
  
  gp_SetPixel16(x+shift_x, y+shift_y, BLACK, framebuffer);
  angle += angle_stepsize;  
  }

}

Enjoy!!
 
Very neat. The use of COS and SIN is quite CPU expensive, however.
Search for Bresenham's Circle Algorithm and you can find code that will draw a circle using only integer variables with simple addition/subtraction!
Combine this with a circle's symmetry and algorithms to check for screen boundary clipping (see Cohen-Sutherland clipping algorithm) and you get a very fast implementation to plot a circle of any radius at any position.
The code expands a lot though; I got a bit carried away a few months ago whilst coding something that requires a lot of circles to be plotted.

I've attached my implementation of the algorithms. Any improvements much appreciated.

Cheers,
Joel

BTW, how can I attach more that one file?
You'll need the header file, "graphicFunctions.h":
Code:
/*
	Graphic Functions.
*/

#ifndef __graphicFunctions_h__
#define __graphicFunctions_h__

#include "gpgraphic.h"

#define SCREENHEIGHT 240
#define SCREEN_MIDDLE_X 160
#define SCREEN_MIDDLE_Y 120



/***************************************************
	Bresenham's Line Algorithm.
***************************************************/
void drawLine16Bit(GPDRAWSURFACE *gpDraw, int x0, int y0, int x1, int y1, short colour);



/***************************************************
	Circle data structure.
***************************************************/
typedef struct
{
	int centreX;
	int centreY;
	int radius;
	short colour;
	
} CIRCLE_DATA;



/***************************************************
	Bresemham's Circle Algorithm.
***************************************************/
void drawCircle16Bit(GPDRAWSURFACE *gpDraw, CIRCLE_DATA circleData);



/***************************************************
	Draw a point.
***************************************************/
void drawPoint16Bit(GPDRAWSURFACE *gpDraw, int x, int y, short colour);



/***************************************************
	Calculate colour.
***************************************************/
short calcColour16Bit(float red, float green, float blue);



#endif
 
Here is another example I have a solid and also a oval routine. VERY FAST!
http://www.nigelibrown.pwp.blueyonder.co.u.../arm/circle.htm

EXPORT OS_Circle
AREA code, CODE, READONLY

;========================================
OS_Circle
;========================================
; on entry:
;
; r0 = screen base address
; r1 x pos
; r2 y pos
; r3 radius
; r4 color (stacked @ #32)
;
; on exit:
;
;========================================

MACRO
CPLOT

;========================================

cmp r8,#240 ; x position maximum x
cmpcc r9,#320 ; y position maximum y
addcc r10,r0,r9,lsl#8 ; r10 = screenbase + (y*64)
subcc r10,r10,r9,lsl#4 ; r10 = screenbase + (y*240)
strccb r4,[r10,r8] ; store colour,[ screenbase + (y*240) + xpos ]

MEND ; macro end

;========================================

sub sp,sp,#4 ; protect the memory where the color param is.
stmfd sp!,{r4-r10} ; save used regs

ldr r4,[sp,#32] ; get color from stack,
; 1 param + 7 saved registers (4 bytes each) 7 x 4 = 32 bytes from sp
mov r5,#0 ; zero
mov r6,r3 ; duplicate radius
mov r3,r3,lsl#1 ; radius = radius x2
rsb r7,r3,#3 ; r7 = PI-radius

rsb r2,r2,#240 ; y = (-y)

cir_00 add r8,r2,r5 ; r8 = ypos + r5 (xp=xp+x)
add r9,r1,r6 ; r9 = xpos + r6 (yp=yp+y)
CPLOT
sub r9,r1,r6
CPLOT
sub r8,r2,r5
add r9,r1,r6
CPLOT
sub r9,r1,r6
CPLOT
add r8,r2,r6
add r9,r1,r5
CPLOT
sub r9,r1,r5
CPLOT
sub r8,r2,r6
add r9,r1,r5
CPLOT
sub r9,r1,r5
CPLOT
cmp r5,r6

bge exit_00

cmp r7,#0
add r7,r7,r5,lsl#2
add r5,r5,#1
add r7,r7,#6
bmi cir_00
sub r7,r7,r6,lsl#2
add r7,r7,#4
sub r6,r6,#1
b cir_00

exit_00 ldmfd sp!,{r4-r10}
add sp,sp,#4
bx lr

END
 
Back
Top