Skip to content

Added filled() and polygon() #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 24, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,30 @@ PROGRAMMING INTERFACE
Drawing functions:

* fill(r,g,b,alpha): select the drawing color.
* filled(filled): set the filled state (true or false)
* background(r,g,b): paint the whole background with the specified color.
* rect(x,y,width,height): draw a rectangle at x,y (left-bottom corner).
* ellipse(x,y,width,height): draw an ellipse centered at x,y.
* line(x1,y1,x2,y2): draw a line from x1,y1 to x2,y2.
* text(x,y,string): print the specified text at x,y using a bitmap font.
* triangle(x1,y1,x2,y2,x3,y3): draw a triangle with the specified vertex.
* getpixel(x,y): return the red,gree,blue value of the specified pixel.
* sprite(file,x,y,[rotation],[antialiasing]): draw sprite at coordinates with the specified rotation (in degrees, default 0) and antialiasing (default false).
* polygon(xv, yv): draw a polygon using a table of X values and a table of Y values.

Sprite functions:

* sprite(file,[x,y,[rotation],[antialiasing]]): draw sprite at coordinates with the specified rotation (in degrees, default 0) and antialiasing (default false).

Returns a sprite userdata object, with the following functions

* getHeight(): returns the height of the sprite.
* getWidth(): returns the height of the sprite.
* getTiles(): returns x,y for the number of tiles horizontally and vertically.
* setTiles(x,y): set the number of tiles horizontally and vertically.
* getTileSize(): return w,h for the size of a tile, calculated from the width and height of the image divided by the number of tiles horizontally and vertically.
* getTileNum(): returns the number of tiles.
* tile(x,y,tileNum,[rotation],[antialiasing]): draw a tile using tileNum at coordinates with the specified rotation (in degrees, default 0) and antialiasing (default: false).
* draw(x,y,[rotation],[antialiasing]): draw sprite at coordinates with the specified rotation (in degrees, default 0) and antialiasing (default: false).

Control functions:

Expand Down
20 changes: 10 additions & 10 deletions editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ void editorDrawCursor(void) {
y -= E.margin_top;
if (!(E.cblink & 0x80)) drawBox(E.fb,x+charmargin,y,
x+charmargin+FONT_KERNING-1,y+FONT_HEIGHT-1,
165,165,255,128);
165,165,255,128,1);
E.cblink += 4;
}

Expand Down Expand Up @@ -412,25 +412,25 @@ void editorDrawChars(void) {
}

void editorDrawPowerOff(int x, int y) {
drawEllipse(E.fb,x,y,12,12,66,66,231,255);
drawEllipse(E.fb,x,y,7,7,165,165,255,255);
drawBox(E.fb,x-4,y,x+4,y+12,165,165,255,255);
drawBox(E.fb,x-2,y,x+2,y+14,66,66,231,255);
drawEllipse(E.fb,x,y,12,12,66,66,231,255,1);
drawEllipse(E.fb,x,y,7,7,165,165,255,255,1);
drawBox(E.fb,x-4,y,x+4,y+12,165,165,255,255,1);
drawBox(E.fb,x-2,y,x+2,y+14,66,66,231,255,1);
}

void editorDrawSaveIcon(int x, int y) {
drawBox(E.fb,x-12,y-12,x+12,y+12,66,66,231,255);
drawBox(E.fb,x-1,y+7,x+1,y+11,165,165,255,255);
drawEllipse(E.fb,x,y,4,4,165,165,255,255);
drawBox(E.fb,x-12,y-12,x+12,y+12,66,66,231,255,1);
drawBox(E.fb,x-1,y+7,x+1,y+11,165,165,255,255,1);
drawEllipse(E.fb,x,y,4,4,165,165,255,255,1);
}

void editorDraw() {
drawBox(E.fb,0,0,E.fb->width-1,E.fb->height-1,165,165,255,255);
drawBox(E.fb,0,0,E.fb->width-1,E.fb->height-1,165,165,255,255,1);
drawBox(E.fb,
E.margin_left,
E.margin_bottom,
E.fb->width-1-E.margin_right,
E.fb->height-1-E.margin_top,66,66,231,255);
E.fb->height-1-E.margin_top,66,66,231,255,1);
editorDrawChars();
editorDrawCursor();
/* Show buttons */
Expand Down
3 changes: 3 additions & 0 deletions examples/flames.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function setup()
refreshCount = 0
skipCount = 0
Flames = { }
filled(false)

