Home So_long ② 배경 지식
Post
Cancel

So_long ② 배경 지식

과제 허용 함수

perror

사용자 메시지 + 오류 메시지를 출력한다.

void perror(const char *s);

전역 변수 errno 의 값을 해석하여 이에 해당하는 시스템 오류 메세지를 표준 오류 출력 스트림(stderr) 에 출력한다.

  • 헤더 : stdio.h
  • 매개변수
    • s : 시스템 오류 메세지 앞에 출력할 사용자 정의 메시지
  • 반환값
    • 없음

strerror

오류 메시지를 리턴한다.

char *strerror(int errnum);

  • 헤더 : string.h
  • 매개변수
    • errnum : 오류 번호
  • 반환값
    • 오류 번호에 해당하는 오류 문자열을 가리키는 포인터

MiniLibX 사용법

MiniLibX 함수

  • void *mlx_init() : 소프트웨어와 디스플레이를 연결해준다.
  • void *mlx_new_window(void *mlx_ptr, int size_x, int size_y, char *title) : 스크린에 창을 하나 생성한다.
  • void *mlx_xpm_file_to_image(void *mlx_ptr, char *filename, int *width, int *height) : 이미지 데이터를 생성하고 그 이미지를 지정한 파일의 데이터로 채움
  • int mlx_put_image_to_window(void *mlx_ptr, void *win_ptr, void *img_ptr, int x, int y) : 창에 이미지를 출력한다.
  • int mlx_destroy_window(void *mlx_ptr, void *win_ptr) : win_ptr로 창을 제거한다.
  • int mlx_string_put(void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string) : 문자열을 창에 출력한다.
  • int mlx_loop (void *mlx_ptr) : 이벤트를 기다리는 무한루프를 실행한다.
  • int mlx_hook(void win_ptr, int x_event, int x_mask, int (funct)(), void *param) : 모든 이벤트를 hook한다. key로 특정하고싶으면 key_hook함수 사용.

Key event

Key codes

key_codes.png

Mouse button codes

  • Left button — 1
  • Right button — 2
  • Third (Middle) button — 3
  • Scroll Up — 4
  • Scroll Down — 5
  • Scroll Left — 6
  • Scroll Right — 7

x_event

KeyEventKeyEvent
02KeyPress20MapRequest
03KeyRelease21ReparentNotify
04ButtonPress22ConfigureNotify
05ButtonRelease23ConfigureRequest
06MotionNotify24GravityNotify
07EnterNotify25ResizeRequest
08LeaveNotify26CirculateNotify
09FocusIn27CirculateRequest
10FocusOut28PropertyNotify
11KeymapNotify29SelectionClear
12Expose30SelectionRequest
13GraphicsExpose31SelectionNotify
14NoExpose32ColormapNotify
15VisibilityNotify33ClientMessage
16CreateNotify34MappingNotify
17DestroyNotify35GenericEvent
18UnmapNotify36LASTEvent
19MapNotify  

간단한 실습

  • 루트 디렉토리에 mlx 폴더 위치시키고 해당 경로 안에 과제에서 제공한 minilibx_opengl(opengl) 또는 minilibx_mms(metal) 파일 넣기
  • mlx에서 make
    • mms의 경우 다음과 같은 오류가 발생하므로 interface.swift의 UInt32(1)boolean_t(1)로 수정
      1
      2
      3
      4
      5
      
        interface.swift:273:41: error: cannot convert value of type 'UInt32' to expected argument type 'boolean_t' (aka 'Int32')
        CGAssociateMouseAndMouseCursorPosition(UInt32(1))
                                               ^
                                               boolean_t( )
        make: *** [interface.o] Error 1
      
  • main.c 작성 후 루트 디렉토리에서 컴파일
    • opengl일 경우 : gcc -L./mlx -lmlx -framework OpenGL -framework AppKit main.c
    • mms일 경우
      1. cp mlx/libmlx.dylib .
      2. gcc -framework Metal -framework Metalkit libmlx.dylib main.c

새 창 띄우기

  • main.c

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      #include "mlx/mlh.h"
        
      int	main(void)
      {
      	void	*mlx;
      	void	*win;
        
      	mlx = mlx_init();
      	win = mlx_new_window(mlx, 500, 500, "test");
      	mlx_loop(mlx);
      }
    

키보드 입력 받기

WASD 키로 x, y 좌표를 변경하는 프로그램

  • main.c

    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
    
      #include <stdio.h>
      #include <stdlib.h>
      #include "mlx/mlx.h"
        
      // 각 키에 해당하는 코드
      # define KEY_ESC 53
      # define KEY_W 13
      # define KEY_A 0
      # define KEY_S 1
      # define KEY_D 2
      # define X_EVENT_KEY_PRESS 2
      # define X_EVENT_DESTROY_NOTIFY 17
        
      // 값을 저장할 구조체
      typedef struct s_key{
      	int		x;
      	int		y;
      }				t_key;
        
      // 구조체 멤버 변수 초기화
      void	key_init(t_key *key)
      {
      	key->x = 0;
      	key->y = 0;
      }
        
      // 키가 눌렸을 때
      int	key_press(int keycode, t_key *key)
      {
      	if (keycode == KEY_W)
      		key->y++;
      	else if (keycode == KEY_S)
      		key->y--;
      	else if (keycode == KEY_A)
      		key->x--;
      	else if (keycode == KEY_D)
      		key->x++;
      	else if (keycode == KEY_ESC)
      		exit(0);
      	else
      		return (0);
      	printf("(%d, %d)\n", key->x, key->y);
      	return (0);
      }
        
      int	close_window(void)
      {
      	exit(0);
      	return (0);
      }
        
      int	main(void)
      {
      	void		*mlx;
      	void		*win;
      	t_key   key;
        
      	mlx = mlx_init(); // mlx포인터 생성
      	win = mlx_new_window(mlx, 500, 500, "key test"); // 윈도우 띄우기
      	key_init(&key); // 구조체 값 초기설정
      	printf("(%d, %d)\n", key.x, key.y);
      	mlx_hook(win, X_EVENT_DESTROY_NOTIFY, 0, &close_window, &key);
      	mlx_hook(win, X_EVENT_KEY_PRESS, 0, &key_press, &key);
      	mlx_loop(mlx);
      }
    

Ref.

key_event_handle

This post is licensed under CC BY 4.0 by the author.

So_long ① Subject

So_long ③ 구현 과정