コード例 #1
0
ファイル: punity.c プロジェクト: gingerBill/LD35
static void
punp_sound_load_stbv(Sound *sound, stb_vorbis *stream)
{
    stb_vorbis_info info = stb_vorbis_get_info(stream);
    sound->volume = PUNP_SOUND_DEFAULT_SOUND_VOLUME;
    sound->rate = info.sample_rate;
    sound->samples_count = stb_vorbis_stream_length_in_samples(stream);
    sound->samples = (i16 *)bank_push(CORE->storage, PUNP_SOUND_SAMPLES_TO_BYTES(sound->samples_count));

    {
        static i16 buffer[1024];
        i16 *it = sound->samples;
        int samples_read_per_channel;
        for (; ;) {
            int samples_read_per_channel =
                    stb_vorbis_get_samples_short_interleaved(stream, PUNP_SOUND_CHANNELS, buffer, 1024);

            if (samples_read_per_channel == 0) {
                break;
            }

            // 2 channels, 16 bits per sample.
            memcpy(it, buffer, PUNP_SOUND_SAMPLES_TO_BYTES(samples_read_per_channel));
            it += samples_read_per_channel * PUNP_SOUND_CHANNELS;
        }
            }
    stb_vorbis_close(stream);
}
コード例 #2
0
ファイル: punity.c プロジェクト: gingerBill/LD35
void
bitmap_init(Bitmap *bitmap, i32 width, i32 height, void *pixels, int bpp)
{
    Palette *palette = &CORE->palette;
    u32 size = width * height;

    bitmap->width = width;
    bitmap->height = height;

    bitmap->pixels = (u8 *)bank_push(CORE->storage, size);
    if (pixels) {
        if (bpp == BITMAP_32) {
            Color pixel;
            Color *pixels_end = ((Color *)pixels) + size;
            Color *pixels_it = (Color *)pixels;

            u8 *it = bitmap->pixels;
            u8 ix;

            for (; pixels_it != pixels_end; ++pixels_it) {
                if (pixels_it->a < 0x7F) {
                    ix = COLOR_TRANSPARENT;
                    // pixels_it->a = 0;
                    goto next;
                }

                pixel = *pixels_it;
                // TODO: This is just for Windows, need to be done a bit better.
                pixel.b = pixels_it->r;
                pixel.r = pixels_it->b;
                pixel.a = 0xFF;
                for (ix = 1; ix < palette->colors_count; ix++) {
                    if (palette->colors[ix].rgba == pixel.rgba)
                        goto next;
                }

                // Add the color.

                ASSERT(palette->colors_count != 0xFF);
                if (palette->colors_count != 0xFF) {
                    ix = palette->colors_count;
                    palette->colors[ix] = pixel;
                    palette->colors_count++;
                    // printf("[palette] + #%0.2x %0.2x%0.2x%0.2x%0.2x\n",
                    //        ix, pixel.r, pixel.g, pixel.b, pixel.a);
                }
            next:
                // Write the indexed color.

                *it++ = ix;
            }

        } else if (bpp == BITMAP_8)  {
            memcpy(bitmap->pixels, pixels, size);
        } else  {
            ASSERT_MESSAGE(0, "bitmap_init: Invalid bpp specified.");
        }
    } // if pixels
}
コード例 #3
0
ファイル: punity.c プロジェクト: gingerBill/LD35
void
sound_play(Sound *sound)
{
    PunPAudioSource *source = NULL;
    if (punp_audio_source_pool == 0) {
        // Pool is empty, therefore we must allocate a new source.
        source = (PunPAudioSource *)bank_push(CORE->storage, sizeof(PunPAudioSource));
        // printf("Allocating audio source.\n");
    } else {
        // We have something in the pool.
        source = punp_audio_source_pool;
        punp_audio_source_pool = source->next;
        // printf("Pooling audio source.\n");
    }

    if (source) {
        memset(source, 0, sizeof(PunPAudioSource));
        source->sound = sound;
        source->rate = (f32)sound->rate / (f32)SOUND_SAMPLE_RATE;
        source->next = punp_audio_source_playback;
        punp_audio_source_playback = source;
    }
}
コード例 #4
0
ファイル: sisy.c プロジェクト: BackupTheBerlios/sisy-svn
int
main (int ac, char **av)
{
    sisy_t sisy;
    bank_t bank;
    audio_t audio;
    int done=0;

    init_tab();

    memset(&sisy, 0, sizeof(sisy));

    bank.pos = 0;
    bank.watches_size = 0;
    bank.name = "sisy IO";
    bank.size = sizeof(sisy_IO_t);
    bank.data = &sisy.IO;
    bank.symtab = IO_symtab;
    bank_push(&bank);

    sisy_getopt(ac, av);

    instru_path[instru_path_size] = Malloc(strlen(getenv("HOME")) + strlen("/.sisy/") + 200);
    strcat(instru_path[instru_path_size], getenv("HOME"));
    strcat(instru_path[instru_path_size++], "/.sisy/");
    instru_path[instru_path_size++] = "/usr/share/sisy/";

    sisy.buffer = buffer_create();

    printf("Init midi: ");

    if(sisy_midi_init(&sisy, midi_device) < 0)
	{
	    fprintf(stderr, "ERROR: got some troubles while opening midi device %s\n", midi_device);
	    goto error;
	}

    printf("Ok\nInit audio: ");

    if(audio_init(&audio, audio_device) < 0)
	{
	    fprintf(stderr, "ERROR: got some troubles while opening audio device %s\n", audio_device);
	    goto error;
	}

    printf("Ok\nEnter in main loop...\n");

    while(!done)
	{
	    int t;
	    done=1;
	    ck_err(buffer_zero(sisy.buffer)<0);
//	    printf("%d\r", midi_timestamp_get());
	    for(t=0; t<sisy.nb_tracks; t++)
		{
		    sisy_track_t *track=&sisy.tracks[t];
		    if(!track->EOT)
			{
			    done=0;//We are not done !
			    ck_err(bank_push(&track->midi.bank));
			    ck_err(buffer_zero(track->buffer) < 0);

			    ck_err(sisy_track_process(track) < 0);

			    ck_err(bank_pop_check(&track->midi.bank));
			    ck_err(buffer_mix(track->buffer, sisy.buffer));
			}
		}
	    
/* 	    if(!is_buffer_flat(sisy.buffer)) */
/* 		printf("sisy: buffer qui bouge\n"); */

	    ck_err(audio_write(&audio, sisy.buffer)<0);
	}

/* 	ck_err(bank_pop_check(&sisy.midi.bank)); */
/* 	ck_err(bank_pop_check(&bank)); */

    audio_quit(&audio);

    return 0;
  error:
    return -1;
}
コード例 #5
0
ファイル: punity.c プロジェクト: gingerBill/LD35
// Called from platform to fill in the audio buffer.
//
static void
punp_sound_mix(i16 *buffer, isize samples_count)
{
    BankState bank_state = bank_begin(CORE->stack);

    isize size =  samples_count * sizeof(f32);
    f32 *channel0 = (f32 *)bank_push(CORE->stack, size);
    f32 *channel1 = (f32 *)bank_push(CORE->stack, size);

    f32 *it0, *it1;
    isize i;

    isize sound_samples, sound_samples_remaining;
    Sound *sound;
    PunPAudioSource **it, *source;

    //
    // Zero the channels.
    //

    it0 = channel0;
    it1 = channel1;

    memset(it0, 0, size);
    memset(it1, 0, size);

    //
    // Mix the sources.
    //

    it = &punp_audio_source_playback;

    while (*it) {
        source = *it;
        ASSERT(source->sound);
        sound = source->sound;
        sound_samples = samples_count;
        sound_samples_remaining = sound->samples_count - source->position;
        if (sound_samples > sound_samples_remaining) {
            sound_samples = sound_samples_remaining;
        }

        it0 = channel0;
        it1 = channel1;
        for (i = 0; i < sound_samples; ++i) {
            i16 *sample = &sound->samples[(source->position + (isize)((f32)i * source->rate)) * 2];
            //sample = punp_audio_source_sample(source, i);
            *it0++ += sample[0] * sound->volume;
            *it1++ += sample[1] * sound->volume;
        }

        source->position += sound_samples * source->rate;

        if (source->position == source->sound->samples_count) {
            *it = source->next;
            source->next = punp_audio_source_pool;
            punp_audio_source_pool = source;
        } else {
            it = &source->next;
        }
    }

    //
    // Put to output buffer, clamp and convert to 16-bit.
    //

// #define MIX_CLIP_(in, clip) (0.5 * (abs(in + clip) - abs(in - clip)) * CORE->audio_volume)

#if 0
    // Make sure sound buffer is not empty
    if (sound) {
        i16 *it_buffer = buffer;
        it0 = channel0;
        it1 = channel1;
        for (i = 0; i < samples_count; ++i) {
            f32 s1 = *it0++ * sound->volume * CORE->audio_volume;
            f32 s2 = *it1++ * sound->volume * CORE->audio_volume;
            // *it_buffer++ = (i16)(MIX_CLIP_(s1, 32767));
            // *it_buffer++ = (i16)(MIX_CLIP_(s2, 32767));
            // *it_buffer++ = (i16)(s1 + 0.5f);
            // *it_buffer++ = (i16)(s2 + 0.5f);
            *it_buffer++ = (i16)clamp(s1, -32768, 32767);
            *it_buffer++ = (i16)clamp(s2, -32768, 32767);
        }
    }
#endif
// #undef MIX_CLIP_

    bank_end(&bank_state);
}
コード例 #6
0
ファイル: punity.c プロジェクト: gingerBill/LD35
int CALLBACK
WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR command_line, int show_code)
{
    static Bank s_stack = {0};
    static Bank s_storage = {0};
    static Core s_core = {0};
    static Bitmap s_canvas = {0};
    WNDCLASSA window_class = {0};
    u32 *window_buffer = NULL;
    BITMAPINFO window_bmi = {0};


    if (align_to(CANVAS_WIDTH, 16) != CANVAS_WIDTH) {
        printf("CANVAS_WIDTH must be aligned to 16.\n");
        return 1;
    }


    CORE = &s_core;
    CORE->running = 1;
    CORE->stack = &s_stack;
    CORE->storage = &s_storage;

    bank_init(CORE->stack, STACK_CAPACITY);
    bank_init(CORE->storage, STORAGE_CAPACITY);

    // TODO: Push canvas to storage? Storage is not initialized yet, so we cannot push it there.
    CORE->canvas = &s_canvas;
    bitmap_init(CORE->canvas, CANVAS_WIDTH, CANVAS_HEIGHT, 0, 0);
    bitmap_clear(CORE->canvas, COLOR_TRANSPARENT);

    clip_reset();

    CORE->audio_volume = PUNP_SOUND_DEFAULT_MASTER_VOLUME;

    //
    //
    //

    punp_win32_instance = instance;
    QueryPerformanceFrequency((LARGE_INTEGER *)&punp_win32_perf_counter_frequency);

    // b32 sleep_is_granular = (timeBeginPeriod(1 /*ms*/) == TIMERR_NOERROR);

#ifndef RELEASE_BUILD
    printf("Debug build...");
    if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
        freopen("CONOUT$", "w", stdout);
        freopen("CONOUT$", "w", stderr);
    }
