⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_pixels.cpp

📁 SDL pixels operation, all sdl games needed it
💻 CPP
字号:
#include <SDL.h>
#include <SDL_endian.h>	/* 僄儞僨傿傾儞偵埶懚偟側偄 24bpp 儌乕僪偺帪偵巊傢傟傞 */
#include "SDL_Draw.h"
#include <stdlib.h>

typedef struct point_st{
	int x, y;
} point_t;

static void SDL_PutPixel(SDL_Surface *screen,
	int x, int y,
	Uint32 color){
	switch(screen->format->BytesPerPixel){
	case 1:{
		Uint8 *bufp;

		bufp = (Uint8 *)screen->pixels + y * screen->pitch + x;
		*bufp = color;
		break;
	}

	case 2:{
		Uint16 *bufp;

		bufp = (Uint16 *)screen->pixels + y * screen->pitch / 2 + x;
		*bufp = color;
		break;
	}

	case 3:{
		Uint8 *bufp;

		bufp = (Uint8 *)screen->pixels + y * screen->pitch + x * 3;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		bufp[0] = color;
		bufp[1] = color >> 8;
		bufp[2] = color >> 16;
#else
		bufp[2] = color;
		bufp[1] = color >> 8;
		bufp[0] = color >> 16;
#endif
		break;
	}

	case 4:{
		Uint32 *bufp;

		bufp = (Uint32 *)screen->pixels + y * screen->pitch / 4 + x;
		*bufp = color;
		break;
	}
	}
}

static Uint32 SDL_GetPixel(SDL_Surface *screen,
	int x, int y){
	Uint32 color = 0;
	switch(screen->format->BytesPerPixel){
	case 1:{
		Uint8 *bufp;

		bufp = (Uint8 *)screen->pixels + y * screen->pitch + x;
		color = *bufp;
		break;
	}

	case 2:{
		Uint16 *bufp;

		bufp = (Uint16 *)screen->pixels + y * screen->pitch / 2 + x;
		color = *bufp;
		break;
	}

	case 3:{
		Uint8 *bufp;

		bufp = (Uint8 *)screen->pixels + y * screen->pitch + x * 3;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		color = bufp[0] | (bufp[1] << 8) | (bufp[2] << 16);
#else
		color = bufp[2] | (bufp[1] << 8) | (bufp[0] << 16);
#endif
		break;
	}

	case 4:{
		Uint32 *bufp;

		bufp = (Uint32 *)screen->pixels + y * screen->pitch / 4 + x;
		color = *bufp;
		break;
	}
	}
	return color;
}

void SDL_DrawPixel(SDL_Surface *screen,
	int x, int y,
	Uint8 R, Uint8 G, Uint8 B){
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);

	if(SDL_MUSTLOCK(screen)){
		if(SDL_LockSurface(screen) < 0){
			return;
		}
	}

	SDL_PutPixel(screen, x, y, color);

	if(SDL_MUSTLOCK(screen)){
		SDL_UnlockSurface(screen);
	}
}

