Jump to content
Азраэль

Курилка программистов

Recommended Posts

Malandrinus    596
7 hours ago, abramcumner said:

И ни одного гото. 

=) Злостное трюкачество. Да и вообще-то речь о другом. Я только хотел сказать, что сам по себе оператор switch - это в сущности не что иное, как goto на метку case xxx: У case даже синтаксис почти как у метки - заканчивается двоеточием - и логика работы в точности как у метки для перехода, т.е. туда тупо передаётся управление и продолжается выполнение далее по ходу (если нет break конечно). Сам break - это не что иное, как goto на метку, расположенную сразу за оператором for или switch. Оператор continue - просто замаскированный goto на метку, расположенную в конце тела цикла. Оператор return для внутренней реализации часто требует или дублирования кода завершения функции либо опять же представляет собой просто аналог перехода на метку в конце тела функции. Т.е. сам язык по-сути набит фиговыми листиками, едва-едва прикрывающими этот самый goto. Посему не вижу большого смысла быть святее Папы Римского и разводить большие разговоры насчёт неприемлемости использования этого оператора.

  • Like 1

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Share this post


Link to post
Share on other sites
Malandrinus    596

возможно кого-то это покоробит, но лично мне глубоко безразлично, что будут думать о моём коде другие люди. Я исхожу из того, что первым человеком, который будет сопровождать мой код, буду я сам. Поэтому я себе упрощаю жизнь. Если есть смысл использовать goto, и код от этого станет лаконичнее и понятнее, то я буду использовать goto. Нет смысла - не буду. Чаще всего он и не нужен. Но если таки нужен, то все теоретики идут лесом.

 

5 hours ago, Desertir said:

Проблемы же не в компьютере, а в субъекте по ту сторону клавиатуры

 

Я признаться не понял, ты споришь со мной или соглашаешься. Судя по этой фразе, обсуждать вообще нечего. Если проблема не в инструменте, а в том, кто его использует, то и с goto нет проблем. Это ведь всего лишь инструмент. Как и любой инструмент, его надо использовать с умом, и будет тогда щастье. Поскольку без головы можно любую программу превратить в нечитаемое, непостижимое и неотлаживаемое УГ. И причём безо всяких там goto.

  • Like 1

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Share this post


Link to post
Share on other sites
НаноБот    589

А во обще if'ы сами по себе довольно вредные из-за особенности работы современных процессоров. В некоторых случаях от них лучше избавляться.

Если процессор делает не правильный прогноз перехода это даёт задержку 10-20 тактов.

Примеры когда от не то что от GOTO надо избавляться, но и от более вредных IF'ов.

Проверить флаг, если установлен, вернуть true или false, проверить объект на не равно nil вернуть true, или false

Скрытый текст

 

С++


if bit_and(m_flags, cfExploding)~=0 then return true
else return false

if (smart_cast<CWeapon*>(obj)) return (true);
else return (false);

Lua


if bit_and(m_flags, cfExploding)~=0 then return true
else return false
if obj:is_weаpon(obj) then return true
else return false

МакроАссемблер


.if ([esi].m_flags & cfExploding)
    mov        eax, TRUE
.else
    mov        eax, FALSE
.endif
...
ret

 

 

 

Лучше так.

Скрытый текст

return (m_flags.test(cfExploding));
return (smart_cast<CWeapon*>(obj));

return bit_and(m_flags, cfExploding)~=0
return obj:is_weаpon(obj)

И наконец то МакроАссемблер
 


test    [esi].m_flags, cfExploding
setnz    al
retn

smart_cast    _AVCWeapon, _AVCGameObject, eax
test    eax, eax
setnz    al

 

Короче, в С++ есть оператор !! преобразовать в булеву, компилятор создаёт код ассемблера указанный чуть выше. Ещё есть SSE команды для проверки одновременно 4-х float'ов, можно например использовать в баллистике XRay.

Здесь:

if(!((bullet->pos.x>=level_box.x1) &&
             (bullet->pos.x<=level_box.x2) &&
             (bullet->pos.y>=level_box.y1) &&
//             (bullet->pos.y<=level_box.y2) &&
             (bullet->pos.z>=level_box.z1) &&
             (bullet->pos.z<=level_box.z2))    )
             return false;

За комментирована проверка вниз, что довольно вредно, а ещё кол. проверок можно снизить до двух.

