void _start(int arg1, int arg2, void *openfirmware) { int chosen; of_init(openfirmware); /* open the input and output handle */ chosen = of_finddevice("/chosen"); of_getprop(chosen, "stdin", &of_input_handle, sizeof(of_input_handle)); of_getprop(chosen, "stdout", &of_output_handle, sizeof(of_output_handle)); puts("this is a test\n"); init_serial(); restart: puts("waiting for command\n"); { int base_address; int entry_point; int length; int command; unsigned char *ptr; void (*func)(int, int, void *); serial_read_int32(&command); if(command != 0x99) { puts("bad command, restarting\n"); goto restart; } serial_read_int32(&base_address); serial_read_int32(&length); serial_read_int32(&entry_point); puts("read base and length, claiming\n"); puts("base "); write_hex(base_address); puts("\nlength "); write_hex(length); puts("\nentry_point "); write_hex(entry_point); puts("\n"); ptr = (void *)base_address; of_claim(base_address, length, 0); puts("reading data\n"); serial_read(ptr, length); puts("done reading data, calling function\n"); func = (void *)entry_point; func(arg1, arg2, openfirmware); } of_exit(); }
/* * Unserializes the data from buffer to a specialized object. * Should return 1 on error, 0 on success. * Serial reder position should be set to correct position before calling this. */ int object_unserialize(object *obj, serial *ser, game_state *gs) { obj->pos.x = serial_read_float(ser); obj->pos.y = serial_read_float(ser); obj->vel.x = serial_read_float(ser); obj->vel.y = serial_read_float(ser); float gravity = serial_read_float(ser); obj->direction = serial_read_int8(ser); obj->group = serial_read_int8(ser); obj->layers = serial_read_int8(ser); uint8_t stride = serial_read_int8(ser); uint8_t repeat = serial_read_int8(ser); obj->sprite_override = serial_read_int8(ser); obj->age = serial_read_int32(ser); random_seed(&obj->rand_state, serial_read_int32(ser)); uint8_t animation_id = serial_read_int8(ser); uint8_t pal_offset = serial_read_int8(ser); int8_t hit_frames = serial_read_int8(ser); int8_t can_hit = serial_read_int8(ser); // Other stuff not included in serialization obj->y_percent = 1.0; obj->cur_animation_own = OWNER_EXTERNAL; obj->cur_animation = NULL; obj->cur_sprite = NULL; obj->sound_translation_table = NULL; obj->cur_surface = NULL; obj->cur_remap = 0; obj->halt = 0; obj->halt_ticks = 0; obj->cast_shadow = 0; player_create(obj); // Read animation state uint16_t anim_str_len = serial_read_int16(ser); char anim_str[anim_str_len+1]; if(anim_str_len > 0) { serial_read(ser, anim_str, anim_str_len); } obj->animation_state.current_tick = (uint16_t)serial_read_int16(ser); obj->animation_state.previous_tick = (uint16_t)serial_read_int16(ser); uint8_t reverse = serial_read_int8(ser); // Read the specialization ID from ther serial "stream". // This should be an int. int specialization_id = serial_read_int8(ser); // This should automatically bootstrap the object so that it has at least // unserialize function callback and local memory allocated object_auto_specialize(obj, specialization_id); // Now, if the object has unserialize function, call it with // serialization data. serial object should be pointing to the // start of that data. if(obj->unserialize != NULL) { obj->unserialize(obj, ser, animation_id, gs); } else { DEBUG("object has no special unserializer"); } // Init animation with correct string and tick if(anim_str_len > 0) { // server is using a custom string DEBUG("serialized object has custom animation string %s", anim_str); player_reload_with_str(obj, anim_str); } if(reverse) { object_set_playback_direction(obj, PLAY_BACKWARDS); } // deserializing hars can reset these, so we have to set this late obj->stride = stride; object_set_gravity(obj, gravity); object_set_repeat(obj, repeat); object_set_pal_offset(obj, pal_offset); obj->hit_frames = hit_frames; obj->can_hit = can_hit; /*DEBUG("Animation state: [%d] %s, ticks = %d stride = %d direction = %d pos = %f,%f vel = %f,%f gravity = %f", strlen(player_get_str(obj))+1, player_get_str(obj), obj->animation_state.ticks, obj->stride, obj->animation_state.reverse, obj->pos.x, obj->pos.y, obj->vel.x, obj->vel.y, obj->gravity);*/ // Return success return 0; }
int net_controller_tick(controller *ctrl, int ticks, ctrl_event **ev) { ENetEvent event; wtf *data = ctrl->data; ENetHost *host = data->host; ENetPeer *peer = data->peer; serial *ser; /*int handled = 0;*/ while (enet_host_service(host, &event, 0) > 0) { switch (event.type) { case ENET_EVENT_TYPE_RECEIVE: ser = malloc(sizeof(serial)); serial_create(ser); ser->data = malloc(event.packet->dataLength); ser->len = event.packet->dataLength; memcpy(ser->data, event.packet->data, event.packet->dataLength); switch(serial_read_int8(ser)) { case EVENT_TYPE_ACTION: { // dispatch keypress to scene int action = serial_read_int16(ser); controller_cmd(ctrl, action, ev); /*handled = 1;*/ serial_free(ser); free(ser); } break; case EVENT_TYPE_HB: { // got a tick int id = serial_read_int8(ser); if (id == data->id) { int start = serial_read_int32(ser); int peerticks = serial_read_int32(ser); int newrtt = abs(start - ticks); data->rttbuf[data->rttpos++] = newrtt; if (data->rttpos >= 100) { data->rttpos = 0; data->rttfilled = 1; } if (data->rttfilled == 1) { ctrl->rtt = avg_rtt(data->rttbuf, 100); data->tick_offset = (peerticks + (ctrl->rtt/2)) - ticks; /*DEBUG("I am %d ticks away from server: %d %d", data->tick_offset, ticks, peerticks);*/ } data->outstanding_hb = 0; data->last_hb = ticks; serial_free(ser); } else { // a heartbeat from the peer, bounce it back ENetPacket *packet; // write our own ticks into it serial_write_int32(ser, ticks); packet = enet_packet_create(ser->data, ser->len, ENET_PACKET_FLAG_UNSEQUENCED); if (peer) { enet_peer_send(peer, 0, packet); enet_host_flush (host); } } free(ser); } break; case EVENT_TYPE_SYNC: controller_sync(ctrl, ser, ev); /*handled = 1;*/ break; default: serial_free(ser); free(ser); } enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: DEBUG("peer disconnected!"); data->disconnected = 1; controller_close(ctrl, ev); return 1; // bail the f**k out break; default: break; } } int tick_interval = 5; if (data->rttfilled) { tick_interval = 20; } if ((data->last_hb == -1 || ticks - data->last_hb > tick_interval) || !data->outstanding_hb) { data->outstanding_hb = 1; serial ser; ENetPacket *packet; serial_create(&ser); serial_write_int8(&ser, EVENT_TYPE_HB); serial_write_int8(&ser, data->id); serial_write_int32(&ser, ticks); packet = enet_packet_create(ser.data, ser.len, ENET_PACKET_FLAG_UNSEQUENCED); if (peer) { enet_peer_send(peer, 0, packet); enet_host_flush (host); } else { DEBUG("peer is null~"); data->disconnected = 1; controller_close(ctrl, ev); } } /*if(!handled) {*/ /*controller_cmd(ctrl, ACT_STOP, ev);*/ /*}*/ return 0; }