Skip to content

Commit

Permalink
Draw graphics on Windows
Browse files Browse the repository at this point in the history
Compiled with MinGW 4.9.2
  • Loading branch information
leonmavr committed Feb 22, 2023
1 parent 09d7a32 commit e4367ab
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 18 deletions.
30 changes: 23 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <stdbool.h>
#include <string.h> // strcmp
#include <limits.h> // UINT_MAX
#include <time.h> // time
#include <time.h> // time
#include <signal.h> // signal


Expand All @@ -29,13 +29,15 @@ static unsigned g_cube_size = 24;
static unsigned g_max_iterations = UINT_MAX;


#ifndef _WIN32
/* Clears the screen and makes the cursor visible when the user hits Ctr+C */
void interrupt_handler(int int_num) {
static void interrupt_handler(int int_num) {
if (int_num == SIGINT) {
draw_end();
exit(0);
}
}
}
#endif

int main(int argc, char** argv) {
int i = 0;
Expand Down Expand Up @@ -76,22 +78,36 @@ int main(int argc, char** argv) {
(-1.0 < g_rot_speed_z) && (g_rot_speed_z < 1.0));
}

#ifndef _WIN32
// make sure we end gracefully if the user hits Ctr+C
signal(SIGINT, interrupt_handler);
#endif

draw_init();
cube_t* cube = obj_cube_new(g_cx, g_cy, g_cz, g_cube_size);

// spinning parameters in case random rotation was selected
if (g_use_random_rotation) {
#ifndef _WIN32
const float radnom_rot_speed_x = 0.002, radnom_rot_speed_y = 0.002, radnom_rot_speed_z = 0.002;
const float amplitude_x = 4.25, amplitude_y = 4.25, amplitude_z = 4.25;
#else
// make it spin faster on windows because terminal refresh functions are sluggish there
const float radnom_rot_speed_x = 0.01, radnom_rot_speed_y = 0.01, radnom_rot_speed_z = 0.01;
const float amplitude_x = 10.0, amplitude_y = 10.0, amplitude_z = 10.0;
#endif
}
for (size_t t = 0; t < g_max_iterations; ++t) {
if (g_use_random_rotation)
obj_cube_rotate(cube, 4.25*sin(random_bias_x*sin(0.002*t) + 2*random_bias_x),
4.25*sin(random_bias_y*0.002*t + 2*random_bias_y),
4.25*sin(random_bias_z*0.002*t + 2*random_bias_z));
obj_cube_rotate(cube, amplitude_x*sin(random_bias_x*sin(random_bias_x*t) + 2*random_bias_x),
amplitude_y*sin(random_bias_y*random_bias_y*t + 2*random_bias_y),
amplitude_z*sin(random_bias_z*random_bias_z*t + 2*random_bias_z));
else
obj_cube_rotate(cube, g_rot_speed_x/20*t, g_rot_speed_y/20*t, g_rot_speed_z/20*t);
draw_cube(cube);
draw_flush_screen();
#ifndef _WIN32
nanosleep((const struct timespec[]) {{0, (int)(1.0 / g_fps * 1e9)}}, NULL);
#endif
}
obj_cube_free(cube);
draw_end();
Expand Down
71 changes: 60 additions & 11 deletions src/draw.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,57 @@
#include "vector.h"
#include "draw.h" // g_colors
#include "objects.h"
#include <sys/ioctl.h>
#include <stdio.h>
#ifndef _WIN32
#include <sys/ioctl.h> // ioctl
#else
#include <windows.h>
#endif
#include <stdio.h> // printf, fgets
#include <limits.h> // INT_MIN
#include <unistd.h>
#include <stdlib.h> // exit
#include <stdbool.h> // true/false
#include <stdbool.h> // true/false
#include <string.h> // memset