for i=1,MaxFlames do
x = math.random(WIDTH/3) + (WIDTH/3)
Expand All @@ -26,9 +27,11 @@ function draw()
background(0,0,0)
for i,f in pairs(Flames) do
if f.l > 35 then
filled(true)
fill(255, 255, 255, 0.9)
minMove = 0
elseif f.l > 30 then
filled(false)
fill(255, 255, 192, 0.8)
minMove = 1
elseif f.l > 20 then
Expand Down
164 changes: 140 additions & 24 deletions framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ frameBuffer *createFrameBuffer(int width, int height, int bpp, int fullscreen) {
SDL_initFramerate(&fb->fps_mgr);
/* Load the bitmap font */
bfLoadFont((char**)BitmapFont);
gfb = fb;
return fb;
}

Expand All @@ -51,22 +52,40 @@ void drawHline(frameBuffer *fb, int x1, int x2, int y, int r, int g, int b, int
hlineRGBA(fb->screen, x1, x2, fb->height-1-y, r, g, b, alpha);
}

void drawEllipse(frameBuffer *fb, int xc, int yc, int radx, int rady, int r, int g, int b, int alpha) {
filledEllipseRGBA(fb->screen, xc, fb->height-1-yc, radx, rady, r, g, b, alpha);
void drawEllipse(frameBuffer *fb, int xc, int yc, int radx, int rady, int r, int g, int b, int alpha, char filled) {
if (filled)
filledEllipseRGBA(fb->screen, xc, fb->height-1-yc, radx, rady, r, g, b, alpha);
else
ellipseRGBA(fb->screen, xc, fb->height-1-yc, radx, rady, r, g, b, alpha);
}

void drawBox(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha) {
boxRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, r, g, b, alpha);
void drawBox(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha, char filled) {
if (filled)
boxRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, r, g, b, alpha);
else
rectangleRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, r, g, b, alpha);
}

void drawTriangle(frameBuffer *fb, int x1, int y1, int x2, int y2, int x3, int y3, int r, int g, int b, int alpha) {
filledTrigonRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, x3, fb->height-1-y3, r, g, b, alpha);
void drawTriangle(frameBuffer *fb, int x1, int y1, int x2, int y2, int x3, int y3, int r, int g, int b, int alpha, char filled) {
if (filled)
filledTrigonRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, x3, fb->height-1-y3, r, g, b, alpha);
else
trigonRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, x3, fb->height-1-y3, r, g, b, alpha);
}

void drawLine(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha) {
lineRGBA(fb->screen, x1, fb->height-1-y1, x2, fb->height-1-y2, r, g, b, alpha);
}

void drawPolygon(frameBuffer *fb, Sint16* xv, Sint16* yv, int n, int r, int g, int b, int alpha, char filled) {
int i;
for (i=0; i<n; i++) yv[i] = fb->height-1-yv[i];
if (filled)
filledPolygonRGBA(fb->screen, xv, yv, n, r, g, b, alpha);
else
polygonRGBA(fb->screen, xv, yv, n, r, g, b, alpha);
}

