Example #1
0
sd_stringparser* sd_stringparser_create() {
    sd_stringparser *parser = (sd_stringparser*)malloc(sizeof(sd_stringparser));
    parser->is_frame_ready = 0;
    memset(&parser->current_frame, 0, sizeof(sd_stringparser_frame));
    parser->current_frame.parser = parser;
    parser->frame_list = malloc(sizeof(frame_list));
    memset(parser->frame_list, 0 , sizeof(frame_list));
    parser->string = 0;
    sd_stringparser_reset(parser);
    return parser;
}
Example #2
0
int sd_stringparser_set_string(sd_stringparser *parser, const char *string) {
    if(parser->string) free(parser->string);
    parser->string = sd_strdup(string);

    sd_stringparser_reset(parser);

    int frames=0;
    parse_string(parser, cb_count_frame, NULL, &frames);
    sd_framelist_resize(parser->frame_list, frames);

    // ignore animation string that does not contain frame letters
    if(frames > 0) {
        frames = 0;
        parse_string(parser, cb_set_frame, NULL, &frames);

        // now store the tags and params into the frame struct
        frames = 0;
        parse_string(parser, cb_count_frame, cb_store_tag, &frames);
        return 0;
    }
    return SD_ANIM_INVALID_STRING;
}
Example #3
0
void player_run(object *obj) {
    // Some vars for easier life
    player_animation_state *state = &obj->animation_state;
    player_sprite_state *rstate = &obj->sprite_state;
    if(state->finished) return;

    // Handle slide operation
    if(obj->slide_state.timer > 0) {
        obj->pos.x += obj->slide_state.vel.x;
        obj->pos.y += obj->slide_state.vel.y;
        obj->slide_state.timer--;
    }

    // Not sure what this does
    int run_ret;
    if(state->end_frame == UINT32_MAX) {
        run_ret = sd_stringparser_run(
            state->parser, 
            state->ticks - 1);
    } else {
        run_ret = sd_stringparser_run_frames(
            state->parser, 
            state->ticks - 1, 
            state->end_frame);
    }

    // Handle frame
    if(run_ret == 0) {
        // Handle frame switch
        sd_stringparser_frame *param = &state->parser->current_frame;
        sd_stringparser_frame n_param;
        sd_stringparser_frame *f = param;
        sd_stringparser_frame *n = &n_param;
        int real_frame = param->letter - 65;

        // Do something if animation is finished!
        if(param->is_animation_end) {
            if(state->repeat) {
                player_reset(obj);
                sd_stringparser_run(state->parser, state->ticks - 1);
                real_frame = param->letter - 65;
            } else if(obj->finish != NULL) {
                obj->cur_sprite = NULL;
                obj->finish(obj);
                return;
            } else {
                obj->cur_sprite = NULL;
                state->finished = 1;
                return;
            }
        }

        // If frame changed, do something
        if(param->id != state->previous) {
            player_clear_frame(obj);
            
            // Tick management
            if(isset(f, "d"))   {
                cmd_tickjump(obj, get(f, "d"));
                sd_stringparser_reset(state->parser);
            }
        
            // Animation management
            if(isset(f, "m") && state->spawn != NULL) {
                int mx = isset(f, "mx") ? get(f, "mx") : 0;
                int my = isset(f, "my") ? get(f, "my") : 0;
                int mg = isset(f, "mg") ? get(f, "mg") : 0;
                DEBUG("Spawning %d, with g = %d, pos = (%d,%d)", 
                    get(f, "m"), mg, mx, my);
                state->spawn(
                    obj, get(f, "m"), 
                    vec2i_create(mx, my), mg, 
                    state->spawn_userdata);
            }
            if(isset(f, "md") && state->destroy != NULL) { 
                state->destroy(obj, get(f, "md"), state->destroy_userdata);
            }

            // Music playback
            if(isset(f, "smo")) { 
                cmd_music_on(get(f, "smo"));
            }
            if(isset(f, "smf")) { 
                cmd_music_off();
            }

            // Sound playback
            if(isset(f, "s")) {
                float pitch = PITCH_DEFAULT;
                float volume = VOLUME_DEFAULT * (settings_get()->sound.sound_vol/10.0f);
                float panning = PANNING_DEFAULT;
                if(isset(f, "sf")) {
                    int p = clamp(get(f, "sf"), -16, 239);
                    pitch = clampf((p/239.0f)*3.0f + 1.0f, PITCH_MIN, PITCH_MAX);
                }
                if(isset(f, "l")) {
                    int v = clamp(get(f, "l"), 0, 100);
                    volume = (v / 100.0f) * (settings_get()->sound.sound_vol/10.0f);
                }
                if(isset(f, "sb")) {
                    panning = clamp(get(f, "sb"), -100, 100) / 100.0f;
                }
                int sound_id = obj->sound_translation_table[get(f, "s")] - 1;
                sound_play(sound_id, volume, panning, pitch);
            }

            // Blend mode stuff
            if(isset(f, "b1")) { rstate->method_flags &= 0x2000; }
            if(isset(f, "b2")) { rstate->method_flags &= 0x4000; }
            if(isset(f, "bb")) { 
                rstate->method_flags &= 0x0010; 
                rstate->blend_finish = get(f, "bb"); 
            }
            if(isset(f, "be")) { rstate->method_flags &= 0x0800; }
            if(isset(f, "bf")) { 
                rstate->method_flags &= 0x0001; 
                rstate->blend_finish = get(f, "bf"); 
            }
            if(isset(f, "bh")) { rstate->method_flags &= 0x0040; }
            if(isset(f, "bl")) { 
                rstate->method_flags &= 0x0008; 
                rstate->blend_finish = get(f, "bl"); 
            }
            if(isset(f, "bm")) { 
                rstate->method_flags &= 0x0100; 
                rstate->blend_finish = get(f, "bm"); 
            }
            if(isset(f, "bj")) { 
                rstate->method_flags &= 0x0400; 
                rstate->blend_finish = get(f, "bj"); 
            }
            if(isset(f, "bs")) { 
                rstate->blend_start = get(f, "bs"); 
            }
            if(isset(f, "bu")) { rstate->method_flags &= 0x8000; }
            if(isset(f, "bw")) { rstate->method_flags &= 0x0080; }
            if(isset(f, "bx")) { rstate->method_flags &= 0x0002; }

            // Palette tricks
            if(isset(f, "bpd")) { rstate->pal_ref_index = get(f, "bpd"); }
            if(isset(f, "bpn")) { rstate->pal_entry_count = get(f, "bpn"); }
            if(isset(f, "bps")) { rstate->pal_start_index = get(f, "bps"); }
            if(isset(f, "bpb")) { rstate->pal_begin = get(f, "bpb"); }
            if(isset(f, "bpd")) { rstate->pal_end = get(f, "bpd"); }
            if(isset(f, "bz"))  { rstate->pal_tint = get(f, "bz"); }

            // Handle movement
            if (isset(f, "v")) {
                int x = 0, y = 0;
                if(isset(f, "y-")) {
                    y = get(f, "y-") * -1;
                } else if(isset(f, "y+")) {
                    y = get(f, "y+");
                }
                if(isset(f, "x-")) {
                    x = get(f, "x-") * -1 * object_get_direction(obj);
                } else if(isset(f, "x+")) {
                    x = get(f, "x+") * object_get_direction(obj);
                }

                if (x || y) {
                    obj->vel.x += x;
                    obj->vel.y += y;
                }
            }
            // handle scaling on the Y axis
            if(isset(f, "y")) { 
                obj->y_percent = get(f, "y") / 100.0f; 
            }
            if (isset(f, "e")) {
                // x,y relative to *enemy's* position
                int x = 0, y = 0;
                if(isset(f, "y-")) {
                    y = get(f, "y-") * -1;
                } else if(isset(f, "y+")) {
                    y = get(f, "y+");
                }
                if(isset(f, "x-")) {
                    x = get(f, "x-") * -1 * object_get_direction(obj);
                } else if(isset(f, "x+")) {
                    x = get(f, "x+") * object_get_direction(obj);
                }

                float x_dist = dist(obj->pos.x, state->enemy_x + x);
                float y_dist = dist(obj->pos.y, state->enemy_y + y);
                obj->slide_state.timer = param->duration;
                obj->slide_state.vel.x = x_dist / (float)param->duration;
                obj->slide_state.vel.y = y_dist / (float)param->duration;
                DEBUG("Slide object %d for (x,y) = (%f,%f) for %d ticks.", 
                    obj->cur_animation->id,
                    obj->slide_state.vel.x, 
                    obj->slide_state.vel.y, 
                    param->duration);
            }
            if (isset(f, "v") == 0 && 
                isset(f, "e") == 0 && 
                (isset(f, "x+") || isset(f, "y+") || isset(f, "x-") || isset(f, "y-"))) {
                // check for relative X interleaving
                int x = 0, y = 0;
                if(isset(f, "y-")) {
                    y = get(f, "y-") * -1;
                } else if(isset(f, "y+")) {
                    y = get(f, "y+");
                }
                if(isset(f, "x-")) {
                    x = get(f, "x-") * -1 * object_get_direction(obj);
                } else if(isset(f, "x+")) {
                    x = get(f, "x+") * object_get_direction(obj);
                }

                obj->slide_state.timer = param->duration;
                obj->slide_state.vel.x = (float)x / (float)param->duration;
                obj->slide_state.vel.y = (float)y / (float)param->duration;
                DEBUG("Slide object %d for (x,y) = (%f,%f) for %d ticks.",
                    obj->cur_animation->id,
                    obj->slide_state.vel.x, 
                    obj->slide_state.vel.y, 
                    param->duration);
            }

            // Check if next frame contains X=nnn or Y=nnn 
            if(!param->is_final_frame) {
                sd_stringparser_peek(state->parser, param->id + 1, &n_param);
                int slide = 0;
                float xpos = obj->pos.x;
                float ypos = obj->pos.y;
                if(isset(n, "x=") || isset(n, "y=")) {
                    obj->slide_state.vel = vec2f_create(0,0);
                }
                if(isset(n, "x=")) {
                    slide = get(n, "x=");
                    if(object_get_direction(obj) == OBJECT_FACE_LEFT) {
                        // if the sprite is flipped horizontally, adjust the X coordinates
                        slide = 320 - slide;
                    }
                    if(slide != xpos) {
                        obj->slide_state.vel.x = dist(xpos, slide) / (float)param->duration;
                        obj->slide_state.timer = param->duration;
                        DEBUG("Slide object %d for X = %f for a total of %d ticks.", 
                            obj->cur_animation->id,
                            obj->slide_state.vel.x, 
                            param->duration);
                    }
                }
                if(isset(n, "y=")) { 
                    slide = get(n, "y=");
                    if(slide != ypos) {
                        obj->slide_state.vel.y = dist(ypos, slide) / (float)param->duration;
                        obj->slide_state.timer = param->duration;
                        DEBUG("Slide object %d for Y = %f for a total of %d ticks.", 
                            obj->cur_animation->id,
                            obj->slide_state.vel.y, 
                            param->duration);
                    }
                }
            }
            
            // Set render settings
            if(real_frame < 25) {
                object_select_sprite(obj, real_frame);
                if(obj->cur_sprite != NULL) {
                    rstate->duration = param->duration;
                    rstate->blendmode = isset(f, "br") ? BLEND_ADDITIVE : BLEND_ALPHA;
                    if(isset(f, "r")) {
                        rstate->flipmode ^= FLIP_HORIZONTAL;
                    }
                    if(isset(f, "f")) {
                        rstate->flipmode ^= FLIP_VERTICAL;
                    }
                }
            } else {
                obj->cur_sprite = NULL;
            }

        }
        state->previous = param->id;
    }

    // Animation ticks
    if(state->reverse) {
        state->ticks--;
    } else {
        state->ticks++;
    }

    // Sprite ticks
    rstate->timer++;
    
    // All done.
    return;
}
Example #4
0
void player_reset(object *obj) {
    obj->animation_state.ticks = 1;
    obj->animation_state.finished = 0;
    obj->animation_state.previous = -1;
    sd_stringparser_reset(obj->animation_state.parser);
}