@@ 60,7 60,7 @@ cchr(int v, int cap)
int
valid(Grid *g, int x, int y)
{
- return x >= 0 && x <= g->w && y >= 0 && y <= g->h;
+ return x >= 0 && x <= g->w - 1 && y >= 0 && y <= g->h;
}
int
@@ 183,9 183,15 @@ opb(Grid *g, int x, int y, char c)
void
opc(Grid *g, int x, int y, char c)
{
+ char mod = getport(g, x + 1, y, 0);
char rate = getport(g, x - 1, y, 0);
- char mod = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, cchr(g->f / rate % mod, ciuc(mod)));
+ int mod_ = cint(mod);
+ int rate_ = cint(rate);
+ if(!rate_)
+ rate_ = 1;
+ if(!mod_)
+ mod_ = 8;
+ setport(g, x, y + 1, cchr(g->f / rate_ % mod_, ciuc(mod)));
(void)c;
}
@@ 193,37 199,50 @@ void
opd(Grid *g, int x, int y, char c)
{
char rate = getport(g, x - 1, y, 0);
- char mod = getport(g, x + 1, y, 1);
- setport(g, x, y + 1, g->f % (rate * mod) == 0 ? '*' : '.');
+ char mod = getport(g, x + 1, y, 0);
+ int rate_ = cint(rate);
+ int mod_ = cint(mod);
+ if(!rate_)
+ rate_ = 1;
+ if(!mod_)
+ mod_ = 8;
+ setport(g, x, y + 1, g->f % (rate_ * mod_) == 0 ? '*' : '.');
(void)c;
}
void
ope(Grid *g, int x, int y, char c)
{
- if(x == g->w || get(g, x + 1, y) != '.')
+ if(!valid(g, x + 1, y) || get(g, x + 1, y) != '.')
set(g, x, y, '*');
else {
set(g, x, y, '.');
+ settype(g, x, y, 0);
setport(g, x + 1, y, c);
+ lock(g, x + 1, y);
}
}
void
opf(Grid *g, int x, int y, char c)
{
- setport(g, x, y + 1, getport(g, x - 1, y, 0) == getport(g, x + 1, y, 1) ? '*' : '.');
+ char a = getport(g, x - 1, y, 0);
+ char b = getport(g, x + 1, y, 1);
+ setport(g, x, y + 1, a == b ? '*' : '.');
(void)c;
}
void
opg(Grid *g, int x, int y, char c)
{
- int tx = cint(getport(g, x - 3, y, 0));
- int ty = cint(getport(g, x - 2, y, 0));
- int i, len = cint(getport(g, x - 1, y, 0));
- for(i = 0; i < len; ++i)
- setport(g, x + i + tx, y + 1 + ty, getport(g, x + 1 + i, y, 1));
+ char px = getport(g, x - 3, y, 0);
+ char py = getport(g, x - 2, y, 0);
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cint(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
+ setport(g, x + i + cint(px), y + 1 + cint(py), getport(g, x + 1 + i, y, 1));
(void)c;
}
@@ 237,18 256,24 @@ oph(Grid *g, int x, int y, char c)
void
opi(Grid *g, int x, int y, char c)
{
- char step = getport(g, x - 1, y, 0);
+ char rate = getport(g, x - 1, y, 0);
char mod = getport(g, x + 1, y, 1);
char val = getport(g, x, y + 1, 1);
- setport(g, x, y + 1, cchr((cint(val) + cint(step)) % (cint(mod) || 1), ciuc(mod)));
+ int rate_ = cint(rate);
+ int mod_ = cint(mod);
+ if(!rate_)
+ rate_ = 1;
+ if(!mod_)
+ mod_ = 36;
+ setport(g, x, y + 1, cchr((cint(val) + rate_) % mod_, ciuc(mod)));
(void)c;
}
void
opj(Grid *g, int x, int y, char c)
{
- int i;
char link = getport(g, x, y - 1, 0);
+ int i;
if(link != c) {
for(i = 1; y + i < g->h; ++i)
if(get(g, x, y + i) != c)
@@ 260,12 285,14 @@ opj(Grid *g, int x, int y, char c)
void
opk(Grid *g, int x, int y, char c)
{
- int i, len = cint(getport(g, x - 1, y, 0));
- for(i = 0; i < len; ++i) {
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cint(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i) {
char key = getport(g, x + 1 + i, y, 1);
- if(key == '.')
- continue;
- setport(g, x + 1 + i, y + 1, load(g, key));
+ if(key != '.')
+ setport(g, x + 1 + i, y + 1, load(g, key));
}
(void)c;
}
@@ 291,43 318,51 @@ opm(Grid *g, int x, int y, char c)
void
opn(Grid *g, int x, int y, char c)
{
- if(y == 0 || get(g, x, y - 1) != '.')
+ if(!valid(g, x, y - 1) || get(g, x, y - 1) != '.')
set(g, x, y, '*');
else {
set(g, x, y, '.');
+ settype(g, x, y, 0);
setport(g, x, y - 1, c);
+ lock(g, x, y - 1);
}
}
void
opo(Grid *g, int x, int y, char c)
{
- int tx = cint(getport(g, x - 2, y, 0));
- int ty = cint(getport(g, x - 1, y, 0));
- setport(g, x, y + 1, getport(g, x + 1 + tx, y + ty, 1));
+ char px = getport(g, x - 2, y, 0);
+ char py = getport(g, x - 1, y, 0);
+ setport(g, x, y + 1, getport(g, x + 1 + cint(px), y + cint(py), 1));
(void)c;
}
void
opp(Grid *g, int x, int y, char c)
{
- int key = cint(getport(g, x - 2, y, 0));
- int i, len = cint(getport(g, x - 1, y, 0));
- /* TODO */
- for(i = 0; i < len; ++i)
+ char key = getport(g, x - 2, y, 0);
+ char len = getport(g, x - 1, y, 0);
+ char val = getport(g, x + 1, y, 1);
+ int i, len_ = cint(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
lock(g, x + i, y + 1);
- setport(g, x + (key % len), y + 1, get(g, x + 1, y));
+ setport(g, x + (cint(key) % len_), y + 1, val);
(void)c;
}
void
opq(Grid *g, int x, int y, char c)
{
- int tx = cint(getport(g, x - 3, y, 0));
- int ty = cint(getport(g, x - 2, y, 0));
- int i, len = cint(getport(g, x - 1, y, 0));
- for(i = 0; i < len; ++i)
- setport(g, x + 1 - len + i, y + 1, getport(g, x + 1 + tx + i, y + ty, 1));
+ char px = getport(g, x - 3, y, 0);
+ char py = getport(g, x - 2, y, 0);
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cint(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
+ setport(g, x + 1 - len_ + i, y + 1, getport(g, x + 1 + cint(px) + i, y + cint(py), 1));
(void)c;
}
@@ 343,22 378,27 @@ opr(Grid *g, int x, int y, char c)
void
ops(Grid *g, int x, int y, char c)
{
- if(y == g->h || get(g, x, y + 1) != '.')
+ if(!valid(g, x, y + 1) || get(g, x, y + 1) != '.')
set(g, x, y, '*');
else {
set(g, x, y, '.');
- setport(g, x, y + 1, c);
+ settype(g, x, y, 0);
+ set(g, x, y + 1, c);
+ lock(g, x, y + 1);
}
}
void
opt(Grid *g, int x, int y, char c)
{
- int key = cint(getport(g, x - 2, y, 0));
- int i, len = cint(getport(g, x - 1, y, 0));
- for(i = 0; i < len; ++i)
+ char key = getport(g, x - 2, y, 0);
+ char len = getport(g, x - 1, y, 0);
+ int i, len_ = cint(len);
+ if(!len_)
+ len_ = 1;
+ for(i = 0; i < len_; ++i)
lock(g, x + 1 + i, y);
- setport(g, x, y + 1, getport(g, x + 1 + (key % len), y, 1));
+ setport(g, x, y + 1, getport(g, x + 1 + (cint(key) % len_), y, 1));
(void)c;
}
@@ 387,28 427,31 @@ opv(Grid *g, int x, int y, char c)
void
opw(Grid *g, int x, int y, char c)
{
- if(x == 0 || get(g, x - 1, y) != '.')
+ if(!valid(g, x - 1, y) || get(g, x - 1, y) != '.')
set(g, x, y, '*');
else {
set(g, x, y, '.');
+ settype(g, x, y, 0);
setport(g, x - 1, y, c);
+ lock(g, x - 1, y);
}
}
void
opx(Grid *g, int x, int y, char c)
{
- int tx = cint(getport(g, x - 2, y, 0));
- int ty = cint(getport(g, x - 1, y, 0));
- setport(g, x + tx, y + ty + 1, getport(g, x + 1, y, 1));
+ char px = getport(g, x - 2, y, 0);
+ char py = getport(g, x - 1, y, 0);
+ char val = getport(g, x + 1, y, 1);
+ setport(g, x + cint(px), y + cint(py) + 1, val);
(void)c;
}
void
opy(Grid *g, int x, int y, char c)
{
- int i;
char link = getport(g, x - 1, y, 0);
+ int i;
if(link != c) {
for(i = 1; x + i < g->w; ++i)
if(get(g, x + i, y) != c)
@@ 420,12 463,13 @@ opy(Grid *g, int x, int y, char c)
void
opz(Grid *g, int x, int y, char c)
{
- int rate = cint(getport(g, x - 1, y, 0));
+ char rate = getport(g, x - 1, y, 0);
char target = getport(g, x + 1, y, 1);
- char val = cint(getport(g, x, y + 1, 1));
- int t = cint(target);
- int mod = val < t ? rate : val > t ? -rate : 0;
- setport(g, x, y + 1, cchr(val + mod, ciuc(target)));
+ char val = getport(g, x, y + 1, 1);
+ int rate_ = cint(rate);
+ int target_ = cint(target);
+ int val_ = cint(val);
+ setport(g, x, y + 1, cchr(val_ + val_ < target_ ? rate_ : val_ > target_ ? -rate_ : 0, ciuc(target)));
(void)c;
}
@@ 458,6 502,7 @@ opspecial(Grid *g, int x, int y)
void
operate(Grid *g, int x, int y, char c)
{
+ settype(g, x, y, 3);
switch(clca(c)) {
case 'a': opa(g, x, y, c); break;
case 'b': opb(g, x, y, c); break;
@@ 489,7 534,6 @@ operate(Grid *g, int x, int y, char c)
case '#': opcomment(g, x, y); break;
default: opspecial(g, x, y);
}
- settype(g, x, y, 3);
}
/* General */
@@ 529,6 573,8 @@ run(Grid *g)
y = i / g->w;
if(c == '.' || g->lock[i])
continue;
+ if(cinu(c))
+ continue;
if(cilc(c) && !bang(g, x, y))
continue;
operate(g, x, y, c);
@@ 5,12 5,12 @@
#define HOR 32
#define VER 16
#define PAD 8
-#define ZOOM 1
+#define ZOOM 2
#define color1 0x000000
#define color2 0x72DEC2
-#define color3 0x888888
-#define color4 0xFFFFFF
-#define color0 0x222222
+#define color3 0xFFFFFF
+#define color4 0x444444
+#define color0 0xffb545
#define PLIMIT 256
#define SZ (HOR * VER * 16)
@@ 23,7 23,7 @@ typedef struct {
int x, y, w, h;
} Rect2d;
-unsigned char font[80];
+unsigned char font[1200];
int colors[] = {color1, color2, color3, color4, color0};
int WIDTH = 8 * HOR + PAD * 2;
int HEIGHT = 8 * VER + PAD * 2;
@@ 36,7 36,6 @@ SDL_Texture *gTexture = NULL;
uint32_t *pixels;
Rect2d selection;
-
Grid g;
Point2d
@@ 56,36 55,27 @@ clampt(Point2d p, int step)
return p;
}
-void
-select(int x, int y, int w, int h)
+int
+clamp(int val, int min, int max)
{
- selection.x = x;
- selection.y = y;
- selection.w = w;
- selection.h = h;
- draw(pixels);
+ return (val >= min) ? (val <= max) ? val : max : min;
}
int
selected(int x, int y)
{
- return selection.x == x && selection.y == y;
+ return x < selection.x + selection.w && x >= selection.x && y < selection.y + selection.h && y >= selection.y;
}
void
-move(int x, int y)
+insert(char c)
{
- int reqdraw = 0;
- if((x < 0 && selection.x > 0) || (x > 0 && selection.x < HOR - 1)) {
- selection.x += x;
- reqdraw = 1;
- }
- if((y < 0 && selection.y > 0) || (y > 0 && selection.y < VER - 1)) {
- selection.y += y;
- reqdraw = 1;
+ int x, y;
+ for(x = 0; x < selection.w; ++x) {
+ for(y = 0; y < selection.h; ++y) {
+ set(&g, selection.x + x, selection.y + y, c);
+ }
}
- if(reqdraw)
- draw(pixels);
}
/* misc */
@@ 102,20 92,65 @@ guide(int x, int y)
return 0;
}
+int
+getfont(int x, int y, char c, int type, int sel)
+{
+ if(c >= 'A' && c <= 'Z')
+ return c - 'A' + 36;
+ if(c >= 'a' && c <= 'z')
+ return c - 'a' + 10;
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c == '*')
+ return 62;
+ if(c == '#')
+ return 63;
+ if(c == ':')
+ return 65;
+ if(x % 8 == 0 && y % 8 == 0)
+ return 68;
+ if(c == '.' && type)
+ return 64;
+ if(c == '.' && !sel)
+ return 70;
+ if(selection.x == x && selection.y == y)
+ return 66;
+ if(sel)
+ return 64;
+ return 70;
+}
+
+int
+getstyle(int clr, int type, int sel)
+{
+ if(sel)
+ return colors[clr == 0 ? 4 : 0];
+ if(type == 2)
+ return colors[clr == 0 ? 0 : 1];
+ if(type == 3)
+ return colors[clr == 0 ? 1 : 0];
+ if(type == 4)
+ return colors[clr == 0 ? 0 : 2];
+ if(type == 5)
+ return colors[clr == 0 ? 2 : 0];
+ return colors[clr == 0 ? 0 : 3];
+}
+
void
drawtile(uint32_t *dst, int x, int y, char c, int type)
{
int v, h;
- int target = 0;
+ int sel = selected(x, y);
+ int offset = getfont(x, y, c, type, sel) * 8 * 2;
for(v = 0; v < 8; v++)
- for(h = 7; h >= 0; h--) {
- int px = (x * 8) + h;
+ for(h = 0; h < 8; h++) {
+ int px = (x * 8) + (8 - h);
int py = (y * 8) + v;
- int ch1 = font[v];
- int ch2 = font[v + 8];
- int clr = ((ch1 >> h) & 0x1) + (((ch2 >> h) & 0x1) << 1);
+ int ch1 = font[offset + v];
+ int ch2 = font[offset + v + 8];
+ int clr = ((ch1 >> h) & 0x1) + ((ch2 << h) & 0x1);
int key = (py + PAD) * WIDTH + (px + PAD);
- dst[key] = selected(x, y) ? colors[(clr + 1) % 5] : colors[clr];
+ dst[key] = getstyle(clr, type, sel);
}
}
@@ 132,6 167,36 @@ draw(uint32_t *dst)
SDL_RenderPresent(gRenderer);
}
+void
+select(int x, int y, int w, int h)
+{
+ selection.x = x;
+ selection.y = y;
+ selection.w = w;
+ selection.h = h;
+ draw(pixels);
+}
+
+void
+move(int x, int y)
+{
+ selection.x += x;
+ selection.y += y;
+ selection.x = clamp(selection.x, 0, HOR);
+ selection.y = clamp(selection.y, 0, VER);
+ draw(pixels);
+}
+
+void
+scale(int w, int h)
+{
+ selection.w += w;
+ selection.h += h;
+ selection.w = clamp(selection.w, 1, 8);
+ selection.h = clamp(selection.h, 1, 8);
+ draw(pixels);
+}
+
int
error(char *msg, const char *err)
{
@@ 164,17 229,15 @@ domouse(SDL_Event *event)
{
Point2d touch = clampt(
Pt2d(
- (event->motion.x - (PAD * ZOOM)) / ZOOM,
- (event->motion.y - (PAD * ZOOM)) / ZOOM),
+ (event->motion.x - (PAD * ZOOM) - (8 * ZOOM / 2)) / ZOOM,
+ (event->motion.y - (PAD * ZOOM) - (8 * ZOOM / 2)) / ZOOM),
8);
switch(event->type) {
case SDL_MOUSEBUTTONUP:
- printf("mouse-up\n");
+ select(selection.x, selection.y, touch.x / 8 - selection.x + 1, touch.y / 8 - selection.y + 1);
break;
case SDL_MOUSEBUTTONDOWN:
- printf("%d,%d\n", touch.x / 8, touch.y / 8);
select(touch.x / 8, touch.y / 8, 1, 1);
- printf("mouse-down\n");
break;
case SDL_MOUSEMOTION:
break;
@@ 184,29 247,55 @@ domouse(SDL_Event *event)
void
dokey(SDL_Event *event)
{
+ int shift = SDL_GetModState() & KMOD_LSHIFT || SDL_GetModState() & KMOD_RSHIFT;
switch(event->key.keysym.sym) {
- case SDLK_s:
- set(&g, selection.x, selection.y, 'S');
- break;
- case SDLK_0:
- set(&g, selection.x, selection.y, '0');
- break;
- case SDLK_UP:
- move(0, -1);
- printf("up\n");
- break;
- case SDLK_DOWN:
- move(0, 1);
- printf("down\n");
- break;
- case SDLK_LEFT:
- move(-1, 0);
- printf("left\n");
- break;
- case SDLK_RIGHT:
- move(1, 0);
- printf("right\n");
- break;
+ case SDLK_BACKSPACE: insert('.'); break;
+ case SDLK_ASTERISK: insert('*'); break;
+ case SDLK_HASH: insert('#'); break;
+ case SDLK_PERIOD: insert('.'); break;
+ case SDLK_COLON: insert(':'); break;
+ case SDLK_SEMICOLON: insert(':'); break;
+ case SDLK_ESCAPE: select(selection.x, selection.y, 1, 1); break;
+ case SDLK_0: insert('0'); break;
+ case SDLK_1: insert('1'); break;
+ case SDLK_2: insert('2'); break;
+ case SDLK_3: insert(shift ? '#' : '3'); break;
+ case SDLK_4: insert('4'); break;
+ case SDLK_5: insert('5'); break;
+ case SDLK_6: insert('6'); break;
+ case SDLK_7: insert('7'); break;
+ case SDLK_8: insert('8'); break;
+ case SDLK_9: insert('9'); break;
+ case SDLK_a: insert(shift ? 'A' : 'a'); break;
+ case SDLK_b: insert(shift ? 'B' : 'b'); break;
+ case SDLK_c: insert(shift ? 'C' : 'c'); break;
+ case SDLK_d: insert(shift ? 'D' : 'd'); break;
+ case SDLK_e: insert(shift ? 'E' : 'e'); break;
+ case SDLK_f: insert(shift ? 'F' : 'f'); break;
+ case SDLK_g: insert(shift ? 'G' : 'g'); break;
+ case SDLK_h: insert(shift ? 'H' : 'h'); break;
+ case SDLK_i: insert(shift ? 'I' : 'i'); break;
+ case SDLK_j: insert(shift ? 'J' : 'j'); break;
+ case SDLK_k: insert(shift ? 'K' : 'k'); break;
+ case SDLK_l: insert(shift ? 'L' : 'l'); break;
+ case SDLK_m: insert(shift ? 'M' : 'm'); break;
+ case SDLK_n: insert(shift ? 'N' : 'n'); break;
+ case SDLK_o: insert(shift ? 'O' : 'o'); break;
+ case SDLK_p: insert(shift ? 'P' : 'p'); break;
+ case SDLK_q: insert(shift ? 'Q' : 'q'); break;
+ case SDLK_r: insert(shift ? 'R' : 'r'); break;
+ case SDLK_s: insert(shift ? 'S' : 's'); break;
+ case SDLK_t: insert(shift ? 'T' : 't'); break;
+ case SDLK_u: insert(shift ? 'U' : 'u'); break;
+ case SDLK_v: insert(shift ? 'V' : 'v'); break;
+ case SDLK_w: insert(shift ? 'W' : 'w'); break;
+ case SDLK_x: insert(shift ? 'X' : 'x'); break;
+ case SDLK_y: insert(shift ? 'Y' : 'y'); break;
+ case SDLK_z: insert(shift ? 'Z' : 'z'); break;
+ case SDLK_UP: shift ? scale(0, -1) : move(0, -1); break;
+ case SDLK_DOWN: shift ? scale(0, 1) : move(0, 1); break;
+ case SDLK_LEFT: shift ? scale(-1, 0) : move(-1, 0); break;
+ case SDLK_RIGHT: shift ? scale(1, 0) : move(1, 0); break;
}
/* update(); */
}
@@ 217,7 306,7 @@ init(void)
int i, j;
if(SDL_Init(SDL_INIT_VIDEO) < 0)
return error("Init", SDL_GetError());
- gWindow = SDL_CreateWindow("Toy",
+ gWindow = SDL_CreateWindow("Orca",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH * ZOOM,
@@ 247,7 336,6 @@ init(void)
int
loadfont(void)
{
- int i;
FILE *f = fopen("font.chr", "rb");
if(f == NULL)
return error("Font", "Invalid input file");
@@ 269,14 357,7 @@ main(int argc, char *argv[])
return error("Font", "Failure");
create(&g, HOR, VER);
- set(&g, 3, 3, 'S');
- set(&g, 3, 6, 'A');
- set(&g, 4, 6, 'a');
- set(&g, 7, 2, '0');
- set(&g, 8, 7, '0');
- run(&g);
-
- select(0, 0, 0, 0);
+ select(0, 0, 1, 1);
draw(pixels);
while(1) {
@@ 286,7 367,7 @@ main(int argc, char *argv[])
SDL_Delay(ticknext - tick);
ticknext = tick + (1000 / FPS);
- if(tickrun == 10) {
+ if(tickrun == 8) {
run(&g);
draw(pixels);
tickrun = 0;