CEDAR Logic Simulator

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar - а не подскажешь, чем их исходники собирать под Вендой?
Какой версии "срака такая C++ " нужна? :wink:

Я так понимаю, эмуляцию Z80 отдельно от симулятора рассматривать глупо...


PS. И если не трудно - дай ссылку на твой zip-архив оригинальных исходников.
Я такого не нашел - а я как раз не люблю скачивать по одному файлу...
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Я так понимаю, эмуляцию Z80 отдельно от симулятора рассматривать глупо...
Ну... Смотря с какими целями рассматривать. Я ж говорю, логика от графики отделена в коде. И думается мне, что сорцы из директорий logic и Z80, путём несложных правок можно минут за десять-двадцать довести до состояния самостоятельного приложения. Конечно, совершенно без юзер-интерфейса, но зато оно будет запускаться и будет симулировать. И всё это дело можно будет запустить под дебуггером, чтобы посмотреть как оно работает.
Кстати более того, Z80 там в отдельной директории лежит. Я не смотрел, но уверен, что собственно это и есть эмулятор Z80. На остальное, быть может, даже и смотреть не стоит, если оно не интересно само по себе.
И если не трудно - дай ссылку на твой zip-архив оригинальных исходников.
Я такого не нашел - а я как раз не люблю скачивать по одному файлу...
Тот zip файл, я боюсь, тебе не очень нужен, поскольку там нету Z80. Но по ссылке которую ты привёл, есть надпись: Download GNU tarball. Тыкни по ней, и будет тебе щщасте. ;)
Какой версии "срака такая C++ " нужна?
Интересный на самом деле вопрос-то оказался, а? Я сразу почему-то решил, что половина моих проблем порождена тем, что изначально код заточен под msvc++, но... Повтыкав в содержимое файликов внутри projectset.zip, я пришёл к выводу, что речь про Eclipse, cygwin и gcc. А если так, то тебе нужен Eclipse. С cygwin, как я понимаю (судя по тому, что cygwin упоминается там в projectset.zip, быть может для компиляции окажется недостаточно MinGW). При этом в систему надо поставить wxWidgets, да так, чтобы Eclipse нашёл заголовки и библиотеки. Но есть некая вероятность того, что Cygwin'овский setup.exe всё разрулит. Хотя я хз, если честно. Я лишь один раз пытался что-то там собрать в венде, использовал для этого MinGW, но нужная мне версия gtk так и не собралась. Собственно это я к тому, что здесь мой опыт стремится к нулю, и говорить что-то определённое я не решусь.

Но если они собирали при помощи gcc... Надо думать, что они собирали приложение в режиме юникода, и ихний string состоял из wchar_t, что ли? Или может у них wxWidgets был собран без поддержки unicoda, и егойный wxChar совпадал с char'ом? Да, наверное второе, не вижу другого способа объяснить то, каким образом в коде проводились преобразования строк между std и wx. Значит тебе wxWidgets нужен без юникода. =)

ps. Я мергнул свои труды с ихней версией 1.5. Довёл до состояния компилируемости и тут...

Code: Select all

/home/rgo/my/cedar/cedar-logic/GUI/RamPopupDialog.cpp:56: undefined reference to `wxGridNameStr'
/home/rgo/my/cedar/cedar-logic/GUI/RamPopupDialog.cpp:56: undefined reference to `wxGrid::wxGrid(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&)'
Чувствуется, что скоро услышав слово wxWidgets я буду рефлекторно и незмедлительно изрыгать весь свой матерный лексикон на голову того, кто сказал такую гадость.
Совершенно не понимаю: ./configure --enable-gui у wxWidgets включает опцию --enable-grid. В ебилде на wxWidgets есть опция --enable-gui и нету опции --disable-grid. Ну и куда, спрашивается, подевался этот мазафака грид?
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar wrote:
Я так понимаю, эмуляцию Z80 отдельно от симулятора рассматривать глупо...
Ну... Смотря с какими целями рассматривать.
Цель у меня немного другая - я хочу, посмотрев как здесь делается, попробовать
сделать модель Z80 (или i8080) для Proteus.

И вот тут самый непонятный для меня затык происходит... Для Proteus всё весьма
неплохо было документировано. И хотя "протезисты" попытались изъять всю
документацию, я её по разным источникам собрал.

Вот тут и начинается самое для меня непонятное: для сборки dll-модели под
Proteus нужен этот самый msvc++ причем последних версий.

Ясен пень, что под моей Вендой 98 этот msvc++ работать не будет...

Но я вполне пишу себе нужные dll-ки на Борланд Билдер 5.0.
Откуда и есть вопрос - почему я не могу собрать модель в виде dll на своём Билдере?
Что мне принципиально-то помешает?

Некоторые нужные вещи у меня получалось перетаскивать из-под msvc++ под Билдер...
И я всегда удивлялся - вроде же и msvc++ и Билдер 5.0 - это та же самая "срака
такая
C++ ", и Борланд тщилась фичи msvc++ поддержать, а порой получается, -
никак замесы от msvc++ не обойти... :(

В чём основная проблема-то?
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Как я понимаю, там, две причины:
1. C++ меняется со временем, и код, вполне приемлимый для компилятора 10-ти летней давности, обнаруживает в себе кучи ошибок, с точки зрения современного компилятора C++. И наоборот, если компилятору десятилетней давности, скормить заголовочный файл современной библиотеки, то скорее всего компилятор офигеет от такой наглости и выдаст кучи ошибок.
2. Стандарт C++ не имеет сколько-нибудь внятного определения ABI. И, я подозреваю, что мало того, что каждый компилятор использует свой собственный ABI, так ещё и эти ABI меняются вместе с версиями компиляторов.
Есть ещё третья причина, про которую я наслышан: msvc++ имеет свои собственные несовместимости со стандартом, которыми программисты подчастую пользуются не задумываясь, а в результате их код компилируется только в msvc++.

Но, может быть имеет смысл попробовать поставить WinXP в режиме Dual-boot, в неё поставить MSVC++ Express, а поработав с msvc++ снести к чертям всё, кроме win98? При этом можно на раздел с win98 на время загрузки в winxp вешать флаг неактивности, и тогда winxp будет просто игнорировать этот раздел, и с гарантией ничего там не изменит.
Правда там требования к железу, мама не горюй: http://www.microsoft.com/visualstudio/e ... quirements
Гиг оперативки и 1.6ГГц проц. Но я думаю, что это в случае Windows7. В случае windows XP, пожалуй, хватит вполовину меньшего. А если при этом, умудриться обойтись без IDE и использовать лишь компилятор -- утилитку командной строки, то хватит и минимальных для XP 128 мегабайт оперативки. Кстати утилиты командной строки из msvc++ express, в общем-то имеют шансы заработать и в win98.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

DLL-и как правило имеют сишный интерфейс - надо почитать доки на API у протеуса и если оно сишное, то DLL можно компилить чем угодно - хоть паскалем...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

Shaos wrote:DLL-и как правило имеют сишный интерфейс - надо почитать доки на API у протеуса и если оно сишное, то DLL можно компилить чем угодно - хоть паскалем...
Вооот! Вот и я так считаю, поскольку с DLL в своё время плотно разбирался! :o

Но вот тут и bar прав "msvc++ имеет свои собственные несовместимости со стандартом"...
Я сталкивался - что-то было связанно с общей областью памяти для DLL и вызывающей
программы: MSVC++ делал в одну строчку, a Борланд Билдер 5.0 - не мог! :lol:

Я одно время держал параллельно Борланд Билдер 5.0 и MSVC++ 5.0, но потом от
MSVC++ 5.0 отказался, поскольку всё-равно я через вызовы WinAPI привык писать,
а Билдер 5.0, на мой взгляд, при прочих равных генерирует более компактный код.
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

А как себя ведёт klsMiniMap (миниатюра схемы) в вендовой версии CEDAR? Просто у меня этот klsMiniMap, по-моему, страдает какими-то психическими расстройствами, и справится с ним крайне сложно. Я даже затрудняюсь описать его поведение. Ни о какой интуитивности речи нет. Я это к тому спрашиваю, что мне надо определиться, куда накладывать патчи: на психику klsMiniMap или на свою интуицию.
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

От tinyxml2 тоже надо отказываться, так же как и от CEDAR'ского парсера xml. Что за идиотизм писать парсеры которые тупо роняют программу столкнувшись с кривым синтаксисом на входе? Если бы мне нужен был парсер так себя ведущий, то я бы совершенно точно написал бы парсер вручную, и он бы стопудов работал бы быстрее tinyxml2, как бы там авторы не выпендривались оптимизируя то, что оптимизации не требует по-определению.
Вот ведь, а? И при этом, исходный xml парсер, при всей кривизне его API и уменю падать был всё же лучше. Потому что он, когда оказывался несогласным с синтаксисом, в ужасе падал, наводя такого шороху, что не заметить его падение было невозможно.
А долбаный tinyxml2 вместо того, чтобы с героическим грохотом свалиться, тихонько сдыхал в каком-то безвестном уголке. Я так и не понял каким образом. gdb не замечал ничего, пока процесс не завершался. grep по коду tinyxml2 не показал никаких throw. Когда же я повесил бряк на exit, то бряк сработал, но на стеке было всего лишь три фрейма: exit, и ещё два, которые вообще-то должны быть ниже main. Как собственно такое могло случится не очень понятно. Вот ведь сука а? Столько времени об него убил.

Короче вывод можно делать один: в C++ не стоит полагаться на работоспособность маленьких и заточенных на конкретную задачу библиотек. Собственно этот вывод можно было сделать и раньше: я некоторое время развлекался тролля C++-программистов, на разные темы, и они не раз и не два принимались убеждать меня в том, что качественный C++ код может писать лишь профессионал со стажем программирования на C++ от трёх лет. А такие, как я понимаю, не пишут маленьких и заточенных на конкретную задачу библиотек.

Буду значит переписывать всё связанное с xml на libxml++: в ней, как я понимаю, реально рабочего кода нету, лишь бинды к libxml2, а libxml2 написана на C и поэтому не может не работать. И там есть SAX парсер. Правда не очень понятно как хорошо, красиво и удобно использовать SAX парсер не имея в языке лексических замыканий... Хотя, говорят, что в новом C++11 есть что-то типа замыканий. Но C++11 будет совершенно точно несовместим к lavr'овским билдером 5.0. =)
User avatar
Lavr
Supreme God
Posts: 16689
Joined: 21 Oct 2009 08:08
Location: Россия

Post by Lavr »

bar wrote:Но C++11 будет совершенно точно несовместим к lavr'овским билдером 5.0. =)
Да ладно прикалывать-то... :lol: Я C++ освоил, как раз чтобы писать DLL-ки,
поскольку в Венде некоторые задачи без DLL никак не решить...

И лишь потом убедился, что и небольшого размера программу я на C++ слепить могу.

Ну и поскольку я этому тогда учился, вот и приходилось решения, приводимые
авторами на разных версиях C++ подгонять под свой Билдер 5.0 ...
Он вовсе даже неплох... хотя конечно же - устарел... :oops:
iLavr
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Был разговор о том, чтобы взять CEDAR и переписать. Собственно этим я потихоньку и занимаюсь. И у меня в голове начинает складываться примерно такой план действий:

1. Подебажу немного для страху, чтоб CEDAR падал у меня пореже. Я оригинальную v1.5 мергнул в то, что сам сделал из v1.0. Сейчас даже довёл до запускабельного состояния. Но нестабильного: рандомные падения на разных действиях. Можно при этом попытаться довести до состояния достаточно стабильного для того, чтобы те кто заинтересован могли бы погонять её, но не вижу большого смысла в этом. Но хотелось бы, чтобы кидая элемент в схему или поворачивая его на бок, я не ждал бы с замиранием сердца очередного падения.

2. Геометрия: авторы явно сфейлились в задаче инкапсулировать всю геометрию для collision detection в CollisionChecker.cpp. Поэтому в разных местах вылезают ужасные циклы, с жуткой геометрией внутри, поди ещё разберись, что этот код делает. Но я как-то интересовался тем, как умные люди детектят коллизии, причём в трёхмерном варианте. Геометрии там конечно немало, но её всю можно аккуратненько сложить в один файл и больше к ней не возвращаться. Как раз для двумерного случая у меня где-то валяется сорец, правда на lisp'е, но недолго его и переписать на C++. Именно это мне и хочется сделать в первую очередь. Точнее в первую очередь, стоит разобраться насколько там вообще нужен навороченный детект коллизий. Я как-то не до конца понимаю нахрена было городить весь этот огород с bounding boxes. Всё ж таки симулируется не механика, где надо десятками раз в секунду проверять на столкновения десятки и сотни многогранников, каждый из которых состоит из сотен и тысяч геометрических примитивов. Симулируется-то логика, причём на статичной схеме, в которой скорость внесения изменений сильно зависит от того, с какой частотой пользователь может клацать мышиными кнопками. Оно конечно можно, приделать возможность смоделировать ситуацию падения схемы на пол... С отскакиванием логических элементов от пола и друг друга после столкновений, с гнущимися ногами, и с треском рвущихся проводов... Это было бы прикольно, но мне кажется, совершенно необязательно. Хотя, быть может, стОит приделать это, в качестве фишки уникальной для недо-симулятора. :)

3. Следующий этап -- это рисование всяких там гейтов, вайров и черектеров. Вовсе не обязательно для рисования их в память привлекать OpenGL. Отрисовывать же вручную шрифты в своём собственном формате -- вообще моветон, для таких задач есть freetype или pango и огромный выбор шрифтов установленных в систему без помощи CEDAR.

4. После этого, я думаю, поделить GUI и логику на два самостоятельных процесса, связав их пайпом. Таким образом избавившись от долбаных мьютексов: я вроде разобрался, в чём там заковыка была, откуда лезли дедлоки и почему в Windows версии дедлоки не лезли. Но меня всё равно напрягает существование этих мьютексов.

5. Добравшись же до этого пункта, пожалуй, надо будет вышвыривать весь существующий GUI код, кроме написанного мною, и писать его заново. Основную геометрию и рендеринг к этому моменту я перепишу. Останется лишь написать непосредственно user-interface код, без каких-то сложных алгоритмов, которые хрен отладишь.
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Глядя на то, как Shaos планирует писать на C, я начинаю завидувать. C++ -- это всё же жесть. Я, как не имеющий пятилетнего опыта профессионального кодинга на C++, не хочу продолжать эти эксперименты -- вчера часа три дебуггером и валгриндом мучал первый набросок: http://desmond.imageshack.us/Himg29/sca ... es=landing
На ровном месте ругается валгринд про использование неинициализированной переменной, и почему, я так и не смог понять. И ладно бы он просто ругался, но иногда, судя по картинкам гейтов, они на самом деле имеют неинициализированные вершины.

Но, поскольку в CEDARLogic-таки нет ничего, что хотелось бы скипипастить, а раз так, то действительно C++ не очень-то и нужен, можно обойтись и pedantic C. И тогда, выбор GUI тулкита ограничивается gtk+-2.x. Всякие Xlib, понятно, я даже не рассматриваю.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

bar - скажи подробнее куда глянуть, может я чего увижу...
Я тут за главного - если что шлите мыло на me собака shaos точка net
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Я вычислил ту проблему. Вот есть такие объявления:

Code: Select all

namespace geometry
{
class point : public primitive
{
public:
	point(float x = 0, float y = 0) : x(x), y(y) {}
	virtual void draw(Cairo::RefPtr<Cairo::Context> cr);
	virtual struct bbox bbox() const {
		return (struct bbox){x, y, x, y};
	}
	float x, y;
};
class line_segment : public primitive
{
public:
	line_segment(float x1, float y1, float x2, float y2) :
		p1(x1, y1), p2(x2, y2) {}
	line_segment(point p1, point p2) : p1(p1), p2(p2) {}
	virtual void draw(Cairo::RefPtr<Cairo::Context> cr);
	virtual struct bbox bbox() const {
		struct bbox ret;
		ret.x1 = std::min(p1.x, p2.x);
		ret.x2 = std::max(p1.x, p2.x);
		ret.y1 = std::min(p1.y, p2.y);
		ret.y2 = std::max(p1.y, p2.y);
		return ret;
	}
	point p1, p2;
};
А фейлящийся код -- это функа:

Code: Select all

void library_parser::on_shape_line(float x1, float y1, float x2, float y2)
{
	geometry::line_segment l(x1, y1, x2, y2);
	gate->shape.push_back(l);
}
Которая вызывается ровно из одного места кода вот так:

Code: Select all

		istringstream iss(cur_char_data);
		float x1, y1, x2, y2;
		char comma;
		iss >> x1 >> comma >> y1 >> comma >> x2 >> comma >> y2;
		on_shape_line(x1 + dx, y1 + dy, x2 + dx, y2 + dy);
}
Дык выяснилось, что dx, dy я не инициализировал. Точнее
инициализировал, но неинициализированными значениями. Как-то я не замечал раньше за валгриндом такой манеры. Давно не пользовался пожалуй.
bar
Senior
Posts: 185
Joined: 07 Aug 2006 10:18

Post by bar »

Вобщем я думал о том, чтобы переписать CEDAR, и даже пытался это сделать. Но, с учётом того, что там надо переписывать всё -- а с учётом того, что он где-то имеет проблемы с wxWidgets в процессе сборки, значит вообще всё надо переписывать. И сейчас мне надоело переписывать cedar кусочками, и ваяя очередной кусочек думать о том как его вложить в cedar.
С теми же мьютексами и синхронизацией: ребята, по-моему, вообще с дуба рухнули писать то, что они написали. Есть ими созданная очередь сообщений, на которую подвязана вся работа программы. Они лочат эту очередь, и в течение одного лока начинают выуживать оттуда сообщения и рассылать их дальше. В процессе рассылки какой-нибудь код решает, что ему надо отправить сообщение, пытается залочить очередь, чтобы добавить туда сообщение -- а она уже залочена. Как это у них вообще работало -- я не знаю. Может мьютексы на вендовс позволяют одному треду лочить себя много раз? По науке, тут надо делать гораздо аккуратнее: залочить очередь, вынуть сообщение, разлочить очередь, обработать сообщение. Либо так: залочить очередь, вынуть все сообщения, разлочить очередь, обработать сообщения.
Я сделал по второму варианту -- и, есть у меня предположение, что непонятности в работе CEDAR вызваны именно этим: ведь семантика моего подхода несколько иная: в момент когда весь этот цикл обработки сообщений завершится в очереди могут оставаться необработанные сообщения -- те которые там появились в процессе обработки существующих.
Но если я прав, и именно это вызывает непонятности в работе -- то это же вообще ппц. Привязывать логику работы программы к тому, что сообщения будут обработаны именно в этом вызове OnIdle или OnTimer -- ну это же однозначно получать совершенно непредсказуемое поведение.

Ну вот и что можно сделать со всем этим? Сидеть и переписывать и отлаживать? Или может выкинуть ту очередь, взять систему ивентов из glib и сделать на ней? Но чтобы взять систему ивентов из glib, надо чтобы в программе были бы классы производные от Glib::Object. Да и вообще если с glib, то там всё совершенно иначе делается. Можно, конечно, перепахать CEDAR под ту архитектуру. А потом перепахивать его раз за разом, исправляя то один косяк, то другой. Мне кажется, быстрее и проще написать с нуля.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

можно на обычный юниксовый MessageQueue переписать...

а вообще мьютекс можно создать так, чтобы один и тот же тред мог его лочить много раз - я с этим сталкивался на экзотических операционках для телевизионных приставок...
Я тут за главного - если что шлите мыло на me собака shaos точка net