Edited by НаноБот

...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites
НаноБот    589

Нашёл у себя на компе программу, просто памятник быдлокоду, но вроде работает.

program oskolok2;label m1,m2,m3,m4;
var u0,a,d,q,ux,uy,aa,x,y,x1:real;
begin m4:
write(' nach skorost U0=');read(u0);
write(' tolshina obolochki(mm) d=');read(d);
write(' udelnaya plotnost obolochki q=');read(q);a:=0;
m2:a:=a+1;
aa:=a/180*3.14;ux:=u0*cos(aa);uy:=u0*sin(aa);
x:=0;y:=0;
m1:x:=x+ux*0.0001;y:=y+uy*0.0001;ux:=ux-0.0001*1.29*ux*sqrt(sqr(ux))/(d*q);
uy:=uy-9.8*0.0001-1.29*0.0001*uy*sqrt(sqr(uy))/(d*q);if y>0 then begin goto m1;
end;if x1>x then goto m3;x1:=x;goto m2;
m3:write( ' rasstoyanie ',x:2:2,'metrov');
write(' na skorosti ',sqrt(ux*ux+uy*uy):2:2,'m/s');goto m4;
end.

Просто демонстрация как нельзя использовать GOTO.


...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites
Malandrinus    596
On 11/22/2017 at 3:54 PM, НаноБот said:

if bit_and(m_flags, cfExploding)~=0 then return true else return false

 

Ну это вообще классика. Конструкции вида:

if (<условие>)
	return true;
else
	return false;

Вместо простого return <условие> всегда вызывали у меня ступор. Начинаешь гадать, а не имел ли в виду автор что-то премудрое, например последующее расширение кода типа такого:

if (<условие>) {
  	// сделать что-то перед возвратом значения
	return true;
}
else
	return false;

Но потом всегда оказывается, что это стиль такой. :dash2:

 

On 11/22/2017 at 3:54 PM, НаноБот said:

в С++ есть оператор !! преобразовать в булеву

Немного позанудствую, но это не оператор. Это два последовательных оператора логического отрицания. И поскольку в С/С++ значения и так автоматом интерпретируются как логические, то в использовании этой конструкции чаще всего нет нужды.

 

19 hours ago, НаноБот said:

памятник быдлокоду

О, да! Особенно использование неинициализированной переменной x1. Понятно, что это Паскаль, и там есть значения по умолчанию, но всё же это подрастрельная статья.

 

Однако, этот код напомнил мне ещё об одном вполне легитимном использовании goto. Если надо организовать цикл из кода, который не влезает в один экран, то использование goto может оказаться предпочтительным перед встроенным циклом. Дело в том, что к структурным операторам прилагается соответствующее форматирование, в частности отступ. А если отступ идёт на огромный блок кода, то он не улучшает читаемость, а только ухудшает (структуру всё равно не показывает, поскольку не видно обеих границ, а только увеличивает пустое пространство слева). goto же отступа не требует. Типичный случай - главный цикл программы. Это обычно бесконечный цикл, и внутри него может быть до чёрта напихано.

Это помимо уже упоминавшегося выхода из вложенных циклов.

Ещё весьма важный случай - для нужд отладки и эксперимента. Хоть это и не должно попасть в готовую программу, но наличие такого инструмента может сильно упростить процесс разработки.

Ещё вспомнил случай из своей практики. Был у меня код вида такого:

lab1:
// фрагмент сложного цикла 1
lab2:
// фрагмент сложного цикла 2
if () goto lab1;
// фрагмент сложного цикла 3
if () goto lab2;

Т.е. цикл состоит из трёх фрагментов, где постоянной частью является фрагмент 2, а зависимости от условий перед ним или после него выполняется ещё какой-то код. Я пытался заменить это на использование структурных операторов, но всё выходило существенно хуже: более громоздко и намного менее очевидно.


 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,602
В 24.11.2017 в 03:15, Malandrinus сказал:

if (<условие>) return true; else return false;

 

#define TRUE FALSE  же !

Share this post


Link to post
Share on other sites
Expropriator    1,986

Не подскажите, где нибудь подобное по отражению на поверхности в x-ray было на сайте или еще где?

Интересует как это сделать и желательно для 1602

http://media.moddb.com/images/mods/1/26/25940/ssr.jpg

 


andreyholkin.gif

rod_cccp.gif

 