/* ============================= Bitmap font =============================== */
void bfLoadFont(char **c) {
/* Set all the entries to NULL. */
Expand Down Expand Up @@ -105,32 +124,71 @@ void bfWriteString(frameBuffer *fb, int xp, int yp, const char *s, int len, int
* the same interface with load81.c. */
#define SPRITE_MT "l81.sprite_mt"

void spriteBlit(frameBuffer *fb, void *sprite, int x, int y, int angle, int aa) {
/*
void spriteBlit(frameBuffer *fb, sprite *sprite, int x, int y, int angle, int aa) {
SDL_Surface *s = sprite;
if (s == NULL) return;
if (angle) s = rotozoomSurface(s,angle,1,aa);
SDL_Rect dst = {x, fb->height-1-y - s->h, s->w, s->h};
SDL_BlitSurface(s, NULL, fb->screen, &dst);
if (angle) SDL_FreeSurface(s);
}
*/

void spriteBlit(frameBuffer *fb, sprite *sp, int x, int y, int tileNum, int angle, int aa) {
SDL_Surface *s = sp->surf;
if (s == NULL) return;

if (tileNum >= 0) {
SDL_Rect dst = {x, fb->height-1-y - sp->tileH, sp->tileW, sp->tileH};
SDL_Rect src = {(tileNum%sp->tileY) * sp->tileW, (tileNum / sp->tileY) * sp->tileH, sp->tileW, sp->tileH};
if (angle) {
SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, sp->tileW, sp->tileH, fb->screen->format->BitsPerPixel, 0, 0, 0, 0);
SDL_Surface *tempRot;
SDL_BlitSurface(s, &src, temp, NULL);
tempRot = rotozoomSurface(temp,angle,1,aa);
SDL_BlitSurface(tempRot, NULL, fb->screen, &dst);
SDL_FreeSurface(tempRot);
SDL_FreeSurface(temp);
}
else {
SDL_BlitSurface(s, &src, fb->screen, &dst);
}
}
else {
SDL_Rect dst = {x, fb->height-1-y - s->h, s->w, s->h};
if (angle) s = rotozoomSurface(s,angle,1,aa);
SDL_BlitSurface(s, NULL, fb->screen, &dst);
if (angle) SDL_FreeSurface(s);
}
}


/* Load sprite. Return surface pointer and object on top of stack */
void *spriteLoad(lua_State *L, const char *filename) {
SDL_Surface **pps;
sprite *spriteLoad(lua_State *L, const char *filename) {
sprite *pps;

/* check if image was already loaded and cached */
lua_getglobal(L, "sprites");
lua_getfield(L, -1, filename);
if (lua_isnil(L, -1)) {
/* load image into surface */
SDL_Surface *ps = IMG_Load(filename);
if (ps == NULL) {
sprite ps;
ps.surf = IMG_Load(filename);
if (ps.surf == NULL) {
luaL_error(L, "failed to load sprite %s", filename);
return NULL;
}

ps.w = ps.surf->w;
ps.h = ps.surf->h;
ps.tileX = 0;
ps.tileY = 0;
ps.tileW = ps.w;
ps.tileH = ps.h;

/* box the surface pointer in a userdata */
pps = (SDL_Surface **)lua_newuserdata(L, sizeof(SDL_Surface *));
pps = (sprite*)lua_newuserdata(L, sizeof(sprite));
*pps = ps;

/* set sprite metatable */
Expand All @@ -142,34 +200,92 @@ void *spriteLoad(lua_State *L, const char *filename) {
lua_setfield(L, -4, filename);
} else {
/* unbox surface pointer */
pps = (SDL_Surface **)luaL_checkudata(L, -1, SPRITE_MT);
pps = (sprite *)luaL_checkudata(L, -1, SPRITE_MT);
}
return *pps;
return pps;
}

int spriteGC(lua_State *L) {
SDL_Surface **pps = (SDL_Surface **)luaL_checkudata(L, 1, SPRITE_MT);
if (pps) SDL_FreeSurface(*pps);
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
if (pps) SDL_FreeSurface(pps->surf);
return 0;
}

int spriteGetHeight(lua_State *L) {
SDL_Surface **pps = (SDL_Surface **)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, (*pps)->h);
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, pps->h);
return 1;
}

int spriteGetWidth(lua_State *L) {
SDL_Surface **pps = (SDL_Surface **)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, (*pps)->w);
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, pps->w);
return 1;
}

int spriteGetTiles(lua_State *L) {
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, pps->tileX);
lua_pushnumber(L, pps->tileY);
return 2;
}

int spriteSetTiles(lua_State *L) {
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
pps->tileX = lua_tonumber(L, 2);
pps->tileY = lua_tonumber(L, 3);
pps->tileW = pps->w / pps->tileX;
pps->tileH = pps->h / pps->tileY;
return 0;
}

int spriteGetTileSize(lua_State *L) {
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, pps->tileW);
lua_pushnumber(L, pps->tileH);
return 2;
}