#else
    printf("Release build...");
#endif

    window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    window_class.lpfnWndProc = win32_window_callback;
    window_class.hInstance = punp_win32_instance;
    // window_class.hIcon = (HICON)LoadImage(0, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED);
    window_class.hIcon = (HICON)LoadIcon(instance, "icon.ico");
    window_class.hCursor = LoadCursor(0, IDC_ARROW);
    window_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    window_class.lpszClassName = "Punity";

    if (!RegisterClassA(&window_class)) {
        printf("RegisterClassA failed.\n");
        return 1;
    }

    {
        int screen_width = GetSystemMetrics(SM_CXSCREEN);
        int screen_height = GetSystemMetrics(SM_CYSCREEN);
        RECT rc;
        DWORD style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;

        rc.left = (screen_width - (PUNP_WINDOW_WIDTH)) / 2;
        rc.top = (screen_height - (PUNP_WINDOW_HEIGHT)) / 2;
        rc.right = rc.left + PUNP_WINDOW_WIDTH;
        rc.bottom = rc.top + PUNP_WINDOW_HEIGHT;


        ASSERT(AdjustWindowRect(&rc, style, FALSE) != 0);

        // int window_width  = rc.right - rc.left;
        // int window_height = rc.bottom - rc.top;
        // rc.left = (screen_width  - width) / 2;
        // rc.top  = (screen_height - height) / 2;

        punp_win32_window = CreateWindowExA(
                0,
                window_class.lpszClassName,
                WINDOW_TITLE,
                style,
                rc.left, rc.top,
                rc.right - rc.left, rc.bottom - rc.top,
                0, 0,
                punp_win32_instance,
                0);
    }
    if (!punp_win32_window) {
        printf("CreateWindowExA failed.\n");
        return 1;
    }

    // Canvas
    window_bmi.bmiHeader.biSize = sizeof(window_bmi.bmiHeader);
    window_bmi.bmiHeader.biWidth = CANVAS_WIDTH;
    window_bmi.bmiHeader.biHeight = CANVAS_HEIGHT;
    window_bmi.bmiHeader.biPlanes = 1;
    window_bmi.bmiHeader.biBitCount = 32;
    window_bmi.bmiHeader.biCompression = BI_RGB;

    window_buffer = (u32 *)bank_push(CORE->stack, (CANVAS_WIDTH * 4) * CANVAS_HEIGHT);
    ASSERT(window_buffer);

    // Sound

    if (punp_win32_sound_init() == 0) {
        punp_win32_audio_buffer = 0;
    }


    init();


    // TODO: Center window
    ShowWindow(punp_win32_window, SW_SHOW);

    {
        f64 frame_time_stamp, frame_time_now, frame_time_delta;
        int x, y;
        u32 *window_row;
        u8 *canvas_it;
        MSG message;
        perf_from(&CORE->perf_frame);
        while (CORE->running) {
            perf_to(&CORE->perf_frame);
            perf_from(&CORE->perf_frame_inner);

            memset(&CORE->key_deltas, 0, KEYS_MAX);

            while (PeekMessage(&message, 0, 0, 0, PM_REMOVE)) {
                if (message.message == WM_QUIT) {
                    CORE->running = 0;
                }

                TranslateMessage(&message);
                DispatchMessageA(&message);
            }

            perf_from(&CORE->perf_step);
            step();
            perf_to(&CORE->perf_step);

            perf_from(&CORE->perf_audio);
            if (punp_win32_audio_buffer) {
                punp_win32_sound_step();
            }
            perf_to(&CORE->perf_audio);

            perf_from(&CORE->perf_blit);
            perf_from(&CORE->perf_blit_cvt);
            canvas_it = CORE->canvas->pixels;
            for (y = CANVAS_HEIGHT; y != 0; --y) {
                window_row = window_buffer + ((y - 1) * CANVAS_WIDTH);
                for (x = 0; x != CANVAS_WIDTH; ++x) {
                    *(window_row++) = CORE->palette.colors[*canvas_it++].rgba;
                }
            }
            perf_to(&CORE->perf_blit_cvt);

            perf_from(&CORE->perf_blit_gdi);
            {
                HDC dc = GetDC(punp_win32_window);
        #if 1
                // TODO: This is sadly slow (50us on my machine), need to find a faster way to do this.
                StretchDIBits(dc,
                              0, 0, CANVAS_WIDTH * CANVAS_SCALE, CANVAS_HEIGHT * CANVAS_SCALE,
                              0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
                              window_buffer,
                              &window_bmi,
                              DIB_RGB_COLORS,
                              SRCCOPY);
        #else
        #endif
                ReleaseDC(punp_win32_window, dc);
            }
            perf_to(&CORE->perf_blit_gdi);
            perf_to(&CORE->perf_blit);

            perf_to(&CORE->perf_frame_inner);

            {
                f32 frame_delta = perf_delta(&CORE->perf_frame);
                if (frame_delta < PUNP_FRAME_TIME) {
                    // printf("sleeping ... %.3f\n", (f32)PUNP_FRAME_TIME - frame_delta);
                    Sleep((PUNP_FRAME_TIME - frame_delta) * 1e3);
                }
            }
            CORE->frame++;

    #if 0
            printf("stack %d storage %d\n",
                   CORE->stack->it - CORE->stack->begin,
                   CORE->storage->it - CORE->storage->begin);
    #endif
        }
    }

#if PUNP_SOUND_DEBUG_FILE
    fclose(punp_audio_buf_file);
#endif

    return 0;
}