#define SIZE_INVALID 0
// printf macros to manipulate the terminal
#ifndef _WIN32
#define SCREEN_CLEAR() printf("\033[H\033[J")
#define SCREEN_GOTO_TOPLEFT() printf("\033[0;0H")
#define SCREEN_HIDE_CURSOR() printf("\e[?25l")
#define SCREEN_SHOW_CURSOR() printf("\e[?25h");
#else
HANDLE g_cons_out;

// Credits to @Jerry Coffin: https://stackoverflow.com/a/2732327
static void gotoxy(int x, int y) {
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}

// Credits to @oogabooga:
// https://cboard.cprogramming.com/c-programming/161186-undefined-reference.html
static void clrscr() {
COORD top_left = {0, 0};
DWORD c_chars_written;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(g_cons_out, &csbi);
DWORD dw_con_size = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(g_cons_out, ' ', dw_con_size,
top_left, &c_chars_written);
FillConsoleOutputAttribute(g_consOut, csbi.wAttributes,
dw_con_size, top_left, &c_chars_written);
SetConsoleCursorPosition(g_consOut, top_left);
}
#define SCREEN_CLEAR() clrscr()
#define SCREEN_GOTO_TOPLEFT() gotoxy(0, 0)
#define SCREEN_HIDE_CURSOR() ;
#define SCREEN_SHOW_CURSOR() ;
#endif

// colors for each face of the cube
color_t g_colors[6] = {'~', '.', '=', '@', '%', '|'};
static color_t g_colors[6] = {'~', '.', '=', '@', '%', '|'};

// rows, columns and aspect ratio of the terminal
int g_rows;
Expand All @@ -27,9 +60,9 @@ int g_min_rows;
int g_max_rows;
int g_min_cols;
int g_max_cols;
// columns over rows for the terminal
// columns over rows for the terminal
static float g_cols_over_rows;
// screen resolution (pixels over pixels)
// screen resolution (pixels over pixels)
static float g_screen_res;
color_t* g_screen_buffer;
int g_screen_buffer_size;
Expand Down Expand Up @@ -65,9 +98,10 @@ static bool draw__is_decimal(char* string) {
* `g_max_cols`
*/
static void draw__get_screen_info() {
#ifndef _WIN32
FILE *fp;
char path[512];

//// 1st way - ioctl call
struct winsize wsize;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &wsize);
Expand Down Expand Up @@ -100,6 +134,21 @@ static void draw__get_screen_info() {
}
//// 3rd way - assume a common resolution
g_screen_res = 1920.0/1080.0;
#else
// get terminal info on Windows - credits @quantum:
// https://stackoverflow.com/a/12642749
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
g_cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
g_rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
g_cols_over_rows = (float)g_cols/g_rows;
g_min_rows = -g_rows;
g_max_rows = g_rows/2;
g_min_cols = -g_cols/2+1;
g_max_cols = g_cols/4;
//// assume a common resolution on Windows
g_screen_res = 1920.0/1080.0;
#endif
}


Expand Down Expand Up @@ -159,12 +208,12 @@ void draw_cube(cube_t* cube) {
* z_hit are the z of the two intersections and z_rend is the closer one.
*
* The ray below intersects faces (p0, p1, p2, p3) and (p4, p5, p6, p7)
*
* O camera origin
*
* O camera origin
* \
* \
* V ray
* p3 \ p2 o cube's centre
* p3 \ p2 o cube's centre
* +-------------------+ + cube's vertices
* | \ \ | \ # ray-cube intersections
* | \ # z_rend | \ (z_hit)
Expand Down Expand Up @@ -249,7 +298,7 @@ void draw_cube(cube_t* cube) {
if (obj_ray_hits_rectangle(ray, p7, p6, p2, p3) && (z_hit > rendered_point.z)) {
rendered_color = g_colors[4];
rendered_point = (vec3i_t) {j, i, z_hit};
}
}
// through (p0, p4, p5);
obj_plane_set(plane, p0, p4, p5);
z_hit = obj_plane_z_at_xy(plane, j, i);
Expand Down

0 comments on commit e4367ab

Please sign in to comment.