int spriteGetTileNum(lua_State *L) {
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
lua_pushnumber(L, pps->tileX * pps->tileY);
return 1;
}

int spriteDrawTile(lua_State *L) {
int x, y, tileNum, angle, antialiasing;
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
x = lua_tonumber(L, 2);
y = lua_tonumber(L, 3);
tileNum = lua_tonumber(L,4);
angle = luaL_optnumber(L,5,0);
antialiasing = lua_toboolean(L,6);
spriteBlit(gfb, pps, x, y, tileNum, angle, antialiasing);
return 0;
}

int spriteDraw(lua_State *L) {
int x, y, angle, antialiasing;
sprite *pps = (sprite *)luaL_checkudata(L, 1, SPRITE_MT);
x = lua_tonumber(L, 2);
y = lua_tonumber(L, 3);
angle = luaL_optnumber(L,4,0);
antialiasing = lua_toboolean(L,5);
spriteBlit(gfb, pps, x, y, -1, angle, antialiasing);
return 0;
}

static const struct luaL_Reg sprite_m[] = {
{ "__gc", spriteGC },
{ "getHeight", spriteGetHeight },
{ "getWidth", spriteGetWidth },
{ NULL, NULL }
{ "__gc", spriteGC },
{ "getHeight", spriteGetHeight },
{ "getWidth", spriteGetWidth },
{ "getTiles", spriteGetTiles },
{ "setTiles", spriteSetTiles },
{ "getTileSize", spriteGetTileSize },
{ "getTileNum", spriteGetTileNum },
{ "tile", spriteDrawTile },
{ "draw", spriteDraw },
{ NULL, NULL }
};

void initSpriteEngine(lua_State *L) {
Expand Down
23 changes: 18 additions & 5 deletions framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,39 @@ typedef struct frameBuffer {
FPSmanager fps_mgr;
} frameBuffer;

frameBuffer *gfb;

/* Frame buffer */
frameBuffer *createFrameBuffer(int width, int height, int bpp, int fullscreen);

/* Drawing primitives */
void setPixelWithAlpha(frameBuffer *fb, int x, int y, int r, int g, int b, int alpha);
void fillBackground(frameBuffer *fb, int r, int g, int b);
void drawHline(frameBuffer *fb, int x1, int x2, int y, int r, int g, int b, int alpha);
void drawEllipse(frameBuffer *fb, int xc, int yc, int radx, int rady, int r, int g, int b, int alpha);
void drawBox(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha);
void drawTriangle(frameBuffer *fb, int x1, int y1, int x2, int y2, int x3, int y3, int r, int g, int b, int alpha);
void drawEllipse(frameBuffer *fb, int xc, int yc, int radx, int rady, int r, int g, int b, int alpha, char filled);
void drawBox(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha, char filled);
void drawTriangle(frameBuffer *fb, int x1, int y1, int x2, int y2, int x3, int y3, int r, int g, int b, int alpha, char filled);
void drawLine(frameBuffer *fb, int x1, int y1, int x2, int y2, int r, int g, int b, int alpha);
void drawPolygon(frameBuffer *fb, Sint16* xv, Sint16* yv, int n, int r, int g, int b, int alpha, char filled);

/* Bitmap font */
void bfLoadFont(char **c);
void bfWriteChar(frameBuffer *fb, int xp, int yp, int c, int r, int g, int b, int alpha);
void bfWriteString(frameBuffer *fb, int xp, int yp, const char *s, int len, int r, int g, int b, int alpha);

typedef struct sprite {
int w;
int h;
int tileX;
int tileY;
int tileW;
int tileH;
SDL_Surface *surf;
} sprite;

/* Sprites */
void spriteBlit(frameBuffer *fb, void *sprite, int x, int y, int angle, int aa);
void *spriteLoad(lua_State *L, const char *filename);
void spriteBlit(frameBuffer *fb, sprite *sp, int x, int y, int tileNum, int angle, int aa);
sprite *spriteLoad(lua_State *L, const char *filename);
void initSpriteEngine(lua_State *L);

#endif /* FRAMEBUFFER_H */
Loading