void movedir_add(Move **move_list, const int speed, const int teta, const int newSeq, pthread_cond_t *cond) { Move *new_move = calloc(1, sizeof(Move)); bzero(new_move, sizeof(Move)); if (speed < 0) new_move->goal.t = (teta + 180)%360; else new_move->goal.t = teta; new_move->speed = speed; new_move->type = DIRECTION; LOG_DEBUG("MVD : %d, %d\n", speed, teta); if (newSeq == 1) { Move *old_list = *move_list; *move_list = new_move; pthread_cond_signal(cond); move_free(old_list); } else { // Append new move at the end while (*move_list != NULL) { move_list = &((*move_list)->next_move); } *move_list = new_move; pthread_cond_signal(cond); } }
Unit::Unit(int X, int Y, unsigned char team, int maxAP): isMoving(false) { this->team = team; this->maxAP = maxAP; this->currentAP = maxAP; moveSpeed = 0.05f; currentPosX = 0.0f; currentPosY = 0.0f; currentPosZ = 0.0f; destinationPosY = 0.0f; currentCell.X = 0; currentCell.Y = 0; D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.ByteWidth = sizeof(ModelData); // Размер буфера bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; HRESULT hr = device->CreateBuffer(&bd, nullptr, &modelBuffer); if (FAILED(hr)) { throw "ID3D11Device::CreateBuffer failed"; } modelData.world = XMMatrixIdentity(); modelData.color = colors[1]; move_free(X, Y); vertexShader = ShaderFactory::createVertexShader(TEXT("VertexShader.hlsl"), "main"); D3D11_INPUT_ELEMENT_DESC inputElementDesc[] = { {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; ID3DBlob* blob = ShaderFactory::compileFromFile(TEXT("VertexShader.hlsl"), "main", "vs_4_0"); hr = device->CreateInputLayout( inputElementDesc, 2, blob->GetBufferPointer(), blob->GetBufferSize(), &inputLayout ); if (FAILED(hr)) { throw "ID3D11Device::CreateInputLayout failed"; } pixelShader = ShaderFactory::createPixelShader(TEXT("PixelShader.hlsl"), "main"); model = new Model(TEXT("models\\Unit.dae")); }
// Stop all moves for a given stepper (used in end stop homing). IRQs // must be off. void stepper_stop(struct stepper *s) { sched_del_timer(&s->time); s->next_step_time = 0; s->position = -stepper_get_position(s); s->count = 0; s->flags = (s->flags & SF_INVERT_STEP) | SF_NEED_RESET; gpio_out_write(s->dir_pin, 0); gpio_out_write(s->step_pin, s->flags & SF_INVERT_STEP); while (s->first) { struct stepper_move *next = s->first->next; move_free(s->first); s->first = next; } }
// Setup a stepper for the next move in its queue static uint_fast8_t stepper_load_next(struct stepper *s, uint32_t min_next_time) { struct stepper_move *m = s->first; if (!m) { if (s->interval - s->add < s->min_stop_interval && !(s->flags & SF_NO_NEXT_CHECK)) shutdown("No next step"); s->count = 0; return SF_DONE; } s->next_step_time += m->interval; s->add = m->add; s->interval = m->interval + m->add; if (CONFIG_STEP_DELAY <= 0) { if (CONFIG_MACH_AVR) // On AVR see if the add can be optimized away s->flags = m->add ? s->flags|SF_HAVE_ADD : s->flags & ~SF_HAVE_ADD; s->count = m->count; } else { // On faster mcus, it is necessary to schedule unstep events // and so there are twice as many events. Also check that the // next step event isn't too close to the last unstep. if (unlikely(timer_is_before(s->next_step_time, min_next_time))) { if ((int32_t)(s->next_step_time - min_next_time) < (int32_t)(-timer_from_us(1000))) shutdown("Stepper too far in past"); s->time.waketime = min_next_time; } else { s->time.waketime = s->next_step_time; } s->count = (uint32_t)m->count * 2; } if (m->flags & MF_DIR) { s->position = -s->position + m->count; gpio_out_toggle_noirq(s->dir_pin); } else { s->position += m->count; } s->first = m->next; move_free(m); return SF_RESCHEDULE; }
void move_add(Move **move_list, const Position *cur_pos, const int speed, const int teta, const int distance, const int newSeq, pthread_cond_t *cond) { Move *new_move = calloc(1, sizeof(Move)); bzero(new_move, sizeof(Move)); const Position *p; if (newSeq == 1) p = cur_pos; else p = &last_move(*move_list)->goal; new_move->speed = speed; new_move->goal.x = p->x - sin(teta * M_PI / 180) * distance; new_move->goal.y = p->y + cos(teta * M_PI / 180) * distance; new_move->type = POSITION; if (speed < 0) new_move->goal.t = (teta + 180)%360; else new_move->goal.t = teta; LOG_DEBUG("MV : %d, %d, %d\n", speed, (int) new_move->goal.x, (int) new_move->goal.y); if (newSeq == 1) { Move *old_list = *move_list; *move_list = new_move; pthread_cond_signal(cond); move_free(old_list); } else { // Append new move at the end while (*move_list != NULL) { move_list = &((*move_list)->next_move); } *move_list = new_move; pthread_cond_signal(cond); } }
// Schedule a set of steps with a given timing void command_queue_step(uint32_t *args) { struct stepper *s = stepper_oid_lookup(args[0]); struct stepper_move *m = move_alloc(); m->interval = args[1]; m->count = args[2]; if (!m->count) shutdown("Invalid count parameter"); m->add = args[3]; m->next = NULL; m->flags = 0; irq_disable(); uint8_t flags = s->flags; if (!!(flags & SF_LAST_DIR) != !!(flags & SF_NEXT_DIR)) { flags ^= SF_LAST_DIR; m->flags |= MF_DIR; } flags &= ~SF_NO_NEXT_CHECK; if (m->count == 1 && (m->flags || flags & SF_LAST_RESET)) // count=1 moves after a reset or dir change can have small intervals flags |= SF_NO_NEXT_CHECK; s->flags = flags & ~SF_LAST_RESET; if (s->count) { if (s->first) *s->plast = m; else s->first = m; s->plast = &m->next; } else if (flags & SF_NEED_RESET) { move_free(m); } else { s->first = m; stepper_load_next(s, s->next_step_time + m->interval); sched_add_timer(&s->time); } irq_enable(); }