LOLWUT: version 6 initial concept.
This commit is contained in:
parent
7dd5d37b45
commit
a8c9f29787
@ -106,7 +106,7 @@ lwCanvas *lwDrawSchotter(int console_cols, int squares_per_row, int squares_per_
|
|||||||
* logical canvas. The actual returned string will require a terminal that is
|
* logical canvas. The actual returned string will require a terminal that is
|
||||||
* width/2 large and height/4 tall in order to hold the whole image without
|
* width/2 large and height/4 tall in order to hold the whole image without
|
||||||
* overflowing or scrolling, since each Barille character is 2x4. */
|
* overflowing or scrolling, since each Barille character is 2x4. */
|
||||||
sds lwRenderCanvas(lwCanvas *canvas) {
|
static sds renderCanvas(lwCanvas *canvas) {
|
||||||
sds text = sdsempty();
|
sds text = sdsempty();
|
||||||
for (int y = 0; y < canvas->height; y += 4) {
|
for (int y = 0; y < canvas->height; y += 4) {
|
||||||
for (int x = 0; x < canvas->width; x += 2) {
|
for (int x = 0; x < canvas->width; x += 2) {
|
||||||
@ -166,7 +166,7 @@ void lolwut5Command(client *c) {
|
|||||||
|
|
||||||
/* Generate some computer art and reply. */
|
/* Generate some computer art and reply. */
|
||||||
lwCanvas *canvas = lwDrawSchotter(cols,squares_per_row,squares_per_col);
|
lwCanvas *canvas = lwDrawSchotter(cols,squares_per_row,squares_per_col);
|
||||||
sds rendered = lwRenderCanvas(canvas);
|
sds rendered = renderCanvas(canvas);
|
||||||
rendered = sdscat(rendered,
|
rendered = sdscat(rendered,
|
||||||
"\nGeorg Nees - schotter, plotter on paper, 1968. Redis ver. ");
|
"\nGeorg Nees - schotter, plotter on paper, 1968. Redis ver. ");
|
||||||
rendered = sdscat(rendered,REDIS_VERSION);
|
rendered = sdscat(rendered,REDIS_VERSION);
|
||||||
|
@ -36,6 +36,94 @@
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "lolwut.h"
|
#include "lolwut.h"
|
||||||
|
|
||||||
|
/* Render the canvas using the four gray levels of the standard color
|
||||||
|
* terminal: they match very well to the grayscale display of the gameboy. */
|
||||||
|
static sds renderCanvas(lwCanvas *canvas) {
|
||||||
|
sds text = sdsempty();
|
||||||
|
for (int y = 0; y < canvas->height; y++) {
|
||||||
|
for (int x = 0; x < canvas->width; x++) {
|
||||||
|
int color = lwGetPixel(canvas,x,y);
|
||||||
|
char *ce; /* Color escape sequence. */
|
||||||
|
|
||||||
|
/* Note that we set both the foreground and background color.
|
||||||
|
* This way we are able to get a more consistent result among
|
||||||
|
* different terminals implementations. */
|
||||||
|
switch(color) {
|
||||||
|
case 0: ce = "0;30;40m"; break; /* Black */
|
||||||
|
case 1: ce = "0;90;100m"; break; /* Gray 1 */
|
||||||
|
case 2: ce = "0;37;47m"; break; /* Gray 2 */
|
||||||
|
case 3: ce = "0;97;107m"; break; /* White */
|
||||||
|
}
|
||||||
|
text = sdscatprintf(text,"\033[%s \033[0m",ce);
|
||||||
|
}
|
||||||
|
if (y != canvas->height-1) text = sdscatlen(text,"\n",1);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw a skyscraper on the canvas, according to the parameters in the
|
||||||
|
* 'skyscraper' structure. Window colors are random and are always selected
|
||||||
|
* to be different than the color of the skyscraper itsefl. */
|
||||||
|
struct skyscraper {
|
||||||
|
int xoff; /* X offset. */
|
||||||
|
int width; /* Pixels width. */
|
||||||
|
int height; /* Pixels height. */
|
||||||
|
int windows; /* Draw windows if true. */
|
||||||
|
int color; /* Color of the skyscraper. */
|
||||||
|
};
|
||||||
|
|
||||||
|
void generateSkyscraper(lwCanvas *canvas, struct skyscraper *si) {
|
||||||
|
int starty = canvas->height-1;
|
||||||
|
int endy = starty - si->height + 1;
|
||||||
|
for (int y = starty; y >= endy; y--) {
|
||||||
|
for (int x = si->xoff; x < si->xoff+si->width; x++) {
|
||||||
|
/* The roof is four pixels less wide. */
|
||||||
|
if (y == endy && (x <= si->xoff+1 || x >= si->xoff+si->width-2))
|
||||||
|
continue;
|
||||||
|
int color = si->color;
|
||||||
|
/* Alter the color if this is a place where we want to
|
||||||
|
* draw a window. We check that we are in the inner part of the
|
||||||
|
* skyscraper, so that windows are far from the borders. */
|
||||||
|
if (si->windows &&
|
||||||
|
x > si->xoff+1 &&
|
||||||
|
x < si->xoff+si->width-2 &&
|
||||||
|
y > endy+1 &&
|
||||||
|
y < starty-1)
|
||||||
|
{
|
||||||
|
/* Calculate the x,y position relative to the start of
|
||||||
|
* the window area. */
|
||||||
|
int relx = x - (si->xoff+1);
|
||||||
|
int rely = y - (endy+1);
|
||||||
|
|
||||||
|
/* Note that we want the windows to be two pixels wide
|
||||||
|
* but just one pixel tall, because terminal "pixels"
|
||||||
|
* (characters) are not square. */
|
||||||
|
if (relx/2 % 2 && rely % 2) {
|
||||||
|
do {
|
||||||
|
color = rand() % 4;
|
||||||
|
} while (color == si->color);
|
||||||
|
/* Except we want adjacent pixels creating the same
|
||||||
|
* window to be the same color. */
|
||||||
|
if (relx % 2) color = lwGetPixel(canvas,x-1,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lwDrawPixel(canvas,x,y,color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a skyline inspired by the parallax backgrounds of 8 bit games. */
|
||||||
|
void generateSkyline(lwCanvas *canvas) {
|
||||||
|
struct skyscraper si = {
|
||||||
|
.xoff = 4,
|
||||||
|
.width = 13,
|
||||||
|
.height = 15,
|
||||||
|
.windows = 1,
|
||||||
|
.color = 1
|
||||||
|
};
|
||||||
|
generateSkyscraper(canvas, &si);
|
||||||
|
}
|
||||||
|
|
||||||
/* The LOLWUT 6 command:
|
/* The LOLWUT 6 command:
|
||||||
*
|
*
|
||||||
* LOLWUT [columns] [rows]
|
* LOLWUT [columns] [rows]
|
||||||
@ -45,7 +133,7 @@
|
|||||||
*/
|
*/
|
||||||
void lolwut6Command(client *c) {
|
void lolwut6Command(client *c) {
|
||||||
long cols = 80;
|
long cols = 80;
|
||||||
long rows = 40;
|
long rows = 20;
|
||||||
|
|
||||||
/* Parse the optional arguments if any. */
|
/* Parse the optional arguments if any. */
|
||||||
if (c->argc > 1 &&
|
if (c->argc > 1 &&
|
||||||
@ -64,12 +152,14 @@ void lolwut6Command(client *c) {
|
|||||||
if (rows > 1000) rows = 1000;
|
if (rows > 1000) rows = 1000;
|
||||||
|
|
||||||
/* Generate the city skyline and reply. */
|
/* Generate the city skyline and reply. */
|
||||||
sds rendered = sdsempty();
|
lwCanvas *canvas = lwCreateCanvas(cols,rows);
|
||||||
|
generateSkyline(canvas);
|
||||||
|
sds rendered = renderCanvas(canvas);
|
||||||
rendered = sdscat(rendered,
|
rendered = sdscat(rendered,
|
||||||
"\nDedicated to the 8 bit game developers of the past. Redis ver. ");
|
"\nDedicated to the 8 bit game developers of the past. Redis ver. ");
|
||||||
rendered = sdscat(rendered,REDIS_VERSION);
|
rendered = sdscat(rendered,REDIS_VERSION);
|
||||||
rendered = sdscatlen(rendered,"\n",1);
|
rendered = sdscatlen(rendered,"\n",1);
|
||||||
addReplyVerbatim(c,rendered,sdslen(rendered),"txt");
|
addReplyVerbatim(c,rendered,sdslen(rendered),"txt");
|
||||||
sdsfree(rendered);
|
sdsfree(rendered);
|
||||||
// lwFreeCanvas(canvas);
|
lwFreeCanvas(canvas);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user