void SDL_DrawLine(SDL_Surface *screen,
	int x1, int y1,
	int x2, int y2,
	Uint8 R, Uint8 G, Uint8 B){
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);

	int dx, dy, dx2, dy2;
	int sx, sy;
	int i, l;
	int e;

	if( (x1 < 0) | (screen->w <= x1) |
	    (x2 < 0) | (screen->w <= x2) |
	    (y1 < 0) | (screen->h <= y1) |
	    (y2 < 0) | (screen->h <= y2))
		return;

	if(SDL_MUSTLOCK(screen)){
		if(SDL_LockSurface(screen) < 0){
			return;
		}
	}

	dx = x2 - x1 < 0 ? x1 - x2 : x2 - x1;
	dy = y2 - y1 < 0 ? y1 - y2 : y2 - y1;
	sx = x2 - x1 < 0 ? -1 : 1;
	sy = y2 - y1 < 0 ? -1 : 1;
	dx2 = dx * 2;
	dy2 = dy * 2;

	if(x1 == x2){
		if(y1 < y2){
			for(i = y1;i < y2;i++){
				SDL_PutPixel(screen, x1, i, color);
			}
		}
		else{
			for(i = y2;i < y1;i++){
				SDL_PutPixel(screen, x1, i, color);
			}
		}
	}
	else if(y1 == y2){
		if(x1 < x2){
			for(i = x1;i < x2;i++){
				SDL_PutPixel(screen, i, y1, color);
			}
		}
		else{
			for(i = x2;i < x1;i++){
				SDL_PutPixel(screen, i, y1, color);
			}
		}
	}
	else if(dx >= dy){
		e = -dx;
		l = (dx + 1) / 2;
		for(i = 0;i < l;i++){
			SDL_PutPixel(screen, x1, y1, color);
			SDL_PutPixel(screen, x2, y2, color);
			x1 += sx;
			x2 -= sx;
			e += dy2;
			if(e >= 0){
				y1 += sy;
				y2 -= sy;
				e -= dx2;
			}
		}
		if(dx % 2 == 0)
			SDL_PutPixel(screen, x1, y1, color);
	}
	else{
		e = -dy;
		l = (dy + 1) / 2;
		for(i = 0;i < l;i++){
			SDL_PutPixel(screen, x1, y1, color);
			SDL_PutPixel(screen, x2, y2, color);
			y1 += sy;
			y2 -= sy;
			e += dx2;
			if(e >= 0){
				x1 += sx;
				x2 -= sx;
				e -= dy2;
			}
		}
		if(dy % 2 == 0)
			SDL_PutPixel(screen, x1, y1, color);
	}

	if(SDL_MUSTLOCK(screen)){
		SDL_UnlockSurface(screen);
	}
}

void DrawBox(SDL_Surface *screen,
	int x1, int y1,
	int x2, int y2,
	Uint8 R, Uint8 G, Uint8 B){
	SDL_DrawLine(screen, x1, y1, x2, y1, R, G, B);
	SDL_DrawLine(screen, x2, y1, x2, y2, R, G, B);
	SDL_DrawLine(screen, x2, y2, x1, y2, R, G, B);
	SDL_DrawLine(screen, x1, y2, x1, y1, R, G, B);
}

void SDL_DrawCircle(SDL_Surface *screen,
	int x1, int y1,
	int x2, int y2,
	Uint8 R, Uint8 G, Uint8 B){
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);

	int r;
	int dx, dy;
	int xa, ya, xb, yb;
	int f;

	if( (x1 < 0) | (screen->w <= x1) |
	    (x2 < 0) | (screen->w <= x2) |
	    (y1 < 0) | (screen->h <= y1) |
	    (y2 < 0) | (screen->h <= y2))
		return;
	if(x1 == x2 && y1 == y2)
		return;

	if(SDL_MUSTLOCK(screen)){
		if(SDL_LockSurface(screen) < 0){
			return;
		}
	}

	if(x1 > x2){
		int tmp = x2;
		x2 = x1;
		x1 = tmp;
	}
	if(y1 > y2){
		int tmp = y2;
		y2 = y1;
		y1 = tmp;
	}

	dx = x2 - x1 < 0 ? x1 - x2 : x2 - x1;
	dy = y2 - y1 < 0 ? y1 - y2 : y2 - y1;
	if(dx >= dy){
		r = dx / 2;
		xa = r;
		ya = 0;
		f = 3 - 2 * r;
		x1 += dx / 2;
		y1 += dy / 2;
		x2 = x1 + dx % 2;
		y2 = y1 + dy % 2;
		while(xa >= ya){
			xb = (xa * dy) / dx;
			yb = (ya * dy) / dx;
			SDL_PutPixel(screen, xa + x2,-yb + y1, color); /*A*/
			SDL_PutPixel(screen, ya + x2,-xb + y1, color); /*B*/
			SDL_PutPixel(screen,-ya + x1,-xb + y1, color); /*C*/
			SDL_PutPixel(screen,-xa + x1,-yb + y1, color); /*D*/
			SDL_PutPixel(screen,-xa + x1, yb + y2, color); /*E*/
			SDL_PutPixel(screen,-ya + x1, xb + y2, color); /*F*/
			SDL_PutPixel(screen, ya + x2, xb + y2, color); /*G*/
			SDL_PutPixel(screen, xa + x2, yb + y2, color); /*H*/
			if(f >= 0){
				xa--;
				f -= 4 * xa;
			}
			ya++;
			f += 4 * ya + 2;
		}
	}
	else{
		r = dy / 2;
		ya = r;
		xa = 0;
		f = 3 - 2 * r;
		x1 += dx / 2;
		y1 += dy / 2;
		x2 = x1 + dx % 2;
		y2 = y1 + dy % 2;
		while(ya >= xa){
			xb = (xa * dx) / dy;
			yb = (ya * dx) / dy;
			SDL_PutPixel(screen, xb + x2,-ya + y1, color); /*A*/
			SDL_PutPixel(screen, yb + x2,-xa + y1, color); /*B*/
			SDL_PutPixel(screen,-yb + x1,-xa + y1, color); /*C*/
			SDL_PutPixel(screen,-xb + x1,-ya + y1, color); /*D*/
			SDL_PutPixel(screen,-xb + x1, ya + y2, color); /*E*/
			SDL_PutPixel(screen,-yb + x1, xa + y2, color); /*F*/
			SDL_PutPixel(screen, yb + x2, xa + y2, color); /*G*/
			SDL_PutPixel(screen, xb + x2, ya + y2, color); /*H*/
			if(f >= 0){
				ya--;
				f -= 4 * ya;
			}
			xa++;
			f += 4 * xa + 2;
		}
	}

	if(SDL_MUSTLOCK(screen)){
		SDL_UnlockSurface(screen);
	}
}

