/*
 *          
 * Posner Demo - Lab 231 
 * NZ, july 2004
 * JL
 *
 */

#include <tscope.h>
#include <tscope/oldscope.h>

#define ECCENT      100         // eccentricity of frames
#define NBLOCKS     2
#define NTRIALS     20
#define ALLTRIALS   NBLOCKS * NTRIALS
#define TFIX        mtt(1500)
#define TCUE        mtt(50)
#define MAXTARGET   mtt(1000)   // maximum time the target stays onscreen
#define MAXRESPONSE mtt(2000)   // maximum time a response can be given
#define ENDO        1           // 0 for exogenous cuing


//////////
// All needed bitmaps
//////////
map *fixpunt, *target, *vierkant_dun, *vierkant_dik, *fix, *cue_l, *cue_r,
    *arrow_r, *target_l, *target_r;

//////////
// Quick 'n' dirty solution for 8/2 proportion valid/invalid trials
// 1 & 2 are valid trials, 3 & 4 invalid
//
// idem for SOA proportion
//////////
int stimlijst[NTRIALS] = { 1, 1, 1, 1, 2, 2, 2, 2, 3, 4,
    1, 1, 1, 1, 2, 2, 2, 2, 3, 4
};
int soalijst[NTRIALS] = { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
    200, 200, 200, 200, 200, 200, 200, 200, 200, 200
};

struct {
    int rt, err;
    int stim;
    int resp;
    int soa;
    int acc;
} data[ALLTRIALS];


struct {
    __int64 junk;
    __int64 t1, e1;
    __int64 t2, e2;
    __int64 t3, e3;
} tmp;


void PrepareStuff()
{
    int a;

    // :: Stimuli ::

    // produce basic elements
    fixpunt = ts_makebmp(40, 40);
    target = ts_makebmp(20, 20);
    vierkant_dun = ts_makebmp(60, 60);
    vierkant_dik = ts_makebmp(60, 60);
    arrow_r = ts_makebmp(20, 10);

    ts_tobmp(fixpunt);
    ts_fill(1);
    ts_circle(0, 0, 5);
    ts_fill(0);

    ts_tobmp(target);
    ts_fill(1);
    ts_rect(-20, -20, 20, 20);
    ts_fill(0);

    ts_tobmp(vierkant_dun);
    ts_rect(-25, -25, 25, 25);

    ts_tobmp(vierkant_dik);
    ts_rect(-25, -25, 25, 25);
    ts_rect(-28, -28, 28, 28);
    ts_rect(-29, -29, 29, 29);

    ts_tobmp(arrow_r);
    ts_fill(1);
    ts_rect(-9, -1, 9, 1);
    ts_line(10, 0, 3, -8);
    ts_line(9, 0, 2, -8);
    ts_line(10, 0, 3, 8);
    ts_line(9, 0, 2, 8);
    ts_fill(0);

    // produce the displays 
    fix = ts_makebmp(400, 60);
    cue_l = ts_makebmp(400, 60);
    cue_r = ts_makebmp(400, 60);
    target_l = ts_makebmp(400, 60);
    target_r = ts_makebmp(400, 60);

    // fixatie
    ts_tobmp(fix);
    ts_blit(fixpunt, 0, 0);
    ts_blit(vierkant_dun, -ECCENT, 0);
    ts_blit(vierkant_dun, ECCENT, 0);

    if (ENDO) {
        // endo cue_l
        ts_tobmp(cue_l);
        ts_blit(fixpunt, 0, 0);
        ts_flipblit(arrow_r, HFLIP, 0, -20);
        ts_blit(vierkant_dun, -ECCENT, 0);
        ts_blit(vierkant_dun, ECCENT, 0);

        // endo cue_r
        ts_tobmp(cue_r);
        ts_blit(fixpunt, 0, 0);
        ts_blit(arrow_r, 0, -20);
        ts_blit(vierkant_dun, -ECCENT, 0);
        ts_blit(vierkant_dun, ECCENT, 0);
    }

    else {
        // exo cue_l
        ts_tobmp(cue_l);
        ts_blit(fixpunt, 0, 0);
        ts_blit(vierkant_dik, -ECCENT, 0);
        ts_blit(vierkant_dun, ECCENT, 0);

        // exo cue_r
        ts_tobmp(cue_r);
        ts_blit(fixpunt, 0, 0);
        ts_blit(vierkant_dun, -ECCENT, 0);
        ts_blit(vierkant_dik, ECCENT, 0);
    }

    // target_l display
    ts_tobmp(target_l);
    ts_blit(fixpunt, 0, 0);
    ts_blit(vierkant_dun, -ECCENT, 0);
    ts_blit(vierkant_dun, ECCENT, 0);
    ts_blit(target, -ECCENT, 0);

    // target_r display
    ts_tobmp(target_r);
    ts_blit(fixpunt, 0, 0);
    ts_blit(vierkant_dun, -ECCENT, 0);
    ts_blit(vierkant_dun, ECCENT, 0);
    ts_blit(target, ECCENT, 0);

    // we're finished with making bitmaps so back to the screen 
    ts_toscr();

    // :: Responses ::
    ts_defkey(KEY_Z);
    ts_defkey(KEY_M);
    ts_defkey(KEY_ESC);

    // empty stuff, just in case
    for (a = 0; a < ALLTRIALS; a++) {
        data[a].rt = 0;
        data[a].err = 0;
        data[a].resp = 0;
        data[a].stim = 0;
    }
}

void DestroyStims()
{
    ts_killbmp(fix);
    ts_killbmp(cue_l);
    ts_killbmp(cue_r);
    ts_killbmp(target_l);
    ts_killbmp(target_r);
    ts_killbmp(fixpunt);
    ts_killbmp(target);
    ts_killbmp(vierkant_dun);
    ts_killbmp(vierkant_dik);
    ts_killbmp(arrow_r);
}

void trial(int trialnr)
{
    // 4 types of trials. 2 Valid and 2 invalid
    //
    // 1 = valid cue left  target left
    // 2 = valid cue right target right
    // 3 = invalid cue right target left
    // 4 = invalid cue left target right

    // show fix
    ts_vsync(&tmp.junk, &tmp.junk);
    ts_blit(fix, 0, 0);
    ts_wait(TFIX);

    // show cue_l
    if (data[trialnr].stim == 1 || data[trialnr].stim == 4) {
        ts_vsync(&tmp.t1, &tmp.e1);
        ts_blit(cue_l, 0, 0);
        ts_wait(TCUE);
    }
    // show cue_r
    if (data[trialnr].stim == 2 || data[trialnr].stim == 3) {
        ts_vsync(&tmp.t1, &tmp.e1);
        ts_blit(cue_r, 0, 0);
        ts_wait(TCUE);
    }
    // soa
    ts_vsync(&tmp.junk, &tmp.junk);
    ts_blit(fix, 0, 0);
    ts_wait(mtt(data[trialnr].soa));

    // show target_l
    if (data[trialnr].stim == 1 || data[trialnr].stim == 3) {
        ts_vsync(&tmp.t2, &tmp.e2);
        ts_blit(target_l, 0, 0);
    }
    // show target_r
    if (data[trialnr].stim == 2 || data[trialnr].stim == 4) {
        ts_vsync(&tmp.t2, &tmp.e2);
        ts_blit(target_r, 0, 0);
    }
    // time until response or maxtarget, 
    // then clear screen (well put back fixation point display)
    data[trialnr].resp = ts_resp(&tmp.t3, &tmp.e3, MAXTARGET);
    ts_blit(fix, 0, 0);

    // if necessary, wait longer for response, but only until maxresponse
    if (!data[trialnr].resp)
        data[trialnr].resp = ts_resp(&tmp.t3, &tmp.e3, MAXRESPONSE);

    // to always should be a way out
    if (data[trialnr].resp == 3)
        exit(0);

    // rt 
    data[trialnr].rt = ttm(tmp.t3 - tmp.t2);
    data[trialnr].err = ttmu(tmp.e2 + tmp.e3);
}

void Block(int blocknr)
{
    int a;
    int c, list[NTRIALS];

    // Randomisation, the easy way
    ts_rlist(NTRIALS, 1, list);

    for (c = 0; c < NTRIALS; c++) {
        data[blocknr * NTRIALS + c].stim = stimlijst[list[c]];
        data[blocknr * NTRIALS + c].soa = soalijst[list[c]];
    }

    // Trials
    for (a = 0; a < NTRIALS; a++) {
        trial(blocknr * NTRIALS + a);
    }
}

void Feedback()
{
    int a;
    // "v_rt_correct" contains: 
    // sum of all rt's from valid cued trials that were responded to correctly
    // "v_n_correct" contains: 
    // number of valid cued trials that were responded to correctly
    int v_rt_correct = 0, i_rt_correct = 0, v_rt_wrong = 0, i_rt_wrong =
        0, v_n_correct = 0, i_n_correct = 0, v_n_wrong = 0, i_n_wrong = 0;
    float v_mrt = 0, i_mrt = 0;
    float v_pe = 0, i_pe = 0;

    for (a = 0; a < ALLTRIALS; a++) {
        if (data[a].stim == 1) {
            if (data[a].resp == 1) {
                v_rt_correct += data[a].rt;
                v_n_correct++;
                data[a].acc = 1;
            } else {
                v_rt_wrong += data[a].rt;
                v_n_wrong++;
                data[a].acc = 0;
            }
        }
        if (data[a].stim == 2) {
            if (data[a].resp == 2) {
                v_rt_correct += data[a].rt;
                v_n_correct++;
                data[a].acc = 1;
            } else {
                v_rt_wrong += data[a].rt;
                v_n_wrong++;
                data[a].acc = 0;
            }
        }
        if (data[a].stim == 3) {
            if (data[a].resp == 1) {
                i_rt_correct += data[a].rt;
                i_n_correct++;
                data[a].acc = 1;
            } else {
                i_rt_wrong += data[a].rt;
                i_n_wrong++;
                data[a].acc = 0;
            }
        }
        if (data[a].stim == 4) {
            if (data[a].resp == 2) {
                i_rt_correct += data[a].rt;
                i_n_correct++;
                data[a].acc = 1;
            } else {
                i_rt_wrong += data[a].rt;
                i_n_wrong++;
                data[a].acc = 0;
            }
        }
    }

    v_mrt = v_rt_correct / v_n_correct;
    i_mrt = i_rt_correct / i_n_correct;
    v_pe =
        ((float) (v_n_wrong) /
         ((float) (v_n_correct) + (float) (v_n_wrong))) * 100;
    i_pe =
        ((float) (i_n_wrong) /
         ((float) (i_n_correct) + (float) (i_n_wrong))) * 100;


    ts_fgcolor(GREEN);
    ts_clrscr();
    ts_printf_centre(0, 0, "mean reaction times");
    ts_printf_centre(0, -10, "-------------------");
    ts_printf_centre(0, -30,
                     "Valid cues (#%d)  : %5.0lf ms (%.0lf%% err.)",
                     v_n_correct + v_n_wrong, v_mrt, v_pe);
    ts_printf_centre(0, -40,
                     "Invalid cues (#%d): %5.0lf ms (%.0lf%% err.)",
                     i_n_correct + i_n_wrong, i_mrt, i_pe);

    ts_fgcolor(WHITE);

    ts_button(XMAX - 20, -YMAX + 20);
}

void Instructions()
{
    ts_tobuff();

    // Valid left
    ts_blit(fix, 0, 100);
    ts_blit(cue_l, 0, 0);
    ts_blit(target_l, 0, -100);
    ts_fgcolor(GREEN);
    ts_printf_centre(0, YMAX - 40, "Valid cue left");
    ts_printf_right(-200, 100, "fixation");
    ts_printf_right(-200, 0, "cue");
    ts_printf_right(-200, -100, "target");
    ts_printf_right(-200, -YMAX + 40, "Response:");
    ts_printf_centre(0, -YMAX + 40, "at target onset, press 'z'");
    ts_fgcolor(WHITE);

    ts_blitbuff();
    ts_clrbuff();
    ts_button(XMAX - 20, -YMAX + 20);

    // Valid right
    ts_blit(fix, 0, 100);
    ts_blit(cue_r, 0, 0);
    ts_blit(target_r, 0, -100);
    ts_fgcolor(GREEN);
    ts_printf_centre(0, YMAX - 40, "Valid cue right");
    ts_printf_right(-200, 100, "fixation");
    ts_printf_right(-200, 0, "cue");
    ts_printf_right(-200, -100, "target");
    ts_printf_right(-200, -YMAX + 40, "Response:");
    ts_printf_centre(0, -YMAX + 40, "at target onset, press 'm'");
    ts_fgcolor(WHITE);

    ts_blitbuff();
    ts_clrbuff();
    ts_button(XMAX - 20, -YMAX + 20);

    // Invalid left
    ts_blit(fix, 0, 100);
    ts_blit(cue_l, 0, 0);
    ts_blit(target_r, 0, -100);
    ts_fgcolor(GREEN);
    ts_printf_centre(0, YMAX - 40, "Invalid cue left");
    ts_printf_right(-200, 100, "fixation");
    ts_printf_right(-200, 0, "cue");
    ts_printf_right(-200, -100, "target");
    ts_printf_right(-200, -YMAX + 40, "Response:");
    ts_printf_centre(0, -YMAX + 40, "at target onset, press 'm'");
    ts_fgcolor(WHITE);

    ts_blitbuff();
    ts_clrbuff();
    ts_button(XMAX - 20, -YMAX + 20);

    // Invalid right
    ts_blit(fix, 0, 100);
    ts_blit(cue_r, 0, 0);
    ts_blit(target_l, 0, -100);
    ts_fgcolor(GREEN);
    ts_printf_centre(0, YMAX - 40, "Invalid cue right");
    ts_printf_right(-200, 100, "fixation");
    ts_printf_right(-200, 0, "cue");
    ts_printf_right(-200, -100, "target");
    ts_printf_right(-200, -YMAX + 40, "Response:");
    ts_printf_centre(0, -YMAX + 40, "at target onset, press 'z'");
    ts_fgcolor(WHITE);

    ts_blitbuff();
    ts_clrbuff();
    ts_button(XMAX - 20, -YMAX + 20);
    ts_clrscr();

    ts_printf_centre(0, 0, "Get Ready!");
    ts_blitbuff();
    ts_button(XMAX - 20, -YMAX + 20);

    ts_clrscr();

    ts_toscr();
}

int main()
{
    int a;

    // Intro
    ts_scrsize(SIZE3);
    ts_scrmode(FULLSCREEN_ACCEL);
    ts_doublebuff(TRUE);
    ts_init();
    PrepareStuff();
    Instructions();

    // Experiment
    ts_priority(HIGH);
    for (a = 0; a < NBLOCKS; a++) {
        Block(a);
    }
    ts_priority(NORMAL);

    // Outro
    Feedback();
    DestroyStims();
    return 0;
}

END_OF_MAIN();


top
Persoonlijke pagina Universiteit GentTscope
Allegro | Cygwin | Gcc
© See license.html for copyright information