651 lines
11 KiB
Plaintext
651 lines
11 KiB
Plaintext
/* What will I use my programming skill for? */
|
|
|
|
#include "EXTERN.h"
|
|
#include "perl.h"
|
|
#include "XSUB.h"
|
|
|
|
#include "caca.h"
|
|
|
|
/* ref($sprite) eq 'HASH' && $sprite->{__address__} */
|
|
void *
|
|
address_of(SV *sprite)
|
|
{
|
|
/* make sure sprite is a hashref */
|
|
if (SvTYPE(SvRV(sprite)) != SVt_PVHV) {
|
|
return NULL;
|
|
}
|
|
return (struct caca_sprite *)
|
|
SvIV(*hv_fetch((HV *) SvRV(sprite), "__address__", 11, 0));
|
|
}
|
|
|
|
/* turn a perl array of numbers into a c array */
|
|
void *
|
|
c_array(SV *p_array)
|
|
{
|
|
}
|
|
|
|
MODULE = Term::Caca PACKAGE = Term::Caca
|
|
|
|
# -==[- Basic functions -]==--------------------------------------------------
|
|
|
|
void
|
|
_init()
|
|
CODE:
|
|
caca_init();
|
|
|
|
void
|
|
_set_delay(usec)
|
|
unsigned int usec
|
|
CODE:
|
|
caca_set_delay(usec);
|
|
|
|
unsigned int
|
|
_get_feature(feature)
|
|
unsigned int feature
|
|
CODE:
|
|
RETVAL = caca_get_feature(feature);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_set_feature(feature)
|
|
unsigned int feature
|
|
CODE:
|
|
caca_set_feature(feature);
|
|
|
|
const char *
|
|
_get_feature_name(feature)
|
|
unsigned int feature
|
|
CODE:
|
|
RETVAL = caca_get_feature_name(feature);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_rendertime()
|
|
CODE:
|
|
RETVAL = caca_get_rendertime();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_width()
|
|
CODE:
|
|
RETVAL = caca_get_width();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_height()
|
|
CODE:
|
|
RETVAL = caca_get_height();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_set_window_title(title)
|
|
const char *title
|
|
CODE:
|
|
RETVAL = caca_set_window_title(title);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_window_width()
|
|
CODE:
|
|
RETVAL = caca_get_window_width();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_window_height()
|
|
CODE:
|
|
RETVAL = caca_get_window_height();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_refresh()
|
|
CODE:
|
|
caca_refresh();
|
|
|
|
void
|
|
_end()
|
|
CODE:
|
|
caca_end();
|
|
|
|
# -==[- Event handling -]==---------------------------------------------------
|
|
|
|
unsigned int
|
|
_get_event(event_mask)
|
|
unsigned int event_mask
|
|
CODE:
|
|
RETVAL = caca_get_event(event_mask);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_mouse_x()
|
|
CODE:
|
|
RETVAL = caca_get_mouse_x();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_mouse_y()
|
|
CODE:
|
|
RETVAL = caca_get_mouse_y();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_wait_event(event_mask)
|
|
unsigned int event_mask
|
|
CODE:
|
|
RETVAL = caca_wait_event(event_mask);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
# -==[- Character printing -]==-----------------------------------------------
|
|
|
|
void
|
|
_set_color(fgcolor, bgcolor)
|
|
unsigned int fgcolor;
|
|
unsigned int bgcolor;
|
|
CODE:
|
|
caca_set_color(fgcolor, bgcolor);
|
|
|
|
unsigned int
|
|
_get_fg_color()
|
|
CODE:
|
|
RETVAL = caca_get_fg_color();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_get_bg_color()
|
|
CODE:
|
|
RETVAL = caca_get_bg_color();
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
const char *
|
|
_get_color_name(color)
|
|
unsigned int color
|
|
CODE:
|
|
RETVAL = caca_get_color_name(color);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_putchar(x, y, c)
|
|
int x;
|
|
int y;
|
|
char c;
|
|
CODE:
|
|
caca_putchar(x, y, c);
|
|
|
|
void
|
|
_putstr(x, y, s)
|
|
int x;
|
|
int y;
|
|
const char *s;
|
|
CODE:
|
|
caca_putstr(x, y, s);
|
|
|
|
# skip caca_printf for now.
|
|
# handle va_args on perl side.
|
|
|
|
void
|
|
_clear()
|
|
CODE:
|
|
caca_clear();
|
|
|
|
# -==[- Primitives drawing -]==-----------------------------------------------
|
|
|
|
void
|
|
_draw_line(x1, y1, x2, y2, c)
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
char c;
|
|
CODE:
|
|
caca_draw_line(x1, y1, x2, y2, c);
|
|
|
|
void
|
|
_draw_polyline(x, y, n, c)
|
|
SV *x;
|
|
SV *y;
|
|
int n;
|
|
char c;
|
|
INIT:
|
|
int *xc;
|
|
int *yc;
|
|
int i;
|
|
/* make sure x and y are perl arrayrefs */
|
|
if ( (SvTYPE(SvRV(x)) != SVt_PVAV)
|
|
|| (SvTYPE(SvRV(y)) != SVt_PVAV) )
|
|
{
|
|
XSRETURN_UNDEF;
|
|
}
|
|
|
|
/* create a C int array out of x and y */
|
|
xc = (int *) malloc((n+1) * sizeof(int *));
|
|
if (!xc) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
yc = (int *) malloc((n+1) * sizeof(int *));
|
|
if (!yc) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
for (i = 0; i <= n; i++) {
|
|
SV **integer;
|
|
|
|
integer = av_fetch((AV *) SvRV(x), i, 0);
|
|
if (integer) {
|
|
xc[i] = SvIV(*integer);
|
|
} else {
|
|
xc[i] = 0;
|
|
}
|
|
|
|
integer = av_fetch((AV *) SvRV(y), i, 0);
|
|
if (integer) {
|
|
yc[i] = SvIV(*integer);
|
|
} else {
|
|
yc[i] = 0;
|
|
}
|
|
}
|
|
CODE:
|
|
caca_draw_polyline(xc, yc, n, c);
|
|
free(yc);
|
|
free(xc);
|
|
|
|
void
|
|
_draw_thin_line(x1, y1, x2, y2)
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
CODE:
|
|
caca_draw_thin_line(x1, y1, x2, y2);
|
|
|
|
void
|
|
_draw_thin_polyline(x, y, n)
|
|
SV *x;
|
|
SV *y;
|
|
int n;
|
|
INIT:
|
|
int *xc;
|
|
int *yc;
|
|
int i;
|
|
/* make sure x and y are perl arrayrefs */
|
|
if ( (SvTYPE(SvRV(x)) != SVt_PVAV)
|
|
|| (SvTYPE(SvRV(y)) != SVt_PVAV) )
|
|
{
|
|
XSRETURN_UNDEF;
|
|
}
|
|
|
|
/* create a C int array out of x and y */
|
|
xc = (int *) malloc((n+1) * sizeof(int *));
|
|
if (!xc) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
yc = (int *) malloc((n+1) * sizeof(int *));
|
|
if (!yc) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
for (i = 0; i <= n; i++) {
|
|
SV **integer;
|
|
|
|
integer = av_fetch((AV *) SvRV(x), i, 0);
|
|
if (integer) {
|
|
xc[i] = SvIV(*integer);
|
|
} else {
|
|
xc[i] = 0;
|
|
}
|
|
|
|
integer = av_fetch((AV *) SvRV(y), i, 0);
|
|
if (integer) {
|
|
yc[i] = SvIV(*integer);
|
|
} else {
|
|
yc[i] = 0;
|
|
}
|
|
}
|
|
CODE:
|
|
caca_draw_thin_polyline(xc, yc, n);
|
|
free(yc);
|
|
free(xc);
|
|
|
|
void
|
|
_draw_circle(x, y, r, c)
|
|
int x;
|
|
int y;
|
|
int r;
|
|
char c;
|
|
CODE:
|
|
caca_draw_circle(x, y, r, c);
|
|
|
|
void
|
|
_draw_ellipse(x0, y0, a, b, c)
|
|
int x0;
|
|
int y0;
|
|
int a;
|
|
int b;
|
|
char c;
|
|
CODE:
|
|
caca_draw_ellipse(x0, y0, a, b, c);
|
|
|
|
void
|
|
_draw_thin_ellipse(x0, y0, a, b)
|
|
int x0;
|
|
int y0;
|
|
int a;
|
|
int b;
|
|
CODE:
|
|
caca_draw_thin_ellipse(x0, y0, a, b);
|
|
|
|
void
|
|
_fill_ellipse(x0, y0, a, b, c)
|
|
int x0;
|
|
int y0;
|
|
int a;
|
|
int b;
|
|
char c;
|
|
CODE:
|
|
caca_fill_ellipse(x0, y0, a, b, c);
|
|
|
|
void
|
|
_draw_box(x0, y0, x1, y1, c)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
char c;
|
|
CODE:
|
|
caca_draw_box(x0, y0, x1, y1, c);
|
|
|
|
void
|
|
_draw_thin_box(x0, y0, x1, y1)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
CODE:
|
|
caca_thin_box(x0, y0, x1, y1);
|
|
|
|
void
|
|
_fill_box(x0, y0, x1, y1, c)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
char c;
|
|
CODE:
|
|
caca_fill_box(x0, y0, x1, y1, c);
|
|
|
|
void
|
|
_draw_triangle(x0, y0, x1, y1, x2, y2, c)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
char c;
|
|
CODE:
|
|
caca_draw_triangle(x0, y0, x1, y1, x2, y2, c);
|
|
|
|
void
|
|
_draw_thin_triangle(x0, y0, x1, y1, x2, y2)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
CODE:
|
|
caca_draw_thin_triangle(x0, y0, x1, y1, x2, y2);
|
|
|
|
void
|
|
_fill_triangle(x0, y0, x1, y1, x2, y2, c)
|
|
int x0;
|
|
int y0;
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
char c;
|
|
CODE:
|
|
caca_fill_triangle(x0, y0, x1, y1, x2, y2, c);
|
|
|
|
# -==[- Mathematical functions -]==-------------------------------------------
|
|
|
|
int
|
|
_rand(min, max)
|
|
int min;
|
|
int max;
|
|
CODE:
|
|
RETVAL = caca_rand(min, max);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
unsigned int
|
|
_sqrt(n)
|
|
unsigned int n;
|
|
CODE:
|
|
RETVAL = caca_sqrt(n);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
# -==[- Sprite handling -]==-
|
|
|
|
SV *
|
|
_load_sprite(file)
|
|
const char *file
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
HV *sprite;
|
|
CODE:
|
|
if (!file) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
c_sprite = caca_load_sprite(file);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
} else {
|
|
sprite = (HV *) sv_2mortal((SV *) newHV());
|
|
if (!sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
hv_store(sprite, "__address__", 11, newSViv((int) c_sprite), 0);
|
|
RETVAL = newRV((SV *) sprite);
|
|
}
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_get_sprite_frames(sprite)
|
|
SV *sprite
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
RETVAL = caca_get_sprite_frames(c_sprite);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_get_sprite_width(sprite, f)
|
|
SV *sprite;
|
|
int f;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
RETVAL = caca_get_sprite_width(c_sprite, f);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_get_sprite_height(sprite, f)
|
|
SV *sprite;
|
|
int f;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
RETVAL = caca_get_sprite_height(c_sprite, f);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_get_sprite_dx(sprite, f)
|
|
SV *sprite;
|
|
int f;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
RETVAL = caca_get_sprite_dx(c_sprite, f);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
int
|
|
_get_sprite_dy(sprite, f)
|
|
SV *sprite;
|
|
int f;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
RETVAL = caca_get_sprite_dy(c_sprite, f);
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_draw_sprite(x, y, sprite, f)
|
|
int x;
|
|
int y;
|
|
SV *sprite;
|
|
int f;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
caca_draw_sprite(x, y, c_sprite, f);
|
|
|
|
void
|
|
_free_sprite(sprite)
|
|
SV *sprite;
|
|
INIT:
|
|
struct caca_sprite *c_sprite;
|
|
c_sprite = address_of(sprite);
|
|
if (!c_sprite) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
caca_free_sprite(c_sprite);
|
|
|
|
# -==[- Bitmap handling -]==--------------------------------------------------
|
|
|
|
SV *
|
|
_create_bitmap(bpp, w, h, pitch, rmask, gmask, bmask, amask)
|
|
unsigned int bpp;
|
|
unsigned int w;
|
|
unsigned int h;
|
|
unsigned int pitch;
|
|
unsigned int rmask;
|
|
unsigned int gmask;
|
|
unsigned int bmask;
|
|
unsigned int amask;
|
|
INIT:
|
|
struct caca_bitmap *c_bitmap;
|
|
HV *bitmap;
|
|
CODE:
|
|
c_bitmap =
|
|
caca_create_bitmap(bpp, w, h, pitch, rmask, gmask, bmask, amask);
|
|
if (!c_bitmap) {
|
|
XSRETURN_UNDEF;
|
|
} else {
|
|
bitmap = (HV *) sv_2mortal((SV *) newHV());
|
|
if (!bitmap) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
hv_store(bitmap, "__address__", 11, newSViv((int) c_bitmap), 0);
|
|
hv_store(bitmap, "__bpp__", 7, newSViv((int) bpp ), 0);
|
|
RETVAL = newRV((SV *) bitmap);
|
|
}
|
|
OUTPUT:
|
|
RETVAL
|
|
|
|
void
|
|
_set_bitmap_palette(bitmap, red, green, blue, alpha)
|
|
SV *bitmap;
|
|
SV *red;
|
|
SV *green;
|
|
SV *blue;
|
|
SV *alpha;
|
|
INIT:
|
|
struct caca_bitmap *c_bitmap;
|
|
unsigned int *c_red;
|
|
unsigned int *c_green;
|
|
unsigned int *c_blue;
|
|
unsigned int *c_alpha;
|
|
|
|
c_bitmap = address_of(bitmap);
|
|
if (!c_bitmap) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
/* TODO: perl array to c array */
|
|
c_red = c_array(red);
|
|
c_green = c_array(green);
|
|
c_blue = c_array(blue);
|
|
c_alpha = c_array(alpha);
|
|
CODE:
|
|
caca_set_bitmap_palette(c_bitmap, c_red, c_green, c_blue, c_alpha);
|
|
|
|
void
|
|
_draw_bitmap(x1, y1, x2, y2, bitmap, pixels)
|
|
int x1;
|
|
int y1;
|
|
int x2;
|
|
int y2;
|
|
SV *bitmap;
|
|
SV *pixels;
|
|
INIT:
|
|
/* TODO: implement Tie::Scalar::Pointer for pixel support */
|
|
CODE:
|
|
|
|
void
|
|
_free_bitmap(bitmap)
|
|
SV *bitmap;
|
|
INIT:
|
|
struct caca_bitmap *c_bitmap;
|
|
c_bitmap = address_of(bitmap);
|
|
if (!c_bitmap) {
|
|
XSRETURN_UNDEF;
|
|
}
|
|
CODE:
|
|
caca_free_bitmap(c_bitmap);
|
|
|
|
# vim:sw=2 sts=2 expandtab
|