void SDL_DrawPaint(SDL_Surface *screen,
	int x, int y,
	Uint8 R, Uint8 G, Uint8 B){
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);

	point_t *buffer;
	int pbuf;
	Uint32 bcol;
	int i;
	int bx1,bx2,by;

	if( (x < 0) | (screen->w <= x) |
	    (y < 0) | (screen->h <= y))
		return;

	buffer = malloc(sizeof(point_t) * (screen->w + 1));
	if(buffer == NULL)
		return;

	if(SDL_MUSTLOCK(screen)){
		if(SDL_LockSurface(screen) < 0){
			free(buffer);
			return;
		}
	}

	bcol = SDL_GetPixel(screen, x, y);
	if(bcol == color){
		if(SDL_MUSTLOCK(screen)){
			SDL_UnlockSurface(screen);
		}
		free(buffer);
		return;
	}
	buffer[0].x = x;
	buffer[0].y = y;
	pbuf = 1;
	while(pbuf){
		pbuf--;
		bx1 = bx2 = buffer[pbuf].x;
		by = buffer[pbuf].y;
		while(bx1 >= 0 && SDL_GetPixel(screen, bx1, by) == bcol)
			bx1--;
		while(bx2 < screen->w && SDL_GetPixel(screen, bx2, by) == bcol)
			bx2++;
		bx1++;
		bx2--;
		for(i = bx1;i <= bx2;i++)
			SDL_PutPixel(screen, i, by, color);
		if(by > 0){
			i = bx1;
			by--;
			if(SDL_GetPixel(screen, i, by) == bcol){
				while(i >= 0 && SDL_GetPixel(screen, i, by) == bcol)
					i--;
				i++;
			}
			else
				while(i <= bx2 && SDL_GetPixel(screen, i, by) != bcol)
					i++;
			while(i <= bx2){
				buffer[pbuf].x = i;
				buffer[pbuf].y = by;
				pbuf++;
				while(i < screen->w && SDL_GetPixel(screen, i, by) == bcol)
					i++;
				while(i <= bx2 && SDL_GetPixel(screen, i, by) != bcol)
					i++;
			}
		}
		else
			by--;
		if(by + 2 < screen->h){
			i = bx1;
			by += 2;
			if(SDL_GetPixel(screen, i, by) == bcol){
				while(i >= 0 && SDL_GetPixel(screen, i, by) == bcol)
					i--;
				i++;
			}
			else
				while(i <= bx2 && SDL_GetPixel(screen, i, by) != bcol)
					i++;
			while(i <= bx2){
				buffer[pbuf].x = i;
				buffer[pbuf].y = by;
				pbuf++;
				while(i < screen->w && SDL_GetPixel(screen, i, by) == bcol)
					i++;
				while( i <= bx2 && SDL_GetPixel(screen, i, by) != bcol)
					i++;
			}
		}
	}

	if(SDL_MUSTLOCK(screen)){
		SDL_UnlockSurface(screen);
	}
	free(buffer);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -