/* * trifiller texture mapping features * Copyright (c) 2009 Jean-Yves Lamoureux * All Rights Reserved * * $Id: trifiller.c 2821 2008-09-27 13:12:46Z sam $ * * This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://sam.zoy.org/wtfpl/COPYING for more details. */ #include "config.h" #if !defined(__KERNEL__) # include # include #endif /* libcaca header */ #include "caca.h" /* Image loading functions */ #include "../src/common-image.h" /* M_PI / cos / sin */ #include #define SQUARE_SIZE 20 int main(int argc, char *argv[]) { /* libcaca/libcaca contexts */ caca_canvas_t *cv; caca_display_t *dp; caca_canvas_t *tex; /* cached canvas size */ int ww, wh, tw, th; /* logic */ int quit = 0; int update = 1; int px, py; float angle = 0; float square[4][2] = { {-SQUARE_SIZE, -SQUARE_SIZE}, { SQUARE_SIZE, -SQUARE_SIZE}, { SQUARE_SIZE, SQUARE_SIZE}, {-SQUARE_SIZE, SQUARE_SIZE}, }; float rotated[4][2]; /* Create displayed canvas */ cv = caca_create_canvas(0, 0); if(!cv) { fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); return 1; } /* Create texture holding canvas */ tex = caca_create_canvas(16, 16); if(!tex) { fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); return 1; } /* Open window */ dp = caca_create_display(cv); if(!dp) { fprintf(stderr, "%s: unable to initialise libcaca\n", argv[0]); return 1; } /* Set the window title */ caca_set_display_title(dp, "trifiller"); /* Frame duration */ caca_set_display_time(dp, 10000); /* Get displayed canvas size */ ww = caca_get_canvas_width(cv); wh = caca_get_canvas_height(cv); /* Texture size */ tw = caca_get_canvas_width(tex); th = caca_get_canvas_height(tex); /* Load texture if any */ if(argc == 2) { struct image *im = load_image(argv[1]); if(!im) { fprintf(stderr, "%s: unable to load image '%s'\n", argv[0], argv[1]); return 1; } caca_set_dither_algorithm(im->dither, caca_get_dither_algorithm_list(NULL)[4]); caca_dither_bitmap(tex, 0, 0, tw, th, im->dither, im->pixels); unload_image(im); } /* or generate one */ else { int i; for(i = 0; i < 16; i ++) { caca_set_color_ansi(tex, (i+1)%0xF, i); caca_put_str(tex, 0, i, "123456789ABCDEF"); } } px = 0; py = 0; while(!quit) { caca_event_t ev; unsigned int const event_mask = CACA_EVENT_KEY_PRESS | CACA_EVENT_RESIZE | CACA_EVENT_QUIT; int event; if(update) event = caca_get_event(dp, event_mask, &ev, 0); else event = caca_get_event(dp, event_mask, &ev, -1); while(event) { if(caca_get_event_type(&ev) & CACA_EVENT_KEY_PRESS) switch(caca_get_event_key_ch(&ev)) { case 'q': case 'Q': case CACA_KEY_ESCAPE: quit = 1; break; case CACA_KEY_UP: py--; break; case CACA_KEY_DOWN: py++; break; case CACA_KEY_LEFT: px--; break; case CACA_KEY_RIGHT: px++; break; case 'a': angle+=1.0f; break; case 's': angle-=1.0f; break; } else if(caca_get_event_type(&ev) == CACA_EVENT_RESIZE) { caca_refresh_display(dp); ww = caca_get_event_resize_width(&ev); wh = caca_get_event_resize_height(&ev); update = 1; } else if(caca_get_event_type(&ev) & CACA_EVENT_QUIT) quit = 1; event = caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 0); } /* 2D Rotation around screen center */ int p; for(p=0; p<4; p++) { rotated[p][0] = square[p][0] * cos(angle*M_PI/180.0f) - square[p][1] * sin(angle*M_PI/180.0f); rotated[p][1] = square[p][0] * sin(angle*M_PI/180.0f) + square[p][1] * cos(angle*M_PI/180.0f); rotated[p][0] += ww/2 + px; rotated[p][1] += wh/2 + py; } angle+=1.0f; /* Display two triangles */ caca_fill_triangle_textured(cv, /* triangle screen coordinates */ rotated[0][0], rotated[0][1], rotated[1][0], rotated[1][1], rotated[2][0], rotated[2][1], /* texture coordinates */ 0, 0, 1, 0, 1, 1, tex); caca_fill_triangle_textured(cv, /* triangle screen coordinates */ rotated[0][0], rotated[0][1], rotated[2][0], rotated[2][1], rotated[3][0], rotated[3][1], /* texture coordinates */ 0, 0, 1, 1, 0, 1, tex); /* Refresh display and clear for next frame */ caca_refresh_display(dp); caca_clear_canvas(cv); } caca_free_display(dp); caca_free_canvas(cv); caca_free_canvas(tex); return 0; }