8

a CHIP-8 emulator
Log | Files | Refs | README

av.c (2971B)


      1 #include <SDL.h>
      2 #include <SDL_mixer.h>
      3 #include <err.h>
      4 #include <stdint.h>
      5 #include <stdio.h>
      6 #include <unistd.h>
      7 
      8 #include "av.h"
      9 
     10 extern uint8_t delaytmr;
     11 extern uint8_t soundtmr;
     12 
     13 int key[16];
     14 int quit;
     15 
     16 static int WIDTH = 64 * 8;
     17 static int HEIGHT = 32 * 8;
     18 
     19 static SDL_Window *W;
     20 static SDL_Renderer *R;
     21 static Mix_Music *M;
     22 static SDL_TimerID T;
     23 
     24 void
     25 handleev(void)
     26 {
     27 	SDL_Event e;
     28 	const Uint8 *kstate;
     29 
     30 	quit = 0;
     31 	if (SDL_PollEvent(&e)) {
     32 		kstate = SDL_GetKeyboardState(NULL);
     33 		switch (e.type) {
     34 		case SDL_QUIT:
     35 			quit = 1;
     36 			break;
     37 		default:
     38 			if (kstate[SDL_SCANCODE_ESCAPE])
     39 				quit = 1;
     40 			key[0] = kstate[SDL_SCANCODE_1];
     41 			key[1] = kstate[SDL_SCANCODE_2];
     42 			key[2] = kstate[SDL_SCANCODE_3];
     43 			key[3] = kstate[SDL_SCANCODE_4];
     44 			key[4] = kstate[SDL_SCANCODE_Q];
     45 			key[5] = kstate[SDL_SCANCODE_W];
     46 			key[6] = kstate[SDL_SCANCODE_E];
     47 			key[7] = kstate[SDL_SCANCODE_R];
     48 			key[8] = kstate[SDL_SCANCODE_A];
     49 			key[9] = kstate[SDL_SCANCODE_S];
     50 			key[10] = kstate[SDL_SCANCODE_D];
     51 			key[11] = kstate[SDL_SCANCODE_F];
     52 			key[12] = kstate[SDL_SCANCODE_Z];
     53 			key[13] = kstate[SDL_SCANCODE_X];
     54 			key[14] = kstate[SDL_SCANCODE_C];
     55 			key[15] = kstate[SDL_SCANCODE_V];
     56 			break;
     57 		}
     58 	}
     59 }
     60 
     61 unsigned int
     62 timer(unsigned int interval, void *)
     63 {
     64 	if (delaytmr > 0)
     65 		delaytmr--;
     66 	if (soundtmr > 0) {
     67 		soundtmr--;
     68 		beep();
     69 	}
     70 	return interval;
     71 }
     72 
     73 void
     74 sdlinit(void)
     75 {
     76 	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
     77 		errx(1, "SDL_Init failed: %s\n", SDL_GetError());
     78 	W = SDL_CreateWindow("8", SDL_WINDOWPOS_UNDEFINED,
     79 			SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT,
     80 			SDL_WINDOW_SHOWN);
     81 	if (W == NULL)
     82 		errx(1, "SDL_CreateWindow failed: %s\n", SDL_GetError());
     83 	R = SDL_CreateRenderer(W, -1, SDL_RENDERER_ACCELERATED);
     84 	if (R == NULL)
     85 		errx(1, "SDL_CreateRenderer failed: %s\n", SDL_GetError());
     86 	if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
     87 		errx(1, "Mix_OpenAudio failed: %s\n", Mix_GetError());
     88 	M = Mix_LoadMUS("assets/beep.wav");
     89 	if (M == NULL)
     90 		errx(1, "Mix_LoadMUS failed: %s\n", Mix_GetError());
     91 	T = SDL_AddTimer(16, timer, NULL);
     92 	if (T == 0)
     93 		errx(1, "Mix_LoadMUS failed: %s\n", Mix_GetError());
     94 }
     95 
     96 int
     97 makesound(void *)
     98 {
     99 	unsigned int tick;
    100 
    101 	tick = SDL_GetTicks();
    102 	while (1) {
    103 		if (Mix_PlayingMusic()) {
    104 			if ((SDL_GetTicks() - tick) > 4) {
    105 				Mix_HaltMusic();
    106 				return 0;
    107 			}
    108 		} else {
    109 			Mix_PlayMusic(M, -1);
    110 		}
    111 	}
    112 }
    113 
    114 void
    115 beep(void)
    116 {
    117 	SDL_CreateThread(makesound, "BEEP", NULL);
    118 }
    119 
    120 int
    121 draw(unsigned char *scene)
    122 {
    123 	SDL_Rect r;
    124 
    125 	r.w = 8;
    126 	r.h = 8;
    127 	SDL_SetRenderDrawColor(R, 0, 0, 0, 255);
    128 	SDL_RenderClear(R);
    129 	SDL_SetRenderDrawColor(R, 255, 255, 255, 255);
    130 
    131 	for (int y = 0; y < 32; ++y)
    132 		for (int x = 0; x < 64; ++x)
    133 			if (scene[x + (y * 64)]) {
    134 				r.x = x * 8;
    135 				r.y = y * 8;
    136 				SDL_RenderFillRect(R, &r);
    137 			}
    138 
    139 	SDL_RenderPresent(R);
    140 	return 0;
    141 }
    142 
    143 void
    144 sdlquit(void)
    145 {
    146 	SDL_DestroyRenderer(R);
    147 	SDL_DestroyWindow(W);
    148 	Mix_FreeMusic(M);
    149 	SDL_RemoveTimer(T);
    150 	SDL_Quit();
    151 }