@@ 51,11 51,11 @@ Uint32 theme[] = {
0xffb545};
Uint8 icons[][8] = {
- {0x86, 0xc6, 0xe6, 0xf6, 0xe6, 0xc6, 0x86, 0x00}, /* play */
- {0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00}, /* pause */
- {0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00},
- {0x06, 0x18, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00},
- {0x02, 0x02, 0x04, 0x38, 0x40, 0x80, 0x80, 0x00},
+ {0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00}, /* play */
+ {0x38, 0x7c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x00}, /* stop */
+ {0x86, 0xc6, 0xe6, 0xf6, 0xe6, 0xc6, 0x86, 0x00}, /* step */
+ {0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x00, 0x00}, /* bang */
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* null */
{0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00},
{0x1e, 0x06, 0x0a, 0x12, 0x20, 0x40, 0x80, 0x00},
{0x06, 0x18, 0x22, 0x40, 0x42, 0x80, 0xaa, 0x00},
@@ 63,8 63,80 @@ Uint8 icons[][8] = {
{0x00, 0x38, 0x44, 0x92, 0x28, 0x10, 0x00, 0x00} /* eye closed */
};
+Uint8 font[][8] = {
+ {0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00},
+ {0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x00},
+ {0x00, 0x00, 0x7c, 0x02, 0x3c, 0x40, 0x7e, 0x00},
+ {0x00, 0x00, 0x7c, 0x02, 0x7c, 0x02, 0x7c, 0x00},
+ {0x00, 0x00, 0x12, 0x22, 0x42, 0x7e, 0x02, 0x00},
+ {0x00, 0x00, 0x7e, 0x40, 0x3c, 0x02, 0x7e, 0x00},
+ {0x00, 0x00, 0x3e, 0x40, 0x7c, 0x42, 0x3c, 0x00},
+ {0x00, 0x00, 0x7e, 0x02, 0x04, 0x08, 0x10, 0x00},
+ {0x00, 0x00, 0x7e, 0x42, 0x3c, 0x42, 0x7e, 0x00},
+ {0x00, 0x00, 0x7e, 0x42, 0x3e, 0x02, 0x02, 0x00},
+ {0x00, 0x00, 0x7c, 0x02, 0x3e, 0x42, 0x7a, 0x00},
+ {0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x7c, 0x00},
+ {0x00, 0x00, 0x00, 0x3e, 0x40, 0x40, 0x3e, 0x00},
+ {0x00, 0x00, 0x02, 0x02, 0x3e, 0x42, 0x3e, 0x00},
+ {0x00, 0x00, 0x3c, 0x42, 0x7c, 0x40, 0x3e, 0x00},
+ {0x00, 0x00, 0x3c, 0x42, 0x70, 0x40, 0x40, 0x00},
+ {0x00, 0x00, 0x3e, 0x42, 0x3e, 0x02, 0x7c, 0x00},
+ {0x00, 0x00, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00},
+ {0x00, 0x00, 0x7e, 0x04, 0x04, 0x44, 0x38, 0x00},
+ {0x00, 0x00, 0x42, 0x44, 0x78, 0x44, 0x42, 0x00},
+ {0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x3e, 0x00},
+ {0x00, 0x00, 0x6c, 0x52, 0x52, 0x52, 0x52, 0x00},
+ {0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x1c, 0x22, 0x42, 0x44, 0x38, 0x00},
+ {0x00, 0x00, 0x7c, 0x42, 0x7c, 0x40, 0x40, 0x00},
+ {0x00, 0x00, 0x3e, 0x42, 0x3e, 0x02, 0x02, 0x00},
+ {0x00, 0x00, 0x5c, 0x62, 0x40, 0x40, 0x40, 0x00},
+ {0x00, 0x00, 0x3e, 0x40, 0x3c, 0x02, 0x7c, 0x00},
+ {0x00, 0x00, 0x7e, 0x10, 0x10, 0x10, 0x08, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x42, 0x46, 0x3a, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x24, 0x24, 0x18, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x52, 0x52, 0x6c, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x3e, 0x02, 0x7c, 0x00},
+ {0x00, 0x00, 0x7e, 0x04, 0x18, 0x20, 0x7e, 0x00},
+ {0x00, 0x00, 0x3c, 0x42, 0x7e, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x7c, 0x42, 0x7c, 0x42, 0x7c, 0x00},
+ {0x00, 0x00, 0x3e, 0x40, 0x40, 0x40, 0x3e, 0x00},
+ {0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x00},
+ {0x00, 0x00, 0x7e, 0x40, 0x7e, 0x40, 0x7e, 0x00},
+ {0x00, 0x00, 0x7e, 0x40, 0x70, 0x40, 0x40, 0x00},
+ {0x00, 0x00, 0x3e, 0x40, 0x5c, 0x42, 0x3e, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00},
+ {0x00, 0x00, 0x7e, 0x02, 0x02, 0x42, 0x3c, 0x00},
+ {0x00, 0x00, 0x46, 0x48, 0x70, 0x48, 0x46, 0x00},
+ {0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00},
+ {0x00, 0x00, 0x6e, 0x52, 0x52, 0x52, 0x52, 0x00},
+ {0x00, 0x00, 0x62, 0x52, 0x4a, 0x46, 0x42, 0x00},
+ {0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00},
+ {0x00, 0x00, 0x7e, 0x42, 0x7c, 0x40, 0x40, 0x00},
+ {0x00, 0x00, 0x3c, 0x42, 0x4a, 0x44, 0x3a, 0x00},
+ {0x00, 0x00, 0x7e, 0x42, 0x7c, 0x42, 0x42, 0x00},
+ {0x00, 0x00, 0x3e, 0x40, 0x7e, 0x02, 0x7c, 0x00},
+ {0x00, 0x00, 0x7e, 0x10, 0x10, 0x10, 0x10, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00},
+ {0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00},
+ {0x00, 0x00, 0x52, 0x52, 0x52, 0x52, 0x6e, 0x00},
+ {0x00, 0x00, 0x42, 0x24, 0x18, 0x24, 0x42, 0x00},
+ {0x00, 0x00, 0x42, 0x24, 0x10, 0x10, 0x10, 0x00},
+ {0x00, 0x00, 0x7e, 0x02, 0x3c, 0x40, 0x7e, 0x00},
+ {0x00, 0x00, 0x5a, 0x24, 0x42, 0x24, 0x5a, 0x00},
+ {0x00, 0x00, 0x24, 0x7e, 0x24, 0x7e, 0x24, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00},
+ {0x00, 0x00, 0x66, 0x5a, 0x24, 0x5a, 0x66, 0x00},
+ {0x00, 0x00, 0x00, 0x32, 0x42, 0x4c, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
char clip[1024];
-Uint8 font[1200];
Note playing[16];
SDL_Window *gWindow = NULL;
@@ 85,15 157,6 @@ selected(int x, int y)
return x < cursor.x + cursor.w && x >= cursor.x && y < cursor.y + cursor.h && y >= cursor.y;
}
-void
-insert(char c)
-{
- int x, y;
- for(x = 0; x < cursor.w; ++x)
- for(y = 0; y < cursor.h; ++y)
- set(&g, cursor.x + x, cursor.y + y, c);
-}
-
/* misc */
int
@@ 136,24 199,6 @@ getstyle(int clr, int type, int sel)
return clr == 0 ? 0 : 3;
}
-void
-drawtile(Uint32 *dst, int x, int y, char c, int type)
-{
- int v, h;
- int sel = selected(x, y);
- int offset = getfont(x, y, c, type, sel) * 8 * 2;
- for(v = 0; v < 8; v++)
- for(h = 0; h < 8; h++) {
- int px = (x * 8) + (8 - h);
- int py = (y * 8) + v;
- 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] = theme[getstyle(clr, type, sel)];
- }
-}
-
int
keypixel(int x, int y)
{
@@ 168,6 213,20 @@ putpixel(Uint32 *dst, int x, int y, int color)
}
void
+drawtile(Uint32 *dst, int x, int y, char c, int type)
+{
+ int v, h;
+ int sel = selected(x, y);
+ int offset = getfont(x, y, c, type, sel);
+ Uint8 *icon = font[offset];
+ for(v = 0; v < 8; v++)
+ for(h = 0; h < 8; h++) {
+ int style = getstyle((icon[v] >> (7 - h)) & 0x1, type, sel);
+ putpixel(dst, x * 8 + h, y * 8 + v, style);
+ }
+}
+
+void
drawicon(Uint32 *dst, int x, int y, Uint8 *icon, int color)
{
int v, h;
@@ 182,7 241,9 @@ void
drawui(Uint32 *dst)
{
int bottom = VER * 8 + 8;
- drawicon(dst, 0, bottom, icons[PAUSE == 1 ? 1 : 0], 1);
+ drawicon(dst, 0, bottom, icons[0], PAUSE ? 3 : 1);
+ drawicon(dst, 8, bottom, icons[2], PAUSE ? 1 : 3);
+ drawicon(dst, 8 * 3, bottom, icons[(g.f - 1) % 8 == 0 ? 3 : 4], 2);
}
void
@@ 199,6 260,101 @@ redraw(Uint32 *dst)
SDL_RenderPresent(gRenderer);
}
+/* midi */
+
+int
+nteval(int o, char c)
+{
+ switch(c) {
+ case 'A': return 9;
+ case 'a': return 10;
+ case 'B': return 11;
+ case 'b':
+ case 'C': return 0;
+ case 'c': return 1;
+ case 'D': return 2;
+ case 'd': return 3;
+ case 'E': return 4;
+ case 'e':
+ case 'F': return 5;
+ case 'f': return 6;
+ case 'G': return 7;
+ case 'g': return 8;
+ default:
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ else
+ return nteval(o + 12, c - 7);
+ }
+ return 0;
+}
+
+Note *
+sendmidi(int chn, int val, int vel, int len)
+{
+ int i = 0;
+ for(i = 0; i < 16; ++i) {
+ Note *n = &playing[i];
+ if(n->length < 1) {
+ n->channel = chn;
+ n->value = val;
+ n->velocity = vel;
+ n->length = len;
+ Pm_WriteShort(midi,
+ Pt_Time(),
+ Pm_Message(0x90 + chn, val, vel * 3));
+ return n;
+ }
+ }
+ return NULL;
+}
+
+void
+parsemidi(char *msg, int msglen)
+{
+ char chn, oct, nte, vel = 'z', len = '1';
+ if(msglen < 3)
+ return;
+ chn = msg[0];
+ oct = msg[1];
+ nte = msg[2];
+ if(msglen > 3)
+ vel = msg[3];
+ if(msglen > 4)
+ len = msg[4];
+ sendmidi(
+ base36(chn),
+ 12 * base36(oct) + nteval(0, nte),
+ base36(vel),
+ base36(len));
+}
+
+void
+runmsg(void)
+{
+ int i, j = 0;
+ char buf[128];
+ /* release */
+ for(i = 0; i < 16; ++i) {
+ Note *n = &playing[i];
+ if(n->length > 0) {
+ n->length--;
+ if(n->length == 0)
+ Pm_WriteShort(midi,
+ Pt_Time(),
+ Pm_Message(0x90 + n->channel, n->value, 0));
+ }
+ }
+ /* split messages */
+ for(i = 0; i < g.msglen + 1; ++i)
+ if(!g.msg[i] || cisp(g.msg[i])) {
+ buf[j] = '\0';
+ parsemidi(buf, j);
+ j = 0;
+ } else
+ buf[j++] = g.msg[i];
+}
+
/* options */
int
@@ 235,6 391,16 @@ select(int x, int y, int w, int h)
}
void
+insert(char c)
+{
+ int x, y;
+ for(x = 0; x < cursor.w; ++x)
+ for(y = 0; y < cursor.h; ++y)
+ set(&g, cursor.x + x, cursor.y + y, c);
+ redraw(pixels);
+}
+
+void
move(int x, int y)
{
select(cursor.x + x, cursor.y + y, cursor.w, cursor.h);
@@ 247,10 413,22 @@ scale(int w, int h)
}
void
+frame(void)
+{
+ rungrid(&g);
+ runmsg();
+ redraw(pixels);
+}
+
+void
selectoption(int option)
{
switch(option) {
case 0: setplay(!PAUSE); break;
+ case 1:
+ setplay(1);
+ frame();
+ break;
}
}
@@ 313,101 491,6 @@ moveclip(Rect2d *r, char *c, int x, int y)
pasteclip(r, c);
}
-/* midi */
-
-int
-nteval(int o, char c)
-{
- switch(c) {
- case 'A': return 9;
- case 'a': return 10;
- case 'B': return 11;
- case 'b':
- case 'C': return 0;
- case 'c': return 1;
- case 'D': return 2;
- case 'd': return 3;
- case 'E': return 4;
- case 'e':
- case 'F': return 5;
- case 'f': return 6;
- case 'G': return 7;
- case 'g': return 8;
- default:
- if(c >= '0' && c <= '9')
- return c - '0';
- else
- return nteval(o + 12, c - 7);
- }
- return 0;
-}
-
-Note *
-sendmidi(int chn, int val, int vel, int len)
-{
- int i = 0;
- for(i = 0; i < 16; ++i) {
- Note *n = &playing[i];
- if(n->length < 1) {
- n->channel = chn;
- n->value = val;
- n->velocity = vel;
- n->length = len;
- Pm_WriteShort(midi,
- Pt_Time(),
- Pm_Message(0x90 + chn, val, vel * 3));
- return n;
- }
- }
- return NULL;
-}
-
-void
-parsemidi(char *msg, int msglen)
-{
- char chn, oct, nte, vel = 'z', len = '1';
- if(msglen < 3)
- return;
- chn = msg[0];
- oct = msg[1];
- nte = msg[2];
- if(msglen > 3)
- vel = msg[3];
- if(msglen > 4)
- len = msg[4];
- sendmidi(
- base36(chn),
- 12 * base36(oct) + nteval(0, nte),
- base36(vel),
- base36(len));
-}
-
-void
-runmsg(void)
-{
- int i, j = 0;
- char buf[128];
- /* release */
- for(i = 0; i < 16; ++i) {
- Note *n = &playing[i];
- if(n->length > 0) {
- n->length--;
- if(n->length == 0)
- Pm_WriteShort(midi,
- Pt_Time(),
- Pm_Message(0x90 + n->channel, n->value, 0));
- }
- }
- /* split messages */
- for(i = 0; i < g.msglen + 1; ++i)
- if(!g.msg[i] || cisp(g.msg[i])) {
- buf[j] = '\0';
- parsemidi(buf, j);
- j = 0;
- } else
- buf[j++] = g.msg[i];
-}
-
/* triggers */
void
@@ 574,26 657,12 @@ init(void)
}
int
-loadfont(void)
-{
- FILE *f = fopen("font.chr", "rb");
- if(f == NULL)
- return error("Font", "Invalid font file");
- if(!fread(font, sizeof(font), 1, f))
- return error("Font", "Invalid font size");
- fclose(f);
- return 1;
-}
-
-int
main(int argc, char *argv[])
{
int ticknext = 0, tickrun = 0;
if(!init())
return error("Init", "Failure");
- if(!loadfont())
- return error("Font", "Failure");
initgrid(&g, HOR, VER);
select(0, 0, 1, 1);
@@ 612,9 681,7 @@ main(int argc, char *argv[])
ticknext = tick + (1000 / FPS);
if(!PAUSE && tickrun >= 8) {
- rungrid(&g);
- runmsg();
- redraw(pixels);
+ frame();
tickrun = 0;
}
tickrun++;