mirror of
				https://github.com/thunderbrewhq/thunderbrew
				synced 2025-10-31 00:06:05 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  touch.c
 | |
|  *  written by Holmes Futrell
 | |
|  *  use however you want
 | |
|  */
 | |
| 
 | |
| #include "SDL.h"
 | |
| #include <math.h>
 | |
| #include "common.h"
 | |
| 
 | |
| #define BRUSH_SIZE 32           /* width and height of the brush */
 | |
| #define PIXELS_PER_ITERATION 5  /* number of pixels between brush blots when forming a line */
 | |
| 
 | |
| static SDL_Texture *brush = 0;       /* texture for the brush */
 | |
| 
 | |
| /*
 | |
|     draws a line from (startx, starty) to (startx + dx, starty + dy)
 | |
|     this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart
 | |
| */
 | |
| void
 | |
| drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy)
 | |
| {
 | |
| 
 | |
|     float distance = SDL_sqrt(dx * dx + dy * dy);   /* length of line segment (pythagoras) */
 | |
|     int iterations = distance / PIXELS_PER_ITERATION + 1;       /* number of brush sprites to draw for the line */
 | |
|     float dx_prime = dx / iterations;   /* x-shift per iteration */
 | |
|     float dy_prime = dy / iterations;   /* y-shift per iteration */
 | |
|     SDL_Rect dstRect;           /* rect to draw brush sprite into */
 | |
|     float x;
 | |
|     float y;
 | |
|     int i;
 | |
| 
 | |
|     dstRect.w = BRUSH_SIZE;
 | |
|     dstRect.h = BRUSH_SIZE;
 | |
| 
 | |
|     /* setup x and y for the location of the first sprite */
 | |
|     x = startx - BRUSH_SIZE / 2.0f;
 | |
|     y = starty - BRUSH_SIZE / 2.0f;
 | |
| 
 | |
|     /* draw a series of blots to form the line */
 | |
|     for (i = 0; i < iterations; i++) {
 | |
|         dstRect.x = x;
 | |
|         dstRect.y = y;
 | |
|         /* shift x and y for next sprite location */
 | |
|         x += dx_prime;
 | |
|         y += dy_prime;
 | |
|         /* draw brush blot */
 | |
|         SDL_RenderCopy(renderer, brush, NULL, &dstRect);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|     loads the brush texture
 | |
| */
 | |
| void
 | |
| initializeTexture(SDL_Renderer *renderer)
 | |
| {
 | |
|     SDL_Surface *bmp_surface;
 | |
|     bmp_surface = SDL_LoadBMP("stroke.bmp");
 | |
|     if (!bmp_surface) {
 | |
|         fatalError("could not load stroke.bmp");
 | |
|     }
 | |
|     brush =
 | |
|         SDL_CreateTextureFromSurface(renderer, bmp_surface);
 | |
|     SDL_FreeSurface(bmp_surface);
 | |
|     if (!brush) {
 | |
|         fatalError("could not create brush texture");
 | |
|     }
 | |
|     /* additive blending -- laying strokes on top of eachother makes them brighter */
 | |
|     SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD);
 | |
|     /* set brush color (red) */
 | |
|     SDL_SetTextureColorMod(brush, 255, 100, 100);
 | |
| }
 | |
| 
 | |
| int
 | |
| main(int argc, char *argv[])
 | |
| {
 | |
| 
 | |
|     int x, y, dx, dy;           /* mouse location          */
 | |
|     Uint8 state;                /* mouse (touch) state */
 | |
|     SDL_Event event;
 | |
|     SDL_Window *window;         /* main window */
 | |
|     SDL_Renderer *renderer;
 | |
|     SDL_Texture *target;
 | |
|     int done;                   /* does user want to quit? */
 | |
|     int w, h;
 | |
| 
 | |
|     /* initialize SDL */
 | |
|     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
 | |
|         fatalError("Could not initialize SDL");
 | |
|     }
 | |
| 
 | |
|     /* create main window and renderer */
 | |
|     window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
 | |
|     renderer = SDL_CreateRenderer(window, 0, 0);
 | |
| 
 | |
|     SDL_GetWindowSize(window, &w, &h);
 | |
|     SDL_RenderSetLogicalSize(renderer, w, h);
 | |
| 
 | |
|     /* load brush texture */
 | |
|     initializeTexture(renderer);
 | |
| 
 | |
|     /* fill canvass initially with all black */
 | |
|     target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h);
 | |
|     SDL_SetRenderTarget(renderer, target);
 | |
|     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
 | |
|     SDL_RenderClear(renderer);
 | |
|     SDL_SetRenderTarget(renderer, NULL);
 | |
| 
 | |
|     done = 0;
 | |
|     while (!done) {
 | |
|         while (SDL_PollEvent(&event) == 1) {
 | |
|             switch (event.type) {
 | |
|             case SDL_QUIT:
 | |
|                 done = 1;
 | |
|                 break;
 | |
|             case SDL_MOUSEMOTION:
 | |
|                 state = SDL_GetMouseState(&x, &y);  /* get its location */
 | |
|                 SDL_GetRelativeMouseState(&dx, &dy);        /* find how much the mouse moved */
 | |
|                 if (state & SDL_BUTTON_LMASK) {     /* is the mouse (touch) down? */
 | |
|                     SDL_SetRenderTarget(renderer, target);
 | |
|                     drawLine(renderer, x - dx, y - dy, dx, dy);       /* draw line segment */
 | |
|                     SDL_SetRenderTarget(renderer, NULL);
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         SDL_RenderCopy(renderer, target, NULL, NULL);
 | |
|         SDL_RenderPresent(renderer);
 | |
|     }
 | |
| 
 | |
|     /* cleanup */
 | |
|     SDL_DestroyTexture(brush);
 | |
|     SDL_DestroyTexture(target);
 | |
|     SDL_Quit();
 | |
| 
 | |
|     return 0;
 | |
| }
 | 
