File: surface_provider.cpp

package info (click to toggle)
clanlib 0.5.4-1-6
  • links: PTS
  • area: main
  • in suites: woody
  • size: 10,320 kB
  • ctags: 10,893
  • sloc: cpp: 76,056; xml: 3,281; sh: 2,961; perl: 1,204; asm: 837; makefile: 775
file content (219 lines) | stat: -rw-r--r-- 4,602 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
	Small application demonstrating how to write a surface provider.
*/

#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>

class OurSurfaceProvider : public CL_SurfaceProvider
{
public:
	OurSurfaceProvider();
	virtual ~OurSurfaceProvider();

	virtual unsigned int get_pitch() const;
	virtual unsigned int get_width() const;
	virtual unsigned int get_height() const;
	virtual unsigned int get_num_frames() const;
	virtual unsigned int get_depth() const;
	virtual unsigned int get_red_mask() const;
	virtual unsigned int get_green_mask() const;
	virtual unsigned int get_blue_mask() const;
	virtual unsigned int get_alpha_mask() const;
	virtual bool is_indexed() const;
	virtual CL_Palette *get_palette() const;
	virtual bool uses_src_colorkey() const;
	virtual unsigned int get_src_colorkey() const;
	virtual void *get_data() const;
	virtual void lock();
	virtual void unlock();

private:
	int lock_refs;
	unsigned char *buffer;
};

class SurfaceProviderApp : public CL_ClanApplication
{
public:
	virtual char *get_title() { return "SurfaceProvider application"; }

	virtual int main(int, char **)
	{
		// Create a console window for text-output if not available
		CL_ConsoleWindow console("Console");
		console.redirect_stdio();

		try
		{
			CL_SetupCore::init();
			CL_SetupDisplay::init();

			// Set mode: 320x240 16 bpp
			CL_Display::set_videomode(320, 240, 16, false);
			
			CL_Surface *surface = CL_Surface::create(
				new OurSurfaceProvider,
				true); // true -> delete surfaceprovider when surface is deleted
			
			// Loop until the user hits escape:
			while (CL_Keyboard::get_keycode(CL_KEY_ESCAPE) == false)
			{
				// Draw the surface:
				surface->put_screen(0, 0);
				
				//improve response
				CL_System::sleep(10);
				
				// Flip front and backbuffer. This makes the changes visible:
				CL_Display::flip_display();
				
				// Update keyboard input and handle system events:
				CL_System::keep_alive();
			}

			CL_SetupDisplay::deinit();
			CL_SetupCore::deinit();
		}
		catch (CL_Error err)
		{
			std::cout << "Error: " << err.message.c_str() << std::endl;

			// Display console close message and wait for a key
			console.display_close_message();

			return -1;
		}

		return 0;
	}
} app;


OurSurfaceProvider::OurSurfaceProvider()
{
	buffer = NULL;
	lock_refs = 0;
}

OurSurfaceProvider::~OurSurfaceProvider()
{
	delete[] buffer;
}

/* The next functions return the properties of our surface
*/

unsigned int OurSurfaceProvider::get_pitch() const
{
	return 4*get_width();
}

unsigned int OurSurfaceProvider::get_width() const
{
	return 320;
}

unsigned int OurSurfaceProvider::get_height() const
{
	return 240;
}

unsigned int OurSurfaceProvider::get_num_frames() const
{
	return 1;
}

unsigned int OurSurfaceProvider::get_depth() const
{
	return 32;
}

unsigned int OurSurfaceProvider::get_red_mask() const
{
	if (CL_Endian::is_system_big()) return 0x000000ff;
	return 0xff000000;
}

unsigned int OurSurfaceProvider::get_green_mask() const
{
	if (CL_Endian::is_system_big()) return 0x0000ff00;
	return 0x00ff0000;
}

unsigned int OurSurfaceProvider::get_blue_mask() const
{
	if (CL_Endian::is_system_big()) return 0x00ff0000;
	return 0x0000ff00;
}

unsigned int OurSurfaceProvider::get_alpha_mask() const
{
	if (CL_Endian::is_system_big()) return 0xff000000;
	return 0x000000ff;
}

bool OurSurfaceProvider::is_indexed() const
{
	return false;
}

CL_Palette *OurSurfaceProvider::get_palette() const
{
	return NULL; // no palette used by our surface provider.
}

bool OurSurfaceProvider::uses_src_colorkey() const
{
	return false;
}

unsigned int OurSurfaceProvider::get_src_colorkey() const
{
	return 0; // no source colorkey (single color transparency) used.
}

void *OurSurfaceProvider::get_data() const
{
	return buffer;
}

void OurSurfaceProvider::lock()
{
	// If the buffer has not been locked yet?
	if (lock_refs == 0)
	{
		// Create a new buffer
		buffer = new unsigned char[get_pitch()*get_height()];
		
		// And start filling it with data
		for (int y=0; y<240; y++)
		{
			for (int x=0; x<320; x++)
			{
				buffer[(x+y*320)*4 + 0] = 255; // alpha component of pixel
				buffer[(x+y*320)*4 + 1] =   x; // blue component
				buffer[(x+y*320)*4 + 2] =   y; // green component
				buffer[(x+y*320)*4 + 3] = x+y; // red component
			}
		}
	}
	
	// Increase the lock reference counter
	lock_refs++;
}

void OurSurfaceProvider::unlock()
{
	// Decrease the lock reference counter
	lock_refs--;

	// And if nobody uses the surface
	if (lock_refs == 0)
	{
		// Cleanup allocated memory
		delete[] buffer;
		buffer = NULL;
	}
}