Share this post


Link to post
Share on other sites
 HellRatz    1,918

@Дизель да это наверняка выдрано из крайнего Огсе чисто шейдерно (возможно water.ps или как там). Отдельно инструкции не попадались.

  • Согласен 1
  • Полезно 1

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,602

xr_3da\xrGame\ai\monsters\controller\controller_psy_aura.cpp:

#define    FAKE_AURA_DURATION    3000
#define    FAKE_AURA_DELAY        8000
#define FAKE_MAX_ADD_DIST    90.f
#define FAKE_MIN_ADD_DIST    20.f


void CControllerAura::update_schedule()
{
    if (!m_object->g_Alive()) return;

    float dist_to_actor        = Actor()->Position().distance_to(m_object->Position());

    if ((dist_to_actor > aura_radius + FAKE_MIN_ADD_DIST) && (dist_to_actor < aura_radius + FAKE_MAX_ADD_DIST))
    {

Чудны дела твои...

 

Или это я чего-то не понимаю ?

  • Sad 1

Share this post


Link to post
Share on other sites
abramcumner    879
1 час назад, Dennis_Chikin сказал:

Или это я чего-то не понимаю ?

Вроде все, как должно быть, - корректная проверка на попадание в диапазон.

Share this post


Link to post
Share on other sites
Dennis_Chikin    3,602

Ага, а aura_radius, стало быть, надо ставить отрицательным... Какая прелесть...

И вообще, на кой выносить в конфиг то, что все равно будет игнорироваться ?

 

 

Кстати, я вот тут сегодня подумал, и возникла у меня странная мысль... Вот есть движок. Скажем, 1.0004. Ставим новую версию, и то, что работало, уже вдруг не работает. Надо переписывать. Ладно, хорошо, переписали, поменяли number на string.  Опять новая версия. ЧН. Опять ничего не работает, и переписывать уже не реально. Дальше - больше. ЗП - и опять точно та же картина.

Нет, я понимаю, требовать от Крайзиса или Ведьмака, чтобы на нем работало то, что к ним вообще ни какого отношения не имеет - это странно. Но здесь - даже в рамках minor version - и то совместимости нет даже минимальной. Это вообще нормально ?
 

Share this post


Link to post
Share on other sites
Expropriator    1,986

@Dennis_Chikin , а ты думаешь в Кризисе по другому? Там еще хуже. Там даже в пределах одной версии движка (скажем 3.3.5 отличается от 3.5.3 или 3.8.4)нет совместимости идеальной.


andreyholkin.gif

rod_cccp.gif

 

Share this post


Link to post
Share on other sites
НаноБот    589

Работаю над гусеничной техникой в XRay. Есть несколько методов реализации. Простые и сложные, ресурсоёмкие и не очень.

Я помню, предлагал сделать траки костями и включать их видимость определённым образом для анимации. Не знаю, нет модели, есть ограничение по кол. костей, не больше 64. Короче, реализовать не реально.

Ещё предлагал сделать гусеницы отдельными объектами и приатачивать к танку. Нету моделей гусениц, и так же 64-х костей может не хватит. Реализовать не реально.

Потом Vlad808 зарелизел свои танки, и макрон анимировал гусеницы с помощью seq анимации. Я начал разбираться как эта анимация работает. Определил, что в активную текстуру копируется ссылка шкурки т.е. структуры IDirect3DBaseTexture9 из вектора seqDATA. Начал думать как бы это использовать в танках. Сделал текстуру гусеницы уникальной для каждого объекта. Копируется ссылка нужного кадра из массива текстур гусениц, как и в seq-анимации. Но количество кадров всего 6, так что движения гусеницы не очень плавное, особенно если танк медленно движется.  Потом ковырял методы класса IDirect3DDevice9 и IDirect3DResource9 решил копировать куски текстуры из источника в активную текстуру гусеницы. Да, гусеница будет плавно крутится на любой скорости. Но копирования текстуры почти каждый фрейм достаточно дорого. По этому возможно целесообразно сделать нужное количество кадров гусеницы и копировать ссылку. Ещё можно сразу задавать смещение текстуры, этот метод даст плавность и скорость, вот только как задать смещения текстуры не имею понятия. Нету соответствующих методов, или я их не знаю.

В общем есть идея сделать так.

Создаём нужное количество кадров анимации текстуры, движок сам это делает. И просто копируем ссылку в активной текстуре.
 

// определение
CTexture*    		m_track_texture;   // текстура гусеницы. Уникальная для каждого объекта!
IDirect3DBaseTexture9*	m_textures_tracks[]; // кадры текстур гусениц
// апдейт
m_track_texture.pSurface = m_textures_tracks[curr_track];  // просто копируем нужный кадр в активную текстуру гусеницы

Если кадров штук 10-16 то плавность думаю будет обеспечена.

ЗЫ

Ах да. Ещё надо разделить поверхность гусениц на левую и правую. А то криво получится. Я ещё попробую физику гусеничной техники реализовать.

Edited by НаноБот
  • Like 1

...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites
НаноБот    589

Использую МАСМ. Но я считаю что он не полноценен. Там есть встроенные макрооператоры .if, .while, .until и другие.
Но мне этого мало, там нельзя использовать xmm регистры и не правильно работают макрофункции. В общем есть идея, разработать внешний транслятор операторов высокого уровня. Короче, что больше МАСМ на С/С++ больше был похож. Так же добавить выражения. Что то вроде такого.

if(eax<10){
   xmm0=xmm2*(float)eax/param
   eax=xmm0/xmm9
}

Транслятор на выходе генерирует asm-код который нормально компилируется уже самим ml.exe. Вот как то так, можно конечно сделать и макросами(кое какой код есть существует(не мой)). Но в МАСМе есть некоторые ошибки которое это затрудняют, и которые никто не будет исправлять.

Edited by НаноБот

...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites
Malandrinus    596
On 3/27/2018 at 6:39 PM, НаноБот said:

нельзя использовать xmm регистры

Можно. Используются же в XE повсеместно.

 

On 3/27/2018 at 6:39 PM, НаноБот said:

не правильно работают макрофункции

Это как? Может у тебя версия старая?

 

On 3/27/2018 at 6:39 PM, НаноБот said:

МАСМ на С/С++ больше был похож

Такого эффекта добиваются с использованием макропроцессора. Но в целом это путь в никуда. Ассемблер нужен для выполнения узких задач, в целом же лучше положиться на оптимизацию С/С++. Кроме того, у Микрософт-а ассемблер можно встраивать прямо в С/С++ код. Но из 64-х разрядного компилятора это убрали. Подозреваю, что именно потому, что это в широкой перспективе неправильно и неэффективно. Лучше скомпилировать отдельно модуль с нужными функциями чисто на ассемблере.


 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Share this post


Link to post
Share on other sites
НаноБот    589

@Malandrinus А можно использовать С/С++ в проекте XRayExtensions?(вставка С/С++ кода в готовый файл) Есть ли операторы типа ORG в С/С++?

Макропроцессор в МАСМе это просто лютая хрень, куча ограничений, море багов, эти баги НИКТО НЕ БУДЕТ исправлять. Проще создать на основе, например, Lua, свой макроязык для транслятора.

Ассемблер вполне можно использовать для сложных проектов, конечно глупо всё делать голыми командами процессора, для этого и нужны операторы высокого уровня, которые транслируются в асм-код, который затем можно вручную оптимизировать, если надо. Я вот, утилиту для инъекции своего кода в исполняемый файл, написал именно на МАСМ, т.е. макроассемблере, затем уже рабочий вариант портировал в С код, намучился хорошо, при этом. Так что Ассемблер Высокого Уровня рулит, всё остальное ерунда.


...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites
abramcumner    879
32 минуты назад, НаноБот сказал:

А можно использовать С/С++ в проекте XRayExtensions?(вставка С/С++ кода в готовый файл).

Можно, линкеру все равно откуда берутся объектные файлы.

 

Есть ли операторы типа ORG в С/С++?

Они там не нужны. В с++ части extern CActor* g_actor; а ORG асмовой части. Разбираешься с манглингом имен и можно писать в хрей-экст на с++.

Share this post


Link to post
Share on other sites
НаноБот    589

@abramcumner Да ладно, это только на словах всё просто, а на деле просто не возможно. Оператор ORG в асме, это задать адрес кода, без него всё это невозможно. И плюс, у компилятора куча ограничений, не не получится, С/С++ невозможно использовать в  XRayExtensions  проекте.


...в конце концов, важен лишь, машинный код.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

AMK-Team.ru

×
×
  • Create New...