#include #include #include #define CONSTANT 1.009f SDL_Surface *d_screen; int white, black; unsigned char *sample; int pos, lpos; int pos2; float beat_pos, speed; int bend_up, bend_down; int mods[17]; char bit_codes[] = { "qwertyuiasdfghjk" }; void q_input(void) { int i; SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == 'z') { bend_down = 1; bend_up = 0; speed = 1.0f; } if (event.key.keysym.sym == 'x') { bend_up = 1; bend_down = 0; speed = 1.0f; } for (i = 0; i < 16; i++) if (event.key.keysym.sym == bit_codes[i]) mods[i + 1] = 1; if (event.key.keysym.sym == ' ') mods[17] = 1; break; case SDL_KEYUP: if (event.key.keysym.sym == 'z') { bend_down = 0; speed = 1.0f; } if (event.key.keysym.sym == 'x') { bend_up = 0; speed = 1.0f; } for (i = 0; i < 16; i++) if (event.key.keysym.sym == bit_codes[i]) mods[i + 1] = 0; if (event.key.keysym.sym == ' ') mods[17] = 0; break; } } } #define SET_BIT(x,y) (x|(1<>y)&1) int mod_pos(int in) { int out, pool, i; pool = 0; out = in; for (i = 0; i < 16; i++) if (mods[i + 1] == 1) if (TEST_BIT(out, i) == 1) pool = 1; if (mods[17] == 1 && pool == 1) return 0; for (i = 0; i < 16; i++) if (mods[i + 1] == 1 && pool == 1) out = SET_BIT(out, i); return out % 0xffff; } void draw_vline(int x, signed char h, int color) { int i, j; unsigned char *pix, *src; pix = (unsigned char *) ((int) d_screen->pixels + ((h + 128) * d_screen->pitch) + (d_screen->format->BytesPerPixel * x)); src = (unsigned char *) &color; for (i = 0; i < abs(h); i++) { for (j = 0; j < d_screen->format->BytesPerPixel; j++) pix[j] = src[j]; if (h < 0) pix += d_screen->pitch; else pix -= d_screen->pitch; } } void audio(void *userdata, Uint8 * stream, int len) { int i, j; int qq; SDL_FillRect(d_screen, NULL, white); if (bend_up == 1) speed *= CONSTANT; if (bend_down == 1) speed /= CONSTANT; SDL_LockSurface(d_screen); for (i = 0; i < len; i++) { lpos = pos2; pos2 = mod_pos(pos); if (((pos2 - 1) % 0xffff) != lpos) { beat_pos = (float) pos2; } qq = (int) beat_pos; qq &= 0xffff; if (abs(qq - pos2) > 0x7ff) stream[i] = 0x7f; else stream[i] = sample[qq]; beat_pos += speed; pos++; pos %= 0xffff; draw_vline(i, (signed char) stream[i], black); } SDL_UnlockSurface(d_screen); SDL_UpdateRect(d_screen, 0, 0, 0, 0); } SDL_AudioSpec audio_spec; int main(int argc, char **argv) { int i; FILE *fp; signed char j; SDL_AudioSpec spec; if (argc < 2) exit(-1); if (!(fp = fopen(argv[1], "rb"))) { perror(argv[1]); exit(-1); } sample = (unsigned char *) malloc(0xffff); fread(sample, 1, 0xffff, fp); fclose(fp); SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_TIMER); spec.freq = 22050; spec.format = AUDIO_S8; spec.channels = 1; spec.samples = 512; spec.callback = audio; if (SDL_OpenAudio(&spec, &audio_spec) < 0) { printf(SDL_GetError()); exit(-1); } if ((d_screen = SDL_SetVideoMode(512, 256, 16, 0)) < 0) { printf(SDL_GetError()); exit(-1); } white = SDL_MapRGB(d_screen->format, 255, 255, 255); black = SDL_MapRGB(d_screen->format, 0, 0, 0); pos = 0; lpos = 43; speed = 1.0f; bend_up = 0; bend_down = 0; bzero(mods, 256); SDL_PauseAudio(0); for (;;) q_input(); }