1+ /*
2+ * PSP Software Development Kit - https://github.com/pspdev
3+ * -----------------------------------------------------------------------
4+ * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
5+ *
6+ * Copyright (c) 2024 PSP Software Development Kit Contributors
7+ *
8+ * Scissor sample - Demonstrates scissor functionality with a scanning effect
9+ */
10+
11+ #include <pspkernel.h>
12+ #include <pspdisplay.h>
13+ #include <pspdebug.h>
14+ #include <pspgu.h>
15+ #include <pspctrl.h>
16+ #include <stdlib.h>
17+ #include <string.h>
18+ #include <stdio.h>
19+ #include <math.h>
20+
21+ #include "../common/callbacks.h"
22+
23+ PSP_MODULE_INFO ("Scissor Sample" , 0 , 1 , 1 );
24+ PSP_MAIN_THREAD_ATTR (THREAD_ATTR_USER );
25+
26+ static unsigned int __attribute__((aligned (16 ))) list [262144 ];
27+
28+ #define BUF_WIDTH (512)
29+ #define SCR_WIDTH (480)
30+ #define SCR_HEIGHT (272)
31+ #define SCISSOR_SIZE (68)
32+ #define MAX_X (412) // Maximum x coordinate for our pattern
33+
34+ // Color definitions (RGBA format)
35+ #define COLOR_RED 0xFF0000FF
36+ #define COLOR_BLUE 0xFFFF0000
37+
38+ // Structure to hold scissor movement state
39+ typedef struct {
40+ int x , y ; // Current position
41+ int target_x ; // Target x position
42+ int target_y ; // Target y position
43+ int reverse ; // Whether we're in reverse mode
44+ } ScissorState ;
45+
46+ // Initialize scissor state
47+ static void init_scissor_state (ScissorState * state ) {
48+ state -> x = 0 ;
49+ state -> y = 0 ;
50+ state -> target_x = MAX_X ;
51+ state -> target_y = 0 ;
52+ state -> reverse = 0 ;
53+ }
54+
55+ // Update scissor position for the specific pattern
56+ static void update_scissor (ScissorState * state ) {
57+ // Move one pixel at a time towards target
58+ if (state -> x < state -> target_x ) {
59+ state -> x ++ ;
60+ } else if (state -> x > state -> target_x ) {
61+ state -> x -- ;
62+ }
63+
64+ if (state -> y < state -> target_y ) {
65+ state -> y ++ ;
66+ } else if (state -> y > state -> target_y ) {
67+ state -> y -- ;
68+ }
69+
70+ // If we've reached the target, set the next target
71+ if (state -> x == state -> target_x && state -> y == state -> target_y ) {
72+ if (!state -> reverse ) {
73+ // Forward pattern
74+ if (state -> x == 0 && state -> y == 0 ) {
75+ state -> target_x = MAX_X ;
76+ state -> target_y = 0 ;
77+ } else if (state -> x == MAX_X && state -> y == 0 ) {
78+ state -> target_x = MAX_X ;
79+ state -> target_y = SCISSOR_SIZE ;
80+ } else if (state -> x == MAX_X && state -> y == SCISSOR_SIZE ) {
81+ state -> target_x = 0 ;
82+ state -> target_y = SCISSOR_SIZE ;
83+ } else if (state -> x == 0 && state -> y == SCISSOR_SIZE ) {
84+ state -> target_x = 0 ;
85+ state -> target_y = SCISSOR_SIZE * 2 ;
86+ } else if (state -> x == 0 && state -> y == SCISSOR_SIZE * 2 ) {
87+ state -> target_x = MAX_X ;
88+ state -> target_y = SCISSOR_SIZE * 2 ;
89+ } else if (state -> x == MAX_X && state -> y == SCISSOR_SIZE * 2 ) {
90+ state -> target_x = MAX_X ;
91+ state -> target_y = SCISSOR_SIZE * 3 ;
92+ } else if (state -> x == MAX_X && state -> y == SCISSOR_SIZE * 3 ) {
93+ state -> target_x = 0 ;
94+ state -> target_y = SCISSOR_SIZE * 3 ;
95+ } else if (state -> x == 0 && state -> y == SCISSOR_SIZE * 3 ) {
96+ // Start reverse pattern
97+ state -> reverse = 1 ;
98+ state -> target_x = MAX_X ;
99+ state -> target_y = SCISSOR_SIZE * 3 ;
100+ }
101+ } else {
102+ // Reverse pattern
103+ if (state -> x == MAX_X && state -> y == SCISSOR_SIZE * 3 ) {
104+ state -> target_x = MAX_X ;
105+ state -> target_y = SCISSOR_SIZE * 2 ;
106+ } else if (state -> x == MAX_X && state -> y == SCISSOR_SIZE * 2 ) {
107+ state -> target_x = 0 ;
108+ state -> target_y = SCISSOR_SIZE * 2 ;
109+ } else if (state -> x == 0 && state -> y == SCISSOR_SIZE * 2 ) {
110+ state -> target_x = 0 ;
111+ state -> target_y = SCISSOR_SIZE ;
112+ } else if (state -> x == 0 && state -> y == SCISSOR_SIZE ) {
113+ state -> target_x = MAX_X ;
114+ state -> target_y = SCISSOR_SIZE ;
115+ } else if (state -> x == MAX_X && state -> y == SCISSOR_SIZE ) {
116+ state -> target_x = MAX_X ;
117+ state -> target_y = 0 ;
118+ } else if (state -> x == MAX_X && state -> y == 0 ) {
119+ state -> target_x = 0 ;
120+ state -> target_y = 0 ;
121+ } else if (state -> x == 0 && state -> y == 0 ) {
122+ // Start over
123+ state -> reverse = 0 ;
124+ state -> target_x = MAX_X ;
125+ state -> target_y = 0 ;
126+ }
127+ }
128+ }
129+ }
130+
131+ int main (int argc , char * argv [])
132+ {
133+ pspDebugScreenInit ();
134+ setupCallbacks ();
135+
136+ // Setup GU
137+ void * fbp0 = guGetStaticVramBuffer (BUF_WIDTH , SCR_HEIGHT , GU_PSM_8888 );
138+ void * fbp1 = guGetStaticVramBuffer (BUF_WIDTH , SCR_HEIGHT , GU_PSM_8888 );
139+
140+ sceGuInit ();
141+ sceGuStart (GU_DIRECT , list );
142+ sceGuDrawBuffer (GU_PSM_8888 , fbp0 , BUF_WIDTH );
143+ sceGuDispBuffer (SCR_WIDTH , SCR_HEIGHT , fbp1 , BUF_WIDTH );
144+ sceGuOffset (2048 - (SCR_WIDTH /2 ), 2048 - (SCR_HEIGHT /2 ));
145+ sceGuViewport (2048 , 2048 , SCR_WIDTH , SCR_HEIGHT );
146+ sceGuScissor (0 , 0 , SCR_WIDTH , SCR_HEIGHT );
147+ sceGuEnable (GU_SCISSOR_TEST );
148+ sceGuFinish ();
149+ sceGuSync (GU_SYNC_FINISH , GU_SYNC_WHAT_DONE );
150+
151+ sceDisplayWaitVblankStart ();
152+ sceGuDisplay (GU_TRUE );
153+
154+ // Initialize scissor state
155+ ScissorState scissor ;
156+ init_scissor_state (& scissor );
157+
158+ // Main loop
159+ while (running ())
160+ {
161+ sceGuStart (GU_DIRECT , list );
162+
163+ // Clear screen to red
164+ sceGuClearColor (COLOR_RED );
165+ sceGuClear (GU_COLOR_BUFFER_BIT );
166+
167+ // Update scissor position
168+ update_scissor (& scissor );
169+
170+ // Enable scissor test and set new scissor area
171+ sceGuEnable (GU_SCISSOR_TEST );
172+ sceGuScissor (scissor .x , scissor .y , SCISSOR_SIZE , SCISSOR_SIZE );
173+ // sceGuScissor(0, 0, SCISSOR_SIZE, SCISSOR_SIZE);
174+
175+ // Draw blue rectangle in scissor area
176+ sceGuClearColor (COLOR_BLUE );
177+ sceGuClear (GU_COLOR_BUFFER_BIT );
178+
179+ // Disable scissor test for next frame
180+ sceGuDisable (GU_SCISSOR_TEST );
181+
182+ sceGuFinish ();
183+ sceGuSync (GU_SYNC_FINISH , GU_SYNC_WHAT_DONE );
184+
185+ pspDebugScreenSetOffset ((int )fbp0 );
186+ pspDebugScreenSetXY (0 ,0 );
187+ pspDebugScreenPrintf ("Scissor: (%d, %d), (%d, %d)" ,
188+ scissor .x , scissor .y ,
189+ scissor .x + SCISSOR_SIZE , scissor .y + SCISSOR_SIZE );
190+
191+ sceDisplayWaitVblankStart ();
192+ fbp0 = sceGuSwapBuffers ();
193+ }
194+
195+ sceGuTerm ();
196+ return 0 ;
197+ }
0 commit comments