Skip to content

Instantly share code, notes, and snippets.

@JuneParkCode
Last active September 7, 2022 10:42
Show Gist options
  • Save JuneParkCode/ec1bbb9c6d0f1eda34dcc9206e856af0 to your computer and use it in GitHub Desktop.
Save JuneParkCode/ec1bbb9c6d0f1eda34dcc9206e856af0 to your computer and use it in GitHub Desktop.
아름다운 gradation
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* keyboard_handler.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sungjpar <sungjpar@student.42seoul.kr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/09/01 13:40:57 by minkyeki #+# #+# */
/* Updated: 2022/09/07 19:35:13 by sungjpar ### ########seoul.kr */
/* */
/* ************************************************************************** */
#include <stdio.h>
#include "gl_color.h"
#include "gl_device.h"
#include "gl_draw.h"
#include "gl_engine.h"
#include "gl_input.h"
#include "gl_keymap_macos.h"
#include "libbmp.h"
extern int input_key_get_index(int key_code);
int handle_key_press(int key_code, void *param)
{
t_device *device;
int key_index;
device = param;
printf("(key pressed): keycode = %d\n", key_code);
if (key_code == KEY_ESC)
{
printf("ESC pressed\n");
engine_exit(device, SUCCESS);
}
else if (key_code == KEY_S)
{
gl_draw_background(&device->viewport, BLACK);
}
else if (key_code == KEY_A)
{
bmp_img img;
t_image *_image = &(device->viewport);
bmp_img_init_df(&img, device->viewport.width, device->viewport.height);
for (int _x = 0; _x < device->viewport.width; ++_x)
{
for (int _y = 0; _y < device->viewport.height; ++_y)
{
char *pixel = _image->addr + (_y * _image->line_length \
+ _x * (_image->bits_per_pixel / 8));
unsigned int *color = (unsigned int *)pixel;
const unsigned char r = gl_color_get_red(*color);
const unsigned char g = gl_color_get_green(*color);
const unsigned char b = gl_color_get_blue(*color);
bmp_pixel_init(&img.img_pixels[_y][_x], r, g, b);
}
}
bmp_img_write (&img, "test.bmp");
bmp_img_free (&img);
}
else
{
key_index = input_key_get_index(key_code);
if (key_index != -1)
{
device->input.key_state[key_index] = E_INPUT_IS_PRESSED;
}
}
return (0);
}
int handle_key_release(int key_code, void *param)
{
t_device *device;
int key_index;
device = param;
printf("key released\n");
key_index = input_key_get_index(key_code);
if (key_index != -1)
{
device->input.key_state[key_index] = E_INPUT_UN_PRESSED;
}
return (0);
}
/* Copyright 2016 - 2017 Marc Volker Dickmann
* Project: LibBMP
*/
#include <stdio.h>
#include <stdlib.h>
#include "libbmp.h"
// BMP_HEADER
void
bmp_header_init_df (bmp_header *header,
const int width,
const int height)
{
header->bfSize = (sizeof (bmp_pixel) * width + BMP_GET_PADDING (width))
* abs (height);
header->bfReserved = 0;
header->bfOffBits = 54;
header->biSize = 40;
header->biWidth = width;
header->biHeight = height;
header->biPlanes = 1;
header->biBitCount = 24;
header->biCompression = 0;
header->biSizeImage = 0;
header->biXPelsPerMeter = 0;
header->biYPelsPerMeter = 0;
header->biClrUsed = 0;
header->biClrImportant = 0;
}
enum bmp_error
bmp_header_write (const bmp_header *header,
FILE *img_file)
{
if (header == NULL)
{
return BMP_HEADER_NOT_INITIALIZED;
}
else if (img_file == NULL)
{
return BMP_FILE_NOT_OPENED;
}
// Since an adress must be passed to fwrite, create a variable!
const unsigned short magic = BMP_MAGIC;
fwrite (&magic, sizeof (magic), 1, img_file);
// Use the type instead of the variable because its a pointer!
fwrite (header, sizeof (bmp_header), 1, img_file);
return BMP_OK;
}
enum bmp_error
bmp_header_read (bmp_header *header,
FILE *img_file)
{
if (img_file == NULL)
{
return BMP_FILE_NOT_OPENED;
}
// Since an adress must be passed to fread, create a variable!
unsigned short magic;
// Check if its an bmp file by comparing the magic nbr:
if (fread (&magic, sizeof (magic), 1, img_file) != 1 ||
magic != BMP_MAGIC)
{
return BMP_INVALID_FILE;
}
if (fread (header, sizeof (bmp_header), 1, img_file) != 1)
{
return BMP_ERROR;
}
return BMP_OK;
}
// BMP_PIXEL
void
bmp_pixel_init (bmp_pixel *pxl,
const unsigned char red,
const unsigned char green,
const unsigned char blue)
{
pxl->red = red;
pxl->green = green;
pxl->blue = blue;
}
// BMP_IMG
void
bmp_img_alloc (bmp_img *img)
{
const size_t h = abs (img->img_header.biHeight);
// Allocate the required memory for the pixels:
img->img_pixels = malloc (sizeof (bmp_pixel*) * h);
for (size_t y = 0; y < h; y++)
{
img->img_pixels[y] = malloc (sizeof (bmp_pixel) * img->img_header.biWidth);
}
}
void
bmp_img_init_df (bmp_img *img,
const int width,
const int height)
{
// INIT the header with default values:
bmp_header_init_df (&img->img_header, width, height);
bmp_img_alloc (img);
}
void
bmp_img_free (bmp_img *img)
{
const size_t h = abs (img->img_header.biHeight);
for (size_t y = 0; y < h; y++)
{
free (img->img_pixels[y]);
}
free (img->img_pixels);
}
enum bmp_error
bmp_img_write (const bmp_img *img,
const char *filename)
{
FILE *img_file = fopen (filename, "wb");
if (img_file == NULL)
{
return BMP_FILE_NOT_OPENED;
}
// NOTE: This way the correct error code could be returned.
const enum bmp_error err = bmp_header_write (&img->img_header, img_file);
if (err != BMP_OK)
{
// ERROR: Could'nt write the header!
fclose (img_file);
return err;
}
// Select the mode (bottom-up or top-down):
const size_t h = abs (img->img_header.biHeight);
const size_t offset = (img->img_header.biHeight > 0 ? h - 1 : 0);
// Create the padding:
const unsigned char padding[3] = {'\0', '\0', '\0'};
// Write the content:
for (size_t y = 0; y < h; y++)
{
// Write a whole row of pixels to the file:
fwrite (img->img_pixels[abs (offset - y)], sizeof (bmp_pixel), img->img_header.biWidth, img_file);
// Write the padding for the row!
fwrite (padding, sizeof (unsigned char), BMP_GET_PADDING (img->img_header.biWidth), img_file);
}
// NOTE: All good!
fclose (img_file);
return BMP_OK;
}
enum bmp_error
bmp_img_read (bmp_img *img,
const char *filename)
{
FILE *img_file = fopen (filename, "rb");
if (img_file == NULL)
{
return BMP_FILE_NOT_OPENED;
}
// NOTE: This way the correct error code can be returned.
const enum bmp_error err = bmp_header_read (&img->img_header, img_file);
if (err != BMP_OK)
{
// ERROR: Could'nt read the image header!
fclose (img_file);
return err;
}
bmp_img_alloc (img);
// Select the mode (bottom-up or top-down):
const size_t h = abs (img->img_header.biHeight);
const size_t offset = (img->img_header.biHeight > 0 ? h - 1 : 0);
const size_t padding = BMP_GET_PADDING (img->img_header.biWidth);
// Needed to compare the return value of fread
const size_t items = img->img_header.biWidth;
// Read the content:
for (size_t y = 0; y < h; y++)
{
// Read a whole row of pixels from the file:
if (fread (img->img_pixels[abs (offset - y)], sizeof (bmp_pixel), items, img_file) != items)
{
fclose (img_file);
return BMP_ERROR;
}
// Skip the padding:
fseek (img_file, padding, SEEK_CUR);
}
// NOTE: All good!
fclose (img_file);
return BMP_OK;
}
#ifndef __LIBBMP_H__
#define __LIBBMP_H__
#define BMP_MAGIC 19778
#define BMP_GET_PADDING(a) ((a) % 4)
#include <stdio.h>
enum bmp_error
{
BMP_FILE_NOT_OPENED = -4,
BMP_HEADER_NOT_INITIALIZED,
BMP_INVALID_FILE,
BMP_ERROR,
BMP_OK = 0
};
typedef struct _bmp_header
{
unsigned int bfSize;
unsigned int bfReserved;
unsigned int bfOffBits;
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} bmp_header;
typedef struct _bmp_pixel
{
unsigned char blue;
unsigned char green;
unsigned char red;
} bmp_pixel;
// This is faster than a function call
#define BMP_PIXEL(r,g,b) ((bmp_pixel){(b),(g),(r)})
typedef struct _bmp_img
{
bmp_header img_header;
bmp_pixel **img_pixels;
} bmp_img;
// BMP_HEADER
void bmp_header_init_df (bmp_header*,
const int,
const int);
enum bmp_error bmp_header_write (const bmp_header*,
FILE*);
enum bmp_error bmp_header_read (bmp_header*,
FILE*);
// BMP_PIXEL
void bmp_pixel_init (bmp_pixel*,
const unsigned char,
const unsigned char,
const unsigned char);
// BMP_IMG
void bmp_img_alloc (bmp_img*);
void bmp_img_init_df (bmp_img*,
const int,
const int);
void bmp_img_free (bmp_img*);
enum bmp_error bmp_img_write (const bmp_img*,
const char*);
enum bmp_error bmp_img_read (bmp_img*,
const char*);
#endif /* __LIBBMP_H__ */
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* render_viewport.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sungjpar <sungjpar@student.42seoul.kr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/09/03 23:30:53 by minkyeki #+# #+# */
/* Updated: 2022/09/07 19:33:59 by sungjpar ### ########seoul.kr */
/* */
/* ************************************************************************** */
#include "gl_color.h"
#include "gl_draw.h"
#include "gl_input.h"
#include "main.h"
/** TODO: mouse 이동에 대한 감지를 좀 더 잘 할 수 있는 방법이 없을까... */
int render_viewport(t_device *device, t_image *viewport)
{
/** NOTE: Use Static Variable for private data member! */
static t_vec2 pressed_location;
static t_vec2 second_location;
static int lock = -1;
static int color;
static int r,g,b;
if (input_is_mouse_down(device, MOUSE_LEFT_CLICK))
{
if (lock == 0 || lock == -1)
{
pressed_location = input_get_mouse_pos(device);
lock = 1;
}
if (lock == -1)
{
r = 255;
g = 0;
b = 0;
}
second_location = input_get_mouse_pos(device);
if (r > 0 && b <= 0)
{
color = gl_color(BLACK, r--, g++, 0);
}
else if (g > 0 && r <= 0)
{
color = gl_color(BLACK, 0, g--, b++);
}
else if (b > 0 && g <= 0)
{
g = 0;
color = gl_color(BLACK, r++, 0, b--);
}
else
{
color = gl_color(BLACK, 255, 0, 0);
r = 255;
g = 0;
b = 0;
}
gl_draw_line(viewport, pressed_location, second_location, color);
pressed_location = second_location;
}
else if (input_is_mouse_unpressed(device, MOUSE_LEFT_CLICK))
{
/** test = GREEN; */
if (pressed_location.x == second_location.x && pressed_location.y == second_location.y)
printf("Simple Press\n");
else
printf("\t#Mouse-moved (%f / %f) -> (%f / %f)\n", pressed_location.x, pressed_location.y, second_location.x, second_location.y);
lock = 0;
}
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment