Skip to content

Commit 869e265

Browse files
crystalctmiigotu
authored andcommitted
Cairo clock example
1 parent 4441cb9 commit 869e265

6 files changed

Lines changed: 617 additions & 0 deletions

File tree

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#---------------------------------------------------------------------------------
2+
# Clear the implicit built in rules
3+
#---------------------------------------------------------------------------------
4+
.SUFFIXES:
5+
#---------------------------------------------------------------------------------
6+
ifeq ($(strip $(PSL1GHT)),)
7+
$(error "Please set PSL1GHT in your environment. export PSL1GHT=<path>")
8+
endif
9+
10+
include $(PSL1GHT)/ppu_rules
11+
12+
#---------------------------------------------------------------------------------
13+
# TARGET is the name of the output
14+
# BUILD is the directory where object files & intermediate files will be placed
15+
# SOURCES is a list of directories containing source code
16+
# INCLUDES is a list of directories containing extra header files
17+
#---------------------------------------------------------------------------------
18+
TARGET := $(notdir $(CURDIR))
19+
BUILD := build
20+
SOURCES := source
21+
DATA := data
22+
INCLUDES := include
23+
24+
TITLE := Cairo clock sample - PSL1GHT
25+
APPID := CAIRO0002
26+
CONTENTID := UP0001-$(APPID)_00-0000000000000000
27+
28+
#---------------------------------------------------------------------------------
29+
# options for code generation
30+
#---------------------------------------------------------------------------------
31+
32+
CFLAGS = -O2 -Wall -mcpu=cell $(MACHDEP) $(INCLUDE)
33+
CXXFLAGS = $(CFLAGS)
34+
35+
LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
36+
37+
#---------------------------------------------------------------------------------
38+
# any extra libraries we wish to link with the project
39+
#---------------------------------------------------------------------------------
40+
LIBS := -lgcm_sys -lrsx -lsysutil -lio -lcairo -lfreetype -lz -lpixman-1 -lm -lrt -llv2
41+
42+
#---------------------------------------------------------------------------------
43+
# list of directories containing libraries, this must be the top level containing
44+
# include and lib
45+
#---------------------------------------------------------------------------------
46+
LIBDIRS := $(PORTLIBS)
47+
48+
#---------------------------------------------------------------------------------
49+
# no real need to edit anything past this point unless you need to add additional
50+
# rules for different file extensions
51+
#---------------------------------------------------------------------------------
52+
ifneq ($(BUILD),$(notdir $(CURDIR)))
53+
#---------------------------------------------------------------------------------
54+
55+
export OUTPUT := $(CURDIR)/$(TARGET)
56+
57+
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
58+
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
59+
60+
export DEPSDIR := $(CURDIR)/$(BUILD)
61+
62+
export BUILDDIR := $(CURDIR)/$(BUILD)
63+
64+
#---------------------------------------------------------------------------------
65+
# automatically build a list of object files for our project
66+
#---------------------------------------------------------------------------------
67+
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
68+
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
69+
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
70+
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
71+
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
72+
73+
#---------------------------------------------------------------------------------
74+
# use CXX for linking C++ projects, CC for standard C
75+
#---------------------------------------------------------------------------------
76+
ifeq ($(strip $(CPPFILES)),)
77+
export LD := $(CC)
78+
else
79+
export LD := $(CXX)
80+
endif
81+
82+
export OFILES := $(addsuffix .o,$(BINFILES)) \
83+
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
84+
$(sFILES:.s=.o) $(SFILES:.S=.o)
85+
86+
#---------------------------------------------------------------------------------
87+
# build a list of include paths
88+
#---------------------------------------------------------------------------------
89+
export INCLUDE := $(foreach dir,$(INCLUDES), -I$(CURDIR)/$(dir)) \
90+
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
91+
$(LIBPSL1GHT_INC) \
92+
-I$(CURDIR)/$(BUILD)
93+
94+
#---------------------------------------------------------------------------------
95+
# build a list of library paths
96+
#---------------------------------------------------------------------------------
97+
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
98+
$(LIBPSL1GHT_LIB)
99+
100+
export OUTPUT := $(CURDIR)/$(TARGET)
101+
.PHONY: $(BUILD) clean
102+
103+
#---------------------------------------------------------------------------------
104+
$(BUILD):
105+
@[ -d $@ ] || mkdir -p $@
106+
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
107+
108+
#---------------------------------------------------------------------------------
109+
clean:
110+
@echo clean ...
111+
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).self $(OUTPUT).fake.self $(OUTPUT).gnpdrm.pkg $(OUTPUT).pkg
112+
113+
114+
#---------------------------------------------------------------------------------
115+
run:
116+
ps3load $(OUTPUT).self
117+
118+
#---------------------------------------------------------------------------------
119+
pkg: $(BUILD) $(OUTPUT).pkg
120+
121+
122+
#---------------------------------------------------------------------------------
123+
else
124+
125+
DEPENDS := $(OFILES:.o=.d)
126+
127+
#---------------------------------------------------------------------------------
128+
# main targets
129+
#---------------------------------------------------------------------------------
130+
$(OUTPUT).self: $(OUTPUT).elf
131+
$(OUTPUT).elf: $(OFILES)
132+
133+
#---------------------------------------------------------------------------------
134+
# This rule links in binary data with the .bin extension
135+
#---------------------------------------------------------------------------------
136+
%.bin.o : %.bin
137+
#---------------------------------------------------------------------------------
138+
@echo $(notdir $<)
139+
@$(bin2o)
140+
141+
-include $(DEPENDS)
142+
143+
#---------------------------------------------------------------------------------
144+
endif
145+
#---------------------------------------------------------------------------------
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
A nice cairo example.
2+
3+
![Cairo Clock](https://github.com/crystalct/PS3LibrariesUpdate/blob/master/samples/cairo_clock/cairo_clock.png)
33.4 KB
Loading
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) Youness Alaoui (KaKaRoTo)
3+
*
4+
* This software is distributed under the terms of the GNU General Public
5+
* License ("GPL") version 3, as published by the Free Software Foundation.
6+
*/
7+
8+
#ifndef __RSXUTIL_H__
9+
#define __RSXUTIL_H__
10+
11+
#include <rsx/rsx.h>
12+
#include <ppu-types.h>
13+
14+
#define CB_SIZE 0x100000
15+
#define HOST_SIZE (32*1024*1024)
16+
17+
typedef struct
18+
{
19+
20+
int height;
21+
int width;
22+
int id;
23+
uint32_t *ptr;
24+
// Internal stuff
25+
uint32_t offset;
26+
} rsxBuffer;
27+
28+
29+
/* Block the PPU thread untill the previous flip operation has finished. */
30+
void waitFlip (void);
31+
/* Flip a buffer onto the screen. Returns TRUE on success */
32+
int flip (gcmContextData *context, s32 buffer);
33+
/* Create a buffer to draw into and assign it to @id. Returns NULL on error */
34+
int makeBuffer (rsxBuffer * buffer, u16 width, u16 height, int id);
35+
/* Get current screen resolution. returns TRUE on success */
36+
int getResolution (u16 *width, u16 *height);
37+
/* Initilize the RSX properly. Returns NULL on error */
38+
gcmContextData *initScreen (void *host_addr, u32 size);
39+
/* Sets the target buffer to render to */
40+
void setRenderTarget(gcmContextData *context, rsxBuffer *buffer);
41+
42+
#endif /* __RSXUTIL_H__ */
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Cairo clock sample by CrystalCT (crystal@unict.it)
2+
3+
#include <ppu-lv2.h>
4+
#include <stdio.h>
5+
#include <malloc.h>
6+
#include <string.h>
7+
#include <unistd.h>
8+
#include <io/pad.h>
9+
#include <time.h>
10+
#include <cairo/cairo.h>
11+
#include <math.h>
12+
#include <time.h>
13+
14+
#include "rsxutil.h"
15+
16+
#define MAX_BUFFERS 2
17+
18+
#define DEBUG(...)
19+
20+
u16 width;
21+
u16 height;
22+
23+
// Draw a single frame, do all your drawing/animation from in here.
24+
void
25+
drawFrame (rsxBuffer *buffer, int frame)
26+
{
27+
cairo_t *cr;
28+
cairo_surface_t *surface = NULL;
29+
30+
31+
32+
33+
34+
35+
surface = cairo_image_surface_create_for_data ((u8 *) buffer->ptr,
36+
CAIRO_FORMAT_RGB24, buffer->width, buffer->height, buffer->width * 4);
37+
38+
if (surface != NULL) {
39+
cr = cairo_create (surface);
40+
if (cr != NULL) {
41+
// Lets start by clearing everything
42+
cairo_scale(cr, height, height);
43+
cairo_translate(cr, 0.5 * width/height, 0.5);
44+
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
45+
cairo_paint (cr);
46+
47+
/* Draw what needs tobe drawn */
48+
{
49+
// ARC
50+
double xc = 0.0;
51+
double yc = 0.0;
52+
double m_radius = 0.42;
53+
double m_line_width = 0.05;
54+
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); // Black
55+
56+
cairo_set_line_width (cr, m_line_width);
57+
58+
cairo_arc (cr, xc, yc, m_radius, 0, 2 * M_PI);
59+
cairo_stroke(cr);
60+
61+
//clock ticks
62+
int i;
63+
for (i = 0; i < 12; i++)
64+
{
65+
double inset = 0.05;
66+
67+
cairo_save(cr);
68+
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
69+
70+
if(i % 3 != 0)
71+
{
72+
inset *= 0.8;
73+
cairo_set_line_width(cr, 0.03);
74+
}
75+
76+
cairo_move_to(cr,
77+
(m_radius - inset) * cos (i * M_PI / 6),
78+
(m_radius - inset) * sin (i * M_PI / 6));
79+
cairo_line_to (cr,
80+
m_radius * cos (i * M_PI / 6),
81+
m_radius * sin (i * M_PI / 6));
82+
cairo_stroke(cr);
83+
cairo_restore(cr); /* stack-pen-size */
84+
}
85+
86+
// store the current time
87+
time_t rawtime;
88+
time(&rawtime);
89+
struct tm * timeinfo = localtime (&rawtime);
90+
91+
// compute the angles of the indicators of our clock
92+
double minutes = timeinfo->tm_min * M_PI / 30;
93+
double hours = timeinfo->tm_hour * M_PI / 6;
94+
double seconds= timeinfo->tm_sec * M_PI / 30;
95+
96+
cairo_save(cr);
97+
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
98+
99+
// draw the seconds hand
100+
cairo_save(cr);
101+
cairo_set_line_width(cr, m_line_width / 3);
102+
cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); // gray
103+
cairo_move_to(cr, 0, 0);
104+
cairo_line_to(cr, sin(seconds) * (m_radius * 0.9),
105+
-cos(seconds) * (m_radius * 0.9));
106+
cairo_stroke(cr);
107+
cairo_restore(cr);
108+
109+
// draw the minutes hand
110+
cairo_set_source_rgb(cr, 0.117, 0.337, 0.612); // blue
111+
cairo_move_to(cr, 0, 0);
112+
cairo_line_to(cr, sin(minutes + seconds / 60) * (m_radius * 0.8),
113+
-cos(minutes + seconds / 60) * (m_radius * 0.8));
114+
cairo_stroke(cr);
115+
116+
// draw the hours hand
117+
cairo_set_source_rgb(cr, 0.337, 0.612, 0.117); // green
118+
cairo_move_to(cr, 0, 0);
119+
cairo_line_to(cr, sin(hours + minutes / 12.0) * (m_radius * 0.5),
120+
-cos(hours + minutes / 12.0) * (m_radius * 0.5));
121+
cairo_stroke(cr);
122+
cairo_restore(cr);
123+
124+
// draw a little dot in the middle
125+
cairo_arc(cr, 0, 0, m_line_width / 3.0, 0, 2 * M_PI);
126+
cairo_fill(cr);
127+
128+
}
129+
130+
cairo_destroy (cr); // Realease Surface
131+
}
132+
133+
cairo_surface_finish (surface);
134+
cairo_surface_destroy (surface); // Flush and destroy the cairo surface
135+
}
136+
137+
}
138+
139+
140+
141+
int
142+
main (s32 argc, const char* argv[])
143+
{
144+
gcmContextData *context;
145+
void *host_addr = NULL;
146+
rsxBuffer buffers[MAX_BUFFERS];
147+
int currentBuffer = 0;
148+
padInfo padinfo;
149+
padData paddata;
150+
151+
int frame = 0;
152+
int i;
153+
154+
/* Allocate a 1Mb buffer, alligned to a 1Mb boundary
155+
* to be our shared IO memory with the RSX. */
156+
host_addr = memalign (1024*1024, HOST_SIZE);
157+
context = initScreen (host_addr, HOST_SIZE);
158+
ioPadInit (7);
159+
160+
getResolution(&width, &height);
161+
for (i = 0; i < MAX_BUFFERS; i++)
162+
makeBuffer (&buffers[i], width, height, i);
163+
164+
flip(context, MAX_BUFFERS - 1);
165+
166+
DEBUG ("Starting Cairo test\n");
167+
168+
while (1) {
169+
ioPadGetInfo (&padinfo);
170+
for(i = 0; i < MAX_PADS; i++) {
171+
if(padinfo.status[i]) {
172+
ioPadGetData (i, &paddata);
173+
if(paddata.BTN_START) {
174+
goto end;
175+
}
176+
}
177+
}
178+
179+
setRenderTarget(context, &buffers[currentBuffer]);
180+
181+
DEBUG ("Drawing frame %d\n", frame);
182+
waitFlip ();
183+
drawFrame (&buffers[currentBuffer], frame++); // Draw into the unused buffer
184+
flip (context, buffers[currentBuffer].id); // Flip buffer onto screen
185+
186+
currentBuffer++;
187+
if (currentBuffer >= MAX_BUFFERS)
188+
currentBuffer = 0;
189+
}
190+
191+
end:
192+
193+
gcmSetWaitFlip(context);
194+
for (i = 0; i < MAX_BUFFERS; i++)
195+
rsxFree (buffers[i].ptr);
196+
197+
rsxFinish (context, 1);
198+
free (host_addr);
199+
ioPadEnd();
200+
201+
return 0;
202+
}
203+

0 commit comments

Comments
 (0)